You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2006/09/06 22:27:23 UTC

svn commit: r440857 - in /incubator/abdera/java/trunk/security/src: main/java/org/apache/abdera/security/ main/java/org/apache/abdera/security/util/ main/java/org/apache/abdera/security/xmlsec/ test/java/org/apache/abdera/test/security/

Author: jmsnell
Date: Wed Sep  6 13:27:22 2006
New Revision: 440857

URL: http://svn.apache.org/viewvc?view=rev&rev=440857
Log:
API improvements for the Signature interface

* Eliminate the separate sign(entry...) and sign(feed...) variations in favor of a
  single (T extends Element)sign(T...) generic approach

* Introduce a new API for extracting X509Certificates from valid signatures contained
  by a feed or entry (necessary if we want to determine if the signature is trustworthy)

* Update the digsig test case to make sure the X509 cert is extracted properly

Modified:
    incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/Signature.java
    incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/SignatureBase.java
    incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/xmlsec/XmlSignature.java
    incubator/abdera/java/trunk/security/src/test/java/org/apache/abdera/test/security/DigitalSignatureTest.java

Modified: incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/Signature.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/Signature.java?view=diff&rev=440857&r1=440856&r2=440857
==============================================================================
--- incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/Signature.java (original)
+++ incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/Signature.java Wed Sep  6 13:27:22 2006
@@ -17,22 +17,19 @@
 */
 package org.apache.abdera.security;
 
-import org.apache.abdera.model.Entry;
-import org.apache.abdera.model.Feed;
+import java.security.cert.X509Certificate;
+
+import org.apache.abdera.model.Element;
 
 public interface Signature {
 
-  boolean isSigned(Entry entry) throws SecurityException;
-  
-  boolean isSigned(Feed feed) throws SecurityException;
-  
-  Entry sign(Entry entry, SignatureOptions options) throws SecurityException;
+  <T extends Element>boolean isSigned(T element) throws SecurityException;
   
-  Feed sign(Feed feed, SignatureOptions options) throws SecurityException;
+  <T extends Element>T sign(T element, SignatureOptions options) throws SecurityException;
   
-  boolean verify(Entry entry, SignatureOptions options) throws SecurityException;
+  <T extends Element>boolean verify(T element, SignatureOptions options) throws SecurityException;
   
-  boolean verify(Feed feed, SignatureOptions options) throws SecurityException;
+  <T extends Element>X509Certificate[] getValidSignatureCertificates(T element, SignatureOptions options) throws SecurityException;
   
   SignatureOptions getDefaultSignatureOptions() throws SecurityException;
   

Modified: incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/SignatureBase.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/SignatureBase.java?view=diff&rev=440857&r1=440856&r2=440857
==============================================================================
--- incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/SignatureBase.java (original)
+++ incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/util/SignatureBase.java Wed Sep  6 13:27:22 2006
@@ -18,9 +18,8 @@
 package org.apache.abdera.security.util;
 
 import org.apache.abdera.Abdera;
-import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Element;
 import org.apache.abdera.model.ExtensibleElement;
-import org.apache.abdera.model.Feed;
 import org.apache.abdera.security.SecurityException;
 import org.apache.abdera.security.Signature;
 
@@ -33,18 +32,15 @@
     super(abdera);
   }
 
-  public boolean isSigned(
-    Entry entry)  throws SecurityException {
+  public <T extends Element>boolean isSigned(
+    T entry)  throws SecurityException {
       return _isSigned(entry);
   }
 
-  public boolean isSigned(
-    Feed feed)  throws SecurityException {
-      return _isSigned(feed);
-  }
-  
-  private boolean _isSigned(ExtensibleElement element) {
-    return element.getExtension(Constants.SIGNATURE) != null;
+  private <T extends Element>boolean _isSigned(T element) {
+    if (element instanceof ExtensibleElement)
+      return ((ExtensibleElement)element).getExtension(Constants.SIGNATURE) != null;
+    else return false;
   }
 
 }

Modified: incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/xmlsec/XmlSignature.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/xmlsec/XmlSignature.java?view=diff&rev=440857&r1=440856&r2=440857
==============================================================================
--- incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/xmlsec/XmlSignature.java (original)
+++ incubator/abdera/java/trunk/security/src/main/java/org/apache/abdera/security/xmlsec/XmlSignature.java Wed Sep  6 13:27:22 2006
@@ -22,11 +22,11 @@
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.apache.abdera.Abdera;
 import org.apache.abdera.model.Element;
-import org.apache.abdera.model.Entry;
-import org.apache.abdera.model.Feed;
 import org.apache.abdera.security.SecurityException;
 import org.apache.abdera.security.SignatureOptions;
 import org.apache.abdera.security.util.Constants;
@@ -56,8 +56,9 @@
     super(abdera);
   }
   
