| |
| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 1999 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "<WebSig>" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 2001, Institute for |
| * Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>. |
| * The development of this software was partly funded by the European |
| * Commission in the <WebSig> project in the ISIS Programme. |
| * For more information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| package org.apache.xml.security.signature; |
| |
| |
| |
| import java.io.IOException; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.apache.xml.security.algorithms.MessageDigestAlgorithm; |
| import org.apache.xml.security.c14n.CanonicalizationException; |
| import org.apache.xml.security.c14n.InvalidCanonicalizerException; |
| import org.apache.xml.security.exceptions.Base64DecodingException; |
| import org.apache.xml.security.exceptions.XMLSecurityException; |
| import org.apache.xml.security.transforms.InvalidTransformException; |
| import org.apache.xml.security.transforms.Transform; |
| import org.apache.xml.security.transforms.TransformationException; |
| import org.apache.xml.security.transforms.Transforms; |
| import org.apache.xml.security.transforms.params.InclusiveNamespaces; |
| import org.apache.xml.security.utils.Base64; |
| import org.apache.xml.security.utils.Constants; |
| import org.apache.xml.security.utils.IdResolver; |
| import org.apache.xml.security.utils.SignatureElementProxy; |
| import org.apache.xml.security.utils.XMLUtils; |
| import org.apache.xml.security.utils.resolver.ResourceResolver; |
| import org.apache.xml.security.utils.resolver.ResourceResolverException; |
| import org.w3c.dom.Attr; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| import org.w3c.dom.Text; |
| |
| |
| /** |
| * Handles <code><ds:Reference></code> elements. |
| * |
| * This includes: |
| * |
| * Constuct a <CODE>ds:Reference</CODE> from an {@link org.w3c.dom.Element}. |
| * |
| * <p>Create a new reference</p> |
| * <pre> |
| * Document _doc; |
| * MessageDigestAlgorithm sha1 = MessageDigestAlgorithm.getInstance("http://#sha1"); |
| * Reference ref = new Reference(new XMLSignatureInput(new FileInputStream("1.gif"), |
| * "http://localhost/1.gif", |
| * (Transforms) null, sha1); |
| * Element refElem = ref.toElement(_doc); |
| * </pre> |
| * |
| * <p>Verify a reference</p> |
| * <pre> |
| * Element refElem = _doc.getElement("Reference"); // PSEUDO |
| * Reference ref = new Reference(refElem); |
| * String url = ref.getURI(); |
| * ref.setData(new XMLSignatureInput(new FileInputStream(url))); |
| * if (ref.verify()) { |
| * System.out.println("verified"); |
| * } |
| * </pre> |
| * |
| * <pre> |
| * <element name="Reference" type="ds:ReferenceType"/> |
| * <complexType name="ReferenceType"> |
| * <sequence> |
| * <element ref="ds:Transforms" minOccurs="0"/> |
| * <element ref="ds:DigestMethod"/> |
| * <element ref="ds:DigestValue"/> |
| * </sequence> |
| * <attribute name="Id" type="ID" use="optional"/> |
| * <attribute name="URI" type="anyURI" use="optional"/> |
| * <attribute name="Type" type="anyURI" use="optional"/> |
| * </complexType> |
| * </pre> |
| * |
| * @author Christian Geuer-Pollmann |
| * @see ObjectContainer |
| * @see Manifest |
| */ |
| public class Reference extends SignatureElementProxy { |
| |
| /** Field CacheSignedNodes */ |
| public static boolean CacheSignedNodes = false; |
| |
| /** {@link org.apache.commons.logging} logging facility */ |
| static org.apache.commons.logging.Log log = |
| org.apache.commons.logging.LogFactory.getLog(Reference.class.getName()); |
| |
| /** Field OBJECT_URI */ |
| public static final String OBJECT_URI = Constants.SignatureSpecNS |
| + Constants._TAG_OBJECT; |
| |
| /** Field MANIFEST_URI */ |
| public static final String MANIFEST_URI = Constants.SignatureSpecNS |
| + Constants._TAG_MANIFEST; |
| //J- |
| Manifest _manifest = null; |
| XMLSignatureInput _transformsInput; |
| XMLSignatureInput _transformsOutput; |
| //J+ |
| |
| /** |
| * Constructor Reference |
| * |
| * @param doc the {@link Document} in which <code>XMLsignature</code> is placed |
| * @param BaseURI the URI of the resource where the XML instance will be stored |
| * @param ReferenceURI URI indicate where is data which will digested |
| * @param manifest |
| * @param transforms {@link Transforms} applied to data |
| * @param messageDigestAlgorithm {@link MessageDigestAlgorithm Digest algorithm} which is applied to the data |
| * $todo$ should we throw XMLSignatureException if MessageDigestAlgoURI is wrong? |
| * @throws XMLSignatureException |
| */ |
| protected Reference(Document doc, String BaseURI, String ReferenceURI, Manifest manifest, Transforms transforms, String messageDigestAlgorithm) |
| throws XMLSignatureException { |
| |
| super(doc); |
| |
| XMLUtils.addReturnToElement(this._constructionElement); |
| |
| this._baseURI = BaseURI; |
| this._manifest = manifest; |
| |
| this.setURI(ReferenceURI); |
| |
| // important: The ds:Reference must be added to the associated ds:Manifest |
| // or ds:SignedInfo _before_ the this.resolverResult() is called. |
| // this._manifest.appendChild(this._constructionElement); |
| // this._manifest.appendChild(this._doc.createTextNode("\n")); |
| Element nscontext = XMLUtils.createDSctx(this._doc, "ds"); |
| |
| if (transforms != null) { |
| this._constructionElement.appendChild(transforms.getElement()); |
| XMLUtils.addReturnToElement(this._constructionElement); |
| } |
| { |
| MessageDigestAlgorithm mda = |
| MessageDigestAlgorithm.getInstance(this._doc, |
| messageDigestAlgorithm); |
| |
| this._constructionElement.appendChild(mda.getElement()); |
| XMLUtils.addReturnToElement(this._constructionElement); |
| } |
| { |
| Element digestValueElement = |
| XMLUtils.createElementInSignatureSpace(this._doc, |
| Constants._TAG_DIGESTVALUE); |
| |
| this._constructionElement.appendChild(digestValueElement); |
| XMLUtils.addReturnToElement(this._constructionElement); |
| } |
| } |
| |
| /** |
| * Constructor Reference |
| * |
| * @param doc this {@link Document} in which <code>XMLsignature</code> is placed |
| * @param BaseURI the URI of the resource where the XML instance will be stored |
| * @param ReferenceURI This referenceURI indicate where the data will for signature validation |
| * @param manifest |
| * @param messageDigestAlgorithm {@link MessageDigestAlgorithm Digest algorithm} which is applied to the data |
| * @throws XMLSignatureException |
| */ |
| protected Reference(Document doc, String BaseURI, String ReferenceURI, Manifest manifest, String messageDigestAlgorithm) |
| throws XMLSignatureException { |
| this(doc, BaseURI, ReferenceURI, manifest, (Transforms) null, |
| messageDigestAlgorithm); |
| } |
| |
| /** |
| * Constructor Reference |
| * |
| * @param doc this {@link Document} in which <code>XMLsignature</code> is placed |
| * @param BaseURI the URI of the resource where the XML instance will be stored |
| * @param ReferenceURI This referenceURI indicate where the data is for signature validation |
| * @param manifest |
| * @param transforms {@link Transforms} applied to data |
| * @throws XMLSignatureException |
| */ |
| protected Reference(Document doc, String BaseURI, String ReferenceURI, Manifest manifest, Transforms transforms) |
| throws XMLSignatureException { |
| this(doc, BaseURI, ReferenceURI, manifest, transforms, |
| Constants.ALGO_ID_DIGEST_SHA1); |
| } |
| |
| /** |
| * Constructor Reference |
| * |
| * @param doc this {@link Document} in which <code>XMLsignature</code> is placed |
| * @param BaseURI the URI of the resource where the XML instance will be stored |
| * @param ReferenceURI This referenceURI indicate where the data is for signature validation |
| * @param manifest |
| * @throws XMLSignatureException |
| */ |
| protected Reference(Document doc, String BaseURI, String ReferenceURI, Manifest manifest) |
| throws XMLSignatureException { |
| this(doc, BaseURI, ReferenceURI, manifest, (Transforms) null, |
| Constants.ALGO_ID_DIGEST_SHA1); |
| } |
| |
| /** |
| * Build a {@link Reference} from an {@link Element} |
| * |
| * @param element <code>Reference</code> element |
| * @param BaseURI the URI of the resource where the XML instance was stored |
| * @param manifest is the {@link Manifest} of {@link SignedInfo} in which the Reference occurs. We need this because the Manifest has the individual {@link ResourceResolver}s whcih have been set by the user |
| * @throws XMLSecurityException |
| */ |
| protected Reference(Element element, String BaseURI, Manifest manifest) |
| throws XMLSecurityException { |
| |
| super(element, BaseURI); |
| |
| this._manifest = manifest; |
| } |
| |
| /** |
| * Returns {@link MessageDigestAlgorithm} |
| * |
| * |
| * @return {@link MessageDigestAlgorithm} |
| * |
| * @throws XMLSignatureException |
| */ |
| public MessageDigestAlgorithm getMessageDigestAlgorithm() |
| throws XMLSignatureException { |
| |
| Element digestMethodElem = this.getChildElementLocalName(0, |
| Constants.SignatureSpecNS, Constants._TAG_DIGESTMETHOD); |
| |
| if (digestMethodElem == null) { |
| return null; |
| } |
| |
| String uri = digestMethodElem.getAttributeNS(null, |
| Constants._ATT_ALGORITHM); |
| |
| return MessageDigestAlgorithm.getInstance(this._doc, uri); |
| } |
| |
| /** |
| * Sets the <code>URI</code> of this <code>Reference</code> element |
| * |
| * @param URI the <code>URI</code> of this <code>Reference</code> element |
| */ |
| public void setURI(String URI) { |
| |
| if ((this._state == MODE_SIGN) && (URI != null)) { |
| this._constructionElement.setAttributeNS(null, Constants._ATT_URI, |
| URI); |
| } |
| } |
| |
| /** |
| * Returns the <code>URI</code> of this <code>Reference</code> element |
| * |
| * @return URI the <code>URI</code> of this <code>Reference</code> element |
| */ |
| public String getURI() { |
| return this._constructionElement.getAttributeNS(null, Constants._ATT_URI); |
| } |
| |
| /** |
| * Sets the <code>Id</code> attribute of this <code>Reference</code> element |
| * |
| * @param Id the <code>Id</code> attribute of this <code>Reference</code> element |
| */ |
| public void setId(String Id) { |
| |
| if ((this._state == MODE_SIGN) && (Id != null)) { |
| this._constructionElement.setAttributeNS(null, Constants._ATT_ID, Id); |
| IdResolver.registerElementById(this._constructionElement, Id); |
| } |
| } |
| |
| /** |
| * Returns the <code>Id</code> attribute of this <code>Reference</code> element |
| * |
| * @return Id the <code>Id</code> attribute of this <code>Reference</code> element |
| */ |
| public String getId() { |
| return this._constructionElement.getAttributeNS(null, Constants._ATT_ID); |
| } |
| |
| /** |
| * Sets the <code>type</code> atttibute of the Reference indicate whether an <code>ds:Object</code>, <code>ds:SignatureProperty</code>, or <code>ds:Manifest</code> element |
| * |
| * @param Type the <code>type</code> attribute of the Reference |
| */ |
| public void setType(String Type) { |
| |
| if ((this._state == MODE_SIGN) && (Type != null)) { |
| this._constructionElement.setAttributeNS(null, Constants._ATT_TYPE, |
| Type); |
| } |
| } |
| |
| /** |
| * Return the <code>type</code> atttibute of the Reference indicate whether an <code>ds:Object</code>, <code>ds:SignatureProperty</code>, or <code>ds:Manifest</code> element |
| * |
| * @return the <code>type</code> attribute of the Reference |
| */ |
| public String getType() { |
| return this._constructionElement.getAttributeNS(null, |
| Constants._ATT_TYPE); |
| } |
| |
| /** |
| * Method isReferenceToObject |
| * |
| * This returns true if the <CODE>Type</CODE> attribute of the |
| * <CODE>Refernce</CODE> element points to a <CODE>#Object</CODE> element |
| * |
| * @return true if the Reference type indicates that this Reference points to an <code>Object</code> |
| */ |
| public boolean typeIsReferenceToObject() { |
| |
| if ((this.getType() != null) |
| && this.getType().equals(Reference.OBJECT_URI)) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Method isReferenceToManifest |
| * |
| * This returns true if the <CODE>Type</CODE> attribute of the |
| * <CODE>Refernce</CODE> element points to a <CODE>#Manifest</CODE> element |
| * |
| * @return true if the Reference type indicates that this Reference points to a {@link Manifest} |
| */ |
| public boolean typeIsReferenceToManifest() { |
| |
| if ((this.getType() != null) |
| && this.getType().equals(Reference.MANIFEST_URI)) { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Method setDigestValueElement |
| * |
| * @param digestValue |
| * @throws XMLSignatureException |
| */ |
| private void setDigestValueElement(byte[] digestValue) |
| throws XMLSignatureException { |
| |
| if (this._state == MODE_SIGN) { |
| Element digestValueElement = this.getChildElementLocalName(0, |
| Constants.SignatureSpecNS, Constants._TAG_DIGESTVALUE); |
| NodeList children = digestValueElement.getChildNodes(); |
| |
| for (int i = 0; i < children.getLength(); i++) { |
| digestValueElement.removeChild(children.item(i)); |
| } |
| |
| String base64codedValue = Base64.encode(digestValue); |
| Text t = this._doc.createTextNode(base64codedValue); |
| |
| digestValueElement.appendChild(t); |
| } |
| } |
| |
| /** |
| * Method generateDigestValue |
| * |
| * @throws ReferenceNotInitializedException |
| * @throws XMLSignatureException |
| */ |
| public void generateDigestValue() |
| throws XMLSignatureException, ReferenceNotInitializedException { |
| |
| if (this._state == MODE_SIGN) { |
| byte calculatedBytes[] = this.calculateDigest(); |
| |
| this.setDigestValueElement(calculatedBytes); |
| } |
| } |
| |
| /** |
| * Returns the XMLSignatureInput which is created by de-referencing the URI attribute. |
| */ |
| public XMLSignatureInput getContentsBeforeTransformation() |
| throws ReferenceNotInitializedException { |
| |
| try { |
| Attr URIAttr = this._constructionElement.getAttributeNodeNS(null, |
| Constants._ATT_URI); |
| String URI; |
| |
| if (URIAttr == null) { |
| URI = null; |
| } else { |
| URI = URIAttr.getNodeValue(); |
| } |
| |
| ResourceResolver resolver = ResourceResolver.getInstance(URIAttr, |
| this._baseURI, this._manifest._perManifestResolvers); |
| |
| if (resolver == null) { |
| Object exArgs[] = { URI }; |
| |
| throw new ReferenceNotInitializedException( |
| "signature.Verification.Reference.NoInput", exArgs); |
| } |
| |
| resolver.addProperties(this._manifest._resolverProperties); |
| |
| XMLSignatureInput input = resolver.resolve(URIAttr, this._baseURI); |
| |
| this._transformsInput = new XMLSignatureInput(input.getBytes()); |
| |
| this._transformsInput.setSourceURI(input.getSourceURI()); |
| |
| return input; |
| } catch (IOException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } catch (ResourceResolverException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } catch (XMLSecurityException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } |
| } |
| |
| /** |
| * Returns the data which is referenced by the URI attribute. This method |
| * only works works after a call to verify. |
| * |
| * @deprecated use |
| */ |
| public XMLSignatureInput getTransformsInput() { |
| return this._transformsInput; |
| } |
| |
| private XMLSignatureInput getContentsAfterTransformation(XMLSignatureInput input) |
| throws XMLSignatureException { |
| |
| try { |
| Transforms transforms = this.getTransforms(); |
| XMLSignatureInput output = null; |
| |
| if (transforms != null) { |
| output = transforms.performTransforms(input); |
| this._transformsOutput = new XMLSignatureInput(output.getBytes()); |
| |
| this._transformsOutput.setSourceURI(output.getSourceURI()); |
| } else { |
| output = input; |
| this._transformsOutput = this._transformsInput; |
| } |
| |
| return output; |
| } catch (IOException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (ResourceResolverException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (CanonicalizationException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (InvalidCanonicalizerException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (TransformationException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (XMLSecurityException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } |
| } |
| |
| /** |
| * Returns the XMLSignatureInput which is the result of the Transforms. |
| */ |
| public XMLSignatureInput getContentsAfterTransformation() |
| throws XMLSignatureException { |
| |
| XMLSignatureInput input = this.getContentsBeforeTransformation(); |
| |
| return this.getContentsAfterTransformation(input); |
| } |
| |
| /** |
| * This method returns the XMLSignatureInput which represents the node set before |
| * some kind of canonicalization is applied for the first time. |
| * |
| * @throws XMLSignatureException |
| */ |
| public XMLSignatureInput getNodesetBeforeFirstCanonicalization() |
| throws XMLSignatureException { |
| |
| try { |
| XMLSignatureInput input = this.getContentsBeforeTransformation(); |
| XMLSignatureInput output = input; |
| Transforms transforms = this.getTransforms(); |
| Transform c14nTransform = null; |
| |
| if (transforms != null) { |
| doTransforms: for (int i = 0; i < transforms.getLength(); i++) { |
| Transform t = transforms.item(i); |
| String URI = t.getURI(); |
| |
| if (URI.equals(Transforms |
| .TRANSFORM_C14N_EXCL_OMIT_COMMENTS) || URI |
| .equals(Transforms |
| .TRANSFORM_C14N_EXCL_WITH_COMMENTS) || URI |
| .equals(Transforms |
| .TRANSFORM_C14N_OMIT_COMMENTS) || URI |
| .equals(Transforms |
| .TRANSFORM_C14N_WITH_COMMENTS)) { |
| c14nTransform = t; |
| |
| break doTransforms; |
| } |
| |
| output = t.performTransform(output); |
| } |
| |
| output.setSourceURI(input.getSourceURI()); |
| } |
| |
| if (c14nTransform != null) { |
| String URI = c14nTransform.getURI(); |
| |
| if (URI.equals(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS) |
| || URI.equals( |
| Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS)) { |
| if (c14nTransform |
| .length(InclusiveNamespaces |
| .ExclusiveCanonicalizationNamespace, InclusiveNamespaces |
| ._TAG_EC_INCLUSIVENAMESPACES) == 1) { |
| Element inE = c14nTransform.getChildElementLocalName(0, |
| InclusiveNamespaces.ExclusiveCanonicalizationNamespace, |
| InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES); |
| InclusiveNamespaces in = new InclusiveNamespaces(inE, |
| this.getBaseURI()); |
| String ins = in.getInclusiveNamespaces(); |
| } |
| } |
| } |
| |
| return output; |
| } catch (IOException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (ResourceResolverException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (CanonicalizationException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (InvalidCanonicalizerException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (TransformationException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (XMLSecurityException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } |
| } |
| |
| /** |
| * Method getHTMLRepresentation |
| * |
| * @throws XMLSignatureException |
| */ |
| public String getHTMLRepresentation() throws XMLSignatureException { |
| |
| try { |
| XMLSignatureInput nodes = this.getNodesetBeforeFirstCanonicalization(); |
| Set inclusiveNamespaces = new HashSet(); |
| |
| { |
| Transforms transforms = this.getTransforms(); |
| Transform c14nTransform = null; |
| |
| if (transforms != null) { |
| doTransforms: for (int i = 0; i < transforms.getLength(); i++) { |
| Transform t = transforms.item(i); |
| String URI = t.getURI(); |
| |
| if (URI.equals(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS) |
| || URI.equals( |
| Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS)) { |
| c14nTransform = t; |
| |
| break doTransforms; |
| } |
| } |
| } |
| |
| if (c14nTransform != null) { |
| String URI = c14nTransform.getURI(); |
| |
| if (c14nTransform |
| .length(InclusiveNamespaces |
| .ExclusiveCanonicalizationNamespace, InclusiveNamespaces |
| ._TAG_EC_INCLUSIVENAMESPACES) == 1) { |
| |
| // there is one InclusiveNamespaces element |
| InclusiveNamespaces in = new InclusiveNamespaces(c14nTransform |
| .getChildElementLocalName(0, InclusiveNamespaces |
| .ExclusiveCanonicalizationNamespace, InclusiveNamespaces |
| ._TAG_EC_INCLUSIVENAMESPACES), this.getBaseURI()); |
| |
| inclusiveNamespaces = InclusiveNamespaces.prefixStr2Set( |
| in.getInclusiveNamespaces()); |
| } |
| } |
| } |
| |
| return nodes.getHTMLRepresentation(inclusiveNamespaces); |
| } catch (TransformationException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (InvalidTransformException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } catch (XMLSecurityException ex) { |
| throw new XMLSignatureException("empty", ex); |
| } |
| } |
| |
| /** |
| * This method only works works after a call to verify. |
| * |
| */ |
| public XMLSignatureInput getTransformsOutput() { |
| return this._transformsOutput; |
| } |
| |
| /** |
| * This method returns the {@link XMLSignatureInput} which is referenced by the |
| * <CODE>URI</CODE> Attribute. |
| * |
| * @throws XMLSignatureException |
| * @see Manifest#verifyReferences |
| */ |
| protected void dereferenceURIandPerformTransforms() |
| throws XMLSignatureException { |
| |
| try { |
| XMLSignatureInput input = this.getContentsBeforeTransformation(); |
| XMLSignatureInput output = this.getContentsAfterTransformation(input); |
| |
| /* at this stage, this._transformsInput and this._transformsOutput |
| * contain a huge amount of nodes. When we do not cache these nodes |
| * but only preserve the octets, the memory footprint is dramatically |
| * reduced. |
| */ |
| if (!Reference.CacheSignedNodes) { |
| this._transformsInput = new XMLSignatureInput(input.getBytes()); |
| |
| this._transformsInput.setSourceURI(input.getSourceURI()); |
| |
| this._transformsOutput = new XMLSignatureInput(output.getBytes()); |
| |
| this._transformsOutput.setSourceURI(output.getSourceURI()); |
| } |
| } catch (IOException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } catch (CanonicalizationException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } catch (InvalidCanonicalizerException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } catch (XMLSecurityException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } |
| } |
| |
| /** |
| * Method getTransforms |
| * |
| * |
| * @throws InvalidTransformException |
| * @throws TransformationException |
| * @throws XMLSecurityException |
| * @throws XMLSignatureException |
| */ |
| public Transforms getTransforms() |
| throws XMLSignatureException, InvalidTransformException, |
| TransformationException, XMLSecurityException { |
| |
| Element transformsElement = this.getChildElementLocalName(0, |
| Constants.SignatureSpecNS, Constants._TAG_TRANSFORMS); |
| |
| if (transformsElement != null) { |
| Transforms transforms = new Transforms(transformsElement, |
| this._baseURI); |
| |
| return transforms; |
| } else { |
| return null; |
| } |
| } |
| |
| /** |
| * Method getReferencedBytes |
| * |
| * |
| * @throws ReferenceNotInitializedException |
| * @throws XMLSignatureException |
| */ |
| public byte[] getReferencedBytes() |
| throws ReferenceNotInitializedException, XMLSignatureException { |
| |
| try { |
| this.dereferenceURIandPerformTransforms(); |
| |
| byte[] signedBytes = this.getTransformsOutput().getBytes(); |
| |
| return signedBytes; |
| } catch (IOException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } catch (CanonicalizationException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } catch (InvalidCanonicalizerException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } |
| } |
| |
| /** |
| * Method resolverResult |
| * |
| * |
| * @throws ReferenceNotInitializedException |
| * @throws XMLSignatureException |
| */ |
| private byte[] calculateDigest() |
| throws ReferenceNotInitializedException, XMLSignatureException { |
| |
| try { |
| byte[] data = this.getReferencedBytes(); |
| MessageDigestAlgorithm mda = this.getMessageDigestAlgorithm(); |
| |
| mda.reset(); |
| mda.update(data); |
| |
| byte calculatedDigestValue[] = mda.digest(); |
| |
| //J- |
| if (data.length < 20) { |
| log.debug(new String(data)); |
| } else { |
| log.debug(new String(data).substring(0, 20) + " ..."); |
| } |
| //J+ |
| return calculatedDigestValue; |
| } catch (XMLSecurityException ex) { |
| throw new ReferenceNotInitializedException("empty", ex); |
| } |
| } |
| |
| /** |
| * Returns the digest value. |
| * |
| * @return the digest value. |
| * @throws Base64DecodingException if Reference contains no proper base64 encoded data. |
| */ |
| public byte[] getDigestValue() throws Base64DecodingException { |
| Element digestValueElem = this.getChildElementLocalName(0, |
| Constants.SignatureSpecNS, Constants._TAG_DIGESTVALUE); |
| byte[] elemDig = Base64.decode(digestValueElem); |
| return elemDig; |
| } |
| |
| |
| /** |
| * Tests reference valdiation is success or false |
| * |
| * @return true if reference valdiation is success, otherwise false |
| * @throws ReferenceNotInitializedException |
| * @throws XMLSecurityException |
| */ |
| public boolean verify() |
| throws ReferenceNotInitializedException, XMLSecurityException { |
| |
| byte[] elemDig = this.getDigestValue(); |
| byte[] calcDig = this.calculateDigest(); |
| boolean equal = MessageDigestAlgorithm.isEqual(elemDig, calcDig); |
| |
| if (!equal) { |
| log.warn("Verification failed for URI \"" + this.getURI() + "\""); |
| } else { |
| log.info("Verification successful for URI \"" + this.getURI() + "\""); |
| } |
| |
| return equal; |
| } |
| |
| /** |
| * Method getBaseLocalName |
| * |
| * |
| */ |
| public String getBaseLocalName() { |
| return Constants._TAG_REFERENCE; |
| } |
| } |