[Webfunds-commits] java/webfunds/sox Account.java

Ian Grigg iang@cypherpunks.ai
Fri, 13 Oct 2000 21:39:46 -0400 (AST)


iang        00/10/13 21:39:46

  Modified:    webfunds/sox Account.java
  Log:
  added Request signing;
  cleaned up example();
  added a flags so that user code could store numbers there, to complement
  the Application string;

Revision  Changes    Path
1.72      +127 -27   java/webfunds/sox/Account.java

Index: Account.java
===================================================================
RCS file: /home/webfunds/cvsroot/java/webfunds/sox/Account.java,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -r1.71 -r1.72
--- Account.java	2000/09/04 11:53:03	1.71
+++ Account.java	2000/10/14 01:39:46	1.72
@@ -1,4 +1,4 @@
-/* $Id: Account.java,v 1.71 2000/09/04 11:53:03 iang Exp $
+/* $Id: Account.java,v 1.72 2000/10/14 01:39:46 iang Exp $
  *
  * Copyright (c) Systemics Inc. 1995-2000 on behalf of
  * The WebFunds Development Team. All rights reserved.
@@ -25,7 +25,7 @@
  * information, except perhaps for holding a key passphrase,
  * which is not stored in the Store (only in a runtime object).
  *
- * @version $Revision: 1.71 $
+ * @version $Revision: 1.72 $
  * @author  Jeroen C. van Gelderen (gelderen@webfunds.org)
  * @author  Unknown
  */
@@ -33,11 +33,12 @@
 {
     /**         
      * The version of the encoded object:
+     *    6 - added record of registrations
      *    5 - added application string.
      *    4 - keys not certs.
      *    3 - added separate sub accounts.
      */
-    public static final int VERSION = 5;
+    public static final int VERSION = 6;
 
     protected int req_version = VERSION;
 
@@ -45,13 +46,13 @@
      * The account name, can be assigned locally.
      * Note the fingerprint of the public key, stored in id, is also a name.
      */
-    protected String name;
+    protected String name = null;
     public String       getName()               { return name; }
     public void         setName(String name)
     {
-        this.name = name;
         if (name != null && name.length() == 0)
-            name = null;
+            name = null;         // empty string is null
+        this.name = name;
     }
 
     /**
@@ -59,15 +60,27 @@
      * Should not be touched by SOX, just transported.  A cheap
      * way of avoiding extend.
      */
-    protected String appl;
+    protected String appl = "";
     public String       getApplication()        { return appl; }
     public void         setApplication(String appl)
     {
-        this.appl = appl;
         if (appl != null && appl.length() == 0)
-            appl = null;
+            appl = null;         // empty string is null
+
+        this.appl = appl;
     }
 
+    /**
+     * The Application flags - can be set by a super application.
+     *
+     *  SOX:            1-16
+     *  Trader:         17-24
+     */
+    protected long flags;
+    public long         getFlags()        { return flags; }
+    public void         setFlags(long f)  { flags |= f; }
+    public boolean      isFlags(long f)   { return (flags & f) == f; }
+
     static void logmsg(String s)                { System.err.println(s) ; }
 
     /**
@@ -80,18 +93,13 @@
      * The private key that authorises account transactions.
      */
     protected PrivateKey key;
+    //
+    //  Hmm, shouldn't this be kept local and any sigs make here,
+    //  rather than spreading the key around?
+    //
     public PrivateKey   getKey()                { return key; }
 
     /**
-     * @return a signature from this key on the data
-     */
-    public byte[]       sign(byte[] b)
-        throws KeyException
-    {
-        return Crypto.sign(getKey(), b);
-    }
-
-    /**
      * The account id (which must match the public key fingerprint)
      */
     protected AccountId id;
@@ -125,6 +133,15 @@
     }
 
 
+    /**
+     *  Sometimes need to know who this account has been registered with.
+     *  Just use a Hashtable as a Vector for now.
+    protected Hashtable regos                      = new Hashtable();
+    public Object isRegistered(String name)        { return regos.get(name) ; }
+    public void setRegistered(String name, Object v)  { regos.put(name,v); }
+     */
+
+
 
 //////// Construction /////////////////////////////////////
 
@@ -217,6 +234,51 @@
 
 
 
