anon.crypto
Class XMLSignature

java.lang.Object
  extended by anon.crypto.XMLSignature
All Implemented Interfaces:
IXMLEncodable

public final class XMLSignature
extends java.lang.Object
implements IXMLEncodable

This class stores and creates signatures of XML nodes. The signing and verification processes and the underlying XML signature structure are completely transparent to the using code. Therefore, the XML_ELEMENT_NAME is not public. Just sign and verify what you want, you do not need to know how it works! It is not allowed to change the structure of an element`s signature node for other code than methods of this class. Otherwise, some methods could give false results. XMLSignature objects can only be created by signing or verifying XML nodes, or by getting an unverified signature from an XML node.

Author:
Rolf Wendolsky
See Also:
http://www.w3.org/TR/xmldsig-core/

Field Summary
private static java.lang.String ATTR_ALGORITHM
           
private static java.lang.String ATTR_URI
           
private static java.lang.String DIGEST_METHOD_ALGORITHM
           
private static java.lang.String ELEM_CANONICALIZATION_METHOD
           
private static java.lang.String ELEM_DIGEST_METHOD
           
private static java.lang.String ELEM_DIGEST_VALUE
           
private static java.lang.String ELEM_KEY_INFO
           
private static java.lang.String ELEM_REFERENCE
           
private static java.lang.String ELEM_SIGNATURE_METHOD
           
private static java.lang.String ELEM_SIGNATURE_VALUE
           
private static java.lang.String ELEM_SIGNED_INFO
           
private  java.util.Vector m_appendedCerts
          Stores all appended certificates It is very important, that whenever this Vector is changed, we also have to change m_appendedCertXMLElements, because the values have to be at the same index of the Vectors
private  java.util.Vector m_appendedCertXMLElements
          Stores the XML represenation of the appended certificates
private  boolean m_bVerified
          Indicates if the Signature was verfied already
private  CertPath m_certPath
          Stores the certification Path of this XMLSignature
private  java.lang.String m_digestMethod
           
private  java.lang.String m_digestValue
           
private  org.w3c.dom.Element m_elemSignature
           
private  java.lang.String m_referenceURI
           
private  java.lang.String m_signatureMethod
           
private  java.lang.String m_signatureValue
           
private  byte[] m_signedInfoCanonical
           
private static java.lang.String XML_ELEMENT_NAME
           
 
Fields inherited from interface anon.util.IXMLEncodable
FIELD_XML_ELEMENT_CONTAINER_NAME, FIELD_XML_ELEMENT_NAME, XML_ATTR_ID, XML_ATTR_VERSION
 
Constructor Summary
private XMLSignature()
          Creates a new and empty signature.
private XMLSignature(org.w3c.dom.Element a_element)
          Creates a new signature from a signature element.
 
Method Summary
 boolean addCertificate(JAPCertificate a_certificate)
          Adds a certificate to the signature.
 boolean appendSignatureTo(org.w3c.dom.Node a_node)
          Appends this XMLSignature to an XML node.
private static boolean checkMessageDigest(org.w3c.dom.Node a_node, XMLSignature a_signature)
           
private static boolean checkSignature(XMLSignature a_signature, IMyPublicKey a_publicKey)
          Checks if the signature of the XMLSignature`s SIGNED_INFO is valid.
 void clearCertificates()
          Deletes all certificates from this signature.
 boolean containsCertificate(JAPCertificate a_certificate)
          Returns if the specified certificate is already contained in this signature element.
 int countCertificates()
          Returns the number of certificates appended to this signature.
private static java.util.Hashtable findCertificates(org.w3c.dom.Element a_xmlSignature)
          Returns all certificates that are appended to the given signature element.
private static XMLSignature findXMLSignature(org.w3c.dom.Node a_node)
          Finds the signature element of the given node if present.
 java.util.Vector getCertificates()
          Returns all X509 certificates that are embedded in this XMLSignature.
 CertPath getCertPath()
           
 java.lang.String getDigestMethod()
          Returns the digest method that was used for creating this signature.
