blob: 4b94d5d8e83c60d57c3af215cb59fddc99c559b3 [file] [log] [blame]
/**
* 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.
*/
package org.apache.xml.security.signature;
import java.io.IOException;
import java.io.OutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.apache.xml.security.algorithms.Algorithm;
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.XMLSecurityException;
import org.apache.xml.security.signature.reference.ReferenceData;
import org.apache.xml.security.signature.reference.ReferenceNodeSetData;
import org.apache.xml.security.signature.reference.ReferenceOctetStreamData;
import org.apache.xml.security.signature.reference.ReferenceSubTreeData;
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.Constants;
import org.apache.xml.security.utils.DigesterOutputStream;
import org.apache.xml.security.utils.SignatureElementProxy;
import org.apache.xml.security.utils.UnsyncBufferedOutputStream;
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.Node;
import org.w3c.dom.Text;
/**
* Handles <code>&lt;ds:Reference&gt;</code> elements.
*
* This includes:
*
* Construct 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>
* &lt;element name="Reference" type="ds:ReferenceType"/&gt;
* &lt;complexType name="ReferenceType"&gt;
* &lt;sequence&gt;
* &lt;element ref="ds:Transforms" minOccurs="0"/&gt;
* &lt;element ref="ds:DigestMethod"/&gt;
* &lt;element ref="ds:DigestValue"/&gt;
* &lt;/sequence&gt;
* &lt;attribute name="Id" type="ID" use="optional"/&gt;
* &lt;attribute name="URI" type="anyURI" use="optional"/&gt;
* &lt;attribute name="Type" type="anyURI" use="optional"/&gt;
* &lt;/complexType&gt;
* </pre>
*
* @see ObjectContainer
* @see Manifest
*/
public class Reference extends SignatureElementProxy {
/** 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;
/**
* The maximum number of transforms per reference, if secure validation is enabled.
*/
public static final int MAXIMUM_TRANSFORM_COUNT = 5;
private boolean secureValidation;
/**
* Look up useC14N11 system property. If true, an explicit C14N11 transform
* will be added if necessary when generating the signature. See section
* 3.1.1 of http://www.w3.org/2007/xmlsec/Drafts/xmldsig-core/ for more info.
*/
private static boolean useC14N11 =
AccessController.doPrivileged((PrivilegedAction<Boolean>)
() -> Boolean.getBoolean("org.apache.xml.security.useC14N11"));
private static final org.slf4j.Logger LOG =
org.slf4j.LoggerFactory.getLogger(Reference.class);
private Manifest manifest;
private XMLSignatureInput transformsOutput;
private Transforms transforms;
private Element digestMethodElem;
private Element digestValueElement;
private ReferenceData referenceData;
/**
* 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);
addReturnToSelf();
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"));
if (transforms != null) {
this.transforms = transforms;
appendSelf(transforms);
addReturnToSelf();
}
// Create DigestMethod Element without actually instantiating a MessageDigest Object
Algorithm digestAlgorithm = new Algorithm(getDocument(), messageDigestAlgorithm) {
public String getBaseNamespace() {
return Constants.SignatureSpecNS;
}
public String getBaseLocalName() {
return Constants._TAG_DIGESTMETHOD;
}
};
digestMethodElem = digestAlgorithm.getElement();
appendSelf(digestMethodElem);
addReturnToSelf();
digestValueElement =
XMLUtils.createElementInSignatureSpace(getDocument(), Constants._TAG_DIGESTVALUE);
appendSelf(digestValueElement);
addReturnToSelf();
}
/**
* 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 which have
* been set by the user
* @throws XMLSecurityException
*/
protected Reference(Element element, String baseURI, Manifest manifest) throws XMLSecurityException {
this(element, baseURI, manifest, true);
}
/**
* 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.
* @param secureValidation whether secure validation is enabled or not
* We need this because the Manifest has the individual {@link ResourceResolver}s which have
* been set by the user
* @throws XMLSecurityException
*/
protected Reference(Element element, String baseURI, Manifest manifest, boolean secureValidation)
throws XMLSecurityException {
super(element, baseURI);
this.secureValidation = secureValidation;
this.baseURI = baseURI;
Element el = XMLUtils.getNextElement(element.getFirstChild());
if (el != null && Constants._TAG_TRANSFORMS.equals(el.getLocalName())
&& Constants.SignatureSpecNS.equals(el.getNamespaceURI())) {
transforms = new Transforms(el, this.baseURI);
transforms.setSecureValidation(secureValidation);
if (secureValidation && transforms.getLength() > MAXIMUM_TRANSFORM_COUNT) {
Object[] exArgs = { transforms.getLength(), MAXIMUM_TRANSFORM_COUNT };
throw new XMLSecurityException("signature.tooManyTransforms", exArgs);
}
el = XMLUtils.getNextElement(el.getNextSibling());
}
digestMethodElem = el;
if (digestMethodElem == null) {
throw new XMLSecurityException("signature.Reference.NoDigestMethod");
}
digestValueElement = XMLUtils.getNextElement(digestMethodElem.getNextSibling());
if (digestValueElement == null) {
throw new XMLSecurityException("signature.Reference.NoDigestValue");
}
this.manifest = manifest;
}
/**
* Returns {@link MessageDigestAlgorithm}
*
*
* @return {@link MessageDigestAlgorithm}
*
* @throws XMLSignatureException
*/
public MessageDigestAlgorithm getMessageDigestAlgorithm() throws XMLSignatureException {
if (digestMethodElem == null) {
return null;
}
String uri = digestMethodElem.getAttributeNS(null, Constants._ATT_ALGORITHM);
if ("".equals(uri)) {
return null;
}
if (secureValidation && MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5.equals(uri)) {
Object[] exArgs = { uri };
throw new XMLSignatureException("signature.signatureAlgorithm", exArgs);
}
return MessageDigestAlgorithm.getInstance(getDocument(), 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 (uri != null) {
setLocalAttribute(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 getLocalAttribute(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 (id != null) {
setLocalIdAttribute(Constants._ATT_ID, 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 getLocalAttribute(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 (type != null) {
setLocalAttribute(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 getLocalAttribute(Constants._ATT_TYPE);
}
/**
* Method isReferenceToObject
*
* This returns true if the <CODE>Type</CODE> attribute of the
* <CODE>Reference</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() {
return Reference.OBJECT_URI.equals(this.getType());
}
/**
* Method isReferenceToManifest
*
* This returns true if the <CODE>Type</CODE> attribute of the
* <CODE>Reference</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() {
return Reference.MANIFEST_URI.equals(this.getType());
}
/**
* Method setDigestValueElement
*
* @param digestValue
*/
private void setDigestValueElement(byte[] digestValue) {
Node n = digestValueElement.getFirstChild();
while (n != null) {
digestValueElement.removeChild(n);
n = n.getNextSibling();
}
String base64codedValue = XMLUtils.encodeToString(digestValue);
Text t = createText(base64codedValue);
digestValueElement.appendChild(t);
}
/**
* Method generateDigestValue
*
* @throws ReferenceNotInitializedException
* @throws XMLSignatureException
*/
public void generateDigestValue()
throws XMLSignatureException, ReferenceNotInitializedException {
this.setDigestValueElement(this.calculateDigest(false));
}
/**
* Returns the XMLSignatureInput which is created by de-referencing the URI attribute.
* @return the XMLSignatureInput of the source of this reference
* @throws ReferenceNotInitializedException If the resolver found any
* problem resolving the reference
*/
public XMLSignatureInput getContentsBeforeTransformation()
throws ReferenceNotInitializedException {
try {
Attr uriAttr =
getElement().getAttributeNodeNS(null, Constants._ATT_URI);
ResourceResolver resolver =
ResourceResolver.getInstance(
uriAttr, this.baseURI, this.manifest.getPerManifestResolvers(), secureValidation
);
resolver.addProperties(this.manifest.getResolverProperties());
return resolver.resolve(uriAttr, this.baseURI, secureValidation);
} catch (ResourceResolverException ex) {
throw new ReferenceNotInitializedException(ex);
}
}
private XMLSignatureInput getContentsAfterTransformation(
XMLSignatureInput input, OutputStream os
) throws XMLSignatureException {
try {
Transforms transforms = this.getTransforms();
XMLSignatureInput output = null;
if (transforms != null) {
output = transforms.performTransforms(input, os);
this.transformsOutput = output;//new XMLSignatureInput(output.getBytes());
//this.transformsOutput.setSourceURI(output.getSourceURI());
} else {
output = input;
}
return output;
} catch (ResourceResolverException ex) {
throw new XMLSignatureException(ex);
} catch (CanonicalizationException ex) {
throw new XMLSignatureException(ex);
} catch (InvalidCanonicalizerException ex) {
throw new XMLSignatureException(ex);
} catch (TransformationException ex) {
throw new XMLSignatureException(ex);
} catch (XMLSecurityException ex) {
throw new XMLSignatureException(ex);
}
}
/**
* Returns the XMLSignatureInput which is the result of the Transforms.
* @return a XMLSignatureInput with all transformations applied.
* @throws XMLSignatureException
*/
public XMLSignatureInput getContentsAfterTransformation()
throws XMLSignatureException {
XMLSignatureInput input = this.getContentsBeforeTransformation();
cacheDereferencedElement(input);
return this.getContentsAfterTransformation(input, null);
}
/**
* This method returns the XMLSignatureInput which represents the node set before
* some kind of canonicalization is applied for the first time.
* @return Gets a the node doing everything till the first c14n is needed
*
* @throws XMLSignatureException
*/
public XMLSignatureInput getNodesetBeforeFirstCanonicalization()
throws XMLSignatureException {
try {
XMLSignatureInput input = this.getContentsBeforeTransformation();
cacheDereferencedElement(input);
XMLSignatureInput output = input;
Transforms transforms = this.getTransforms();
if (transforms != null) {
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)
|| uri.equals(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS)
|| uri.equals(Transforms.TRANSFORM_C14N11_WITH_COMMENTS)) {
break;
}
output = t.performTransform(output, null);
}
output.setSourceURI(input.getSourceURI());
}
return output;
} catch (IOException ex) {
throw new XMLSignatureException(ex);
} catch (ResourceResolverException ex) {
throw new XMLSignatureException(ex);
} catch (CanonicalizationException ex) {
throw new XMLSignatureException(ex);
} catch (InvalidCanonicalizerException ex) {
throw new XMLSignatureException(ex);
} catch (TransformationException ex) {
throw new XMLSignatureException(ex);
} catch (XMLSecurityException ex) {
throw new XMLSignatureException(ex);
}
}
/**
* Method getHTMLRepresentation
* @return The HTML of the transformation
* @throws XMLSignatureException
*/
public String getHTMLRepresentation() throws XMLSignatureException {
try {
XMLSignatureInput nodes = this.getNodesetBeforeFirstCanonicalization();
Transforms transforms = this.getTransforms();
Transform c14nTransform = null;
if (transforms != null) {
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;
}
}
}
Set<String> inclusiveNamespaces = new HashSet<>();
if (c14nTransform != null
&& c14nTransform.length(
InclusiveNamespaces.ExclusiveCanonicalizationNamespace,
InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES) == 1) {
// there is one InclusiveNamespaces element
InclusiveNamespaces in =
new InclusiveNamespaces(
XMLUtils.selectNode(
c14nTransform.getElement().getFirstChild(),
InclusiveNamespaces.ExclusiveCanonicalizationNamespace,
InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES,
0
), this.getBaseURI());
inclusiveNamespaces =
InclusiveNamespaces.prefixStr2Set(in.getInclusiveNamespaces());
}
return nodes.getHTMLRepresentation(inclusiveNamespaces);
} catch (TransformationException ex) {
throw new XMLSignatureException(ex);
} catch (InvalidTransformException ex) {
throw new XMLSignatureException(ex);
} catch (XMLSecurityException ex) {
throw new XMLSignatureException(ex);
}
}
/**
* This method only works after a call to verify.
* @return the transformed output(i.e. what is going to be digested).
*/
public XMLSignatureInput getTransformsOutput() {
return this.transformsOutput;
}
/**
* Get the ReferenceData that corresponds to the cached representation of the dereferenced
* object before transformation.
*/
public ReferenceData getReferenceData() {
return referenceData;
}
/**
* This method returns the {@link XMLSignatureInput} which is referenced by the
* <CODE>URI</CODE> Attribute.
* @param os where to write the transformation can be null.
* @return the element to digest
*
* @throws XMLSignatureException
* @see Manifest#verifyReferences()
*/
protected XMLSignatureInput dereferenceURIandPerformTransforms(OutputStream os)
throws XMLSignatureException {
try {
XMLSignatureInput input = this.getContentsBeforeTransformation();
cacheDereferencedElement(input);
XMLSignatureInput output = this.getContentsAfterTransformation(input, os);
this.transformsOutput = output;
return output;
} catch (XMLSecurityException ex) {
throw new ReferenceNotInitializedException(ex);
}
}
/**
* Store the dereferenced Element(s) so that it/they can be retrieved later.
*/
private void cacheDereferencedElement(XMLSignatureInput input) {
if (input.isNodeSet()) {
try {
final Set<Node> s = input.getNodeSet();
referenceData = new ReferenceNodeSetData() {
public Iterator<Node> iterator() {
return new Iterator<Node>() {
Iterator<Node> sIterator = s.iterator();
@Override
public boolean hasNext() {
return sIterator.hasNext();
}
@Override
public Node next() {
return sIterator.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
} catch (Exception e) {
// LOG a warning
LOG.warn("cannot cache dereferenced data: " + e);
}
} else if (input.isElement()) {
referenceData = new ReferenceSubTreeData
(input.getSubNode(), input.isExcludeComments());
} else if (input.isOctetStream() || input.isByteArray()) {
try {
referenceData = new ReferenceOctetStreamData
(input.getOctetStream(), input.getSourceURI(),
input.getMIMEType());
} catch (IOException ioe) {
// LOG a warning
LOG.warn("cannot cache dereferenced data: " + ioe);
}
}
}
/**
* Method getTransforms
*
* @return The transforms that applied this reference.
* @throws InvalidTransformException
* @throws TransformationException
* @throws XMLSecurityException
* @throws XMLSignatureException
*/
public Transforms getTransforms()
throws XMLSignatureException, InvalidTransformException,
TransformationException, XMLSecurityException {
return transforms;
}
/**
* Method getReferencedBytes
*
* @return the bytes that will be used to generated digest.
* @throws ReferenceNotInitializedException
* @throws XMLSignatureException
*/
public byte[] getReferencedBytes()
throws ReferenceNotInitializedException, XMLSignatureException {
try {
XMLSignatureInput output = this.dereferenceURIandPerformTransforms(null);
return output.getBytes();
} catch (IOException ex) {
throw new ReferenceNotInitializedException(ex);
} catch (CanonicalizationException ex) {
throw new ReferenceNotInitializedException(ex);
}
}
/**
* Method calculateDigest
*
* @param validating true if validating the reference
* @return reference Calculate the digest of this reference.
* @throws ReferenceNotInitializedException
* @throws XMLSignatureException
*/
private byte[] calculateDigest(boolean validating)
throws ReferenceNotInitializedException, XMLSignatureException {
XMLSignatureInput input = this.getContentsBeforeTransformation();
if (input.isPreCalculatedDigest()) {
return getPreCalculatedDigest(input);
}
cacheDereferencedElement(input);
MessageDigestAlgorithm mda = this.getMessageDigestAlgorithm();
mda.reset();
try (DigesterOutputStream diOs = new DigesterOutputStream(mda);
OutputStream os = new UnsyncBufferedOutputStream(diOs)) {
XMLSignatureInput output = this.getContentsAfterTransformation(input, os);
this.transformsOutput = output;
// if signing and c14n11 property == true explicitly add
// C14N11 transform if needed
if (Reference.useC14N11 && !validating && !output.isOutputStreamSet()
&& !output.isOctetStream()) {
if (transforms == null) {
transforms = new Transforms(getDocument());
transforms.setSecureValidation(secureValidation);
getElement().insertBefore(transforms.getElement(), digestMethodElem);
}
transforms.addTransform(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS);
output.updateOutputStream(os, true);
} else {
output.updateOutputStream(os);
}
os.flush();
if (output.getOctetStreamReal() != null) {
output.getOctetStreamReal().close();
}
//this.getReferencedBytes(diOs);
//mda.update(data);
return diOs.getDigestValue();
} catch (XMLSecurityException ex) {
throw new ReferenceNotInitializedException(ex);
} catch (IOException ex) {
throw new ReferenceNotInitializedException(ex);
}
}
/**
* Get the pre-calculated digest value from the XMLSignatureInput.
*
* @param input XMLSignature
* @return a pre-calculated digest value.
* @throws ReferenceNotInitializedException if there is an error decoding digest value
* in Base64. Properly encoded pre-calculated digest value must be set.
*/
private byte[] getPreCalculatedDigest(XMLSignatureInput input)
throws ReferenceNotInitializedException {
LOG.debug("Verifying element with pre-calculated digest");
String preCalculatedDigest = input.getPreCalculatedDigest();
return XMLUtils.decode(preCalculatedDigest);
}
/**
* Returns the digest value.
*
* @return the digest value.
* @throws XMLSecurityException if the Reference does not contain a DigestValue element
*/
public byte[] getDigestValue() throws XMLSecurityException {
if (digestValueElement == null) {
// The required element is not in the XML!
Object[] exArgs ={ Constants._TAG_DIGESTVALUE, Constants.SignatureSpecNS };
throw new XMLSecurityException(
"signature.Verification.NoSignatureElement", exArgs
);
}
String content = XMLUtils.getFullTextChildrenFromNode(digestValueElement);
return XMLUtils.decode(content);
}
/**
* Tests reference validation is success or false
*
* @return true if reference validation is success, otherwise false
* @throws ReferenceNotInitializedException
* @throws XMLSecurityException
*/
public boolean verify()
throws ReferenceNotInitializedException, XMLSecurityException {
byte[] elemDig = this.getDigestValue();
byte[] calcDig = this.calculateDigest(true);
boolean equal = MessageDigestAlgorithm.isEqual(elemDig, calcDig);
if (!equal) {
LOG.warn("Verification failed for URI \"" + this.getURI() + "\"");
LOG.warn("Expected Digest: " + XMLUtils.encodeToString(elemDig));
LOG.warn("Actual Digest: " + XMLUtils.encodeToString(calcDig));
} else {
LOG.debug("Verification successful for URI \"{}\"", this.getURI());
}
return equal;
}
/**
* Method getBaseLocalName
* {@inheritDoc}
*/
public String getBaseLocalName() {
return Constants._TAG_REFERENCE;
}
}