View Javadoc
1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.wss4j.stax.impl.processor.input;
20  
21  import java.util.Deque;
22  
23  import javax.xml.stream.XMLStreamException;
24  import javax.xml.stream.events.Attribute;
25  
26  import org.apache.wss4j.common.ext.WSSecurityException;
27  import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
28  import org.apache.wss4j.stax.ext.WSSConstants;
29  import org.apache.wss4j.stax.ext.WSSSecurityProperties;
30  import org.apache.xml.security.binding.xmlenc.ReferenceList;
31  import org.apache.xml.security.binding.xmlenc.ReferenceType;
32  import org.apache.xml.security.exceptions.XMLSecurityException;
33  import org.apache.xml.security.stax.ext.AbstractInputProcessor;
34  import org.apache.xml.security.stax.ext.AbstractInputSecurityHeaderHandler;
35  import org.apache.xml.security.stax.ext.InputProcessor;
36  import org.apache.xml.security.stax.ext.InputProcessorChain;
37  import org.apache.xml.security.stax.ext.XMLSecurityConstants;
38  import org.apache.xml.security.stax.ext.XMLSecurityProperties;
39  import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
40  import org.apache.xml.security.stax.ext.stax.XMLSecStartElement;
41  
42  /**
43   * Processor for the EncryptedData XML Structure in the security header.
44   * Note, this handler is special in respect to when it is called: it is triggered by the
45   * EncryptedData StartElement and not when the EndElement occurs. @see comments in SecurityHeaderInputProcessort
46   */
47  public class EncryptedDataInputHandler extends AbstractInputSecurityHeaderHandler {
48  
49      @Override
50      public void handle(final InputProcessorChain inputProcessorChain, final XMLSecurityProperties securityProperties,
51                         final Deque<XMLSecEvent> eventQueue, final Integer index) throws XMLSecurityException {
52  
53          XMLSecEvent xmlSecEvent = eventQueue.pollFirst();
54          if (!(xmlSecEvent instanceof XMLSecStartElement)) {
55              throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE);
56          }
57          final XMLSecStartElement encryptedDataElement = xmlSecEvent.asStartElement();
58          final Attribute idAttribute = encryptedDataElement.getAttributeByName(XMLSecurityConstants.ATT_NULL_Id);
59  
60          DecryptInputProcessor decryptInputProcessor =
61                  new DecryptInputProcessor(null, new ReferenceList(), (WSSSecurityProperties) securityProperties,
62                          (WSInboundSecurityContext) inputProcessorChain.getSecurityContext()) {
63  
64                      @Override
65                      protected ReferenceType matchesReferenceId(XMLSecStartElement xmlSecStartElement) {
66                          if (xmlSecStartElement == encryptedDataElement) {
67                              ReferenceType referenceType = new ReferenceType();
68                              if (idAttribute != null) {
69                                  final String uri = idAttribute.getValue();
70                                  referenceType.setURI("#" + uri);
71                                  inputProcessorChain.getSecurityContext().putAsList(WSSConstants.PROP_ENCRYPTED_DATA_REFS, uri);
72                              }
73                              return referenceType;
74                          }
75                          return null;
76                      }
77                  };
78          inputProcessorChain.addProcessor(decryptInputProcessor);
79  
80          //replay the EncryptedData event for the DecryptInputProcessor:
81          InputProcessor tmpProcessor = new AbstractInputProcessor(securityProperties) {
82              @Override
83              public XMLSecEvent processHeaderEvent(InputProcessorChain inputProcessorChain)
84                  throws XMLStreamException, XMLSecurityException {
85                  inputProcessorChain.removeProcessor(this);
86                  return encryptedDataElement;
87              }
88  
89              @Override
90              public XMLSecEvent processEvent(InputProcessorChain inputProcessorChain)
91                  throws XMLStreamException, XMLSecurityException {
92                  inputProcessorChain.removeProcessor(this);
93                  return encryptedDataElement;
94              }
95          };
96          tmpProcessor.addBeforeProcessor(decryptInputProcessor);
97          inputProcessorChain.addProcessor(tmpProcessor);
98      }
99  }