ApacheTransform.java revision 11001:3e276a212a96
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/*
24 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
25 */
26/*
27 * $Id: ApacheTransform.java 1333869 2012-05-04 10:42:44Z coheigea $
28 */
29package org.jcp.xml.dsig.internal.dom;
30
31import java.io.OutputStream;
32import java.security.InvalidAlgorithmParameterException;
33import java.security.spec.AlgorithmParameterSpec;
34import java.util.Set;
35import org.w3c.dom.Document;
36import org.w3c.dom.Element;
37import org.w3c.dom.Node;
38
39import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
40import com.sun.org.apache.xml.internal.security.transforms.Transform;
41import com.sun.org.apache.xml.internal.security.transforms.Transforms;
42
43import javax.xml.crypto.*;
44import javax.xml.crypto.dom.DOMCryptoContext;
45import javax.xml.crypto.dsig.*;
46import javax.xml.crypto.dsig.spec.TransformParameterSpec;
47
48/**
49 * This is a wrapper/glue class which invokes the Apache XML-Security
50 * Transform.
51 *
52 * @author Sean Mullan
53 * @author Erwin van der Koogh
54 */
55public abstract class ApacheTransform extends TransformService {
56
57    static {
58        com.sun.org.apache.xml.internal.security.Init.init();
59    }
60
61    private static java.util.logging.Logger log =
62        java.util.logging.Logger.getLogger("org.jcp.xml.dsig.internal.dom");
63    private Transform apacheTransform;
64    protected Document ownerDoc;
65    protected Element transformElem;
66    protected TransformParameterSpec params;
67
68    public final AlgorithmParameterSpec getParameterSpec() {
69        return params;
70    }
71
72    public void init(XMLStructure parent, XMLCryptoContext context)
73        throws InvalidAlgorithmParameterException
74    {
75        if (context != null && !(context instanceof DOMCryptoContext)) {
76            throw new ClassCastException
77                ("context must be of type DOMCryptoContext");
78        }
79        if (parent == null) {
80            throw new NullPointerException();
81        }
82        if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) {
83            throw new ClassCastException("parent must be of type DOMStructure");
84        }
85        transformElem = (Element)
86            ((javax.xml.crypto.dom.DOMStructure) parent).getNode();
87        ownerDoc = DOMUtils.getOwnerDocument(transformElem);
88    }
89
90    public void marshalParams(XMLStructure parent, XMLCryptoContext context)
91        throws MarshalException
92    {
93        if (context != null && !(context instanceof DOMCryptoContext)) {
94            throw new ClassCastException
95                ("context must be of type DOMCryptoContext");
96        }
97        if (parent == null) {
98            throw new NullPointerException();
99        }
100        if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) {
101            throw new ClassCastException("parent must be of type DOMStructure");
102        }
103        transformElem = (Element)
104            ((javax.xml.crypto.dom.DOMStructure) parent).getNode();
105        ownerDoc = DOMUtils.getOwnerDocument(transformElem);
106    }
107
108    public Data transform(Data data, XMLCryptoContext xc)
109        throws TransformException
110    {
111        if (data == null) {
112            throw new NullPointerException("data must not be null");
113        }
114        return transformIt(data, xc, (OutputStream)null);
115    }
116
117    public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
118        throws TransformException
119    {
120        if (data == null) {
121            throw new NullPointerException("data must not be null");
122        }
123        if (os == null) {
124            throw new NullPointerException("output stream must not be null");
125        }
126        return transformIt(data, xc, os);
127    }
128
129    private Data transformIt(Data data, XMLCryptoContext xc, OutputStream os)
130        throws TransformException
131    {
132        if (ownerDoc == null) {
133            throw new TransformException("transform must be marshalled");
134        }
135
136        if (apacheTransform == null) {
137            try {
138                apacheTransform =
139                    new Transform(ownerDoc, getAlgorithm(), transformElem.getChildNodes());
140                apacheTransform.setElement(transformElem, xc.getBaseURI());
141                if (log.isLoggable(java.util.logging.Level.FINE)) {
142                    log.log(java.util.logging.Level.FINE, "Created transform for algorithm: " +
143                            getAlgorithm());
144                }
145            } catch (Exception ex) {
146                throw new TransformException("Couldn't find Transform for: " +
147                                             getAlgorithm(), ex);
148            }
149        }
150
151        if (Utils.secureValidation(xc)) {
152            String algorithm = getAlgorithm();
153            if (Transforms.TRANSFORM_XSLT.equals(algorithm)) {
154                throw new TransformException(
155                    "Transform " + algorithm + " is forbidden when secure validation is enabled"
156                );
157            }
158        }
159
160        XMLSignatureInput in;
161        if (data instanceof ApacheData) {
162            if (log.isLoggable(java.util.logging.Level.FINE)) {
163                log.log(java.util.logging.Level.FINE, "ApacheData = true");
164            }
165            in = ((ApacheData)data).getXMLSignatureInput();
166        } else if (data instanceof NodeSetData) {
167            if (log.isLoggable(java.util.logging.Level.FINE)) {
168                log.log(java.util.logging.Level.FINE, "isNodeSet() = true");
169            }
170            if (data instanceof DOMSubTreeData) {
171                if (log.isLoggable(java.util.logging.Level.FINE)) {
172                    log.log(java.util.logging.Level.FINE, "DOMSubTreeData = true");
173                }
174                DOMSubTreeData subTree = (DOMSubTreeData)data;
175                in = new XMLSignatureInput(subTree.getRoot());
176                in.setExcludeComments(subTree.excludeComments());
177            } else {
178                Set<Node> nodeSet =
179                    Utils.toNodeSet(((NodeSetData)data).iterator());
180                in = new XMLSignatureInput(nodeSet);
181            }
182        } else {
183            if (log.isLoggable(java.util.logging.Level.FINE)) {
184                log.log(java.util.logging.Level.FINE, "isNodeSet() = false");
185            }
186            try {
187                in = new XMLSignatureInput
188                    (((OctetStreamData)data).getOctetStream());
189            } catch (Exception ex) {
190                throw new TransformException(ex);
191            }
192        }
193
194        try {
195            if (os != null) {
196                in = apacheTransform.performTransform(in, os);
197                if (!in.isNodeSet() && !in.isElement()) {
198                    return null;
199                }
200            } else {
201                in = apacheTransform.performTransform(in);
202            }
203            if (in.isOctetStream()) {
204                return new ApacheOctetStreamData(in);
205            } else {
206                return new ApacheNodeSetData(in);
207            }
208        } catch (Exception ex) {
209            throw new TransformException(ex);
210        }
211    }
212
213    public final boolean isFeatureSupported(String feature) {
214        if (feature == null) {
215            throw new NullPointerException();
216        } else {
217            return false;
218        }
219    }
220}
221