private  java.lang.String getDigestValue()
          Returns the Base64 encoded digest value.
 java.lang.String getReferenceURI()
          Returns the reference attribute URI.
private  org.w3c.dom.Element getSignatureElement()
          Gets the signature element held by this XMLSignature.
 java.lang.String getSignatureMethod()
          Returns the signature method that was used for creating this signature.
private  java.lang.String getSignatureValue()
          Returns the signature value as Base64 encoded, (and r-s encoded) String.
private  byte[] getSignedInfoCanonical()
          Returns the canonical representation of the SIGNED_INFO element.
static XMLSignature getUnverified(org.w3c.dom.Node a_node)
          Gets the signature from a node if present.
static XMLSignature getVerified(org.w3c.dom.Node a_node, java.util.Vector a_rootCertificates, java.util.Vector a_directCertificatePaths, boolean a_bCheckValidity)
          New Implementation of the verify()-method.
private static CertPath getVerifier(org.w3c.dom.Node a_node, XMLSignature a_signature, java.util.Vector a_verifyingCertificatePaths, boolean a_bCheckValidity)
          This method is used to verify a node with a previously created XMLSignature.
 boolean isVerified()
           
private static int makeCanonical(org.w3c.dom.Node node, java.io.OutputStream o, boolean bSiblings, org.w3c.dom.Node excludeNode)
           
 boolean removeCertificate(JAPCertificate a_certificate)
          Removes a certificate from this signature.
static boolean removeSignatureFrom(org.w3c.dom.Node a_node)
          Removes the signature from an XML node if a signature exists.
private static org.w3c.dom.Element removeSignatureFromInternal(org.w3c.dom.Node a_node)
          Removes the signature from an XML node if a signature exists.
private  void setCertificates(org.w3c.dom.Element a_xmlSignature)
           
 void setVerified(boolean a_bVerified)
           
static XMLSignature sign(org.w3c.dom.Node a_node, IMyPrivateKey a_privateKey)
          Signs an XML node and creates a new XMLSignature from the signature.
static XMLSignature sign(org.w3c.dom.Node a_node, PKCS12 a_certificate)
          Signs an XML node and creates a new XMLSignature from the signature.
private static XMLSignature signInternal(org.w3c.dom.Node a_node, IMyPrivateKey a_privateKey)
          Signs an XML node and creates a new XMLSignature from the signature.
private static byte[] toCanonical(org.w3c.dom.Node inputNode)
          Creates a byte array from an XML node tree.
private static byte[] toCanonical(org.w3c.dom.Node a_inputNode, org.w3c.dom.Node a_excludeNode)
           
private static byte[] toCanonicalDeprecated(org.w3c.dom.Node a_inputNode)
          Is only used if no digest value is found.
 org.w3c.dom.Element toXmlElement(org.w3c.dom.Document a_doc)
          Creates a new XML element from this signature.
private  org.w3c.dom.Element toXmlElementInternal(org.w3c.dom.Document a_doc)
          Transforms this XMLSignature to an XML element.
static XMLSignature verify(org.w3c.dom.Node a_node, IMyPublicKey a_publicKey)
          Verifies the signature of an XML node and creates a new XMLSignature from a valid signature.
static XMLSignature verify(org.w3c.dom.Node a_node, JAPCertificate a_certificate)
          Verifies the signature of an XML node and creates a new XMLSignature from a valid signature.
static XMLSignature verify(org.w3c.dom.Node a_node, java.util.Vector a_certificateList)
          Verifies the signature of an XML node and creates a new XMLSignature from a valid signature.
private static boolean verify(org.w3c.dom.Node a_node, XMLSignature a_signature, IMyPublicKey a_publicKey)
          This method is used to verify a node with a previously created XMLSignature.
static boolean verifyFast(org.w3c.dom.Node a_node, IMyPublicKey a_publicKey)
          Only verifies the signature of an XML node.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

