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.transformer;
20  
21  import org.apache.wss4j.common.ext.Attachment;
22  import org.apache.wss4j.common.util.CRLFOutputStream;
23  import org.apache.xml.security.exceptions.XMLSecurityException;
24  import org.apache.xml.security.stax.ext.XMLSecurityConstants;
25  import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
26  import org.apache.xml.security.stax.impl.transformer.TransformIdentity;
27  import org.apache.xml.security.stax.impl.transformer.canonicalizer.Canonicalizer20010315_ExclOmitCommentsTransformer;
28  
29  import javax.xml.stream.XMLStreamException;
30  
31  import java.io.InputStream;
32  import java.util.Map;
33  
34  public class AttachmentContentSignatureTransform extends TransformIdentity {
35  
36      public static final String ATTACHMENT = "attachment";
37  
38      private Attachment attachment;
39  
40      @Override
41      public XMLSecurityConstants.TransformMethod getPreferredTransformMethod(XMLSecurityConstants.TransformMethod forInput) {
42          switch (forInput) {
43              case XMLSecEvent:
44                  return XMLSecurityConstants.TransformMethod.InputStream;
45              case InputStream:
46                  return XMLSecurityConstants.TransformMethod.InputStream;
47              default:
48                  throw new IllegalArgumentException("Unsupported class " + forInput.name());
49          }
50      }
51  
52      @Override
53      public void setProperties(Map<String, Object> properties) throws XMLSecurityException {
54          this.attachment = (Attachment) properties.get(ATTACHMENT);
55      }
56  
57      protected Attachment getAttachment() {
58          return attachment;
59      }
60  
61      /*
62               * http://docs.oasis-open.org/wss-m/wss/v1.1.1/os/wss-SwAProfile-v1.1.1-os.html
63               * 5.2 Referencing Attachments
64               * This profile assumes, since it is not defined in RFC 2396 Section 4.2, that
65               * all cid: references are not same-document references and that therefore, under
66               * XMLDSIG, dereferencing a cid: URI always yields an octet stream as input to the
67               * transform chain [RFC2396], [XMLDSIG].
68               */
69      @Override
70      public void transform(XMLSecEvent xmlSecEvent) throws XMLStreamException {
71          throw new UnsupportedOperationException("transform(XMLSecEvent) not allowed");
72      }
73  
74      @Override
75      public void transform(InputStream inputStream) throws XMLStreamException {
76          String mimeType = getAttachment().getMimeType();
77  
78          if (mimeType != null
79              && (mimeType.matches("(?i)(text/xml).*")
80                  || mimeType.matches("(?i)(application/xml).*")
81                  || mimeType.matches("(?i)(application|image)/.*\\+xml.*"))) {
82              /* 5.4.2:
83               * Content of an XML Content-Type MUST be XML canonicalized using
84               * Exclusive XML Canonicalization without comments, as specified by
85               * the URI http://www.w3.org/2001/10/xml-exc-c14n# [Excl-Canon].
86               * The reason for requiring Exclusive Canonicalization is that many
87               * implementations will support Exclusive Canonicalization for other
88               * XML Signature purposes, since this form of canonicalization
89               * supports context changes. The InclusiveNamespace PrefixList
90               * attribute SHOULD be empty or not present.
91               */
92              Canonicalizer20010315_ExclOmitCommentsTransformer canon =
93                      new Canonicalizer20010315_ExclOmitCommentsTransformer();
94              try {
95                  canon.setOutputStream(getOutputStream());
96              } catch (XMLSecurityException e) {
97                  throw new XMLStreamException(e);
98              }
99              canon.transform(inputStream);
100 
101         } else if (mimeType != null && mimeType.matches("(?i)(text/).*")) {
102             CRLFOutputStream crlfOutputStream = new CRLFOutputStream(getOutputStream());    //NOPMD
103             try {
104                 setOutputStream(crlfOutputStream);
105             } catch (XMLSecurityException e) {
106                 throw new XMLStreamException(e);
107             }
108             super.transform(inputStream);
109         } else {
110             super.transform(inputStream);
111         }
112     }
113 }