[Webfunds-commits] java/webfunds/client/contracts/wizard ContractFile.java FinishSig.java KeyContract.java KeyPanel.java KeyServer.java KeyTop.java WizardData.java WizardPanel.java

Ian Grigg iang@cypherpunks.ai
Sun, 27 Aug 2000 23:03:17 -0400 (AST)


iang        00/08/27 23:03:17

  Modified:    webfunds/client/contracts/wizard ContractFile.java
                        FinishSig.java KeyContract.java KeyPanel.java
                        KeyServer.java KeyTop.java WizardData.java
                        WizardPanel.java
  Log:
  1.  moved a lot of generic key stuff from KeyPanel to ricardian.KeyUtil;
      rewrote most of it to work with Strings not filenames;
      and moved some PGPKey business logic into the main dialogs,
      where not easy to hide.
  2.  moved some check*Key() methods to WizardPanel for 2. below so that
      ContractFile can now ... read and "checkin" the keys.
  3.  FinishSig:  added a tryWriting() method so as to rationalise the
      writing of pre & post contracts to files (there were 4 efforts);
  4.  but, the pre-file is now an unsigned contract write (includes keys)
      as opposed to a base-contract write (no keys) -- see 6 below.
  5.  changed the order to do the actual writing where it was needed
      (as the files are produced, rather than dependant on other successes).
  6.  ContractFile now scans for keys and initialises spots with found keys
      (as well as printing out errors on strange keys);
  7.  whilst all screens now accept skip forward if there is no file given
      and there is already a key in place
      (somewhat different for contract secret key);
  8.  and, if both key is in place and new key provided, asks for override;
  9.  removed some blanks from some files :(
  10. added extra methods for error()s where stacktraces undesirable
      (should be no bugs :) and where more info can be printed;
  11. changed Server (keyname) to Operator (keyname) in some places.
  12. also added loadString stuff into WizardPanel, which I guess has
      to stay there whilst error() is called within them.
  13. and that's just the stuff I remember ...
      oh, yeah, it compiles and works, mostly, with some minor bugs
      i'm chasing now...  (Still afflicted by one OpenPGP bug.)
  14. hard hat is On <: exit stage left, running...

Revision  Changes    Path
1.5       +92 -29    java/webfunds/client/contracts/wizard/ContractFile.java

Index: ContractFile.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/contracts/wizard/ContractFile.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ContractFile.java	2000/08/21 17:05:03	1.4
+++ ContractFile.java	2000/08/28 03:03:16	1.5
@@ -1,5 +1,5 @@
 /*
- * $Id: ContractFile.java,v 1.4 2000/08/21 17:05:03 edwin Exp $
+ * $Id: ContractFile.java,v 1.5 2000/08/28 03:03:16 iang Exp $
  *
  * Copyright (c) Systemics Inc 2000 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -18,12 +18,16 @@
 import java.awt.event.*;
 import javax.swing.*;
 
+import webfunds.ricardian.IniFileReader;
+import webfunds.ricardian.Contract;
+import webfunds.ricardian.ContractException;
 
+
 /**
  * Panel that asks for the filename of the contract.
  *
  * @author Edwin Woudt <edwin@webfunds.org>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
  */
 
 public class ContractFile extends WizardPanel 
@@ -156,36 +160,95 @@
     }
 
     public boolean next() {
-        if (!txtFile.getText().equals("")) {
-            try {
-                String filename = txtFile.getText();
-                File f = new File(filename);
-                FileInputStream fis = new FileInputStream(f);
-                DataInputStream dis = new DataInputStream(fis);
-                
-                byte[] contr = new byte[fis.available()];
-                dis.readFully(contr);
-                
-                String s = new String(contr,"ISO8859-1");
-                data.setUnsignedContract(s);
-                data.setContractFilename(txtFile.getText());
-                
-                return true;
-            } catch (IOException ioe) {
-                String s;
-                if (ioe instanceof FileNotFoundException) {
-                    s = "File not found";
-                } else {
-                    s = ioe.toString();
-                }
-                JOptionPane.showMessageDialog(this, "Error opening file: "+s, 
-                                            "Error", JOptionPane.ERROR_MESSAGE);
-                return false;
-            }
-        } else {
+
+        String filename = txtFile.getText();
+
+        if (filename.equals("")) {
             data.setUnsignedContract("");
             return true;
         }
+
+        String s = loadString(filename);
+        if (s == null)
+            return false;
+
+System.err.println("got string " + s.length() + " getting ini");
+        IniFileReader ini;
+        try {
+            ini = new IniFileReader(s.getBytes());
+        } catch (ContractException ex) {
+            error(ex.getMessage());
+            return false;
+        }
+
+        String[] keys = ini.getSectionItems(Contract.SECT_KEYS);
+        if (keys != null && (keys.length > 0))
+        {
+            System.err.println("Base file has " + keys.length + " keys");
+            String prefix = Contract.SECT_KEYS + "_";
+            for (int i = 0; i < keys.length; i++) // quick scan for known keys
+            {
+                String keyName = keys[i];
+                if (keyName == null || (keyName.length() == 0))
+                    continue ;
+                if (
+                    !keyName.equals(prefix + Contract.FIELD_TOP_LEVEL) &&
+                    !keyName.equals(prefix + Contract.FIELD_CONTRACT) &&
+                    !keyName.equals(prefix + Contract.FIELD_OPERATOR) &&
+                   true)
+                {
+                    error("unknown key in contract: " + keyName + " Ignored!");
+                    continue ;
+                }
+            }
+
+            String aKey;
+            aKey = ini.getSectionItemValue(Contract.SECT_KEYS,
+                                    Contract.FIELD_TOP_LEVEL);
+            String topKey = checkTopLevelKey(aKey);
+            if (topKey != null)
+            {
+System.err.println("setting String topKey " + topKey.length());
+                 data.setTopLevelKey(topKey);
+            }
+
+            aKey = ini.getSectionItemValue(Contract.SECT_KEYS,
+                                    Contract.FIELD_CONTRACT);
+            String conKey = checkPublicContractKey(aKey, topKey);
+            if (conKey != null)
+            {
+System.err.println("setting String conKey " + conKey.length());
+                 data.setPublicContractKey(conKey);
+            }
+
+            aKey = ini.getSectionItemValue(Contract.SECT_KEYS,
+                                    Contract.FIELD_OPERATOR);
+            String opKey = checkOperatorKey(aKey);
+            if (opKey != null)
+            {
+System.err.println("setting opKey " + opKey.length());
+                 data.setOperatorKey(opKey);
+            }
+
+        }
+else System.err.println("no keys found");
+
+        String base;
+        try {
+            base = Contract.getBase(s);
+        } catch (ContractException ex) {
+            error(ex.getMessage());
+            return false; 
+        }
+
+System.err.println("got base " + base.length());
+        data.setUnsignedContract(base);
+        data.setContractFilename(txtFile.getText());
+                
+        return true;
+
+        //      JOptionPane.showMessageDialog(this, "Error opening file: "+s, 
+        //                                  "Error", JOptionPane.ERROR_MESSAGE);
     }
 
 



1.9       +151 -158  java/webfunds/client/contracts/wizard/FinishSig.java

Index: FinishSig.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/contracts/wizard/FinishSig.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- FinishSig.java	2000/08/21 17:05:03	1.8
+++ FinishSig.java	2000/08/28 03:03:16	1.9
@@ -1,5 +1,5 @@
 /*
- * $Id: FinishSig.java,v 1.8 2000/08/21 17:05:03 edwin Exp $
+ * $Id: FinishSig.java,v 1.9 2000/08/28 03:03:16 iang Exp $
  *
  * Copyright (c) Systemics Inc 2000 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -30,55 +30,56 @@
 
 import webfunds.ricardian.Contract;
 import webfunds.ricardian.ContractException;
+import webfunds.ricardian.KeyUtil;
 
 
 /**
  * Panel that does the actual signing.
  *
  * @author Edwin Woudt <edwin@webfunds.org>
- * @version $Revision: 1.8 $
+ * @version $Revision: 1.9 $
  */
 
-public class FinishSig extends WizardPanel 
+public class FinishSig extends WizardPanel
                          implements ActionListener {
 
     JTextField txtFile, txtFileUnsigned, txtPass;
-    
+
     WizardData data;
-        
-    
+
+
     public FinishSig(WizardData data) {
-      
+
         this.data = data;
-      
+
         // GridBagLayout is the most flexible (also the most difficult
         // to use) LayoutManager.
         GridBagLayout gridbag = new GridBagLayout();
         GridBagConstraints c = new GridBagConstraints();
 
         setLayout(gridbag);
-        
-        
+
+
         // Define some components we'll use later on.
         JButton    but;
         JLabel     lab;
 
 
-        // Ok, this is where the real dirty work starts. Do not attempt 
-        // to change it, unless you understand the GridBagLayout and 
-        // GridBagConstraints, because in case you don't the result 
+        // Ok, this is where the real dirty work starts. Do not attempt
+        // to change it, unless you understand the GridBagLayout and
+        // GridBagConstraints, because in case you don't the result
         // will probably be a real f*ck up of the layout.
-        
+
         c.gridheight = 1;      c.gridwidth = 2;
         c.gridy      = 0;      c.gridx     = 0;
         c.weighty    = 0;      c.weightx   = 0;
         c.fill       = GridBagConstraints.NONE;
         c.anchor     = GridBagConstraints.WEST;
         c.insets     = new Insets(5, 5, 5, 5);
-        lab = new JLabel("Generating the Signature"); 
+        lab = new JLabel("Generating the Signature");
         gridbag.setConstraints(lab,c); add(lab);
-        
-        
+
+
         c.gridheight = 1;      c.gridwidth = 2;
         c.gridy      = 1;      c.gridx     = 0;
         c.weighty    = 0;      c.weightx   = 1;
@@ -90,10 +91,10 @@
                          "needed to sign the contract. Please specify the "+
                          "filename where you want the signed contract to be "+
                          "stored. "+
-                         "</b></font></html>"); 
+                         "</b></font></html>");
         gridbag.setConstraints(lab,c); add(lab);
 
-        
+
         c.gridheight = 1;      c.gridwidth = 1;
         c.gridy      = 2;      c.gridx     = 0;
         c.weighty    = 0;      c.weightx   = 1;
@@ -110,12 +111,12 @@
         c.fill       = GridBagConstraints.NONE;
         c.anchor     = GridBagConstraints.WEST;
         c.insets     = new Insets(5, 5, 5, 5);
-        but = new JButton("Browse"); 
+        but = new JButton("Browse");
         but.addActionListener(this);
         but.setActionCommand("browse");
         gridbag.setConstraints(but,c); add(but);
-        
-        
+
+
         c.gridheight = 1;      c.gridwidth = 2;
         c.gridy      = 3;      c.gridx     = 0;
         c.weighty    = 0;      c.weightx   = 1;
@@ -128,10 +129,10 @@
                          "this process if needed. In that case, please enter "+
                          "the filename below. If you do not want to save it,  "+
                          "leave the box below empty. "+
-                         "</b></font></html>"); 
+                         "</b></font></html>");
         gridbag.setConstraints(lab,c); add(lab);
 