-  private Element _sign(
-    Element element, 
+  @SuppressWarnings("unchecked")
+  private <T extends Element>T _sign(
+    T element, 
     SignatureOptions options) 
       throws XMLSecurityException, 
              URISyntaxException {    
@@ -79,29 +80,83 @@
     sig.addKeyInfo(cert);
     sig.addKeyInfo(cert.getPublicKey());
     sig.sign(signingKey);    
-    return (Element)domToFom(dom, options);
+    return (T)domToFom(dom, options);
   }
   
-  public Entry sign(
-    Entry entry, 
+  public <T extends Element>T sign(
+    T entry, 
     SignatureOptions options) 
       throws SecurityException {
     try {
-      return (Entry) _sign(entry, options);
+      return (T) _sign(entry, options);
     } catch (Exception e) {
       throw new SecurityException(e);
     }
   }
-
-  public Feed sign(
-    Feed feed, 
+  
+  private boolean is_valid_signature(
+    XMLSignature sig) 
+      throws XMLSignatureException, 
+             XMLSecurityException, 
+             URISyntaxException {
+    boolean answer = false;
+    KeyInfo ki = sig.getKeyInfo();
+    if (ki != null) {
+      X509Certificate cert = ki.getX509Certificate();
+      if (cert != null) {
+        answer = sig.checkSignatureValue(cert);
+      } else {
+        PublicKey key = ki.getPublicKey();
+        if (key != null) {
+          answer = sig.checkSignatureValue(key);
+        }
+      }
+    }
+    return answer;
+  }
+  
+  private <T extends Element>X509Certificate[] _getcerts(
+    T element, 
     SignatureOptions options)
+      throws XMLSignatureException, 
+             XMLSecurityException, 
+             URISyntaxException {
+    List<X509Certificate> certs = new ArrayList<X509Certificate>();
+    org.w3c.dom.Element dom = fomToDom((Element)element, options);
+    NodeList children = dom.getChildNodes();
+    for (int n = 0; n < children.getLength(); n++) {
+      try {
+        Node node = children.item(n);
+        if (node.getNodeType() == Node.ELEMENT_NODE) {
+          org.w3c.dom.Element el = (org.w3c.dom.Element) node;
+          if (Constants.DSIG_NS.equals(el.getNamespaceURI()) &&
+              Constants.LN_SIGNATURE.equals(el.getLocalName())) {
+            URI baseUri = element.getResolvedBaseUri();
+            XMLSignature sig = 
+              new XMLSignature(
+                el, (baseUri != null) ? baseUri.toString() : "");
+            if (is_valid_signature(sig)) {
+              KeyInfo ki = sig.getKeyInfo();
+              if (ki != null) {
+                X509Certificate cert = ki.getX509Certificate();
+                if (cert != null) certs.add(cert);
+              }
+            }
+          }
+        }
+      } catch (Exception e) {}
+    }
+    return certs.toArray(new X509Certificate[certs.size()]);
+  }
+  
+  public <T extends Element>X509Certificate[] getValidSignatureCertificates(
+    T element, 
+    SignatureOptions options) 
       throws SecurityException {
     try {
-      return (Feed) _sign(feed, options);
-    } catch (Exception e) {
-      throw new SecurityException(e);
-    }
+      return _getcerts(element, options);
+    } catch (Exception e) {}
+    return null;
   }
   
   private boolean _verify(
@@ -123,18 +178,7 @@
           XMLSignature sig = 
             new XMLSignature(
               el, (baseUri != null) ? baseUri.toString() : "");
-          KeyInfo ki = sig.getKeyInfo();
-          if (ki != null) {
-            X509Certificate cert = ki.getX509Certificate();
-            if (cert != null) {
-              answer = sig.checkSignatureValue(cert);
-            } else {
-              PublicKey key = ki.getPublicKey();
-              if (key != null) {
-                answer = sig.checkSignatureValue(key);
-              }
-            }
-          }
+          answer = is_valid_signature(sig);
         }
       }
     }
@@ -142,23 +186,12 @@
     return answer;
   }
   
-  public boolean verify(
-    Entry entry, 
+  public <T extends Element>boolean verify(
+    T entry, 
     SignatureOptions options) throws SecurityException {
       if (!isSigned(entry)) return false;
       try {
         return _verify(entry,options);
-      } catch (Exception e) {
-        throw new SecurityException(e);
-      }
-  }
-
-  public boolean verify(
-    Feed feed, 
-    SignatureOptions options) throws SecurityException {
-      if (!isSigned(feed)) return false;
-      try {
-        return _verify(feed,options);
       } catch (Exception e) {
         throw new SecurityException(e);
       }

Modified: incubator/abdera/java/trunk/security/src/test/java/org/apache/abdera/test/security/DigitalSignatureTest.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/security/src/test/java/org/apache/abdera/test/security/DigitalSignatureTest.java?view=diff&rev=440857&r1=440856&r2=440857
==============================================================================
--- incubator/abdera/java/trunk/security/src/test/java/org/apache/abdera/test/security/DigitalSignatureTest.java (original)
+++ incubator/abdera/java/trunk/security/src/test/java/org/apache/abdera/test/security/DigitalSignatureTest.java Wed Sep  6 13:27:22 2006
@@ -92,6 +92,11 @@
           "http://www.w3.org/2000/09/xmldsig#", 
           "Signature")));
       
+    X509Certificate[] certs = sig.getValidSignatureCertificates(entry, options);
+    assertNotNull(certs);
+    assertEquals(certs.length, 1);
+    assertEquals(certs[0].getSubjectDN().getName(), "CN=James M Snell, OU=WebAhead, O=IBM, L=Hanford, ST=California, C=US");
+    
     // Check the round trip
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     entry.writeTo(out); // do not use the pretty writer, it will break the signature