| 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
/**  | 
 | 
 * Licensed to the Apache Software Foundation (ASF) under one  | 
 | 
 * or more contributor license agreements. See the NOTICE file  | 
 | 
 * distributed with this work for additional information  | 
 | 
 * regarding copyright ownership. The ASF licenses this file  | 
 | 
 * to you under the Apache License, Version 2.0 (the  | 
 | 
 * "License"); you may not use this file except in compliance  | 
 | 
 * with the License. You may obtain a copy of the License at  | 
 | 
 *  | 
 | 
 * http://www.apache.org/licenses/LICENSE-2.0  | 
 | 
 *  | 
 | 
 * Unless required by applicable law or agreed to in writing,  | 
 | 
 * software distributed under the License is distributed on an  | 
 | 
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY  | 
 | 
 * KIND, either express or implied. See the License for the  | 
 | 
 * specific language governing permissions and limitations  | 
 | 
 * under the License.  | 
 | 
 */  | 
 | 
/*  | 
 | 
 * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.  | 
 | 
 */  | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
package org.jcp.xml.dsig.internal.dom;  | 
 | 
 | 
 | 
import java.io.OutputStream;  | 
 | 
import java.security.InvalidAlgorithmParameterException;  | 
 | 
import java.security.spec.AlgorithmParameterSpec;  | 
 | 
import java.util.Set;  | 
 | 
 | 
 | 
import org.w3c.dom.Document;  | 
 | 
import org.w3c.dom.Element;  | 
 | 
import org.w3c.dom.Node;  | 
 | 
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;  | 
 | 
import com.sun.org.apache.xml.internal.security.transforms.Transform;  | 
 | 
 | 
 | 
import javax.xml.crypto.*;  | 
 | 
import javax.xml.crypto.dom.DOMCryptoContext;  | 
 | 
import javax.xml.crypto.dsig.*;  | 
 | 
