Author: nextgens
Date: 2006-09-05 21:55:06 +0000 (Tue, 05 Sep 2006)
New Revision: 10399

Modified:
   trunk/freenet/src/freenet/crypt/DiffieHellmanContext.java
   trunk/freenet/src/freenet/crypt/KeyAgreementSchemeContext.java
   trunk/freenet/src/freenet/crypt/StationToStationContext.java
Log:
Still more work toward StS... Review would be welcome

Modified: trunk/freenet/src/freenet/crypt/DiffieHellmanContext.java
===================================================================
--- trunk/freenet/src/freenet/crypt/DiffieHellmanContext.java   2006-09-05 
19:37:45 UTC (rev 10398)
+++ trunk/freenet/src/freenet/crypt/DiffieHellmanContext.java   2006-09-05 
21:55:06 UTC (rev 10399)
@@ -4,7 +4,6 @@
 import java.security.NoSuchAlgorithmException;

 import net.i2p.util.NativeBigInteger;
-import freenet.crypt.ciphers.Rijndael;
 import freenet.support.HexUtil;
 import freenet.support.Logger;

@@ -20,11 +19,7 @@

     // Generated or set later
     NativeBigInteger peerExponential;
-    byte[] key;
-    BlockCipher cipher;
-    

-
        public String toString() {
            StringBuffer sb = new StringBuffer();
            sb.append(super.toString());
@@ -52,19 +47,6 @@
         return myExponential;
     }