XML_ELEMENT_NAME

private static final java.lang.String XML_ELEMENT_NAME
See Also:
Constant Field Values

ELEM_CANONICALIZATION_METHOD

private static final java.lang.String ELEM_CANONICALIZATION_METHOD
See Also:
Constant Field Values

ELEM_SIGNATURE_METHOD

private static final java.lang.String ELEM_SIGNATURE_METHOD
See Also:
Constant Field Values

ELEM_SIGNATURE_VALUE

private static final java.lang.String ELEM_SIGNATURE_VALUE
See Also:
Constant Field Values

ELEM_KEY_INFO

private static final java.lang.String ELEM_KEY_INFO
See Also:
Constant Field Values

ELEM_SIGNED_INFO

private static final java.lang.String ELEM_SIGNED_INFO
See Also:
Constant Field Values

ELEM_REFERENCE

private static final java.lang.String ELEM_REFERENCE
See Also:
Constant Field Values

ELEM_DIGEST_VALUE

private static final java.lang.String ELEM_DIGEST_VALUE
See Also:
Constant Field Values

ELEM_DIGEST_METHOD

private static final java.lang.String ELEM_DIGEST_METHOD
See Also:
Constant Field Values

ATTR_URI

private static final java.lang.String ATTR_URI
See Also:
Constant Field Values

ATTR_ALGORITHM

private static final java.lang.String ATTR_ALGORITHM
See Also:
Constant Field Values

DIGEST_METHOD_ALGORITHM

private static final java.lang.String DIGEST_METHOD_ALGORITHM
See Also:
Constant Field Values

m_elemSignature

private org.w3c.dom.Element m_elemSignature

m_signatureMethod

private java.lang.String m_signatureMethod

m_signatureValue

private java.lang.String m_signatureValue

m_referenceURI

private java.lang.String m_referenceURI

m_digestMethod

private java.lang.String m_digestMethod

m_digestValue

private java.lang.String m_digestValue

m_signedInfoCanonical

private byte[] m_signedInfoCanonical

m_appendedCerts

private java.util.Vector m_appendedCerts
Stores all appended certificates It is very important, that whenever this Vector is changed, we also have to change m_appendedCertXMLElements, because the values have to be at the same index of the Vectors


m_appendedCertXMLElements

private java.util.Vector m_appendedCertXMLElements
Stores the XML represenation of the appended certificates


m_certPath

private CertPath m_certPath
Stores the certification Path of this XMLSignature


m_bVerified

private boolean m_bVerified
Indicates if the Signature was verfied already

Constructor Detail

XMLSignature

private XMLSignature()
Creates a new and empty signature.


XMLSignature

private XMLSignature(org.w3c.dom.Element a_element)
              throws XMLParseException
Creates a new signature from a signature element.

Parameters:
a_element - an XML Element
Throws:
XMLParseException - if the element is no valid signature element
Method Detail

sign

public static XMLSignature sign(org.w3c.dom.Node a_node,
                                PKCS12 a_certificate)
                         throws XMLParseException
Signs an XML node and creates a new XMLSignature from the signature. The signature is added to the node, and any previous signature is removed. Also, the public X509 certificate from the PKCS12 certificate is added to the signature (and the node, respective). If an error occurs while signing, the old signature (if present) is not removed from the node.

Parameters:
a_node - an XML node
a_certificate - a certificate to sign the signature
Returns:
a new XMLSignature or null if no signature could be created
Throws:
XMLParseException - if the node could not be signed because it could not be properly transformed into bytes

sign

public static XMLSignature sign(org.w3c.dom.Node a_node,
                                IMyPrivateKey a_privateKey)
                         throws XMLParseException
Signs an XML node and creates a new XMLSignature from the signature. The signature is added to the node, and any previous signature is removed. No certificate is appended by default; if certificates need to be appended, they must be appended after signing. If an error occurs while signing, the old signature (if present) is not removed from the node.

