[Webfunds-commits] java/webfunds/sox BasicAgent.java BasicRequestPacket.java SimpleIssuer.java

Jeroen C. van Gelderen gelderen@cypherpunks.ai
Sat, 19 Aug 2000 22:59:30 -0400 (AST)


gelderen    00/08/19 22:59:29

  Modified:    webfunds/sox BasicAgent.java BasicRequestPacket.java
                        SimpleIssuer.java
  Log:
  Do proper certification chains.
  
  The scene and the rules (for OpenPGP contracts):
  - A Ricardian contract contains a Server Certification Key.
  - Each server has a Server Key which must be signed by the
    Server Certification Key.
  - Each server has a temporary Comms Keys which is generated
    on the fly (and may be changed periodically). Comms Keys
    are used for sending encrypted messages to the server.
    This key  must be signed by the Server Key.
  
  The implementation:
  1. The current (X.509) issuer is broken and doesn't have the
     appropriate signatures on it's Comms Key. We handle this
     by not veryfying any signature at all when an X.509 cert
     is received. For this reason, X.509 certs are insecure.
  
  2. Added a ServerKeyRequest/Response pair.
  
  3. For X.509 certs we follow a special code path (sse 1) so
     all other issuers can be expected to handle the ServerKey
     messages. We require that any non-X.509 issuer returns
     both a CommsKey and a ServerKey.
  
  4. ServerKey requests are handled in the fetchCommsKey method.
     This is where we verify the certification chain.
  
     Implementing this in the fetchCommsKey method is not
     architecturally correct but minimizes disruption which is
     deemed important right now.

Revision  Changes    Path
1.13      +16 -1     java/webfunds/sox/BasicAgent.java

Index: BasicAgent.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/BasicAgent.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- BasicAgent.java	2000/07/27 17:45:11	1.12
+++ BasicAgent.java	2000/08/20 02:59:29	1.13
@@ -1,5 +1,5 @@
 /*
- * $Id: BasicAgent.java,v 1.12 2000/07/27 17:45:11 gelderen Exp $
+ * $Id: BasicAgent.java,v 1.13 2000/08/20 02:59:29 gelderen Exp $
  *
  * Copyright (c) Systemics Ltd 1995-1999 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -80,6 +80,21 @@
             throw new SOXPacketException("Server rejected request (basic): (" +
                             reply.getErrno() + ") " + reply.getMessage());
         return reply.body();
+    }
+
+
+    public Certificate getServerKey()
+        throws SOXPacketException, SOXLaterException, SOXIssuerException
+    {
+        try {     // as we are doing a KeyRequest, a KeyEx is not on!
+            ServerKeyReply ckr = 
+                new ServerKeyReply(request(new ServerKeyRequest()));
+
+            return ckr.getCertificate();
+
+        } catch (SOXKeyException ex) {
+            throw new SOXPacketException("returned wrong Ex: " + ex);
+        }
     }
 
 



1.8       +7 -2      java/webfunds/sox/BasicRequestPacket.java

Index: BasicRequestPacket.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/BasicRequestPacket.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- BasicRequestPacket.java	2000/07/27 17:45:11	1.7
+++ BasicRequestPacket.java	2000/08/20 02:59:29	1.8
@@ -1,5 +1,5 @@
 /*
- * $Id: BasicRequestPacket.java,v 1.7 2000/07/27 17:45:11 gelderen Exp $
+ * $Id: BasicRequestPacket.java,v 1.8 2000/08/20 02:59:29 gelderen Exp $
  *
  * Copyright (c) Systemics Ltd 1995-1999 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -31,6 +31,7 @@
      */
     public static final String CERT_REQ = "SOX.CertReq";
     public static final String KEY_REQ = "SOX.KeyReq";
+    public static final String SERVER_KEY_REQ = "SOX.ServerKeyReq";
     public static final String ENCR_REQ = "SOX.EncReq";
 
 
@@ -55,9 +56,11 @@
         this.body = body;
         if (body instanceof CommsKeyRequest)
             type = KEY_REQ;
+        else if (body instanceof ServerKeyRequest)
+            type = SERVER_KEY_REQ;
         else if (body instanceof EncryptedRequest)
             type = ENCR_REQ;
-        else     // making a new one, therefore fatal, as bad code.
+        else
             throw new InternalError("Unknown basic request type: "+
                                     body.getClass().getName());
     }
@@ -108,6 +111,8 @@
   
             if (type.equals(KEY_REQ))
                 body = new CommsKeyRequest(encoded);
+            else if (type.equals(SERVER_KEY_REQ))
+                body = new ServerKeyRequest(encoded);
             else if (type.equals(ENCR_REQ))
                 body = new EncryptedRequest(encoded);
             else



1.13      +38 -10    java/webfunds/sox/SimpleIssuer.java

Index: SimpleIssuer.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/SimpleIssuer.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- SimpleIssuer.java	2000/07/30 00:03:47	1.12
+++ SimpleIssuer.java	2000/08/20 02:59:29	1.13
@@ -1,5 +1,5 @@
 /*
- * $Id: SimpleIssuer.java,v 1.12 2000/07/30 00:03:47 gelderen Exp $
+ * $Id: SimpleIssuer.java,v 1.13 2000/08/20 02:59:29 gelderen Exp $
  *
  * Copyright (c) Systemics Ltd 1995-1999 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -147,16 +147,44 @@
             throw ex ;
         }
 
-        //
-        // Verify that the comms key is signed by the issuer's primary cert
-        //
-        PublicKey skey = Crypto.getPublicKeyFromCert(signer);
-        logmsg("Verifying comms cert is signed by server certificate");
-        if (!Crypto.verifyCertificate(commsCert, skey))
-            logmsg("Commskey is not signed by primary cert");
-        //throw new IllegalArgumentException("Invalid comms key! :"+commsCert);
-        else
+        /*
+         * If it's X.509, ignore the signature business because the existing
+         * server is broken and we don't want to fix it.
+         */
+        if( !commsCert.getType().equals("X.509") )
+        {
+            Certificate serverCert;
+            try {
+                logmsg("Requesting serverCert...");
+                serverCert = basicAgent.getServerKey();
+                logmsg("Got a serverCert!");
+            } catch (SOXLaterException ex) {
+                setDead(ex.getMessage()); // URL is wrong or server is down
+                throw ex;
+            } catch (SOXPacketException ex) {
+                setDead(ex.getMessage());
+                throw new SOXIssuerException("packet: " + ex.getMessage());
+            } catch (SOXIssuerException ex) {
+                setDead(ex.getMessage());      // BA thinks info is wrong
+                throw ex ;
+            }
+
+            PublicKey signerKey = Crypto.getPublicKeyFromCert(signer);
+            logmsg("Verifying ServerCert is signed by Server CA certificate");
+            if (!Crypto.verifyCertificate(serverCert, signerKey)) {
+                throw new SOXIssuerException(
+                    "serverCert not signed by server CA");
+            }
+
+            PublicKey serverKey = Crypto.getPublicKeyFromCert(serverCert);
+            logmsg("Verifying CommsCert is signed by serverCert");
+            if (!Crypto.verifyCertificate(commsCert, serverKey)) {
+                throw new SOXIssuerException(
+                    "commsCert not signed by serverCert");
+            }
+            
             logmsg("Using comms key (valid signature by the issuer)");
+        }
 
         // Careful not to set this before validating the signature
         commsKey = Crypto.getPublicKeyFromCert(commsCert);