-        
+
         c.gridheight = 1;      c.gridwidth = 1;
         c.gridy      = 4;      c.gridx     = 0;
         c.weighty    = 0;      c.weightx   = 1;
@@ -148,12 +149,12 @@
         c.fill       = GridBagConstraints.NONE;
         c.anchor     = GridBagConstraints.WEST;
         c.insets     = new Insets(5, 5, 5, 5);
-        but = new JButton("Browse"); 
+        but = new JButton("Browse");
         but.addActionListener(this);
         but.setActionCommand("browse2");
         gridbag.setConstraints(but,c); add(but);
-        
-        
+
+
         c.gridheight = 1;      c.gridwidth = 2;
         c.gridy      = 5;      c.gridx     = 0;
         c.weighty    = 0;      c.weightx   = 1;
@@ -162,10 +163,10 @@
         c.insets     = new Insets(5, 5, 15, 5);
         lab = new JLabel("<html><font size='-1'><b>"+
                          "Enter the passphrase for the contract key: "+
-                         "</b></font></html>"); 
+                         "</b></font></html>");
         gridbag.setConstraints(lab,c); add(lab);
+
 
-        
         c.gridheight = 1;      c.gridwidth = 2;
         c.gridy      = 6;      c.gridx     = 0;
         c.weighty    = 0;      c.weightx   = 1;
