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.dom.transform;
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.IOException;
24  import java.io.OutputStream;
25  
26  import org.apache.jcp.xml.dsig.internal.dom.ApacheOctetStreamData;
27  import org.apache.wss4j.common.ext.Attachment;
28  import org.apache.wss4j.common.util.AttachmentUtils;
29  import org.apache.wss4j.dom.WSConstants;
30  
31  import javax.xml.crypto.Data;
32  import javax.xml.crypto.OctetStreamData;
33  import javax.xml.crypto.XMLCryptoContext;
34  import javax.xml.crypto.dsig.TransformException;
35  
36  public class AttachmentCompleteSignatureTransform extends AttachmentContentSignatureTransform {
37  
38      public static final String TRANSFORM_URI = WSConstants.SWA_ATTACHMENT_COMPLETE_SIG_TRANS;
39  
40      @Override
41      public Data transform(Data data, XMLCryptoContext context) throws TransformException {
42          return transform(data, context, null);
43      }
44  
45      /*
46       * http://docs.oasis-open.org/wss-m/wss/v1.1.1/os/wss-SwAProfile-v1.1.1-os.html
47       * 5.2 Referencing Attachments
48       * This profile assumes, since it is not defined in RFC 2396 Section 4.2, that
49       * all cid: references are not same-document references and that therefore, under
50       * XMLDSIG, dereferencing a cid: URI always yields an octet stream as input to the
51       * transform chain [RFC2396], [XMLDSIG].
52       */
53      @Override
54      public Data transform(Data data, XMLCryptoContext context, OutputStream os) throws TransformException {
55  
56          String attachmentUri = ((ApacheOctetStreamData) data).getURI();
57          String attachmentId = attachmentUri.substring(4);
58  
59          AttachmentTransformParameterSpec attachmentTransformParameterSpec = getAttachmentTransformParameterSpec();
60  
61          Attachment attachment;
62          if (attachmentTransformParameterSpec != null) {
63              attachment = attachmentTransformParameterSpec.getAttachment();
64              context.setProperty(ATTACHMENT_CALLBACKHANDLER,
65                                  attachmentTransformParameterSpec.getAttachmentCallbackHandler());
66          } else {
67              attachment = attachmentRequestCallback(context, attachmentId);
68          }
69  
70          try {
71              OutputStream outputStream = os;
72              if (outputStream == null) {
73                  outputStream = new ByteArrayOutputStream(); //NOPMD
74              }
75              AttachmentUtils.canonizeMimeHeaders(os, attachment.getHeaders());
76              processAttachment(context, os, attachmentUri, attachment);
77  
78              if (os == null) {
79                  String mimeType = attachment.getMimeType();
80                  return new OctetStreamData(
81                          new ByteArrayInputStream(
82                                  ((ByteArrayOutputStream)outputStream).toByteArray()
83                          ),
84                          attachmentUri, mimeType);
85              }
86              return null;
87          } catch (IOException e) {
88              throw new TransformException(e);
89          }
90      }
91  
92      @Override
93      public boolean isFeatureSupported(String feature) {
94          if (feature == null) {
95              throw new NullPointerException();
96          } else {
97              return false;
98          }
99      }
100 }