import javax.xml.crypto.dsig.spec.TransformParameterSpec;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public abstract class ApacheTransform extends TransformService { | 
 | 
 | 
 | 
    static { | 
 | 
        com.sun.org.apache.xml.internal.security.Init.init();  | 
 | 
    }  | 
 | 
 | 
 | 
    private static final com.sun.org.slf4j.internal.Logger LOG =  | 
 | 
        com.sun.org.slf4j.internal.LoggerFactory.getLogger(ApacheTransform.class);  | 
 | 
    private Transform apacheTransform;  | 
 | 
    protected Document ownerDoc;  | 
 | 
    protected Element transformElem;  | 
 | 
    protected TransformParameterSpec params;  | 
 | 
 | 
 | 
    @Override  | 
 | 
    public final AlgorithmParameterSpec getParameterSpec() { | 
 | 
        return params;  | 
 | 
    }  | 
 | 
 | 
 | 
    public void init(XMLStructure parent, XMLCryptoContext context)  | 
 | 
        throws InvalidAlgorithmParameterException  | 
 | 
    { | 
 | 
        if (context != null && !(context instanceof DOMCryptoContext)) { | 
 | 
            throw new ClassCastException  | 
 | 
                ("context must be of type DOMCryptoContext"); | 
 | 
        }  | 
 | 
        if (parent == null) { | 
 | 
            throw new NullPointerException();  | 
 | 
        }  | 
 | 
        if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { | 
 | 
            throw new ClassCastException("parent must be of type DOMStructure"); | 
 | 
        }  | 
 | 
        transformElem = (Element)  | 
 | 
            ((javax.xml.crypto.dom.DOMStructure) parent).getNode();  | 
 | 
        ownerDoc = DOMUtils.getOwnerDocument(transformElem);  | 
 | 
    }  | 
 | 
 | 
 | 
    public void marshalParams(XMLStructure parent, XMLCryptoContext context)  | 
 | 
        throws MarshalException  | 
 | 
    { | 
 | 
        if (context != null && !(context instanceof DOMCryptoContext)) { | 
 | 
            throw new ClassCastException  | 
 | 
                ("context must be of type DOMCryptoContext"); | 
 | 
        }  | 
 | 
        if (parent == null) { | 
 | 
            throw new NullPointerException();  | 
 | 
        }  | 
 | 
        if (!(parent instanceof javax.xml.crypto.dom.DOMStructure)) { | 
 | 
            throw new ClassCastException("parent must be of type DOMStructure"); | 
 | 
        }  | 
 | 
        transformElem = (Element)  | 
 | 
            ((javax.xml.crypto.dom.DOMStructure) parent).getNode();  | 
 | 
        ownerDoc = DOMUtils.getOwnerDocument(transformElem);  | 
 | 
    }  | 
 | 
 | 
 | 
    public Data transform(Data data, XMLCryptoContext xc)  | 
 | 
        throws TransformException  | 
 | 
    { | 
 | 
        if (data == null) { | 
 | 
            throw new NullPointerException("data must not be null"); | 
 | 
        }  | 
 | 
        return transformIt(data, xc, null);  | 
 | 
    }  | 
 | 
 | 
 | 
    public Data transform(Data data, XMLCryptoContext xc, OutputStream os)  | 
 | 
        throws TransformException  | 
 | 
    { | 
 | 
        if (data == null) { | 
 | 
            throw new NullPointerException("data must not be null"); | 
 | 
        }  | 
 | 
        if (os == null) { | 
 | 
            throw new NullPointerException("output stream must not be null"); | 
 | 
        }  | 
 | 
        return transformIt(data, xc, os);  | 
 | 
    }  | 
 | 
 | 
 | 
    private Data transformIt(Data data, XMLCryptoContext xc, OutputStream os)  | 
 | 
        throws TransformException  | 
 | 
    { | 
 | 
        if (ownerDoc == null) { | 
 | 
            throw new TransformException("transform must be marshalled"); | 
 | 
        }  | 
 | 
 | 
 | 
        if (apacheTransform == null) { | 
 | 
            try { | 
 | 
                apacheTransform =  | 
 | 
                    new Transform(ownerDoc, getAlgorithm(), transformElem.getChildNodes());  | 
 | 
                apacheTransform.setElement(transformElem, xc.getBaseURI());  | 
 | 
                boolean secVal = Utils.secureValidation(xc);  | 
 | 
                apacheTransform.setSecureValidation(secVal);  | 
 | 
                LOG.debug("Created transform for algorithm: {}", getAlgorithm()); | 
 | 
            } catch (Exception ex) { | 
 | 
                throw new TransformException("Couldn't find Transform for: " + | 
 | 
                                             getAlgorithm(), ex);  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        if (Utils.secureValidation(xc)) { | 
 | 
            String algorithm = getAlgorithm();  | 
 | 
            if (Policy.restrictAlg(algorithm)) { | 
 | 
                throw new TransformException(  | 
 | 
                    "Transform " + algorithm + " is forbidden when secure validation is enabled"  | 
 | 
                );  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        XMLSignatureInput in;  | 
 | 
        if (data instanceof ApacheData) { | 
 | 
            LOG.debug("ApacheData = true"); | 
 | 
            in = ((ApacheData)data).getXMLSignatureInput();  | 
 | 
        } else if (data instanceof NodeSetData) { | 
 | 
            LOG.debug("isNodeSet() = true"); | 
 | 
            if (data instanceof DOMSubTreeData) { | 
 | 
                LOG.debug("DOMSubTreeData = true"); | 
 | 
                DOMSubTreeData subTree = (DOMSubTreeData)data;  | 
 | 
                in = new XMLSignatureInput(subTree.getRoot());  | 
 | 
                in.setExcludeComments(subTree.excludeComments());  | 
 | 
            } else { | 
 | 
                @SuppressWarnings("unchecked") | 
 | 
                Set<Node> nodeSet =  | 
 | 
                    Utils.toNodeSet(((NodeSetData)data).iterator());  | 
 | 
                in = new XMLSignatureInput(nodeSet);  | 
 | 
            }  | 
 | 
        } else { | 
 | 
            LOG.debug("isNodeSet() = false"); | 
 | 
            try { | 
 | 
                in = new XMLSignatureInput  | 
 | 
                    (((OctetStreamData)data).getOctetStream());  | 
 | 
            } catch (Exception ex) { | 
 | 
                throw new TransformException(ex);  | 
 | 
            }  | 
 | 
        }  | 
 | 
        boolean secVal = Utils.secureValidation(xc);  | 
 | 
        in.setSecureValidation(secVal);  | 
 | 
 | 
 | 
        try { | 
 | 
            if (os != null) { | 
 | 
                in = apacheTransform.performTransform(in, os);  | 
 | 
                if (!in.isNodeSet() && !in.isElement()) { | 
 | 
                    return null;  | 
 | 
                }  | 
 | 
            } else { | 
 | 
                in = apacheTransform.performTransform(in);  | 
 | 
            }  | 
 | 
            if (in.isOctetStream()) { | 
 | 
                return new ApacheOctetStreamData(in);  | 
 | 
            } else { | 
 | 
                return new ApacheNodeSetData(in);  | 
 | 
            }  | 
 | 
        } catch (Exception ex) { | 
 | 
            throw new TransformException(ex);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    public final boolean isFeatureSupported(String feature) { | 
 | 
        if (feature == null) { | 
 | 
            throw new NullPointerException();  | 
 | 
        } else { | 
 | 
            return false;  | 
 | 
        }  | 
 | 
    }  | 
 | 
}  |