@@ -186,10 +187,10 @@
                          "Press next to generate the signature. "+
                          "Please note that this process may take a while, "+
                          "depending on the speed of your computer. "+
-                         "</b></font></html>"); 
+                         "</b></font></html>");
         gridbag.setConstraints(lab,c); add(lab);
-        
 
+
         // Filler, makes sure the whole thing is aligned to the top
         c.gridheight = 1;      c.gridwidth = 2;
         c.gridy      = 8;      c.gridx     = 0;
@@ -197,96 +198,127 @@
         c.fill       = GridBagConstraints.NONE;
         c.anchor     = GridBagConstraints.CENTER;
         c.insets     = new Insets(5, 5, 5, 5);
-        lab = new JLabel(""); 
+        lab = new JLabel("");
         gridbag.setConstraints(lab,c); add(lab);
-        
+
     }
-    
+
 
     public void actionPerformed(java.awt.event.ActionEvent e) {
-      
+
         if (e.getActionCommand().equals("browse")) {
-          
+
             JFileChooser fc = new JFileChooser();
-            
+
             fc.setDialogTitle("Save signed contract");
             fc.setDialogType(fc.OPEN_DIALOG);
             fc.setFileSelectionMode(fc.FILES_ONLY);
             fc.setCurrentDirectory(new File(System.getProperty("user.dir")));
-            
+
             if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) {
-              
+
                 try {
                     txtFile.setText(fc.getSelectedFile().getCanonicalPath());
                 } catch (IOException ioe) { }
-                            
+
             }
-                      
+
         }
-      
+
         if (e.getActionCommand().equals("browse2")) {
-          
+
             JFileChooser fc = new JFileChooser();
-            
+
             fc.setDialogTitle("Save unsigned contract");
             fc.setDialogType(fc.OPEN_DIALOG);
             fc.setFileSelectionMode(fc.FILES_ONLY);
             fc.setCurrentDirectory(new File(System.getProperty("user.dir")));
-            
+
             if (fc.showOpenDialog(this) == fc.APPROVE_OPTION) {
-              
+
                 try {
                     txtFileUnsigned.setText(
                                        fc.getSelectedFile().getCanonicalPath());
                 } catch (IOException ioe) { }
-                            
+
             }
-                      
+
         }
-      
+
     }
-    
+
 
     public void enter() {
-        
+
         if (txtFile.getText().equals("hopsadieee")) {
             String uname = data.getContractFilename();
-            
+
             String name = data.getContractFilename();
             int extpos = name.lastIndexOf(".");
             if (extpos >= 0) {
                 name = name.substring(0,extpos);
             }
             name = name + ".asc";
-            
+
             // unsigned file had .asc, let's change it to .txt
             if (uname.equals(name)) {
                 extpos = uname.lastIndexOf(".");
                 uname = uname.substring(0,extpos);
                 uname = uname + ".txt";
             }
-            
+
             if (uname.equals("")) {
                 uname="mycontract.txt";
                 name ="mycontract.asc";
-            }            
-            
+            }
+
             txtFile.setText(name);
             txtFileUnsigned.setText(uname);
         }
 
     }
-    
+
     public boolean leave() {
         // do nothing
         return true;
     }
 
