1 /*
2  * reserved comment block
3  * DO NOT REMOVE OR ALTER!
4  */
5 /**
6  * Licensed to the Apache Software Foundation (ASF) under one
7  * or more contributor license agreements. See the NOTICE file
8  * distributed with this work for additional information
9  * regarding copyright ownership. The ASF licenses this file
10  * to you under the Apache License, Version 2.0 (the
11  * "License"); you may not use this file except in compliance
12  * with the License. You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing,
17  * software distributed under the License is distributed on an
18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  * KIND, either express or implied. See the License for the
20  * specific language governing permissions and limitations
21  * under the License.
22  */
23 package com.sun.org.apache.xml.internal.security.transforms.implementations;
24 
25 import java.io.OutputStream;
26 
27 import com.sun.org.apache.xml.internal.security.signature.NodeFilter;
28 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
29 import com.sun.org.apache.xml.internal.security.transforms.Transform;
30 import com.sun.org.apache.xml.internal.security.transforms.TransformSpi;
31 import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
32 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
33 import com.sun.org.apache.xml.internal.security.utils.Constants;
34 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
35 import org.w3c.dom.Element;
36 import org.w3c.dom.Node;
37 
38 /**
39  * Implements the {@code http://www.w3.org/2000/09/xmldsig#enveloped-signature}
40  * transform.
41  *
42  */
43 public class TransformEnvelopedSignature extends TransformSpi {
44 
45     /** Field implementedTransformURI */
46     public static final String implementedTransformURI =
47         Transforms.TRANSFORM_ENVELOPED_SIGNATURE;
48 
49     /**
50      * Method engineGetURI
51      *
52      * {@inheritDoc}
53      */
engineGetURI()54     protected String engineGetURI() {
55         return implementedTransformURI;
56     }
57 
58     /**
59      * {@inheritDoc}
60      */
enginePerformTransform( XMLSignatureInput input, OutputStream os, Transform transformObject )61     protected XMLSignatureInput enginePerformTransform(
62         XMLSignatureInput input, OutputStream os, Transform transformObject
63     ) throws TransformationException {
64         /**
65          * If the actual input is an octet stream, then the application MUST
66          * convert the octet stream to an XPath node-set suitable for use by
67          * Canonical XML with Comments. (A subsequent application of the
68          * REQUIRED Canonical XML algorithm would strip away these comments.)
69          *
70          * ...
71          *
72          * The evaluation of this expression includes all of the document's nodes
73          * (including comments) in the node-set representing the octet stream.
74          */
75 
76         Node signatureElement = transformObject.getElement();
77 
78         signatureElement = searchSignatureElement(signatureElement);
79         input.setExcludeNode(signatureElement);
80         input.addNodeFilter(new EnvelopedNodeFilter(signatureElement));
81         return input;
82     }
83 
84     /**
85      * @param signatureElement
86      * @return the node that is the signature
87      * @throws TransformationException
88      */
searchSignatureElement(Node signatureElement)89     private static Node searchSignatureElement(Node signatureElement)
90         throws TransformationException {
91         boolean found = false;
92 
93         while (true) {
94             if (signatureElement == null
95                 || signatureElement.getNodeType() == Node.DOCUMENT_NODE) {
96                 break;
97             }
98             Element el = (Element) signatureElement;
99             if (el.getNamespaceURI().equals(Constants.SignatureSpecNS)
100                 && el.getLocalName().equals(Constants._TAG_SIGNATURE)) {
101                 found = true;
102                 break;
103             }
104 
105             signatureElement = signatureElement.getParentNode();
106         }
107 
108         if (!found) {
109             throw new TransformationException(
110                 "transform.envelopedSignatureTransformNotInSignatureElement");
111         }
112         return signatureElement;
113     }
114 
115     static class EnvelopedNodeFilter implements NodeFilter {
116 
117         Node exclude;
118 
EnvelopedNodeFilter(Node n)119         EnvelopedNodeFilter(Node n) {
120             exclude = n;
121         }
122 
isNodeIncludeDO(Node n, int level)123         public int isNodeIncludeDO(Node n, int level) {
124             if (n == exclude) {
125                 return -1;
126             }
127             return 1;
128         }
129 
130         /**
131          * @see com.sun.org.apache.xml.internal.security.signature.NodeFilter#isNodeInclude(org.w3c.dom.Node)
132          */
isNodeInclude(Node n)133         public int isNodeInclude(Node n) {
134             if (n == exclude || XMLUtils.isDescendantOrSelf(exclude, n)) {
135                 return -1;
136             }
137             return 1;
138             //return !XMLUtils.isDescendantOrSelf(exclude, n);
139         }
140     }
141 }
142