-    public synchronized BlockCipher getCipher() {
-        lastUsedTime = System.currentTimeMillis();
-        if(cipher != null) return cipher;
-        getKey();
-        try {
-            cipher = new Rijndael(256, 256);
-        } catch (UnsupportedCipherException e1) {
-            throw new Error(e1);
-        }
-        cipher.initialize(key);
-        return cipher;
-    }
-
     public synchronized byte[] getKey() {
         lastUsedTime = System.currentTimeMillis();
         if(key != null) return key;

Modified: trunk/freenet/src/freenet/crypt/KeyAgreementSchemeContext.java
===================================================================
--- trunk/freenet/src/freenet/crypt/KeyAgreementSchemeContext.java      
2006-09-05 19:37:45 UTC (rev 10398)
+++ trunk/freenet/src/freenet/crypt/KeyAgreementSchemeContext.java      
2006-09-05 21:55:06 UTC (rev 10399)
@@ -1,6 +1,11 @@
 package freenet.crypt;

+import freenet.crypt.ciphers.Rijndael;
+
 public abstract class KeyAgreementSchemeContext {
+    BlockCipher cipher;
+    byte[] key;
+       
     protected long lastUsedTime;
     protected boolean logMINOR;

@@ -10,4 +15,20 @@
     public synchronized long lastUsedTime() {
         return lastUsedTime;
     }
+    
+    public abstract byte[] getKey();
+    public abstract boolean canGetCipher();
+    
+    public synchronized BlockCipher getCipher() {
+        lastUsedTime = System.currentTimeMillis();
+        if(cipher != null) return cipher;
+        getKey();
+        try {
+            cipher = new Rijndael(256, 256);
+        } catch (UnsupportedCipherException e1) {
+            throw new Error(e1);
+        }
+        cipher.initialize(key);
+        return cipher;
+    }
 }

Modified: trunk/freenet/src/freenet/crypt/StationToStationContext.java
===================================================================
--- trunk/freenet/src/freenet/crypt/StationToStationContext.java        
2006-09-05 19:37:45 UTC (rev 10398)
+++ trunk/freenet/src/freenet/crypt/StationToStationContext.java        
2006-09-05 21:55:06 UTC (rev 10399)
@@ -1,5 +1,8 @@
 package freenet.crypt;

+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.math.BigInteger;
 import java.util.Random;

@@ -21,7 +24,7 @@
     final DSAPublicKey hisPubKey;

     /** Our private key */
-    final DSAPrivateKey ourPrivateKey;
+    final DSAPrivateKey myPrivateKey;

     /** The group we both share */
     final DSAGroup group;
@@ -30,17 +33,17 @@
     final Random random;

     // Generated or set later
-    NativeBigInteger peerExponential = null;
+    NativeBigInteger hisExponential = null;
     NativeBigInteger key = null;

     boolean logMINOR;

     public StationToStationContext(DSAPrivateKey ourKey, DSAGroup group, 
DSAPublicKey hisKey, Random rand) {
-        this.ourPrivateKey = ourKey;
+        this.myPrivateKey = ourKey;
         this.random = rand;
         this.group = group;
         this.hisPubKey = hisKey;
-        // How big is the random ?
+        // How big is the random ? FIXME!
         this.myRandom = random.nextInt();
         this.myExponential = (NativeBigInteger) group.getG().pow(myRandom);
         lastUsedTime = System.currentTimeMillis();
@@ -51,39 +54,93 @@
         lastUsedTime = System.currentTimeMillis();
         return myExponential;
     }
+    
+    public synchronized void setOtherSideExponential(NativeBigInteger a) {
+        lastUsedTime = System.currentTimeMillis();
+        if(hisExponential != null) {
+               if(!hisExponential.equals(a))
+                       throw new IllegalStateException("Assigned other side 
exponential twice");
+               else return;
+        }
+        if(a == null) throw new NullPointerException();
+        hisExponential = a;
+    }

-    public synchronized BigInteger getKey() {
+    public synchronized byte[] getKey() {
         lastUsedTime = System.currentTimeMillis();
-        if(key != null) return key;
-        if(peerExponential == null) throw new IllegalStateException("Can't 
call getKey() until setOtherSideExponential() has been called!");
+        if(hisExponential == null) throw new IllegalStateException("Can't call 
getKey() until setOtherSideExponential() has been called!");
+        if(key != null) return key.toByteArray();

         // Calculate key
         if(logMINOR)
-            Logger.minor(this, "My exponent: "+myExponential.toHexString()+", 
my random: "+myRandom+", peer's exponential: "+peerExponential.toHexString());
-        key = (NativeBigInteger) peerExponential.pow(myRandom);
+            Logger.minor(this, "My exponent: "+myExponential.toHexString()+", 
my random: "+myRandom+", peer's exponential: "+hisExponential.toHexString());
+        key = (NativeBigInteger) hisExponential.pow(myRandom);

         if(logMINOR)
             Logger.minor(this, "Key="+HexUtil.bytesToHex(key.toByteArray()));
-        return key;
+        return key.toByteArray();
     }

     public synchronized byte[] concatAndSignAndCrypt(){
-       if(peerExponential == null) throw new IllegalStateException("Can't call 
concatAndSign() until setOtherSideExponential() has been called!");
-       if(key == null)  throw new IllegalStateException("Can't call 
concatAndSign() until getKey() has been called!");
+       lastUsedTime = System.currentTimeMillis();
+       if(hisExponential == null) throw new IllegalStateException("Can't call 
concatAndSignAndCrypt() until setOtherSideExponential() has been called!");
+       if(key == null)  throw new IllegalStateException("Can't call 
concatAndSignAndCrypt() until getKey() has been called!");

-       String sig = new String(myExponential+","+peerExponential);
-       //FIXME: REDFLAG: it should be encrypted as well!
-       return DSA.sign(group, ourPrivateKey, new BigInteger(sig.getBytes()), 
random).toString().getBytes();
+       String message = new String("("+myExponential+","+hisExponential+")");
+       DSASignature signature = DSA.sign(group, myPrivateKey, new 
BigInteger(message.getBytes()), random);
+       
+       if(logMINOR)
+            Logger.minor(this, "The concat result : "+message+". Its signature 
: "+signature);
+       
+       ByteArrayOutputStream os = new ByteArrayOutputStream();
+       CipherOutputStream cos = new CipherOutputStream(getCipher(), os);
+       byte[] result = null;
+       try{
+               cos.write(signature.toString().getBytes());
+               cos.flush();
+               cos.close();
+               result = os.toByteArray();
+               os.close();
+       } catch(IOException e){
+               Logger.error(this, "Error :"+e);
+               e.printStackTrace();
+       }
+
+       return result;
     }

-    public synchronized void setOtherSideExponential(NativeBigInteger a) {
-        lastUsedTime = System.currentTimeMillis();
-        if(peerExponential != null) {
-               if(!peerExponential.equals(a))
-                       throw new IllegalStateException("Assigned other side 
exponential twice");
-               else return;
-        }
-        if(a == null) throw new NullPointerException();
-        peerExponential = a;
+    public synchronized boolean isAuthentificationSuccessfull(byte[] data){
+       lastUsedTime = System.currentTimeMillis();
+       if(data == null) return false;
+       if(hisExponential == null) throw new IllegalStateException("Can't call 
concatAndSignAndCrypt() until setOtherSideExponential() has been called!");
+       if(key == null)  throw new IllegalStateException("Can't call 
concatAndSignAndCrypt() until getKey() has been called!");
+       
+       ByteArrayInputStream is = new ByteArrayInputStream(data);
+       EncipherInputStream ei = new EncipherInputStream(is, getCipher());
+       final String message = new 
String("("+hisExponential+","+myExponential+")");
+
+       try{
+               String signatureToCheck = ei.toString();
+               ei.close();
+               is.close();
+
+               if(signatureToCheck != null && signatureToCheck.equals(message))
+                       if(DSA.verify(hisPubKey, new 
DSASignature(signatureToCheck), new BigInteger(message.getBytes())))
+                               return true;
+
+       } catch(IOException e){
+               Logger.error(this, "Error :"+e);
+               e.printStackTrace();
+       }
+
+       return false;
     }
+
+    /**
+     * @return True if getCipher() will work. If this returns false, 
getCipher() will
+     * probably NPE.
+     */
+    public boolean canGetCipher() {
+        return hisExponential != null;
+    }
 }


Reply via email to