anon.crypto
Class XMLSignature

java.lang.Object
  extended by anon.crypto.XMLSignature

public final class XMLSignature
extends java.lang.Object

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, revised for MultiSign by Robert Hirschberger
See Also:
http://www.w3.org/TR/xmldsig-core/

Field Summary
private  MultiCertPath m_multiCertPath
          The MultiCertPath assoicated with this signature
private  java.util.Vector m_signatureElements
          The Vector of XMLSignatureElements kept by this object
private  java.lang.String m_xoredID
          The XORed SKIs of all Certs that verified a signature
private static java.lang.String XML_ELEMENT_NAME
           
 
Constructor Summary
private XMLSignature()
          Creates a new and empty signature.
 
Method Summary
 boolean addCertificate(JAPCertificate a_certificate)
           
private  void calculateXORofSKIs()
          Calculates the XOR of the SKIs once and stores it.
 void clearCertificates()
           
 int countSignatures()
          Returns how many signatures the document has.
private static XMLSignature findXMLSignature(org.w3c.dom.Node a_node)
          Finds the signature elements of the given node if present.
private  CertPath[] getCertPaths()
          Create an array of the CertPaths from all the XMLSignatureElements.
static java.lang.String getEncodedHashValue(org.w3c.dom.Element nodeToHash)
          Same method as getHashValueOfElement, except the String returned is already Base64-encoded necessary to avoid discrepancies between the results of getHashValueOfElement between the BI(Java) and PIG (Ruby/Java-bridge)
static java.lang.String getHashValueOfElement(org.w3c.dom.Node nodeToHash)
          getHashValueOfElement: takes an XML node and returns its hash value
 MultiCertPath getMultiCertPath()
           
protected  java.util.Vector getSignatureElements()
          Return a Vector of the -Elements contained in this object.
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, int a_documentType, java.util.Vector a_directCertificatePaths)
          Creates a new XMLSignature from the node and creates a new MultiCertPath object.
 org.w3c.dom.Element[] getXMLElements(org.w3c.dom.Document a_doc)
          Returns all -Elements of this XMLSignature
 java.lang.String getXORofSKIs()
          This method is used by the checkId()-methods of the database classes, that compare the id of a given entry with the SubjectKeyIdentifier of the associated cert(s).
 boolean isVerified()
          The Signature is verified if the MultiCertPath is verified.
private static int makeCanonical(org.w3c.dom.Node node, java.io.OutputStream o, boolean bSiblings, org.w3c.dom.Node excludeNode)
           
private static int makeCanonical(org.w3c.dom.Node node, java.io.OutputStream o, boolean bSiblings, org.w3c.dom.Node excludeNode, boolean a_bKeepSpaces)
           
private static int makeCanonical(org.w3c.dom.Node node, java.io.OutputStream o, boolean bSiblings, java.util.Vector excludedNodes, boolean a_bKeepSpaces, java.lang.String charsetName)
           
static XMLSignature multiSign(org.w3c.dom.Node a_node, java.util.Vector a_privateKeys)
          Signs an XML node with multiple keys and creates a new XMLSignature from the signature.
static boolean removeSignatureFrom(org.w3c.dom.Node a_node)
          Removes the signature from an XML node if a signature exists.
private static java.util.Vector removeSignatureFromInternal(org.w3c.dom.Node a_node)
          Removes the signature from an XML node if a signature exists.
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, java.util.Vector a_privateKeys)
          Signs an XML node with all supplied private keys and creates a new XMLSignature from the signature.
static byte[] toCanonical(org.w3c.dom.Node inputNode)
           
static byte[] toCanonical(org.w3c.dom.Node inputNode, boolean a_bKeepSpaces)
          Creates a byte array from an XML node tree.
static byte[] toCanonical(org.w3c.dom.Node a_inputNode, java.util.Vector a_excludedNodes)
           
static byte[] toCanonicalDeprecated(org.w3c.dom.Node a_inputNode)
          Is only used if no digest value is found.
static java.lang.String toCanonicalString(org.w3c.dom.Element input)
          same as toCanonical(Node):byte[], except returning a String only necessary for use in Ruby (since handling a Java byte array in Ruby wouldnt work)
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 boolean verifyFast(org.w3c.dom.Node a_node, IMyPublicKey a_publicKey)
          Only verifies the signatures of an XML node with the given key.
static boolean verifyFast(org.w3c.dom.Node a_node, java.util.Vector a_publicKeys)
          Only verifies the signatures of an XML node with the given keys.
 
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

m_signatureElements

private java.util.Vector m_signatureElements
The Vector of XMLSignatureElements kept by this object


m_multiCertPath

private MultiCertPath m_multiCertPath
The MultiCertPath assoicated with this signature


m_xoredID

private java.lang.String m_xoredID
The XORed SKIs of all Certs that verified a signature

Constructor Detail

XMLSignature

private XMLSignature()
Creates a new and empty signature.

Method Detail

countSignatures

public int countSignatures()
Returns how many signatures the document has.

Returns:
the number of signatures

getSignatureElements

protected java.util.Vector getSignatureElements()
Return a Vector of the -Elements contained in this object. To be called only by XMLSignatureElement when verifying their signature

Returns:
all Signature-Elements of this XMLSignature

getMultiCertPath

public MultiCertPath getMultiCertPath()

getCertPaths

private CertPath[] getCertPaths()
Create an array of the CertPaths from all the XMLSignatureElements. Note that only verified XMLSignatureElements have CertPaths. But this Method is only called if all Signatures have a verifier.

