/* * Copyright(c) 2002 Center for E-Commerce Infrastructure Development, The * University of Hong Kong (HKU). All Rights Reserved. * * This software is licensed under the Academic Free License Version 1.0 * * Academic Free License * Version 1.0 * * This Academic Free License applies to any software and associated * documentation (the "Software") whose owner (the "Licensor") has placed the * statement "Licensed under the Academic Free License Version 1.0" immediately * after the copyright notice that applies to the Software. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of the Software (1) to use, copy, modify, merge, publish, perform, * distribute, sublicense, and/or sell copies of the Software, and to permit * persons to whom the Software is furnished to do so, and (2) under patent * claims owned or controlled by the Licensor that are embodied in the Software * as furnished by the Licensor, to make, use, sell and offer for sale the * Software and derivative works thereof, subject to the following conditions: * * - Redistributions of the Software in source code form must retain all * copyright notices in the Software as furnished by the Licensor, this list * of conditions, and the following disclaimers. * - Redistributions of the Software in executable form must reproduce all * copyright notices in the Software as furnished by the Licensor, this list * of conditions, and the following disclaimers in the documentation and/or * other materials provided with the distribution. * - Neither the names of Licensor, nor the names of any contributors to the * Software, nor any of their trademarks or service marks, may be used to * endorse or promote products derived from this Software without express * prior written permission of the Licensor. * * DISCLAIMERS: LICENSOR WARRANTS THAT THE COPYRIGHT IN AND TO THE SOFTWARE IS * OWNED BY THE LICENSOR OR THAT THE SOFTWARE IS DISTRIBUTED BY LICENSOR UNDER * A VALID CURRENT LICENSE. EXCEPT AS EXPRESSLY STATED IN THE IMMEDIATELY * PRECEDING SENTENCE, THE SOFTWARE IS PROVIDED BY THE LICENSOR, CONTRIBUTORS * AND COPYRIGHT OWNERS "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE * LICENSOR, CONTRIBUTORS OR COPYRIGHT OWNERS BE LIABLE FOR ANY CLAIM, DAMAGES * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE. * * This license is Copyright (C) 2002 Lawrence E. Rosen. All rights reserved. * Permission is hereby granted to copy and distribute this license without * modification. This license may not be modified without the express written * permission of its copyright owner. */ /* ===== * * $Header: /home/cvsroot/ebxml-pkg/src/hk/hku/cecid/ebms/pkg/Signature.java,v 1.1 2005/07/28 09:36:24 dcmsze Exp $ * * Code authored by: * * cyng [2002-03-21] * * Code reviewed by: * * username [YYYY-MM-DD] * * Remarks: * * ===== */ package hk.hku.cecid.ebms.pkg; import hk.hku.cecid.ebms.pkg.pki.CertResolver; import hk.hku.cecid.ebms.pkg.validation.SOAPValidationException; import java.util.ArrayList; import java.util.Iterator; import javax.activation.DataSource; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPException; /** * <P>An ebXML <code>Signature</code> is a <code>HeaderElement</code> * in <code>HeaderContainer</code> [ebMSS 4.1.1 and 4.1.3].</P> * * <P>This class is a partial implementation of the XML-Signature Syntax and * Processing / RFC 3275. Please refer to these documents for details.</P> * * @see <a href="http://www.w3.org/TR/xmldsig-core/"> * XML-Signature Syntax and Processing</a> * @author cyng * @version $Revision: 1.1 $ */ public abstract class Signature extends HeaderElement { /** * Name of the Signature element [ebMSS 4.1.1, XMLDSIG 4.1]. */ public static final String ELEMENT_SIGNATURE = "Signature"; /** * Name of the SignedInfo element [ebMSS 4.1.3, XMLDSIG 4.3] containing * information about the signature. They include: * <ul> * <li>Canonicalization method</li> * <li>Signature method</li> * <li>References made during signature generation</li> * </ul> */ public static final String ELEMENT_SIGNED_INFO = "SignedInfo"; /** * Name of the Canonicalization Method element [ebMSS 4.1.3, XMLDSIG 4.3.1] * used in signature generation. */ public static final String ELEMENT_CANONICALIZATION_METHOD = "CanonicalizationMethod"; /** * Name of the Signature Method element [ebMSS 4.1.3, XMLDSIG 4.3.2]. */ public static final String ELEMENT_SIGNATURE_METHOD = "SignatureMethod"; /** * Name of the Signature Value element [ebMSS 4.1.3, XMLDSIG 4.2]. */ public static final String ELEMENT_SIGNATURE_VALUE = "SignatureValue"; /** * Name of the Reference element which specifies a digest algorithm and * digest value and other optional information [ebMSS 4.1.3, XMLDSIG 4.3.3]. */ public static final String ELEMENT_REFERENCE = "Reference"; /** * Name of the DigestMethod element which specifies the digest algorithm * to be applied to the signed object [XMLDSIG 4.3.3.5]. */ public static final String ELEMENT_DIGEST_METHOD = "DigestMethod"; /** * Name of the DigestValue element which contains the encoded value of the * digest [XMLDSIG 4.3.3.6]. */ public static final String ELEMENT_DIGEST_VALUE = "DigestValue"; /** * Name of the Transforms element which is an ordered list of * transformations applied to obtain the data object to be signed * [XMLDSIG 4.3.3.4]. */ public static final String ELEMENT_TRANSFORMS = "Transforms"; /** * Name of the Transform element which describes the transformation * applied on the data object [XMLDSIG 4.3.3.4]. Transformation algorithms * are described in XMLDSIG 6.6: Transform Algorithms. */ public static final String ELEMENT_TRANSFORM = "Transform"; /** * Name of the XPath element [XMLDSIG 6.6.3]. */ public static final String ELEMENT_XPATH = "XPath"; /** * Name of the Object element [XMLDSIG 4.5]. */ public static final String ELEMENT_OBJECT = "Object"; /** * Name of the KeyInfo element which enables the recipient(s) to * obtain the key needed to validate the signature [XMLDSIG 4.4]. */ public static final String ELEMENT_KEY_INFO = "KeyInfo"; /** * Name of the X509Data element which contains identifier(s) of * keys or X509 certificates [XMLDSIG 4.4.4]. */ public static final String ELEMENT_X509_DATA = "X509Data"; /** * Name of the X509Certificate element which contains a binary (ASN.1 DER) * X.509 Certificate [XMLDSIG 4.4]. */ public static final String ELEMENT_X509_CERTIFICATE = "X509Certificate"; /** * Name of the Algorithm attribute. */ public static final String ATTRIBUTE_ALGORITHM = "Algorithm"; /** * Name of the Id attribute. */ public static final String ATTRIBUTE_ID = "Id"; /** * Name of the URI attribute. */ public static final String ATTRIBUTE_URI = "URI"; /** * Namespace prefix of <code>Signature</code>. */ public static final String NAMESPACE_PREFIX_DS = "ds"; /** * Namespace URI of <code>Signature</code>. */ public static final String NAMESPACE_URI_DS = "http://www.w3.org/2000/09/xmldsig#"; /** * Namespace URI of the canonicalization method as specified in * <a href="http://www.w3.org/TR/xml-exc-c14n/">Exclusive XML * Canonicalization Version 1.0</a>. */ public static final String CANONICALIZATION_METHOD = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; /** * Name of the digital signature method required, qualified by the * digital signature namespace [XMLDSIG 6.1]. */ public static final String SIGNATURE_METHOD = NAMESPACE_URI_DS + "dsa-sha1"; /** * Name of the enveloped signature required, qualified by the digital * signature namespace [XMLDSIG 6.1]. */ public static final String TRANSFORM_ALGORITHM_ENVELOPED_SIGNATURE = NAMESPACE_URI_DS + "enveloped-signature"; /** * Name of the XPath transform algorithm recommended [XMLDSIG 6.1]. */ public static final String TRANSFORM_ALGORITHM_XPATH = "http://www.w3.org/TR/1999/REC-xpath-19991116"; /** * XPath transform string used in the implementation. */ public static final String TRANSFORM_XPATH = "not(ancestor-or-self::node()[@" + NAMESPACE_PREFIX_SOAP_ENVELOPE + XML_NS_SEPARATOR + HeaderElement. ATTRIBUTE_ACTOR + "=\"" + HeaderElement.ACTOR_NEXT_MSH_URN + "\"] | " + "ancestor-or-self::node()[@" + NAMESPACE_PREFIX_SOAP_ENVELOPE + XML_NS_SEPARATOR + HeaderElement.ATTRIBUTE_ACTOR + "=\"" + HeaderElement.ACTOR_NEXT_MSH_SCHEMAS + "\"])"; /** * Name of the Digest method required, qualified by namespace [XMLDSIG 6.1]. */ public static final String DIGEST_METHOD = NAMESPACE_URI_DS + "sha1"; /** * Name of the digital signature algorithm. */ public static final String SIGNATURE_ALGORITHM = "SHA1withDSA"; /** * Name of the message digest algorithm. */ public static final String DIGEST_ALGORITHM = "SHA"; /** * Default character coding. */ public static final String CHARACTER_ENCODING = "utf-8"; final ArrayList references; String signatureValue; /** * Initializes the <code>Signature</code> object using the given * <code>SOAPEnvelope</code>, local name, namespace prefix and namespace * URI. * * @param soapEnvelope <code>SOAPEnvelope</code> on which digital * signature will be applied. * @param localName Local name of the signature element. * @param prefix Namespace prefix of the signature element. * @param uri Namespace URI of the signature element. * @throws SOAPException */ Signature(SOAPEnvelope soapEnvelope, String localName, String prefix, String uri) throws SOAPException { super(soapEnvelope, localName, prefix, uri); references = new ArrayList(); signatureValue = null; } Signature(SOAPEnvelope soapEnvelope, SOAPElement soapElement) throws SOAPException { super(soapEnvelope, soapElement); references = new ArrayList(); Iterator childElements = getChildElements(soapEnvelope.createName (ELEMENT_SIGNED_INFO, NAMESPACE_PREFIX_DS, NAMESPACE_URI_DS)); if (childElements.hasNext()) { SOAPElement signedInfo = (SOAPElement) childElements.next(); childElements = signedInfo.getChildElements(soapEnvelope.createName (SignatureReference.SIGNATURE_REFERENCE, NAMESPACE_PREFIX_DS, NAMESPACE_URI_DS)); if (childElements.hasNext()) { while (childElements.hasNext()) { references.add(new SignatureReference(soapEnvelope, (SOAPElement) childElements.next())); } } else { throw new SOAPValidationException(SOAPValidationException. SOAP_FAULT_CLIENT, "<" + NAMESPACE_PREFIX_DS + ":" + SignatureReference.SIGNATURE_REFERENCE + "> is not found in <" + NAMESPACE_PREFIX_DS + ":" + ELEMENT_SIGNATURE + ">!"); } } else { throw new SOAPValidationException(SOAPValidationException. SOAP_FAULT_CLIENT, "<" + NAMESPACE_PREFIX_DS + ":" + ELEMENT_SIGNED_INFO + "> is not found in <" + NAMESPACE_PREFIX_DS + ":" + ELEMENT_SIGNATURE + ">!"); } childElements = getChildElements(soapEnvelope.createName (ELEMENT_SIGNATURE_VALUE, NAMESPACE_PREFIX_DS, NAMESPACE_URI_DS)); if (childElements.hasNext()) { signatureValue = ((SOAPElement) childElements.next()).getValue(); } else { throw new SOAPValidationException(SOAPValidationException. SOAP_FAULT_CLIENT, "<" + NAMESPACE_PREFIX_DS + ":" + ELEMENT_SIGNATURE_VALUE + "> is not found in <" + NAMESPACE_PREFIX_DS + ":" + ELEMENT_SIGNATURE + ">!"); } } /** * Get a new instance of <code>Signature</code> which will be used to * sign or verify the given <code>EbxmlMessage</code> */ static Signature newInstance(EbxmlMessage ebxmlMessage) throws SOAPException { synchronized(PKISignatureImpl.class) { return new PKISignatureImpl(ebxmlMessage); } } static Signature newInstance(SOAPEnvelope soapEnvelope, SOAPElement soapElement) throws SOAPException { return new PKISignatureImpl(null, soapEnvelope, soapElement); } static Signature newInstance(EbxmlMessage ebxmlMessage, SOAPEnvelope soapEnvelope, SOAPElement soapElement) throws SOAPException { return new PKISignatureImpl(ebxmlMessage, soapEnvelope, soapElement); } public Iterator getReferences() { return references.iterator(); } String getSignatureValue() { return signatureValue; } /** * Add a reference URI to this <code>Signature</code>. * * @param uri Reference URI to be added. * @throws SignatureException */ abstract void addReference(String uri) throws SignatureException; /** * Sign the <code>EbxmlMessage</code> with the <code>username<code> and * <code>password</code> used to retrieve private key from the keystore. * * @param username User name required to open the private key. * @param password Password required to open the private key. * @throws SignatureException */ abstract void sign(String username, char[] password) throws SignatureException; /** * Sign the <code>EbxmlMessage</code> with the <code>username<code> and * <code>password</code> used to retrieve private key from the keystore * * @param username User name required to open the private key. * @param password Password required to open the private key. * @param keyStoreLocation File location of the keystore. * @param algorithm Name of the algorithm used to sign the * message. * @throws SignatureException */ abstract void sign(String username, char[] password, String keyStoreLocation, String algorithm) throws SignatureException; /** * Sign the <code>EbxmlMessage</code> with the <code>username<code> and * <code>password</code> used to retrieve private key from the keystore * * @param username User name required to open the private key. * @param password Password required to open the private key. * @param keyStoreLocation File location of the keystore. * @param algorithm Name of the algorithm used to sign the * message. * @param digestAlgo Name of the algorithm used to make the * digest. * @param signEnvelopeOnly whether sign the envelope only., * @throws SignatureException */ abstract void sign(String username, char[] password, String keyStoreLocation, String algorithm, String digestAlgo, boolean signEnvelopeOnly) throws SignatureException; /** * Sign the <code>EbxmlMessage</code> with the <code>username<code> and * <code>password</code> used to retrieve private key from the keystore * * @param username User name required to open the private key. * @param password Password required to open the private key. * @param keyStoreLocation File location of the keystore. * @throws SignatureException */ abstract void sign(String username, char[] password, String keyStoreLocation) throws SignatureException; /** * Sign the <code>EbxmlMessage</code> with the <code>username<code> and * <code>password</code> used to retrieve private key from the keystore. * * @param username User name required to open the private key. * @param password Password required to open the private key. * @param keyStoreLocation File location of the keystore * @param type * @param provider * @throws SignatureException */ abstract void sign(String username, char[] password, String keyStoreLocation, String type, String provider) throws SignatureException; /** * Sign the <code>EbxmlMessage</code> using the private key supplied and * attach X.509 certificates to the signature. * * @param privateKey Private key used to sign the message. * @param certificates List of certificates to be included in the * signature. * @throws SignatureException */ abstract void sign(java.security.PrivateKey privateKey, java.security.cert.X509Certificate[] certificates) throws SignatureException; /** * Verify the message using trusted keystore. * * @param password Password to open the keystore. * @param keyStoreLocation File location of the key store. * @param certResolver Resolve a certificate chain in order to * verify the message. If it is null, the * certificate chain is extracted directly * from the <ds:Signature> element in the * message. * * @return true if the digital signature is valid; false otherwise. * @throws SignatureException */ abstract boolean verify(char[] password, String keyStoreLocation, CertResolver certResolver, DataSource datasource) throws SignatureException; /** * Verify the XML signature of the <code>EbxmlMessage</code> * * @param documentElement Document fragment which contains the * digital signature. * @param publicKey Public key used to verify the digitall * signature. * @return true if digital signature is valid; false otherwise. * @throws SignatureException */ abstract boolean verify(org.w3c.dom.Element documentElement, java.security.PublicKey publicKey) throws SignatureException; /** * Verify the XML signature of the <code>EbxmlMessage</code> * * @param publicKey Public key used to verify the digitall * signature. * @return true if digital signature is valid; false otherwise. * @exception SignatureException */ abstract boolean verify(java.security.PublicKey publicKey) throws SignatureException; }