[Webfunds-commits] java/webfunds/ricardian Contract.java

Edwin Woudt edwin@cypherpunks.ai
Mon, 7 Aug 2000 14:39:19 -0400 (AST)


edwin       00/08/07 14:39:19

  Modified:    webfunds/ricardian Contract.java
  Log:
  Support for OpenPGP contracts.

Revision  Changes    Path
1.27      +80 -14    java/webfunds/ricardian/Contract.java

Index: Contract.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/ricardian/Contract.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- Contract.java	2000/08/07 02:14:41	1.26
+++ Contract.java	2000/08/07 18:39:18	1.27
@@ -1,10 +1,11 @@
-/* $Id: Contract.java,v 1.26 2000/08/07 02:14:41 edwin Exp $
+/* $Id: Contract.java,v 1.27 2000/08/07 18:39:18 edwin Exp $
  *
  * Copyright (c) Systemics Ltd 1995-1999 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
  */
 package webfunds.ricardian;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -17,6 +18,8 @@
 import java.net.MalformedURLException;
 import java.security.*;
 import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.util.Enumeration;
 import java.util.Hashtable;
 
@@ -37,9 +40,12 @@
 import webfunds.sox.SOXKeyException;
 import webfunds.sox.utils.Base64;
 
+import cryptix.openpgp.PGPException;
 import cryptix.openpgp.PGPMessage;
 import cryptix.openpgp.PGPPublicKey;
 
+import cryptix.openpgp.util.PGPArmoury;
+
 
 /**
  * Ricardian Contract Base Class
@@ -668,14 +674,6 @@
         return getCert("contract");
     }
 
-
-    // ### FIXME (edwin): Should read the key from the contract
-    private PGPPublicKey getContractCertPGP()
-        throws ContractException
-    {
-        throw new RuntimeException("Not implemented");
-    }
-
     /**
      * This is the top-level Issuer certification key,
      * which signs the contract key above.
@@ -736,11 +734,41 @@
             field = field.substring(0, end) + field.substring(end + 2);
 
         Certificate retval = null;
-        try {
-            retval =  Armoury.decodeCert( field );
-        } catch (SOXKeyException ex) {
-            throw new ContractException("contract signing key: " + ex);
+
+        if (field.indexOf("-----BEGIN PGP") >= 0) {
+        
+            // OpenPGP key
+            PGPArmoury armoured;
+
+            try {
+                armoured = new PGPArmoury(field);
+            } catch (IllegalArgumentException iae) {
+                throw new ContractException("Error parsing cert <"+name+"> -"+
+                                            iae);
+            }
+
+            ByteArrayInputStream bais =
+                                new ByteArrayInputStream(armoured.getPayload());
+
+            try {
+                CertificateFactory factory =
+                                      CertificateFactory.getInstance("OpenPGP");
+                retval = factory.generateCertificate(bais);
+            } catch (CertificateException ce) {
+                throw new ContractException("Error parsing cert <"+name+"> -"+
+                                            ce);
+            }
+            
+        } else {
+        
+            // X.509 key
+            try {
+                retval = Armoury.decodeCert( field );
+            } catch (SOXKeyException ex) {
+                throw new ContractException("contract signing key: " + ex);
+            }
         }
+
         return retval;
     }
 
@@ -758,7 +786,45 @@
         // ### FIXME (edwin): Figure out a better way to check this
         if (s.startsWith("-----BEGIN PGP SIGNED MESSAGE-----")) {
 
-            throw new RuntimeException("OpenPGP Contracts not supported yet.");
+            // get the contract cert and convert it to a PGPPublicKey
+            Certificate contractCert = getContractCert();
+            PGPPublicKey contractKey =
+                                      (PGPPublicKey)contractCert.getPublicKey();
+            
+            // verify the contract
+            boolean result;
+            try {
+                result = PGPMessage.verifyClearSign(s, contractKey);
+            } catch (IOException ioe) {
+                return false;
+            } catch (PGPException pe) {
+                throw new ContractException("Format error in contract - "+pe);
+            }
+             
+            // get the other certs
+            Certificate certificationCert = getCertificationCert();
+            Certificate serverCert = getServerCert();
+            
+            // verify certification path
+            try {
+                contractCert.verify(
+                                (PGPPublicKey)certificationCert.getPublicKey());
+                serverCert.verify(
+                                (PGPPublicKey)certificationCert.getPublicKey());
+            } catch (SignatureException se) {
+                result = false;
+            } catch (NoSuchProviderException nspe) {
+                throw new InternalError("Should not happen - "+nspe);
+            } catch (NoSuchAlgorithmException nsae) {
+                throw new InternalError("Should not happen - "+nsae);
+            } catch (InvalidKeyException ike) {
+                throw new ContractException("Invalid key in contract - "+ike);
+            } catch (CertificateException ce) {
+                throw new ContractException("Invalid cert in contract - "+ce);
+            }
+            
+            // pff... finally
+            return result;
             
         } else {  // X.509 signed contract