+/////////  Signatures  //////////////////////////////
+
+    /**
+     *  Sign a block of data.
+     *
+     *  @return a signature from this key on the data
+     */
+    public byte[] sign(byte[] b)
+        throws KeyException
+    {
+        if (b == null)
+            throw new IllegalArgumentException("Account.sign(null)");
+        if (b.length == 0)
+            throw new IllegalArgumentException("Account.sign('')");
+        return Crypto.sign(getKey(), b);
+    }
+
+    /**
+     *  Sign a Request.
+     *  As it is the most likely thing that the SOX Account is
+     *  called upon to do, it makes sense for the Account to know
+     *  how to do it.
+     *
+     *  @except SOXKeyException if something goes wrong with the key
+     */
+    public void sign(Request req)
+        throws SOXKeyException
+    {
+        if (req == null)
+            throw new IllegalArgumentException("Account.sign(req==null)");
+
+        byte[] reqData = req.encode();
+        byte[] sig;
+        try {
+            sig = this.sign(reqData);
+        } catch (java.security.KeyException kex) {
+            kex.printStackTrace(System.err);
+            throw new SOXKeyException("KeyException: " + kex);
+        }
+      
+        req.setSignature(sig);
+    }
+
+
+
 //////// Access /////////////////////////////////////
 
     public SubAccount[] getSubAccounts()
@@ -309,6 +371,7 @@
 
         writeString(dos, name);
         writeString(dos, appl);
+        dos.writeLong(flags);
         writeByteArray(dos, Crypto.encodePrivateKey(key));
 
         ByteArrayOutputStream baos;
@@ -357,6 +420,11 @@
             if (appl.length() == 0)
                 appl = null;
         }
+        flags = 0;
+        if (version >= 6)
+        {
+            flags = dis.readLong();
+        }
 
         byte b[];
 
@@ -462,6 +530,7 @@
             return false ;
 
         Account other = (Account)obj;
+logmsg("1");
 
         AccountId otherId; 
         otherId = other.getId(); 
@@ -476,18 +545,39 @@
                 return false ;
         }
 
+logmsg("2");
         String hisName = other.getName();
         if (name == null)
         {
+logmsg("2.a <<" + hisName + ">>");
             if (hisName != null)
                 return false ;
         }
         else
         {
+logmsg("2.b " + name );
             if (!name.equals(hisName))
                 return false ;
         }
 
+logmsg("4");
+        String hisAppl = other.getApplication();
+        if (appl == null)
+        {
+            if (hisAppl != null)
+                return false ;
+        }
+        else
+        {
+            if (!appl.equals(hisAppl))
+                return false ;
+        }
+
+logmsg("6");
+        if (flags != other.flags)
+            return false;
+
+logmsg("7");
         //int nel = this.getItemIds().length;
         //int len = other.getItemIds().length;
         if (other.getItemIds().length != subs.size())
@@ -495,6 +585,7 @@
             return false ;
         }
 
+logmsg("8");
         SubAccount[] mySubs  =  this.getSubAccounts();
         for (int i = 0; i < mySubs.length; i++)
         {
@@ -507,6 +598,7 @@
 
             // doesn't cope with duplicates in mySubs and extras in hisSubs!
         }
+logmsg("9");
         
 
         return true;
@@ -517,11 +609,12 @@
      */
     public String toString()
     {
-        String retval = "Account:\n";
+        String s = "Account: " + name + " (flags==" + flags +")\n";
+        s += "\tappl==" + appl + "\n";
 
-        retval += "\tPublic: "+pubKey+"\n";
-        retval += "\tPrivate: "+key;
-        return retval;
+        s += "\tPublic: "+pubKey+"\n";
+        s += "\tPrivate: "+key;
+        return s;
     }
 
     public String fp() { return id.fp(); }
@@ -545,16 +638,23 @@
 
 //logmsg("got an ac " + ac);
         // add some subs
-        byte[] b = Utils.exampleData(10);
-        int num = b[0] & 0x07;
+        byte b = Utils.exampleByte();
+        int num = b & 0x07;
 //logmsg("add " + num + " subs");
         while (num-- > 0)
             ac.insertSub(ValueAccount.example());
 
 //logmsg("needs a name?");
-        ac.setName(webfunds.utils.Hex.data2hex(b));
-        if ((b[1] & 07) == 07)
+        if ((b & 010) == 010)
             ac.setName(null);
+        else
+            ac.setName(Utils.exampleString());
+        if ((b & 020) == 020)
+            ac.setApplication(null);
+        else
+            ac.setApplication(Utils.exampleString());
+
+        ac.setFlags(Utils.exampleLong());
 
 //logmsg("returning ac " + ac);
         return ac;
@@ -563,7 +663,7 @@
     {
         arg = null;
         try {
-            for (int i = 0; i < 20; i++)
+            for (int i = 0; i < 2000; i++)
                 tryit(example());
         } catch(Exception e) {
             e.printStackTrace();