Parameters:
a_node - an XML node
a_privateKey - a private key to sign the signature
Returns:
a new XMLSignature or null if no signature could be created
Throws:
XMLParseException - if the node could not be signed because it could not be properly transformed into bytes

signInternal

private static XMLSignature signInternal(org.w3c.dom.Node a_node,
                                         IMyPrivateKey a_privateKey)
                                  throws XMLParseException
Signs an XML node and creates a new XMLSignature from the signature. The signature is added to the node, and any previous signature is removed. If an error occurs while signing, the old signature (if present) is not removed from the node.

Parameters:
a_node - an XML node
a_privateKey - a private key to sign the signature
Returns:
a new XMLSignature or null if no signature could be created
Throws:
XMLParseException - if the node could not be signed because it could not be properly transformed into bytes

verify

public static XMLSignature verify(org.w3c.dom.Node a_node,
                                  JAPCertificate a_certificate)
                           throws XMLParseException
Verifies the signature of an XML node and creates a new XMLSignature from a valid signature.

Parameters:
a_node - an XML node
a_certificate - a certificate to verify the signature
Returns:
the XMLSignature of the node; null if the node could not be verified
Throws:
XMLParseException - if a signature element exists, but the element has an invalid structure

verify

public static XMLSignature verify(org.w3c.dom.Node a_node,
                                  java.util.Vector a_certificateList)
                           throws XMLParseException
Verifies the signature of an XML node and creates a new XMLSignature from a valid signature.

Parameters:
a_node - an XML node
a_certificateList - certificates to verify the signature
Returns:
the XMLSignature of the node; null if the node could not be verified
Throws:
XMLParseException - if a signature element exists, but the element has an invalid structure

getVerified

public static XMLSignature getVerified(org.w3c.dom.Node a_node,
                                       java.util.Vector a_rootCertificates,
                                       java.util.Vector a_directCertificatePaths,
                                       boolean a_bCheckValidity)
                                throws XMLParseException
New Implementation of the verify()-method. This one can also verify a chain of certificats to verify the Signature of an XML node. While trying to verify the Signature the certification Path is builded. The certification Path is null if the signature could not be verified.

Parameters:
a_node - Node A signed XML node.
a_rootCertificates - Vector A Vector of trusted root certificates which is used to verify the last(or only) certificate appended at the signature
a_directCertificates - A Vector of CertPaths to verify the signature, if there are no appended certificates
a_bCheckValidity - If this is true, the validity of the certs is checked and expired certs are treated as invalid.
Returns:
XMLSignature of the node, if there is one. The signature is also returned if the verification was NOT successfull. to get the result of the verification call isVerified() on the returned XMLSignature object
Throws:
XMLParseException - if a signature element exists, but the element has an invalid structure

verifyFast

public static boolean verifyFast(org.w3c.dom.Node a_node,
                                 IMyPublicKey a_publicKey)
Only verifies the signature of an XML node.

Parameters:
a_node - an XML node
a_publicKey - a public key to verify the signature
Returns:
true if the signatue was ok, false otherwise

verify

public static XMLSignature verify(org.w3c.dom.Node a_node,
                                  IMyPublicKey a_publicKey)
                           throws XMLParseException
Verifies the signature of an XML node and creates a new XMLSignature from a valid signature. This method is not as fast as verify(Node, X509Certificate) as a temporary certificate has to be created from the public key. Therefore, it is not recommended.

Parameters:
a_node - an XML node
a_publicKey - a public key to verify the signature
Returns:
the XMLSignature of the node; null if the node could not be verified
Throws:
XMLParseException - if a signature element exists, but the element has an invalid structure

getUnverified

public static XMLSignature getUnverified(org.w3c.dom.Node a_node)
                                  throws XMLParseException
Gets the signature from a node if present. The signature is not verified.