Returns:
an array of the associated CertPaths
See Also:
anon.crypto.XMLSignature.verify(), anon.crypto.XMLSignatureElement.verify();

getXORofSKIs

public java.lang.String getXORofSKIs()
This method is used by the checkId()-methods of the database classes, that compare the id of a given entry with the SubjectKeyIdentifier of the associated cert(s). If there is only one cert its ski is returned, else the XOR of all included SKIs is returned.

Returns:
the xor of all end-entity-certs' SKIs
See Also:
anon.infoservice.AbstractCertifiedDatabaseEntry.checkId(), anon.infoservice.AbstractDistributableCertifiedDatabaseEntry.checkId()

calculateXORofSKIs

private void calculateXORofSKIs()
Calculates the XOR of the SKIs once and stores it.


isVerified

public boolean isVerified()
The Signature is verified if the MultiCertPath is verified.

Returns:
true if the MultiCertPath is verified.

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

addCertificate

public boolean addCertificate(JAPCertificate a_certificate)

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

multiSign

public static XMLSignature multiSign(org.w3c.dom.Node a_node,
                                     java.util.Vector a_privateKeys)
                              throws XMLParseException
Signs an XML node with multiple keys 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

getHashValueOfElement

public static java.lang.String getHashValueOfElement(org.w3c.dom.Node nodeToHash)
getHashValueOfElement: takes an XML node and returns its hash value

Parameters:
nodeToHash - Node
Returns:
String the SHA1 hash value of the node (might be null if an exception occured)

getEncodedHashValue

public static java.lang.String getEncodedHashValue(org.w3c.dom.Element nodeToHash)
Same method as getHashValueOfElement, except the String returned is already Base64-encoded necessary to avoid discrepancies between the results of getHashValueOfElement between the BI(Java) and PIG (Ruby/Java-bridge)

Parameters:
nodeToHash - Node
Returns:
String

signInternal

private static XMLSignature signInternal(org.w3c.dom.Node a_node,
                                         java.util.Vector a_privateKeys)
                                  throws XMLParseException
Signs an XML node with all supplied private keys and creates a new XMLSignature from the signature. The signatures are added to the node, and any previous signatures are 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_privateKeys - the private keys or private certs 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

getVerified

public static XMLSignature getVerified(org.w3c.dom.Node a_node,
                                       int a_documentType,
                                       java.util.Vector a_directCertificatePaths)
                                throws XMLParseException,
                                       java.security.SignatureException
Creates a new XMLSignature from the node and creates a new MultiCertPath object. To get the verification-result call isVerified() on the retuned XMLSignature.

Parameters:
a_node - Node A signed XML node.
a_documentType - The document-Type of the node.
a_directCertificates - A Vector of CertPaths to verify the signature, if there are no appended certificates
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
java.security.SignatureException - if we found no verifier for one Signature, because the right cert was not appended or cached or the Signature is wrong. In either way we do not know which cert to take for calculating the the XORed ID.

verifyFast

public static boolean verifyFast(org.w3c.dom.Node a_node,
                                 java.util.Vector a_publicKeys)
Only verifies the signatures of an XML node with the given keys. If one of the signatures was verified successfully true is returned.

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

verifyFast

public static boolean verifyFast(org.w3c.dom.Node a_node,
                                 IMyPublicKey a_publicKey)
Only verifies the signatures of an XML node with the given key. If one of the signatures was verified successfully true is returned.

Parameters:
a_node - an XML node
a_publicKey - a public key to verify the signature
Returns:
true if one of the signatures 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.

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 and no MultiCertPath is set, so getCertPath() will return null.

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

removeSignatureFromInternal

private static java.util.Vector 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

findXMLSignature

private static XMLSignature findXMLSignature(org.w3c.dom.Node a_node)
                                      throws XMLParseException
Finds the signature elements of the given node if present. A 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

clearCertificates

public void clearCertificates()

toCanonical

public static byte[] toCanonical(org.w3c.dom.Node a_inputNode,
                                 java.util.Vector a_excludedNodes)
                          throws XMLParseException
Throws:
XMLParseException

toCanonicalDeprecated

public 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

public static byte[] toCanonical(org.w3c.dom.Node inputNode)
                          throws XMLParseException
Throws:
XMLParseException

toCanonical

public static byte[] toCanonical(org.w3c.dom.Node inputNode,
                                 boolean a_bKeepSpaces)
                          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

toCanonicalString

public static java.lang.String toCanonicalString(org.w3c.dom.Element input)
same as toCanonical(Node):byte[], except returning a String only necessary for use in Ruby (since handling a Java byte array in Ruby wouldnt work)

Parameters:
inputNode - Node
Returns:
String
Throws:
XMLParseException

makeCanonical

private static int makeCanonical(org.w3c.dom.Node node,
                                 java.io.OutputStream o,
                                 boolean bSiblings,
                                 org.w3c.dom.Node excludeNode)

makeCanonical

private static int makeCanonical(org.w3c.dom.Node node,
                                 java.io.OutputStream o,
                                 boolean bSiblings,
                                 org.w3c.dom.Node excludeNode,
                                 boolean a_bKeepSpaces)
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

makeCanonical

private static int makeCanonical(org.w3c.dom.Node node,
                                 java.io.OutputStream o,
                                 boolean bSiblings,
                                 java.util.Vector excludedNodes,
                                 boolean a_bKeepSpaces,
                                 java.lang.String charsetName)
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

getXMLElements

public org.w3c.dom.Element[] getXMLElements(org.w3c.dom.Document a_doc)
Returns all -Elements of this XMLSignature

Parameters:
a_doc -
Returns:
the -Elements of this XMLSignature