+    public boolean tryWriting(String fileName,
+                              String name,
+                              String data)
+    {
+        if (fileName == null || fileName.equals(""))
+            return true ;        // user supplied no name, therefore success
+
+        File f = new File(fileName);
+        if (f.exists() &&
+            !confirm("File "+fileName+" already exists! Overwrite?"))
+                return false;
+
+        try {
+            FileOutputStream fos = new FileOutputStream(f);
+            DataOutputStream dos = new DataOutputStream(fos);
+            String fixed = PGPArmoury.fixLineEndings(data,
+                                  System.getProperty("line.separator"));
+            dos.write(fixed.getBytes("ISO8859-1"));
+            dos.close();
+            fos.close();
+        } catch (IOException ioe) {
+            error("Error writing " + name + " to " + fileName, ioe);
+            return false;
+        }
+        return true;
+    }
+
+
+
     public boolean next() {
-        
+
         byte[] signedBytes;
-        
+
         // test for validness of signed contract output file
+        // hmm... creates file in advance for what purpose?
+/*
         String n = txtFile.getText();
         File f = new File(n);
         if (f.exists()) {
@@ -301,122 +333,82 @@
                 return false;
             }
         }
-        
-                
-        // test for validness of unsigned contract output file
-        n = txtFileUnsigned.getText();
-        if (! n.equals("")) {
-            f = new File(n);
-            if (f.exists()) {
-                if (!confirm("File "+n+" already exists! Overwrite?")) 
-                    return false;
-            } else {
-                try {
-                    FileOutputStream fos = new FileOutputStream(f);
-                    fos.write(0);
-                    fos.close();
-                } catch (IOException ioe) {
-                    error("Could not create output file"+n+".", ioe);
-                    return false;
-                }
-            }
+*/
+
+        // parse the armoured key
+        PGPArmoury akey;
+        try {
+            akey = new PGPArmoury(data.getSecretContractKey());
+        } catch (IllegalArgumentException iae) {
+            error("Invalid contract key, not armoured?",iae);
+            return false;
         }
-        
-                
 
+        // get the unarmoured secret key
+        PGPKeyFactory factory = new PGPKeyFactory();
+        PGPSecretKey skey;
         try {
-            
-            // parse the armoured key
-            PGPArmoury akey;
-            try {
-                akey = new PGPArmoury(data.getSecretContractKey());
-            } catch (IllegalArgumentException iae) {
-                error("Invalid contract key, not armoured?",iae);
-                return false;
-            }
-        
 
-            // get the unarmoured secret key
-            PGPKeyFactory factory = new PGPKeyFactory();
-            PGPSecretKey skey;
-            try {
-                
-                Vector keys = factory.decodeKeys(akey.getPayload());
-                if (keys.size() > 1) {
-                    error("More than one key found in input file", null);
-                    return false;
-                } else if (keys.size() < 1) {
-                    error("No key found in input file", null);         
-                    return false;
-                }                
-                skey = (PGPSecretKey)keys.elementAt(0);
-                skey.decrypt(txtPass.getText());
-                
-            } catch (PGPWrongPassphraseException wpe) {
-                error("Wrong passphrase", wpe);
-                return false;
-            } catch (PGPAbstractDataFormatException ape) {
-                error("Error parsing contract key", ape);
+            Vector keys = factory.decodeKeys(akey.getPayload());
+            if (keys.size() > 1) {
+                error("More than one key found in input file", null);
                 return false;
-            } catch (ClassCastException cce) {
-                error("No secret key found",cce);
+            } else if (keys.size() < 1) {
+                error("No key found in input file", null);
                 return false;
             }
-        
-        
-            // put the contract together
-            String all = data.getUnsignedContract();
-            all = all + "\r\n[keys]";
-            all = all + "\r\n\r\nkeys_contract='\r\n\r\n";
-            all = all + data.getPublicContractKey();
-            all = all + "\r\n'\r\n\r\nkeys_certification='\r\n\r\n";
-            all = all + data.getTopLevelKey();
-            all = all + "\r\n'\r\n\r\nkeys_server_certification='\r\n\r\n";
-            all = all + data.getServerKey();
-            all = all + "\r\n'\r\n\r\n[signatures]\r\n";
-        
+            skey = (PGPSecretKey)keys.elementAt(0);
+            skey.decrypt(txtPass.getText());
+
+        } catch (PGPWrongPassphraseException wpe) {
+            error("Wrong passphrase", wpe);
+            return false;
+        } catch (PGPAbstractDataFormatException ape) {
+            error("Error parsing contract key", ape);
+            return false;
+        } catch (ClassCastException cce) {
+            error("No secret key found",cce);
+            return false;
+        }
+
 
+        // put the contract together
+        String all = data.getUnsignedContract();
+        all = all + "\r\n[keys]";
+        all = all + "\r\n\r\nkeys_contract='\r\n\r\n";
+        all = all + data.getPublicContractKey();
+        all = all + "\r\n'\r\n\r\nkeys_certification='\r\n\r\n";
+        all = all + data.getTopLevelKey();
+        all = all + "\r\n'\r\n\r\nkeys_server_certification='\r\n\r\n";
+        all = all + data.getOperatorKey();
+        all = all + "\r\n'\r\n\r\n[signatures]\r\n";
+
+        // write the unsigned contract
+        String unsignedName = txtFileUnsigned.getText();
+        tryWriting(unsignedName, "unsigned contract", all);
+
+        try {
             // prepare and sign contract
             String signedContract = PGPMessage.clearSign(all, skey);
-            
+
             // Convert line endings to local format and convert the result into
             // bytes.
             PGPArmoury.fixLineEndings(signedContract,
                                           System.getProperty("line.separator"));
             signedBytes = signedContract.getBytes("ISO8859-1");
-            
+
         } catch (IOException ioe) {
             throw new InternalError("IOException in "+
                                     "ByteArray[In|Out]putStream");
         }
 
-            
-        // write the signed contract
-        try {
-            f = new File(txtFile.getText());
-            FileOutputStream fos = new FileOutputStream(f);
-            DataOutputStream dos = new DataOutputStream(fos);
-            dos.write(signedBytes);
-            dos.close();
-            fos.close();
-        } catch (IOException ioe) {
-            error("Error writing signed contract file",ioe);
-            return false;
-        }
 
-        // write the unsigned contract
-        if (! txtFileUnsigned.getText().equals("")) {
-            try {
-                f = new File(txtFileUnsigned.getText());
-                FileOutputStream fos = new FileOutputStream(f);
-                DataOutputStream dos = new DataOutputStream(fos);
-                dos.write(data.getUnsignedContract().getBytes("ISO8859-1"));
-                dos.close();
-                fos.close();
-            } catch (IOException ioe) {
-                error("Error writing unsignedcontract file",ioe);
-                return false;
-            }
+        String signedName = txtFile.getText();
+        if (!tryWriting(signedName, "Signed Contract", new String(signedBytes)))
+        {
+            System.err.println("try a quick sanity check anyway...");
+            sanityCheckContract(signedBytes);
+            return false;
         }
 
         if (!sanityCheckContract(signedBytes))
@@ -426,10 +418,11 @@
 
     }
 
-    public final static String eoln = "\r\n";  // how PGP cleartext is prepared
+    static String eoln = KeyUtil.eoln;
 
     private boolean sanityCheckContract(byte[] contractBytes)
     {
+
         String s = "[local]" + eoln +
                    "digest_version=3" + eoln;
         byte[] locFile = s.getBytes();
@@ -441,7 +434,7 @@
             error("Not a contract!", ex);
             return false;
         }
-        
+
         try {
             if (!con.verifyContract())
             {
@@ -455,6 +448,6 @@
 
         return true;
     }
-    
-    
+
+
 }



1.8       +90 -23    java/webfunds/client/contracts/wizard/KeyContract.java

Index: KeyContract.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/contracts/wizard/KeyContract.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- KeyContract.java	2000/08/26 23:35:07	1.7
+++ KeyContract.java	2000/08/28 03:03:16	1.8
@@ -1,5 +1,5 @@
 /*
- * $Id: KeyContract.java,v 1.7 2000/08/26 23:35:07 iang Exp $
+ * $Id: KeyContract.java,v 1.8 2000/08/28 03:03:16 iang Exp $
  *
  * Copyright (c) Systemics Inc 2000 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -24,13 +24,15 @@
 import webfunds.ricardian.Contract;
 
 import webfunds.ricardian.KeyUtil;
+import webfunds.ricardian.ArmouredKeyException;
+import webfunds.ricardian.StripKeyException;
 
 
 /**
  * Panel that asks for the contract key
  *
  * @author Edwin Woudt <edwin@webfunds.org>
- * @version $Revision: 1.7 $
+ * @version $Revision: 1.8 $
  */
 
 public class KeyContract extends KeyPanel 
@@ -305,28 +307,72 @@
 
     public boolean next() {
 
-        String s = data.getTopLevelKey();
-        PGPPublicKey topLevelKey;
-        try {
-            topLevelKey = KeyUtil.publicKeyFromString(s);
-        } catch (PGPException ex) {
-            error("no top level key available?", ex);
-            return false;
-        }
         
-        PGPPublicKey contractKey = loadPublicKey(txtFile.getText());
-        if (contractKey == null)
+        String fileName = txtFile.getText();
+        // have we already got it?
+        String existing = data.getPublicContractKey();
+        boolean alreadyGotAKey = (existing.length() != 0);
+
+        if (!alreadyGotAKey && (fileName.length() == 0))
+        {
+            error("Please specify a filename for contract public key");
             return false;
+        }
+
+        if (fileName.length() != 0)        // got a name, try for a key
+        {
+            String s = loadString(fileName);
+            if (s == null)
+                return false;
+    
+            String topLevelKey = data.getTopLevelKey();
+            if (topLevelKey.length() == 0)
+            {
+                error("Cannot check the contract public" +
+                      "key without a certification key.\n\n" +
+                      "Click on Previous to move back to " +
+                      "Certification Dialog." );
+                return false;
+            }
+
+
+            s = checkPublicContractKey(s, topLevelKey);
+            if (s == null)
+                return false;
+    
+            //  ok, so a good key, should we override and use it?
+            if ( alreadyGotAKey && !confirm("override existing contract key?") )
+                return false;
+
+            data.setPublicContractKey(s);
+            existing = data.getPublicContractKey();
+            
+        }
+
 
+
+/*
 System.err.println("CONTRACT -----------\n" + KeyUtil.publicKeyToString(contractKey));
         final String tag = Contract.USERID_CONTRACT;
-        PGPPublicKey stripped;
+        PGPPublicKey stripped = null;
         try {
-            stripped = KeyUtil.stripAndVerifyKey(contractKey,
+            PGPPublicKey Xstripped = KeyUtil.stripAndVerifyKey(contractKey,
+                                          tag,
+                                          topLevelKey);
+            stripped = KeyUtil.stripAndVerifyKey(Xstripped,
                                           tag,
                                           topLevelKey);
-        } catch (Exception ex) {
-            error("not fit for purpose or unsiged!", ex);
+System.err.println("ok, so double stripping worked!");
+String am = KeyUtil.publicKeyToString(stripped);
+PGPPublicKey unam;
+unam = KeyUtil.publicKeyFromString(am);
+Xstripped = KeyUtil.stripAndVerifyKey(unam,
+                                          tag,
+                                          topLevelKey);
+} catch (ArmouredKeyException ex) { error("test: " + ex); return false;
+
+        } catch (StripKeyException ex) {
+            error("Contract key: " + ex);
             return false;
         }
 
@@ -338,12 +384,31 @@
         } else {
             return false;
         }
+*/
 
         
-        PGPSecretKey secret = loadSecretKey(txtFile2.getText());
-        if (secret == null)
+        fileName = txtFile2.getText();
+        // have we already got it?  perhaps from another run.
+        existing = data.getSecretContractKey();
+System.err.println("got " + fileName + " and got ex " + existing.length());
+        if (fileName.length() == 0 && existing.length() > 0)
+            return true;
+         
+        /*
+         *  This one is a bit different.
+         */
+        String secretString = loadString(fileName, "contract secret key");
+        if (secretString == null)
             return false;
 
+        PGPSecretKey secret;
+        try {
+            secret = KeyUtil.secretKeyFromString(secretString);
+        } catch (ArmouredKeyException ex) {
+            error("Contract secret key: " + ex);
+            return false;
+        }
+
         // how to do this?
         // if (!secret.matches(key))
         // {
@@ -353,12 +418,14 @@
         
         String key2 = KeyUtil.secretKeyToString(secret);
 
-        if (key2 != null) {
-            data.setSecretContractKey(key2);
-            return true;
-        } else {
-            return false;
+        if (existing.length() > 0)         // there was a key there before
+        {
+            if (!confirm("override existing contract secret key?"))
+                return true;
         }
+                                              
+        data.setSecretContractKey(key2);
+        return true;
 
     }
 



1.7       +9 -93     java/webfunds/client/contracts/wizard/KeyPanel.java

Index: KeyPanel.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/contracts/wizard/KeyPanel.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- KeyPanel.java	2000/08/26 23:30:37	1.6
+++ KeyPanel.java	2000/08/28 03:03:16	1.7
@@ -1,5 +1,5 @@
 /*
- * $Id: KeyPanel.java,v 1.6 2000/08/26 23:30:37 iang Exp $
+ * $Id: KeyPanel.java,v 1.7 2000/08/28 03:03:16 iang Exp $
  *
  * Copyright (c) Systemics Inc 2000 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -16,16 +16,10 @@
 
 import cryptix.openpgp.util.PGPArmoury;
 
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-
 import java.util.Vector;
 
 import webfunds.ricardian.KeyUtil;
+import webfunds.ricardian.StripKeyException;
 
 
 /**
@@ -34,7 +28,7 @@
  * These amount to Utility classes for OpenPGP - perhaps better in openpgp?
  *
  * @author Edwin Woudt <edwin@webfunds.org>
- * @version $Revision: 1.6 $
+ * @version $Revision: 1.7 $
  */
 
 public abstract class KeyPanel extends WizardPanel {
@@ -60,39 +54,6 @@
         }
     }
 
-    protected String loadString(String filename) {
-        
-        if (filename.equals("")) {
-            error("Please specify a key", null);
-            return null;
-        }
-            
-        // read file
-        String s;
-        try {
-            File f = new File(filename);
-            FileInputStream fis = new FileInputStream(f);
-            DataInputStream dis = new DataInputStream(fis);
-            
-            byte[] contr = new byte[fis.available()];
-            dis.readFully(contr);
-            
-            s = new String(contr,"ISO8859-1");
-        } catch (IOException ioe) {
-            String e;
-            if (ioe instanceof FileNotFoundException) {
-                e = "File not found";
-            } else {
-                e = ioe.toString();
-            }
-            error("Error opening file: "+e, ioe);
-            return null;
-        }
-
-        return s;
-    }
-        
-
     /**
      *  Load up a key from a filename.
      *  No checking other than that intrinsic in de-armouring and
@@ -119,10 +80,10 @@
         try {
             Vector keys = factory.decodeKeys(akey.getPayload());
             if (keys.size() > 1) {
-                error("More than one key found in input file", null);
+                error("More than one key found in input file");
                 return null;
             } else if (keys.size() < 1) {
-                error("No key found in input file", null);         
+                error("No key found in input file");
                 return null;
             }
             key = (PGPKey)keys.elementAt(0);
@@ -146,30 +107,14 @@
             return null;
 
         if (key instanceof PGPSecretKey) {
-            error(filename + " has a Secret Key!", null);
+            error(filename + " has a Secret Key!");
             return null;
         }
         return (PGPPublicKey)key;
     }
 
-    /**
-     *  Read a Secret Key from a filename and return the key.
-     */
-    protected PGPSecretKey loadSecretKey(String filename) {
-        
-        PGPKey key = loadKey(filename);
-        if (key == null)
-            return null;
 
-        if (key instanceof PGPPublicKey) {
-            error(filename + " has a Public Key!", null);
-            return null;
-        }
-        return (PGPSecretKey)key;
-    }
-
 
-
     /**
      *  Read a Public Key from a filename and return the key.
      *  It must be signed by the signer, if provided (can be null).
@@ -186,48 +131,18 @@
         try {
             pk = KeyUtil.stripAndVerifyKey(pk, tag, signer);
 
-        } catch (Exception ex) {
-            error("not fit for purpose or unsiged!", ex);
+        } catch (StripKeyException ex) {
+            error(ex.toString());
             return null;
         }
 
         return pk;
     }
 
-    /**
-     *  Read a Secret Key from a filename and return the key.
-     *  It must be the same key (pair) as the public key.
-     */
-    protected PGPSecretKey checkSecretKey(String filename,
-                                          PGPPublicKey pk)
-    {
-        
-        PGPSecretKey secret = loadSecretKey(filename);
-        // check that public matches key ???
-
-        return secret;
-    }
-
-    /**
-     *  Read a Secret Key from a filename and return the key.
-     *  It must be the same key (pair) as the public key.
-     */
-    protected String loadAndCheckSecretKey(String filename,
-                                          PGPPublicKey pk)
-    {
-        
-        PGPSecretKey secret = checkSecretKey(filename, pk);
-
-        return KeyUtil.secretKeyToString(secret);
-    }
 
 
-
-
-
     /**
      *  DEPRECATED - original checker.
-     */
     protected String loadAndCheckKey(String filename, boolean secret) {
         
         if (!filename.equals("")) {
@@ -297,5 +212,6 @@
             return null;
         }
     }
+     */
      
 }



1.8       +18 -9     java/webfunds/client/contracts/wizard/KeyServer.java

Index: KeyServer.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/contracts/wizard/KeyServer.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- KeyServer.java	2000/08/26 23:35:07	1.7
+++ KeyServer.java	2000/08/28 03:03:16	1.8
@@ -1,5 +1,5 @@
 /*
- * $Id: KeyServer.java,v 1.7 2000/08/26 23:35:07 iang Exp $
+ * $Id: KeyServer.java,v 1.8 2000/08/28 03:03:16 iang Exp $
  *
  * Copyright (c) Systemics Inc 2000 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -26,7 +26,7 @@
  * Panel that asks for the [operator] certification key
  *
  * @author Edwin Woudt <edwin@webfunds.org>
- * @version $Revision: 1.7 $
+ * @version $Revision: 1.8 $
  */
 
 public class KeyServer extends KeyPanel 
@@ -159,18 +159,27 @@
 
     public boolean next() {
         
-        PGPPublicKey key = checkPublicKey(txtFile.getText(),
-                                           Contract.USERID_OPERATOR,
-                                           null);
-        if (key == null)
+        String fileName = txtFile.getText();
+        // have we already got it?
+        String existing = data.getOperatorKey();
+        if (fileName.length() == 0 && existing.length() > 0)
+            return true;
+
+        String s = loadString(fileName);
+        if (s == null)
             return false;
 
-        String s;
-        s = KeyUtil.publicKeyToString(key);
+        s = checkOperatorKey(s);
         if (s == null)
             return false;
+
+        if (existing.length() > 0)         // there was a key there before
+        {
+            if (!confirm("override existing operator key?"))
+                return true;
+        }
 
-        data.setServerKey(s);
+        data.setOperatorKey(s);
         return true;
     }
 



1.8       +22 -9     java/webfunds/client/contracts/wizard/KeyTop.java

Index: KeyTop.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/contracts/wizard/KeyTop.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- KeyTop.java	2000/08/26 23:35:07	1.7
+++ KeyTop.java	2000/08/28 03:03:16	1.8
@@ -1,5 +1,5 @@
 /*
- * $Id: KeyTop.java,v 1.7 2000/08/26 23:35:07 iang Exp $
+ * $Id: KeyTop.java,v 1.8 2000/08/28 03:03:16 iang Exp $
  *
  * Copyright (c) Systemics Inc 2000 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -22,7 +22,7 @@
  * Panel that asks for the toplevel certification key
  *
  * @author Edwin Woudt <edwin@webfunds.org>
- * @version $Revision: 1.7 $
+ * @version $Revision: 1.8 $
  */
 
 public class KeyTop extends KeyPanel 
@@ -228,16 +228,29 @@
 
     public boolean next() {
         
-        String key = loadAndCheckPublicKey(txtFile.getText(),
-                                           Contract.USERID_TOP_LEVEL,
-                                           null);
-
-        if (key != null) {
-            data.setTopLevelKey(key);
+        String fileName = txtFile.getText();
+        // have we already got it?
+        String existing = data.getTopLevelKey();
+System.err.println("got " + fileName + " and " + existing.length());
+        if (fileName.length() == 0 && existing.length() > 0)
             return true;
-        } else {
+
+        String s = loadString(fileName);
+        if (s == null)
             return false;
+
+        s = checkTopLevelKey(s);
+        if (s == null)
+            return false;
+
+        if (existing.length() > 0)         // there was a key there before
+        {
+            if (!confirm("override existing certification key?"))
+                return true;
         }
+
+        data.setTopLevelKey(s);
+        return true;
 
     }
 



1.4       +6 -6      java/webfunds/client/contracts/wizard/WizardData.java

Index: WizardData.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/contracts/wizard/WizardData.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- WizardData.java	2000/08/21 08:24:20	1.3
+++ WizardData.java	2000/08/28 03:03:16	1.4
@@ -1,5 +1,5 @@
 /*
- * $Id: WizardData.java,v 1.3 2000/08/21 08:24:20 edwin Exp $
+ * $Id: WizardData.java,v 1.4 2000/08/28 03:03:16 iang Exp $
  *
  * Copyright (c) Systemics Inc 2000 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -12,7 +12,7 @@
  * Contains most of data for the wizard.
  *
  * @author Edwin Woudt <edwin@webfunds.org>
- * @version $Revision: 1.3 $
+ * @version $Revision: 1.4 $
  */
 
 public class WizardData {
@@ -22,7 +22,7 @@
     private String toplevelKey       = "";
     private String publiccontractKey = "";
     private String secretcontractKey = "";
-    private String serverKey         = "";
+    private String operatorKey       = "";
     private String signedContract    = "";
     private String contractFilename  = "";
     
@@ -31,7 +31,7 @@
     public String getTopLevelKey       () { return toplevelKey;       }
     public String getPublicContractKey () { return publiccontractKey; }
     public String getSecretContractKey () { return secretcontractKey; }
-    public String getServerKey         () { return serverKey;         }
+    public String getOperatorKey       () { return operatorKey;       }
     public String getSignedContract    () { return signedContract;    }
     public String getContractFilename  () { return contractFilename;    }
 
@@ -39,9 +39,9 @@
     public void setTopLevelKey       (String x) { toplevelKey       = x; }
     public void setPublicContractKey (String x) { publiccontractKey = x; }
     public void setSecretContractKey (String x) { secretcontractKey = x; }
-    public void setServerKey         (String x) { serverKey         = x; }
+    public void setOperatorKey       (String x) { operatorKey       = x; }
     public void setSignedContract    (String x) { signedContract    = x; }
-    public void setContractFilename    (String x) { contractFilename    = x; }
+    public void setContractFilename  (String x) { contractFilename  = x; }
 
 
     private boolean[] invalid   = { false, false, false,



1.5       +169 -9    java/webfunds/client/contracts/wizard/WizardPanel.java

Index: WizardPanel.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/client/contracts/wizard/WizardPanel.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- WizardPanel.java	2000/08/21 08:24:21	1.4
+++ WizardPanel.java	2000/08/28 03:03:16	1.5
@@ -1,5 +1,5 @@
 /*
- * $Id: WizardPanel.java,v 1.4 2000/08/21 08:24:21 edwin Exp $
+ * $Id: WizardPanel.java,v 1.5 2000/08/28 03:03:16 iang Exp $
  *
  * Copyright (c) Systemics Inc 2000 on behalf of
  * the WebFunds Development Team.  All Rights Reserved.
@@ -7,25 +7,37 @@
 
 package webfunds.client.contracts.wizard;
 
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 
 import javax.swing.*;
 
+import cryptix.openpgp.PGPPublicKey;
 
+import webfunds.ricardian.StripKeyException;
+import webfunds.ricardian.ArmouredKeyException;
+import webfunds.ricardian.Contract;
+import webfunds.ricardian.KeyUtil;
+
 /**
  * Abstract superclass for all panels in a wizard.
  *
  * @author Edwin Woudt <edwin@webfunds.org>
- * @version $Revision: 1.4 $
+ * @version $Revision: 1.5 $
  */
 
 public abstract class WizardPanel extends JPanel {
-  
-  
+
+
     /** 
      * Called by Wizard.java when entering this page
      */
     public abstract void enter();
-    
+  
     /** 
      * Called by Wizard.java when leaving this page when not using next.
      *
@@ -41,7 +53,7 @@
     public abstract boolean next();
 
     /**
-     * Convenience method that displays an error message and prints the
+     * Convenience method that displays a User error message and prints the
      * exception on the console.
      *
      * @param message a descriptive message that will be displayed in the popup
@@ -50,13 +62,30 @@
      *        on the console. If no exception is available, then a 'null' can
      *        be provided.
      */
+    protected void error(String message) {
+        System.err.println("ERROR: "+message);
+        JOptionPane.showMessageDialog(this, message, "Error", 
+                                      JOptionPane.ERROR_MESSAGE);
+    }
+ 
+    /**
+     * Convenience method that displays an error message and prints the
+     * exception on the console.  Use where exceptions and stack traces
+     * are called for, and the error is unexpected.  Is noisier than above.
+     *
+     * @param message a descriptive message that will be displayed in the popup
+     *        box.
+     * @param e the exception corresponding to this error, will be displayed
+     *        on the console. If no exception is available, then a 'null' can
+     *        be provided.
+     */
     protected void error(String message, Exception e) {
-        System.out.println("ERROR: "+message);
+        System.err.println("ERROR: "+message);
         if (e != null) { e.printStackTrace(); message += "\n\n\""+e+"\""; }
         JOptionPane.showMessageDialog(this, message, "Error", 
                                       JOptionPane.ERROR_MESSAGE);
     }
-   
+ 
     /**
      * Convenience method that displays an yes/no dialog box with the given
      * message.
@@ -69,6 +98,137 @@
         int result = JOptionPane.showConfirmDialog(this, message, "Confirm", 
                        JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
         return (result == JOptionPane.YES_OPTION);
+    }
+ 
+
+    /**
+     *  Take a string and return a better string for saving,
+     *  if the string represents a good armoured OPERATOR key.
+     *  @param s an armoured key read in from somewhere
+     *  @return the re-armoured key, filtered for contract goodness
+     */
+    protected String checkOperatorKey(String s) {
+
+        PGPPublicKey key;
+        try {
+            key = KeyUtil.checkArmouredPublicKey(s,
+                                           Contract.USERID_OPERATOR,
+                                           null);
+        } catch (StripKeyException ex) {
+            error(ex.getMessage());
+            return null;
+        } catch (ArmouredKeyException ex) {
+            error(ex.getMessage());
+            return null;
+        }
+
+        return KeyUtil.publicKeyToString(key);
+    }
+
+    /**
+     *  Take a string and return a better string for saving,
+     *  if the string represents a good armoured TOP LEVEL key.
+     *  @param s an armoured key read in from somewhere
+     *  @return the re-armoured key, filtered for contract goodness
+     */
+    protected String checkTopLevelKey(String s) {
+
+        PGPPublicKey key;
+        try {
+            key = KeyUtil.checkArmouredPublicKey(s,
+                                           Contract.USERID_TOP_LEVEL,
+                                           null);
+        } catch (StripKeyException ex) {
+            error(ex.getMessage());
+            return null;
+        } catch (ArmouredKeyException ex) {
+            error(ex.getMessage());
+            return null;
+        }
+
+        return KeyUtil.publicKeyToString(key);
+    }
+
+    /**
+     *  Take a string and return a better string for saving,
+     *  if the string represents a good armoured CONTRACT key.
+     *  @param s an armoured key read in from somewhere
+     *  @param top an armoured certification key previously prepared
+     *  @return the re-armoured key, filtered for contract goodness
+     */
+    protected String checkPublicContractKey(String s, String top) {
+
+        // first, recover the top key
+        PGPPublicKey topKey;
+        try {
+            topKey = KeyUtil.checkArmouredPublicKey(top,
+                                           Contract.USERID_TOP_LEVEL,
+                                           null);
+        } catch (StripKeyException ex) {
+            error("certification key error (cannot check contract key): " + ex);
+            return null;
+        } catch (ArmouredKeyException ex) {
+            error("certification key error (cannot check contract key): " + ex);
+            return null;
+        }
+
+        PGPPublicKey key;
+        try {
+            key = KeyUtil.checkArmouredPublicKey(s,
+                                           Contract.USERID_CONTRACT,
+                                           topKey);
+        } catch (StripKeyException ex) {
+            error("StripKeyEx: " + ex.getMessage());
+            return null;
+        } catch (ArmouredKeyException ex) {
+            error("ArmouredKeyEx: " + ex.getMessage());
+            return null;
+        }
+        return KeyUtil.publicKeyToString(key);
     }
-   
+
+    /**
+     *  Load a string from a filename and return it.
+     *  Prints out a suitable error message if bad.
+     */
+    protected String loadString(String filename) {
+
+        return loadString(filename, "");
+    }
+
+    /**
+     *  Load a string from a filename and return it.
+     *  Prints out a suitable error message if bad.
+     */
+    protected String loadString(String filename, String name) {
+        
+        if (filename.equals("")) {
+            error("Please specify a " + name + " filename");
+            return null;
+        }
+     
+        // read file
+        String s;
+        try {
+            File f = new File(filename);
+            FileInputStream fis = new FileInputStream(f);
+            DataInputStream dis = new DataInputStream(fis);
+     
+            byte[] contr = new byte[fis.available()];
+            dis.readFully(contr);
+     
+            s = new String(contr,"ISO8859-1");
+        } catch (IOException ioe) {
+            if (ioe instanceof FileNotFoundException) {
+                error("Error opening file " + filename + ": File not found");
+            } else {
+                error("Error opening file " + filename + ": ", ioe);
+            }
+            return null;
+        }
+
+        return s;
+    }
+
+
 }