Parameters:
a_node - an XML node
Returns:
the node`s XMLSignature or null if no signature was found
Throws:
XMLParseException - if the signature is present but has an invalid XML structure

removeSignatureFrom

public static boolean removeSignatureFrom(org.w3c.dom.Node a_node)
Removes the signature from an XML node if a signature exists.

Parameters:
a_node - an XML Node
Returns:
true if the signature has been removed; false if the node did not have any signature

getCertificates

public java.util.Vector getCertificates()
Returns all X509 certificates that are embedded in this XMLSignature.

Returns:
all X509 certificates that are emmbeded in this XMLSignature;

containsCertificate

public boolean containsCertificate(JAPCertificate a_certificate)
Returns if the specified certificate is already contained in this signature element.

Parameters:
a_certificate - an X509 certificate
Returns:
true if the specified certificate is already contained in this signature element; false otherwise

countCertificates

public int countCertificates()
Returns the number of certificates appended to this signature.

Returns:
the number of certificates appended to this signature

clearCertificates

public void clearCertificates()
Deletes all certificates from this signature.


removeCertificate

public boolean removeCertificate(JAPCertificate a_certificate)
Removes a certificate from this signature.

Parameters:
a_certificate - an X509 certificate
Returns:
true if the certificate has been removed; false otherwise

addCertificate

public boolean addCertificate(JAPCertificate a_certificate)
Adds a certificate to the signature. The certificate is not added if the signature cannot be verified with it, or if the signature already contains the specified certificate.

Parameters:
a_certificate - JAPCertificate
Returns:
true if the certificate was added; false otherwise

appendSignatureTo

public boolean appendSignatureTo(org.w3c.dom.Node a_node)
Appends this XMLSignature to an XML node. If the node already has a signature, it is removed first. The signature is only appended to the node if the node`s message digest is equal to the signature`s stored message digest. If the new signature could not be appended, the old signature is not removed (if present).

Parameters:
a_node - an XML node
Returns:
true if the signature has been appended; false otherwise

toXmlElement

public org.w3c.dom.Element toXmlElement(org.w3c.dom.Document a_doc)
Creates a new XML element from this signature. The element is not connected with this XMLSignature object and should be used with care (or better: it should never be used, as it is not necessary...)

Specified by:
toXmlElement in interface IXMLEncodable
Parameters:
a_doc - an XML document
Returns:
the signature as XML element

getSignatureMethod

public java.lang.String getSignatureMethod()
Returns the signature method that was used for creating this signature.

Returns:
the signature method that was used for creating this signature

getDigestMethod

public java.lang.String getDigestMethod()
Returns the digest method that was used for creating this signature.

Returns:
the digest method that was used for creating this signature

getReferenceURI

public java.lang.String getReferenceURI()
Returns the reference attribute URI.

Returns:
the reference attribute URI

toXmlElementInternal

private org.w3c.dom.Element toXmlElementInternal(org.w3c.dom.Document a_doc)
Transforms this XMLSignature to an XML element. If the given XML document already is the owner document of the signature element kept by this XMLSignature, this signature element is returned. Otherwise, a new element is created.

Parameters:
a_doc - an XML document
Returns:
the signature as XML element

removeSignatureFromInternal

private static org.w3c.dom.Element removeSignatureFromInternal(org.w3c.dom.Node a_node)
Removes the signature from an XML node if a signature exists.

Parameters:
a_node - an XML Node
Returns:
the removed signature node or null if the node did not have any signature

getSignatureElement

private org.w3c.dom.Element getSignatureElement()
Gets the signature element held by this XMLSignature.

Returns:
the signature elements held by this XMLSignature

getSignedInfoCanonical

private byte[] getSignedInfoCanonical()
Returns the canonical representation of the SIGNED_INFO element.

Returns:
the canonical representation of the SIGNED_INFO element

getDigestValue

private java.lang.String getDigestValue()
Returns the Base64 encoded digest value.

Returns:
the Base64 encoded digest value

getSignatureValue

private java.lang.String getSignatureValue()
Returns the signature value as Base64 encoded, (and r-s encoded) String.

Returns:
the signature value as Base64 encoded, (and r-s encoded) String

isVerified

public boolean isVerified()
Returns:
true if the verification of the Signature was successful, false otherwise or if no verification was done

setVerified

public void setVerified(boolean a_bVerified)

getCertPath

public CertPath getCertPath()

findXMLSignature

private static XMLSignature findXMLSignature(org.w3c.dom.Node a_node)
                                      throws XMLParseException
Finds the signature element of the given node if present. This signature element is only found if it is a direct child of a_node. The signature is not verified.

Parameters:
a_node - an XML Node
Returns:
the node`s XMLSignature or null if no signature node was found
Throws:
XMLParseException - if the node has an invalid valid XML signature element structure

