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;
+ }
}