Update of /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23732/src/java/org/neuclear/xml/xmlsec Modified Files: InvalidSignatureException.java Reference.java SignedElement.java SignedInfo.java XMLSecTools.java XMLSignature.java Log Message: More improvements on the XMLSignature. Now uses the Transforms properly, References properly. All the major elements have been refactored to be cleaner and more correct. Index: InvalidSignatureException.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/InvalidSignatureException.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** InvalidSignatureException.java 5 Mar 2004 23:47:17 -0000 1.3 --- InvalidSignatureException.java 8 Mar 2004 23:51:03 -0000 1.4 *************** *** 11,15 **** */ public class InvalidSignatureException extends Exception { ! public InvalidSignatureException(String a, String b) { super("Digest: '" + a + "' not equal to: " + b); } --- 11,15 ---- */ public class InvalidSignatureException extends Exception { ! public InvalidSignatureException(byte[] a, byte[] b) { super("Digest: '" + a + "' not equal to: " + b); } Index: Reference.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/Reference.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Reference.java 5 Mar 2004 23:47:17 -0000 1.15 --- Reference.java 8 Mar 2004 23:51:03 -0000 1.16 *************** *** 1,4 **** --- 1,8 ---- /* $Id$ * $Log$ + * Revision 1.16 2004/03/08 23:51:03 pelle + * More improvements on the XMLSignature. Now uses the Transforms properly, References properly. + * All the major elements have been refactored to be cleaner and more correct. + * * Revision 1.15 2004/03/05 23:47:17 pelle * Attempting to make Reference and SignedInfo more compliant with the standard. *************** *** 162,178 **** import org.dom4j.Element; import org.neuclear.commons.Utility; import org.neuclear.commons.crypto.CryptoTools; - import org.neuclear.xml.XMLException; import org.neuclear.xml.XMLTools; import org.neuclear.xml.c14.Canonicalizer; ! import org.neuclear.xml.c14.CanonicalizerWithoutSignature; - import java.io.BufferedInputStream; - import java.io.ByteArrayOutputStream; import java.io.IOException; - import java.io.InputStream; - import java.net.MalformedURLException; import java.net.URL; public final class Reference extends AbstractXMLSigElement { --- 166,181 ---- import org.dom4j.Element; + import org.dom4j.Node; import org.neuclear.commons.Utility; import org.neuclear.commons.crypto.CryptoTools; import org.neuclear.xml.XMLTools; import org.neuclear.xml.c14.Canonicalizer; ! import org.neuclear.xml.transforms.EnvelopedSignatureTransform; ! import org.neuclear.xml.transforms.Transform; ! import org.neuclear.xml.transforms.TransformerFactory; import java.io.IOException; import java.net.URL; + import java.util.List; public final class Reference extends AbstractXMLSigElement { *************** *** 187,234 **** * <ul> */ ! public Reference(final Element root, final int sigtype) throws XMLSecurityException { ! super(Reference.TAG_NAME); ! final Canonicalizer canon; ! object = root; ! Element transformsElement = addElement("Transforms"); ! // final Element object; ! if (sigtype == XMLSIGTYPE_ENVELOPED) { ! createAttribute("URI", ""); ! canon = new CanonicalizerWithoutSignature(); ! transformsElement.addElement(XMLSecTools.createQName("Transform")).addAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature"); ! } else if (sigtype == XMLSIGTYPE_ENVELOPING) { ! canon = new Canonicalizer(); ! } else { ! throw new XMLSecurityException("Unsupported Signature Method"); ! } ! transformsElement.addElement(XMLSecTools.createQName("Transform")).addAttribute("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"); ! final String id = Utility.denullString(root.attributeValue("Id"), root.attributeValue("ID")); if (!Utility.isEmpty(id)) ! createAttribute("URI", "#" + id); ! digest = addDigest(canon, root); } ! private Reference(Object object, InputStream is) throws XMLSecurityException { super(Reference.TAG_NAME); ! try { ! digest = new String(CryptoTools.digest(is)); ! this.object = object; ! } catch (IOException e) { ! throw new XMLSecurityException(e); } } ! public Reference(final String url) throws XMLSecurityException, IOException { ! this(new URL(url)); } ! public Reference(final URL url) throws XMLSecurityException, IOException { ! this(url, url.openStream()); ! createAttribute("URI", url.toExternalForm()); } /** * Build this from XML Reference Element --- 190,275 ---- * <ul> */ ! public Reference(final Element root, boolean enveloped) throws XMLSecurityException { ! this(root, createTransformerArray(enveloped)); ! } ! private static Transform[] createTransformerArray(boolean enveloped) { ! if (enveloped) ! return new Transform[]{new EnvelopedSignatureTransform(), new Canonicalizer()}; ! else ! return new Transform[]{new Canonicalizer()}; ! } ! ! public Reference(final Element elem, final Transform transforms[]) throws XMLSecurityException { ! this(elem, calculateDigest(elem, transforms), transforms); ! final String id = Utility.denullString(elem.attributeValue("Id"), elem.attributeValue("ID")); if (!Utility.isEmpty(id)) ! createAttribute("URI", "#" + elem.attributeValue("Id")); ! } ! /** ! * Creates a simple Reference to an Element for use in an Enveloped Signature. ! * ! * @param root ! * @return ! * @throws XMLSecurityException ! */ ! public static Reference createEnvelopedReference(final Element root) throws XMLSecurityException { ! return new Reference(root, true); } ! /** ! * Creates a simple Reference to an element which already is inside an Object tag and has a URI. ! * ! * @param root ! * @return ! * @throws XMLSecurityException ! */ ! public static Reference createEnvelopingObjectReference(final Element root) throws XMLSecurityException { ! return new Reference(root, false); ! } ! ! public static Reference createExternalReference(final String url) throws XMLSecurityException { ! return new Reference(url); ! } ! ! private static byte[] calculateDigest(final Element elem, final Transform[] transforms) throws XMLSecurityException { ! Object obj = elem; ! for (int i = 0; i < (transforms.length - 1); i++) ! obj = transforms[i].transformNode(obj); ! if (transforms[transforms.length - 1] instanceof Canonicalizer) ! return CryptoTools.digest(((Canonicalizer) transforms[transforms.length - 1]).canonicalize(obj)); ! throw new XMLSecurityException("Final transform must be a Canonicalizer"); ! } ! ! private Reference(Element elem, byte[] digest, Transform transforms[]) { super(Reference.TAG_NAME); ! this.refObject = elem; ! if (transforms != null && transforms.length > 0) { ! Element transformsElement = addElement("Transforms"); ! for (int i = 0; i < transforms.length; i++) { ! transformsElement.add(transforms[i].getElement()); ! } } + addElement("DigestMethod").addAttribute(XMLSecTools.createQName("Algorithm"), "http://www.w3.org/2000/09/xmldsig#sha1"); + getElement().add(XMLSecTools.base64ToElement("DigestValue", digest)); } ! public Reference(String url) throws XMLSecurityException { ! this(null, digest(url), null); ! createAttribute("URI", url); } ! ! private static byte[] digest(String url) throws XMLSecurityException { ! try { ! return CryptoTools.digest(new URL(url).openStream()); ! } catch (IOException e) { ! throw new XMLSecurityException(e); ! } } + /** * Build this from XML Reference Element *************** *** 241,275 **** if (!elem.getQName().getName().equals(TAG_NAME)) throw new XMLSecurityException("Element: " + elem.getQualifiedName() + " is not a valid: " + XMLSecTools.NS_DS.getPrefix() + ":" + TAG_NAME); ! int type = findSignatureType(elem); ! ! digest = new String(XMLSecTools.decodeBase64Element(getElement().element(XMLSecTools.createQName("DigestValue")))); ! ! object = findRefElement(elem); ! if (object == null) ! throw new XMLSecurityException("Couldnt Dereference Object:\n " + elem.asXML()); ! final Canonicalizer canon; ! if (type == XMLSIGTYPE_ENVELOPED) ! canon = new CanonicalizerWithoutSignature(); ! else ! canon = new Canonicalizer(); ! final String dig2 = createDigest(canon, object); ! if (!digest.equals(dig2)) throw new InvalidSignatureException(digest, dig2); } ! private String addDigest(final Canonicalizer canon, Object root) throws XMLSecurityException { ! addElement("DigestMethod").addAttribute(XMLSecTools.createQName("Algorithm"), "http://www.w3.org/2000/09/xmldsig#sha1"); ! final String digest = createDigest(canon, root); ! getElement().add(XMLSecTools.base64ToElement("DigestValue", digest)); ! return digest; ! } ! ! private static String createDigest(final Canonicalizer canon, Object root) throws XMLSecurityException { final byte[] value = canon.canonicalize(root); // System.out.println("Canonicalized Reference:"); // System.out.println(new String(value)); // System.out.println("------"); ! return new String(CryptoTools.digest(value)); } --- 282,311 ---- if (!elem.getQName().getName().equals(TAG_NAME)) throw new XMLSecurityException("Element: " + elem.getQualifiedName() + " is not a valid: " + XMLSecTools.NS_DS.getPrefix() + ":" + TAG_NAME); ! byte[] digest = XMLSecTools.decodeBase64Element(getElement().element(XMLSecTools.createQName("DigestValue"))); ! final byte[] dig2; ! refObject = findRefElement(elem); ! if (refObject == null) { ! String uri = elem.attributeValue("URI"); ! dig2 = digest(uri); ! } else { ! Node node = refObject; ! final List list = elem.element(XMLSecTools.createQName("Transforms")).elements(XMLSecTools.createQName("Transform")); ! for (int i = 0; i < list.size() - 1; i++) { ! Transform o = TransformerFactory.make((Element) list.get(i)); ! node = (Node) o.transformNode(node); ! } ! dig2 = createDigest((Canonicalizer) TransformerFactory.make((Element) list.get(list.size() - 1)), node); ! } ! if (!CryptoTools.equalByteArrays(digest, dig2)) throw new InvalidSignatureException(digest, dig2); } ! private static byte[] createDigest(final Canonicalizer canon, Object root) throws XMLSecurityException { final byte[] value = canon.canonicalize(root); // System.out.println("Canonicalized Reference:"); // System.out.println(new String(value)); // System.out.println("------"); ! return CryptoTools.digest(value); } *************** *** 284,288 **** } ! private static Object findRefElement(Element elem) throws XMLSecurityException { final String id = elem.attributeValue("URI"); if (!Utility.isEmpty(id) && id.length() > 1) { --- 320,324 ---- } ! private static Element findRefElement(Element elem) throws XMLSecurityException { final String id = elem.attributeValue("URI"); if (!Utility.isEmpty(id) && id.length() > 1) { *************** *** 291,296 **** return XMLTools.getByID(elem, id.substring(1));//.createCopy(); } ! // Non Local URI, we need to load it ! return loadReference(id); } --- 327,332 ---- return XMLTools.getByID(elem, id.substring(1));//.createCopy(); } ! // Non Local URI, we dont set the referenced element ! return null; } *************** *** 299,330 **** } ! private static Object loadReference(final String refuri) throws XMLSecurityException { ! if (Utility.isEmpty(refuri)) ! throw new XMLSecurityException("XMLSignature is not linked to Document"); ! try { ! URL url = new URL(refuri); ! String ref = url.getRef(); ! if (ref != null) // If we have a reference part it is XML ! return XMLTools.loadDocument(url).getRootElement().elementByID(ref); ! BufferedInputStream is = new BufferedInputStream(url.openStream()); ! ByteArrayOutputStream os = new ByteArrayOutputStream(is.available()); ! byte input[] = new byte[is.available()]; ! int count = 0; ! while ((count = is.read(input)) >= 0) { ! os.write(input, 0, count); ! } ! is.close(); ! return new String(os.toByteArray()); ! } catch (XMLException e) { ! throw new XMLSecurityException(e); ! } catch (MalformedURLException e) { ! throw new XMLSecurityException(e); ! } catch (IOException e) { ! throw new XMLSecurityException(e); ! } ! } ! ! public String getDigest() { ! return digest; } --- 335,340 ---- } ! public Element getReferencedElement() { ! return refObject; } *************** *** 333,338 **** } ! private final String digest; ! public final Object object; private static final String TAG_NAME = "Reference"; --- 343,347 ---- } ! public final Element refObject; private static final String TAG_NAME = "Reference"; Index: SignedElement.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/SignedElement.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** SignedElement.java 14 Jan 2004 06:42:38 -0000 1.10 --- SignedElement.java 8 Mar 2004 23:51:03 -0000 1.11 *************** *** 1,4 **** --- 1,8 ---- /* $Id$ * $Log$ + * Revision 1.11 2004/03/08 23:51:03 pelle + * More improvements on the XMLSignature. Now uses the Transforms properly, References properly. + * All the major elements have been refactored to be cleaner and more correct. + * * Revision 1.10 2004/01/14 06:42:38 pelle * Got rid of the verifyXXX() methods *************** *** 146,150 **** import org.dom4j.Namespace; import org.dom4j.QName; - import org.neuclear.commons.crypto.CryptoException; import org.neuclear.commons.crypto.passphraseagents.UserCancellationException; import org.neuclear.commons.crypto.signers.NonExistingSignerException; --- 150,153 ---- *************** *** 153,159 **** import org.neuclear.xml.XMLException; - import java.security.PrivateKey; - import java.security.PublicKey; - public abstract class SignedElement extends AbstractElementProxy { --- 156,159 ---- *************** *** 173,177 **** throw new XMLSecurityException(e); } catch (InvalidSignatureException e) { ! throw new XMLSecurityException(e) ; } --- 173,177 ---- throw new XMLSecurityException(e); } catch (InvalidSignatureException e) { ! throw new XMLSecurityException(e); } *************** *** 220,226 **** return sig; } public boolean verify() throws XMLSecurityException { try { ! sig=new XMLSignature(getElement().element(XMLSecTools.createQName("Signature"))); return true; } catch (InvalidSignatureException e) { --- 220,227 ---- return sig; } + public boolean verify() throws XMLSecurityException { try { ! sig = new XMLSignature(getElement().element(XMLSecTools.createQName("Signature"))); return true; } catch (InvalidSignatureException e) { *************** *** 228,234 **** } } ! public final void sign(final String name, final Signer signer) throws XMLSecurityException, NonExistingSignerException, UserCancellationException { preSign(); ! sig = new XMLSignature(name,signer, getElement(),Reference.XMLSIGTYPE_ENVELOPED); postSign(); } --- 229,236 ---- } } ! ! public final void sign(final String name, final Signer signer) throws XMLSecurityException, UserCancellationException, NonExistingSignerException { preSign(); ! sig = new XMLSignature(name, signer, getElement(), true); postSign(); } Index: SignedInfo.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/SignedInfo.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** SignedInfo.java 5 Mar 2004 23:47:17 -0000 1.2 --- SignedInfo.java 8 Mar 2004 23:51:03 -0000 1.3 *************** *** 1,4 **** --- 1,8 ---- /* $Id$ * $Log$ + * Revision 1.3 2004/03/08 23:51:03 pelle + * More improvements on the XMLSignature. Now uses the Transforms properly, References properly. + * All the major elements have been refactored to be cleaner and more correct. + * * Revision 1.2 2004/03/05 23:47:17 pelle * Attempting to make Reference and SignedInfo more compliant with the standard. *************** *** 104,114 **** import org.dom4j.Element; import org.neuclear.commons.crypto.signers.Signer; import org.neuclear.xml.XMLException; import org.neuclear.xml.c14.Canonicalizer; ! import java.security.NoSuchAlgorithmException; ! import java.security.NoSuchProviderException; ! import java.security.Signature; import java.util.ArrayList; import java.util.Collections; --- 108,120 ---- import org.dom4j.Element; + import org.neuclear.commons.crypto.CryptoException; + import org.neuclear.commons.crypto.CryptoTools; + import org.neuclear.commons.crypto.passphraseagents.UserCancellationException; + import org.neuclear.commons.crypto.signers.NonExistingSignerException; import org.neuclear.commons.crypto.signers.Signer; import org.neuclear.xml.XMLException; import org.neuclear.xml.c14.Canonicalizer; ! import java.security.*; import java.util.ArrayList; import java.util.Collections; *************** *** 117,132 **** public final class SignedInfo extends AbstractXMLSigElement { public SignedInfo(Reference references[], final int sigalg) { ! super(SignedInfo.TAG_NAME); ! final ArrayList list = new ArrayList(references.length); for (int i = 0; i < references.length; i++) { ! list.add(references[i]); addElement(references[i]); } - this.refs = Collections.unmodifiableList(list); } ! public SignedInfo(final Element root, final int sigalg, final int sigtype) throws XMLSecurityException { super(SignedInfo.TAG_NAME); this.algType = sigalg; final Element cm = XMLSecTools.createElementInSignatureSpace("CanonicalizationMethod"); --- 123,153 ---- public final class SignedInfo extends AbstractXMLSigElement { public SignedInfo(Reference references[], final int sigalg) { ! this(sigalg, references.length); for (int i = 0; i < references.length; i++) { ! refs.add(references[i]); addElement(references[i]); } } ! public SignedInfo(final int sigalg, final int refcount) { super(SignedInfo.TAG_NAME); this.algType = sigalg; + refs = new ArrayList(refcount); + + final Element cm = XMLSecTools.createElementInSignatureSpace("CanonicalizationMethod"); + cm.addAttribute("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"); + addElement(cm); + + final Element sm = XMLSecTools.createElementInSignatureSpace("SignatureMethod"); + if (sigalg == SignedInfo.SIG_ALG_RSA) + sm.addAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1"); + else + sm.addAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#dsa-sha1"); + + addElement(sm); + } + + public SignedInfo(final Element root, final int sigalg, final boolean enveloped) throws XMLSecurityException { + this(sigalg, 1); final Element cm = XMLSecTools.createElementInSignatureSpace("CanonicalizationMethod"); *************** *** 142,149 **** addElement(sm); ! Reference ref = new Reference(root, sigtype); ! List list = new ArrayList(1); ! list.add(ref); ! this.refs = Collections.unmodifiableList(list); addElement(ref); } catch (XMLException e) { --- 163,168 ---- addElement(sm); ! Reference ref = new Reference(root, enveloped); ! refs.add(ref); addElement(ref); } catch (XMLException e) { *************** *** 160,169 **** c14nType = Canonicalizer.C14NTYPE_WITH_COMMENTS; final List list = elem.elements(XMLSecTools.createQName("Reference")); ! final List refList = new ArrayList(list.size()); for (int i = 0; i < list.size(); i++) { Element element = (Element) list.get(i); ! refList.add(new Reference(element)); } ! this.refs = Collections.unmodifiableList(refList); } --- 179,209 ---- c14nType = Canonicalizer.C14NTYPE_WITH_COMMENTS; final List list = elem.elements(XMLSecTools.createQName("Reference")); ! refs = new ArrayList(list.size()); for (int i = 0; i < list.size(); i++) { Element element = (Element) list.get(i); ! refs.add(new Reference(element)); } ! } ! ! /** ! * @param elem ! * @throws XMLSecurityException ! */ ! public void setEnvelopedReference(final Element elem) throws XMLSecurityException { ! Reference ref = Reference.createEnvelopedReference(elem); ! this.refs.add(ref); ! addElement(ref); ! } ! ! public void addEnvelopingReference(final Element elem) throws XMLSecurityException { ! Reference ref = Reference.createEnvelopingObjectReference(elem); ! this.refs.add(ref); ! addElement(ref); ! } ! ! public void addExternalReference(final String url) throws XMLSecurityException { ! Reference ref = Reference.createExternalReference(url); ! this.refs.add(ref); ! addElement(ref); } *************** *** 176,180 **** */ public final List getReferences() throws XMLSecurityException { ! return refs; } --- 216,229 ---- */ public final List getReferences() throws XMLSecurityException { ! return Collections.unmodifiableList(refs); ! } ! ! /** ! * Returns the Element of the first Reference ! * ! * @return ! */ ! public final Element getPrimaryReference() { ! return ((Reference) refs.get(0)).getReferencedElement(); } *************** *** 203,206 **** --- 252,282 ---- } + /** + * Signs the SignedInfo and returns the signature + * + * @param key + * @return + * @throws XMLSecurityException + */ + public final byte[] sign(PrivateKey key) throws XMLSecurityException { + try { + return CryptoTools.sign(key, canonicalize()); + } catch (CryptoException e) { + throw new XMLSecurityException(e); + } + } + + public final byte[] sign(String name, Signer signer) throws XMLSecurityException, NonExistingSignerException, UserCancellationException { + return signer.sign(name, canonicalize()); + } + + public final boolean verify(PublicKey pub, byte[] sig) throws XMLSecurityException { + try { + return CryptoTools.verify(pub, canonicalize(), sig); + } catch (CryptoException e) { + throw new XMLSecurityException(e); + } + } + public final String getTagName() { return TAG_NAME; Index: XMLSecTools.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/XMLSecTools.java,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** XMLSecTools.java 5 Mar 2004 23:47:17 -0000 1.12 --- XMLSecTools.java 8 Mar 2004 23:51:03 -0000 1.13 *************** *** 1,4 **** --- 1,8 ---- /* $Id$ * $Log$ + * Revision 1.13 2004/03/08 23:51:03 pelle + * More improvements on the XMLSignature. Now uses the Transforms properly, References properly. + * All the major elements have been refactored to be cleaner and more correct. + * * Revision 1.12 2004/03/05 23:47:17 pelle * Attempting to make Reference and SignedInfo more compliant with the standard. *************** *** 181,190 **** import org.neuclear.xml.XMLException; import org.neuclear.xml.c14.Canonicalizer; - import org.neuclear.xml.c14.CanonicalizerWithoutSignature; import java.io.IOException; import java.io.StringWriter; import java.math.BigInteger; ! import java.security.*; import java.security.cert.Certificate; import java.util.Iterator; --- 185,196 ---- import org.neuclear.xml.XMLException; import org.neuclear.xml.c14.Canonicalizer; import java.io.IOException; import java.io.StringWriter; import java.math.BigInteger; ! import java.security.KeyPair; ! import java.security.KeyStore; ! import java.security.KeyStoreException; ! import java.security.PublicKey; import java.security.cert.Certificate; import java.util.Iterator; *************** *** 232,236 **** */ public static XMLSignature signElement(final Element root, final String name, final org.neuclear.commons.crypto.signers.Signer signer) throws XMLSecurityException, NonExistingSignerException, UserCancellationException {//, KeyStoreException { ! return new XMLSignature(name, signer, root, Reference.XMLSIGTYPE_ENVELOPED); } --- 238,242 ---- */ public static XMLSignature signElement(final Element root, final String name, final org.neuclear.commons.crypto.signers.Signer signer) throws XMLSecurityException, NonExistingSignerException, UserCancellationException {//, KeyStoreException { ! return new XMLSignature(name, signer, root, true); } *************** *** 243,260 **** */ public static XMLSignature signElementEnveloping(final Element root, final KeyPair keypair) throws XMLSecurityException, CryptoException {//, KeyStoreException { ! final XMLSignature sig = new XMLSignature(keypair, root, Reference.XMLSIGTYPE_ENVELOPING); ! return sig; ! } ! ! /** ! * Signs an element with a given Private Key and embeds the element within the Signature. ! * ! * @param baseURI Unique ID of the Element to be signed ! * @param root Element to be signed ! * @param key RSA Private Key ! * @throws XMLSecurityException ! */ ! public static XMLSignature signElementEnveloping(final String baseURI, final Element root, final PrivateKey key) throws XMLSecurityException, CryptoException {//, KeyStoreException { ! final XMLSignature sig = new XMLSignature(key, null, root, Reference.XMLSIGTYPE_ENVELOPING); return sig; } --- 249,253 ---- */ public static XMLSignature signElementEnveloping(final Element root, final KeyPair keypair) throws XMLSecurityException, CryptoException {//, KeyStoreException { ! final XMLSignature sig = new XMLSignature(keypair, root, false); return sig; } *************** *** 392,405 **** /** - * This canonicalizes an object while leaving out any embedded signatures. - * - * @param node - * @return - */ - public static byte[] canonicalizeEmbeddedSignature(final Object node) throws XMLSecurityException { - return canonicalize(new CanonicalizerWithoutSignature(), node); - } - - /** * Canonicalizes an object based on the given Canonicalizer * --- 385,388 ---- Index: XMLSignature.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/XMLSignature.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** XMLSignature.java 2 Mar 2004 23:30:43 -0000 1.14 --- XMLSignature.java 8 Mar 2004 23:51:03 -0000 1.15 *************** *** 1,4 **** --- 1,8 ---- /* $Id$ * $Log$ + * Revision 1.15 2004/03/08 23:51:03 pelle + * More improvements on the XMLSignature. Now uses the Transforms properly, References properly. + * All the major elements have been refactored to be cleaner and more correct. + * * Revision 1.14 2004/03/02 23:30:43 pelle * Renamed SignatureInfo to SignedInfo as that is the name of the Element. *************** *** 200,207 **** import org.neuclear.commons.crypto.signers.PublicKeySource; import org.neuclear.commons.crypto.signers.Signer; - import org.neuclear.xml.XMLException; import java.security.KeyPair; - import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; --- 204,209 ---- *************** *** 219,305 **** * @throws XMLSecurityException */ ! public XMLSignature(final KeyPair keypair, final Element root) throws XMLSecurityException, CryptoException { ! this(keypair.getPrivate(), keypair.getPublic(), root); } - /** - * Creates a Signature object based on given element root. - * - * @param keypair - * @param root - * @param type Reference.XMLSIGTYPE_ENVELOPED,Reference.XMLSIGTYPE_ENVELOPING or Reference.XMLSIGTYPE_DETACHED - * @throws XMLSecurityException - */ - public XMLSignature(final KeyPair keypair, final Element root, final int type) throws XMLSecurityException, CryptoException { - this(keypair.getPrivate(), keypair.getPublic(), root, type); - } ! public XMLSignature(final PrivateKey key, final PublicKey pub, final Element root) throws XMLSecurityException, CryptoException { ! this(key, pub, root, Reference.XMLSIGTYPE_ENVELOPED); } ! /** ! * Internal constructor used for common stuff regardless of key type ! * ! * @param pub ! * @param root ! * @param type ! * @throws XMLSecurityException ! */ ! private XMLSignature(final PublicKey pub, Element root, final int type) throws XMLSecurityException { ! super(XMLSignature.TAG_NAME); ! try { ! if (type == Reference.XMLSIGTYPE_ENVELOPED) { ! root.add(getElement()); ! } else if (type == Reference.XMLSIGTYPE_ENVELOPING) { ! final Element objElem = XMLSecTools.createElementInSignatureSpace("Object"); ! objElem.addAttribute("Id", "data"); ! DocumentHelper.createDocument(getElement());//As Signature Element is parent we will now add a doc ! objElem.add(root); ! root = objElem; ! getElement().add(root); ! } ! final int alg = (pub instanceof RSAPublicKey) ? SignedInfo.SIG_ALG_RSA : SignedInfo.SIG_ALG_DSA; ! si = new SignedInfo(root, alg, type); ! addElement(si); ! sigval = addElement("SignatureValue"); ! if (pub != null) ! addElement(new KeyInfo(pub)); - // If Enveloping add Object element last - if (type == Reference.XMLSIGTYPE_ENVELOPING) { - getElement().remove(root); - getElement().add(root); - } - } catch (XMLException e) { - throw new XMLSecurityException(e); - } } ! public XMLSignature(final PrivateKey key, final PublicKey pub, Element root, final int type) throws XMLSecurityException, CryptoException { ! this(pub, root, type); ! final byte[] cansi = si.canonicalize(); ! // System.out.println("Canonicalized:"); ! // System.out.println(new String(cansi)); ! // System.out.println("------"); ! sigval.setText(Base64.encode(CryptoTools.sign(key, cansi))); } ! public XMLSignature(final String name, final Signer signer, Element root, final int type) throws XMLSecurityException, UserCancellationException, NonExistingSignerException { ! this(getPublicKey(signer, name), root, type); ! final byte[] cansi = si.canonicalize(); ! // System.out.println("Canonicalized SI:"); ! // System.out.println(new String(cansi)); ! // System.out.println("------"); ! sigval.setText(Base64.encode(signer.sign(name, cansi))); } ! private static PublicKey getPublicKey(final Signer signer, final String name) throws XMLSecurityException, NonExistingSignerException { ! if (!(signer instanceof PublicKeySource)) ! throw new XMLSecurityException("The Signer must also be a public key source"); ! return ((PublicKeySource) signer).getPublicKey(name); } public XMLSignature(final Element elem) throws XMLSecurityException, InvalidSignatureException { super(elem); --- 221,279 ---- * @throws XMLSecurityException */ ! public XMLSignature(final KeyPair keypair, final Element root) throws XMLSecurityException { ! this(keypair, root, true); } ! public XMLSignature(final KeyPair kp, final Element elem, final boolean embedded) throws XMLSecurityException { ! this(kp.getPublic(), new SignedInfo(getSignatureAlgorithm(kp.getPublic()), 1)); ! if (embedded) { ! si.setEnvelopedReference(elem); ! elem.add(getElement()); ! } else ! si.addEnvelopingReference(addDataObject("data", elem)); + sign(kp); } ! public XMLSignature(final String name, final Signer signer, final Element elem, final boolean embedded) throws XMLSecurityException, UserCancellationException, NonExistingSignerException { ! this(getPublicKey(name, signer), new SignedInfo(getSignatureAlgorithm(getPublicKey(name, signer)), 1)); ! if (embedded) { ! si.setEnvelopedReference(elem); ! elem.add(getElement()); ! } else ! si.addEnvelopingReference(addDataObject("data", elem)); ! sign(name, signer); } ! private XMLSignature(final PublicKey pub, final SignedInfo si) { ! super(XMLSignature.TAG_NAME); ! this.si = si; ! addElement(si); ! sigval = addElement("SignatureValue"); ! if (pub != null) ! addElement(new KeyInfo(pub)); } ! public XMLSignature(final KeyPair kp, final SignedInfo si) throws XMLSecurityException, CryptoException { ! this(kp.getPublic(), si); ! sign(kp); } ! ! public XMLSignature(final String name, final Signer signer, final SignedInfo si) throws XMLSecurityException, UserCancellationException, NonExistingSignerException { ! this(getPublicKey(name, signer), si); ! sign(name, signer); } + + /** + * Constructor from Raw XML + * + * @param elem + * @throws XMLSecurityException + * @throws InvalidSignatureException + */ public XMLSignature(final Element elem) throws XMLSecurityException, InvalidSignatureException { super(elem); *************** *** 333,343 **** si = new SignedInfo(siElem); final byte[] sig = getSignature(); ! final byte[] cansi = si.canonicalize(); ! try { ! if (!CryptoTools.verify(pub, cansi, sig)) ! throw new InvalidSignatureException(pub); ! } catch (CryptoException e) { ! throw new XMLSecurityException(e); ! } } --- 307,339 ---- si = new SignedInfo(siElem); final byte[] sig = getSignature(); ! if (!si.verify(pub, sig)) ! throw new InvalidSignatureException(pub); ! } ! ! static private int getSignatureAlgorithm(final PublicKey pub) { ! return (pub instanceof RSAPublicKey) ? SignedInfo.SIG_ALG_RSA : SignedInfo.SIG_ALG_DSA; ! } ! ! private void sign(final KeyPair kp) throws XMLSecurityException { ! sigval.setText(Base64.encode(si.sign(kp.getPrivate()))); ! } ! ! private void sign(final String name, final Signer signer) throws XMLSecurityException, NonExistingSignerException, UserCancellationException { ! sigval.setText(Base64.encode(si.sign(name, signer))); ! } ! ! private Element addDataObject(final String id, final Element root) { ! final Element objElem = XMLSecTools.createElementInSignatureSpace("Object"); ! objElem.addAttribute("Id", id); ! DocumentHelper.createDocument(getElement());//As Signature Element is parent we will now add a doc ! objElem.add(root); ! getElement().add(objElem); ! return objElem; ! } ! ! private static PublicKey getPublicKey(final String name, final Signer signer) throws XMLSecurityException, NonExistingSignerException { ! if (!(signer instanceof PublicKeySource)) ! throw new XMLSecurityException("The Signer must also be a public key source"); ! return ((PublicKeySource) signer).getPublicKey(name); } *************** *** 376,380 **** } ! protected final SignedInfo getSi() { return si; } --- 372,376 ---- } ! public final SignedInfo getSi() { return si; } |