setCertificates

private void setCertificates(org.w3c.dom.Element a_xmlSignature)

findCertificates

private static java.util.Hashtable findCertificates(org.w3c.dom.Element a_xmlSignature)
Returns all certificates that are appended to the given signature element.

Parameters:
a_xmlSignature - an XML signature Element
Returns:
all certificates that are appended to the given signature node

toCanonical

private static byte[] toCanonical(org.w3c.dom.Node a_inputNode,
                                  org.w3c.dom.Node a_excludeNode)
                           throws XMLParseException
Throws:
XMLParseException

toCanonicalDeprecated

private static byte[] toCanonicalDeprecated(org.w3c.dom.Node a_inputNode)
Is only used if no digest value is found. Then, the entire document is verified against the signature.

Parameters:
a_inputNode - Node
Returns:
byte[]

toCanonical

private static byte[] toCanonical(org.w3c.dom.Node inputNode)
                           throws XMLParseException
Creates a byte array from an XML node tree.

Parameters:
inputNode - The node (incl. the whole tree) which is flattened to a byte array.
Returns:
the node as a byte array (incl. the whole tree).
Throws:
XMLParseException - if the node could not be properly transformed into bytes

makeCanonical

private static int makeCanonical(org.w3c.dom.Node node,
                                 java.io.OutputStream o,
                                 boolean bSiblings,
                                 org.w3c.dom.Node excludeNode)
Parameters:
node - Node
o - OutputStream
bSiblings - boolean
excludeNode - Node
Returns:
int
See Also:
http://www.w3.org/TR/xmldsig-core/#sec-CanonicalizationMethod, http://www.w3.org/TR/xml-c14n

getVerifier

private static CertPath getVerifier(org.w3c.dom.Node a_node,
                                    XMLSignature a_signature,
                                    java.util.Vector a_verifyingCertificatePaths,
                                    boolean a_bCheckValidity)
                             throws XMLParseException
This method is used to verify a node with a previously created XMLSignature.

Parameters:
a_node - an XML node
a_signature - an XMLSignature
a_verifyingCertificatePaths - a Vector of CertPaths to verify the signature
Returns:
the certificate that verified this signature; null if it could not be verified
Throws:
XMLParseException - if a signature element exists, but the element has an invalid structure

verify

private static boolean verify(org.w3c.dom.Node a_node,
                              XMLSignature a_signature,
                              IMyPublicKey a_publicKey)
                       throws XMLParseException
This method is used to verify a node with a previously created XMLSignature.

Parameters:
a_node - an XML node
a_signature - an XMLSignature
a_publicKey - a public key
Returns:
true if the node could be verified with this signature; false otherwise
Throws:
XMLParseException - if a signature element exists, but the element has an invalid structure

checkSignature

private static boolean checkSignature(XMLSignature a_signature,
                                      IMyPublicKey a_publicKey)
Checks if the signature of the XMLSignature`s SIGNED_INFO is valid.

Parameters:
a_signature - an XMLSignature
a_publicKey - a public key
Returns:
true if the signature of the XMLSignature`s SIGNED_INFO is valid; false otherwise

checkMessageDigest

private static boolean checkMessageDigest(org.w3c.dom.Node a_node,
                                          XMLSignature a_signature)
                                   throws XMLParseException
Throws:
XMLParseException