Update of /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30922/src/java/org/neuclear/xml/xmlsec Modified Files: InvalidSignatureException.java Reference.java SignedInfo.java XMLSecTools.java Log Message: Attempting to make Reference and SignedInfo more compliant with the standard. SignedInfo can now contain more than one reference. Reference is on the way to becoming more flexible and two support more than one transform. I am adding Crypto Channels to commons to help this out and to hopefully speed things up as well. Index: InvalidSignatureException.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/InvalidSignatureException.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** InvalidSignatureException.java 14 Jan 2004 16:34:27 -0000 1.2 --- InvalidSignatureException.java 5 Mar 2004 23:47:17 -0000 1.3 *************** *** 11,19 **** */ public class InvalidSignatureException extends Exception { ! public InvalidSignatureException(byte a[],byte b[]) { ! super("Digest: '"+a+"' not equal to: "+b); } ! public InvalidSignatureException(PublicKey pub){ ! super("Publick Key: "+pub.toString()+ " didnt sign this signature"); } } --- 11,20 ---- */ public class InvalidSignatureException extends Exception { ! public InvalidSignatureException(String a, String b) { ! super("Digest: '" + a + "' not equal to: " + b); } ! ! public InvalidSignatureException(PublicKey pub) { ! super("Public Key: " + pub.toString() + " didnt sign this signature"); } } Index: Reference.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/Reference.java,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** Reference.java 3 Mar 2004 23:23:24 -0000 1.14 --- Reference.java 5 Mar 2004 23:47:17 -0000 1.15 *************** *** 1,4 **** --- 1,10 ---- /* $Id$ * $Log$ + * Revision 1.15 2004/03/05 23:47:17 pelle + * Attempting to make Reference and SignedInfo more compliant with the standard. + * SignedInfo can now contain more than one reference. + * Reference is on the way to becoming more flexible and two support more than one transform. + * I am adding Crypto Channels to commons to help this out and to hopefully speed things up as well. + * * Revision 1.14 2004/03/03 23:23:24 pelle * Interops with enveloped signatures. *************** *** 166,169 **** --- 172,176 ---- import java.io.ByteArrayOutputStream; import java.io.IOException; + import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; *************** *** 183,187 **** super(Reference.TAG_NAME); final Canonicalizer canon; ! Object ref = null; Element transformsElement = addElement("Transforms"); // final Element object; --- 190,194 ---- super(Reference.TAG_NAME); final Canonicalizer canon; ! object = root; Element transformsElement = addElement("Transforms"); // final Element object; *************** *** 190,197 **** canon = new CanonicalizerWithoutSignature(); transformsElement.addElement(XMLSecTools.createQName("Transform")).addAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature"); - ref = root; } else if (sigtype == XMLSIGTYPE_ENVELOPING) { canon = new Canonicalizer(); - ref = root; } else { throw new XMLSecurityException("Unsupported Signature Method"); --- 197,202 ---- *************** *** 199,216 **** transformsElement.addElement(XMLSecTools.createQName("Transform")).addAttribute("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"); - type = sigtype; final String id = Utility.denullString(root.attributeValue("Id"), root.attributeValue("ID")); if (!Utility.isEmpty(id)) createAttribute("URI", "#" + id); ! addDigest(canon, ref); } ! ! public Reference(final String uri) throws XMLSecurityException { super(Reference.TAG_NAME); ! type = XMLSIGTYPE_DETACHED; ! createAttribute("URI", uri); ! addDigest(new Canonicalizer(), loadReference(uri)); } --- 204,232 ---- 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()); } *************** *** 225,233 **** if (!elem.getQName().getName().equals(TAG_NAME)) throw new XMLSecurityException("Element: " + elem.getQualifiedName() + " is not a valid: " + XMLSecTools.NS_DS.getPrefix() + ":" + TAG_NAME); ! type = findSignatureType(elem); ! byte digest[] = XMLSecTools.decodeBase64Element(getElement().element(XMLSecTools.createQName("DigestValue"))); ! final Object object = findRefElement(elem); if (object == null) throw new XMLSecurityException("Couldnt Dereference Object:\n " + elem.asXML()); --- 241,249 ---- 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()); *************** *** 238,257 **** canon = new Canonicalizer(); ! final byte dig2[] = createDigest(canon, object); ! if (!CryptoTools.equalByteArrays(digest, dig2)) throw new InvalidSignatureException(digest, dig2); } ! private void addDigest(final Canonicalizer canon, Object root) throws XMLSecurityException { addElement("DigestMethod").addAttribute(XMLSecTools.createQName("Algorithm"), "http://www.w3.org/2000/09/xmldsig#sha1"); ! getElement().add(XMLSecTools.base64ToElement("DigestValue", createDigest(canon, root))); } ! 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); } --- 254,275 ---- 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)); } *************** *** 307,310 **** --- 325,331 ---- } + public String getDigest() { + return digest; + } public String getUri() { *************** *** 312,318 **** } ! private final int type; ! private static final String TAG_NAME = "Reference"; public final static int XMLSIGTYPE_ENVELOPED = 0; public final static int XMLSIGTYPE_ENVELOPING = 1; --- 333,340 ---- } ! private final String digest; ! public final Object object; + private static final String TAG_NAME = "Reference"; public final static int XMLSIGTYPE_ENVELOPED = 0; public final static int XMLSIGTYPE_ENVELOPING = 1; Index: SignedInfo.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/SignedInfo.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** SignedInfo.java 2 Mar 2004 23:30:43 -0000 1.1 --- SignedInfo.java 5 Mar 2004 23:47:17 -0000 1.2 *************** *** 1,4 **** --- 1,10 ---- /* $Id$ * $Log$ + * Revision 1.2 2004/03/05 23:47:17 pelle + * Attempting to make Reference and SignedInfo more compliant with the standard. + * SignedInfo can now contain more than one reference. + * Reference is on the way to becoming more flexible and two support more than one transform. + * I am adding Crypto Channels to commons to help this out and to hopefully speed things up as well. + * * Revision 1.1 2004/03/02 23:30:43 pelle * Renamed SignatureInfo to SignedInfo as that is the name of the Element. *************** *** 105,110 **** --- 111,129 ---- import java.security.NoSuchProviderException; import java.security.Signature; + import java.util.ArrayList; + import java.util.Collections; + import java.util.List; 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); *************** *** 123,127 **** addElement(sm); ! ref = new Reference(root, sigtype); addElement(ref); } catch (XMLException e) { --- 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) { *************** *** 134,146 **** if (!elem.getQName().equals(XMLSecTools.createQName(TAG_NAME))) throw new XMLSecurityException("Element: " + elem.getQualifiedName() + " is not a valid: " + XMLSecTools.NS_DS.getPrefix() + ":" + TAG_NAME); - this.sig = sig; final Element c14elem = elem.element(XMLSecTools.createQName("CanonicalizationMethod")); if (c14elem != null && c14elem.attributeValue("Algorithm").equals("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments")) c14nType = Canonicalizer.C14NTYPE_WITH_COMMENTS; ! final Element refElem = elem.element(XMLSecTools.createQName("Reference")); ! if (refElem != null) ! ref = new Reference(refElem); ! //Check reference element if signature is enveloped ! } --- 156,169 ---- if (!elem.getQName().equals(XMLSecTools.createQName(TAG_NAME))) throw new XMLSecurityException("Element: " + elem.getQualifiedName() + " is not a valid: " + XMLSecTools.NS_DS.getPrefix() + ":" + TAG_NAME); final Element c14elem = elem.element(XMLSecTools.createQName("CanonicalizationMethod")); if (c14elem != null && c14elem.attributeValue("Algorithm").equals("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments")) 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); } *************** *** 152,157 **** * @throws XMLSecurityException */ ! public final Reference getReference() throws XMLSecurityException { ! return ref; } --- 175,180 ---- * @throws XMLSecurityException */ ! public final List getReferences() throws XMLSecurityException { ! return refs; } *************** *** 164,171 **** } - final XMLSignature getSig() { - return sig; - } - //TODO Ignore this bit for now final Signature getSignatureAlgorithm() throws XMLSecurityException { --- 187,190 ---- *************** *** 189,196 **** private static final String TAG_NAME = "SignedInfo"; ! private Reference ref; private int c14nType = 0; private int algType = 0; - private XMLSignature sig; public final static int SIG_ALG_RSA = Signer.KEY_RSA; --- 208,214 ---- private static final String TAG_NAME = "SignedInfo"; ! private final List refs; private int c14nType = 0; private int algType = 0; public final static int SIG_ALG_RSA = Signer.KEY_RSA; Index: XMLSecTools.java =================================================================== RCS file: /cvsroot/neuclear/neuclear-xmlsig/src/java/org/neuclear/xml/xmlsec/XMLSecTools.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** XMLSecTools.java 19 Feb 2004 19:37:34 -0000 1.11 --- XMLSecTools.java 5 Mar 2004 23:47:17 -0000 1.12 *************** *** 1,4 **** --- 1,10 ---- /* $Id$ * $Log$ + * Revision 1.12 2004/03/05 23:47:17 pelle + * Attempting to make Reference and SignedInfo more compliant with the standard. + * SignedInfo can now contain more than one reference. + * Reference is on the way to becoming more flexible and two support more than one transform. + * I am adding Crypto Channels to commons to help this out and to hopefully speed things up as well. + * * Revision 1.11 2004/02/19 19:37:34 pelle * At times IntelliJ IDEA can cause some real hassle. On my last checkin it optimized away all of the dom4j and command line imports. *************** *** 167,173 **** */ - import org.dom4j.io.XMLWriter; import org.dom4j.*; ! import org.neuclear.commons.crypto.Base64; import org.neuclear.commons.crypto.CryptoException; --- 173,178 ---- */ import org.dom4j.*; ! import org.dom4j.io.XMLWriter; import org.neuclear.commons.crypto.Base64; import org.neuclear.commons.crypto.CryptoException; *************** *** 560,563 **** --- 565,586 ---- /** * Method base64ToElement + * + * @param localName + * @param data + * @return + */ + public static Element base64ToElement(final String localName, + final String data) { + + final Element el = createElementInSignatureSpace(localName); + final Text text = DocumentHelper.createText(Base64.encodeClean(data.getBytes())); + + el.add(text); + + return el; + } + + /** + * Method base64ToElement * * @param localName |