Author: toad
Date: 2006-01-12 15:30:35 +0000 (Thu, 12 Jan 2006)
New Revision: 7842
Modified:
trunk/freenet/src/freenet/io/comm/DMT.java
trunk/freenet/src/freenet/keys/ClientSSK.java
trunk/freenet/src/freenet/keys/ClientSSKBlock.java
trunk/freenet/src/freenet/keys/InsertableClientSSK.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/RequestHandler.java
trunk/freenet/src/freenet/node/RequestSender.java
trunk/freenet/src/freenet/node/Version.java
Log:
341: More work towards getting SSK requests working.
Modified: trunk/freenet/src/freenet/io/comm/DMT.java
===================================================================
--- trunk/freenet/src/freenet/io/comm/DMT.java 2006-01-12 00:44:06 UTC (rev
7841)
+++ trunk/freenet/src/freenet/io/comm/DMT.java 2006-01-12 15:30:35 UTC (rev
7842)
@@ -529,7 +529,7 @@
}};
public static final Message createFNPSSKDataRequest(long id, short htl,
NodeSSK key, double nearestLocation, boolean needPubKey) {
- Message msg = new Message(FNPCHKDataRequest);
+ Message msg = new Message(FNPSSKDataRequest);
msg.set(UID, id);
msg.set(HTL, htl);
msg.set(FREENET_ROUTING_KEY, key);
Modified: trunk/freenet/src/freenet/keys/ClientSSK.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientSSK.java 2006-01-12 00:44:06 UTC
(rev 7841)
+++ trunk/freenet/src/freenet/keys/ClientSSK.java 2006-01-12 15:30:35 UTC
(rev 7842)
@@ -4,6 +4,7 @@
import java.net.MalformedURLException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
import freenet.crypt.DSAPublicKey;
import freenet.crypt.UnsupportedCipherException;
@@ -14,7 +15,7 @@
/** Document name */
public final String docName;
/** Public key */
- public final DSAPublicKey pubKey;
+ public DSAPublicKey pubKey;
/** Public key hash */
public final byte[] pubKeyHash;
/** Encryption key */
@@ -24,18 +25,23 @@
static final int CRYPTO_KEY_LENGTH = 32;
- public ClientSSK(String docName, DSAPublicKey pubKey, byte[] cryptoKey)
{
+ public ClientSSK(String docName, byte[] pubKeyHash, DSAPublicKey
pubKey, byte[] cryptoKey) {
this.docName = docName;
this.pubKey = pubKey;
- byte[] pubKeyAsBytes = pubKey.asBytes();
+ this.pubKeyHash = pubKeyHash;
MessageDigest md;
try {
md = MessageDigest.getInstance("SHA-256");
- md.update(pubKeyAsBytes);
- pubKeyHash = md.digest();
} catch (NoSuchAlgorithmException e) {
throw new Error(e);
}
+ if(pubKey != null) {
+ byte[] pubKeyAsBytes = pubKey.asBytes();
+ md.update(pubKeyAsBytes);
+ byte[] otherPubKeyHash = md.digest();
+ if(!Arrays.equals(otherPubKeyHash, pubKeyHash))
+ throw new IllegalArgumentException();
+ }
this.cryptoKey = cryptoKey;
try {
md.update(docName.getBytes("UTF-8"));
@@ -54,11 +60,17 @@
}
public ClientSSK(FreenetURI origURI) throws MalformedURLException {
- this(origURI.getDocName(), null, origURI.getCryptoKey());
+ this(origURI.getDocName(), origURI.getRoutingKey(), null,
origURI.getCryptoKey());
if(!origURI.getKeyType().equalsIgnoreCase("SSK"))
throw new MalformedURLException();
}
-
+
+ public void setPublicKey(DSAPublicKey pubKey) {
+ if(this.pubKey != null && this.pubKey != pubKey)
+ throw new IllegalArgumentException("Cannot reassign:
was "+this.pubKey+" now "+pubKey);
+ this.pubKey = pubKey;
+ }
+
public FreenetURI getURI() {
return new FreenetURI("SSK", docName, pubKeyHash, cryptoKey,
null);
}
Modified: trunk/freenet/src/freenet/keys/ClientSSKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientSSKBlock.java 2006-01-12 00:44:06 UTC
(rev 7841)
+++ trunk/freenet/src/freenet/keys/ClientSSKBlock.java 2006-01-12 15:30:35 UTC
(rev 7842)
@@ -26,6 +26,10 @@
this.key = key;
}
+ public ClientSSKBlock(SSKBlock block, ClientSSK key) throws
SSKVerifyException {
+ this(block.data, block.headers, key, false);
+ }
+
/**
* Decode the data.
*/
Modified: trunk/freenet/src/freenet/keys/InsertableClientSSK.java
===================================================================
--- trunk/freenet/src/freenet/keys/InsertableClientSSK.java 2006-01-12
00:44:06 UTC (rev 7841)
+++ trunk/freenet/src/freenet/keys/InsertableClientSSK.java 2006-01-12
15:30:35 UTC (rev 7842)
@@ -26,8 +26,8 @@
public final DSAPrivateKey privKey;
- public InsertableClientSSK(String docName, DSAPublicKey pubKey,
DSAPrivateKey privKey, byte[] cryptoKey) {
- super(docName, pubKey, cryptoKey);
+ public InsertableClientSSK(String docName, byte[] pubKeyHash,
DSAPublicKey pubKey, DSAPrivateKey privKey, byte[] cryptoKey) {
+ super(docName, pubKeyHash, pubKey, cryptoKey);
if(pubKey == null) throw new NullPointerException();
this.privKey = privKey;
}
@@ -38,7 +38,14 @@
DSAGroup g = Global.DSAgroupBigA;
DSAPrivateKey privKey = new DSAPrivateKey(new
NativeBigInteger(1, uri.getKeyVal()));
DSAPublicKey pubKey = new DSAPublicKey(g, privKey);
- return new InsertableClientSSK(uri.getDocName(), pubKey,
privKey, uri.getCryptoKey());
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("SHA-256");
+ } catch (NoSuchAlgorithmException e) {
+ throw new Error(e);
+ }
+ md.update(pubKey.asBytes());
+ return new InsertableClientSSK(uri.getDocName(), md.digest(),
pubKey, privKey, uri.getCryptoKey());
}
public ClientSSKBlock encode(Bucket sourceData, boolean asMetadata,
boolean dontCompress, short alreadyCompressedCodec, long sourceLength,
RandomSource r) throws SSKEncodeException, IOException {
@@ -177,7 +184,13 @@
DSAGroup g = Global.DSAgroupBigA;
DSAPrivateKey privKey = new DSAPrivateKey(g, r);
DSAPublicKey pubKey = new DSAPublicKey(g, privKey);
- return new InsertableClientSSK("", pubKey, privKey, ckey);
+ MessageDigest md;
+ try {
+ md = MessageDigest.getInstance("SHA-256");
+ } catch (NoSuchAlgorithmException e) {
+ throw new Error(e);
+ }
+ return new InsertableClientSSK("", md.digest(pubKey.asBytes()),
pubKey, privKey, ckey);
}
public FreenetURI getInsertURI() {
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-01-12 00:44:06 UTC (rev
7841)
+++ trunk/freenet/src/freenet/node/Node.java 2006-01-12 15:30:35 UTC (rev
7842)
@@ -46,12 +46,14 @@
import freenet.keys.ClientCHKBlock;
import freenet.keys.ClientKey;
import freenet.keys.ClientKeyBlock;
+import freenet.keys.ClientSSK;
import freenet.keys.ClientSSKBlock;
import freenet.keys.Key;
import freenet.keys.KeyBlock;
import freenet.keys.NodeCHK;
import freenet.keys.NodeSSK;
import freenet.keys.SSKBlock;
+import freenet.keys.SSKVerifyException;
import freenet.store.BerkeleyDBFreenetStore;
import freenet.store.FreenetStore;
import freenet.support.BucketFactory;
@@ -462,8 +464,10 @@
public ClientKeyBlock realGetKey(ClientKey key, boolean localOnly, boolean
cache) throws LowLevelGetException {
if(key instanceof ClientCHK)
return realGetCHK((ClientCHK)key, localOnly, cache);
+ else if(key instanceof ClientSSK)
+ return realGetSSK((ClientSSK)key, localOnly, cache);
else
- throw new IllegalArgumentException("Not a CHK: "+key);
+ throw new IllegalArgumentException("Not a CHK or SSK: "+key);
}
/**
@@ -552,6 +556,90 @@
}
}
+ /**
+ * Really trivially simple client interface.
+ * Either it succeeds or it doesn't.
+ */
+ ClientSSKBlock realGetSSK(ClientSSK key, boolean localOnly, boolean cache)
throws LowLevelGetException {
+ long startTime = System.currentTimeMillis();
+ long uid = random.nextLong();
+ if(!lockUID(uid)) {
+ Logger.error(this, "Could not lock UID just randomly generated:
"+uid+" - probably indicates broken PRNG");
+ throw new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+ }
+ Object o = makeRequestSender(key.getNodeKey(), MAX_HTL, uid, null,
lm.loc.getValue(), localOnly, cache);
+ if(o instanceof SSKBlock) {
+ try {
+ return new ClientSSKBlock((SSKBlock)o, key);
+ } catch (SSKVerifyException e) {
+ Logger.error(this, "Does not verify: "+e, e);
+ throw new
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
+ }
+ }
+ if(o == null) {
+ throw new
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND_IN_STORE);
+ }
+ RequestSender rs = (RequestSender)o;
+ boolean rejectedOverload = false;
+ while(true) {
+ if(rs.waitUntilStatusChange() && (!rejectedOverload)) {
+ requestThrottle.requestRejectedOverload();
+ rejectedOverload = true;
+ }
+
+ int status = rs.getStatus();
+
+ if(status == RequestSender.NOT_FINISHED)
+ continue;
+
+ if(status == RequestSender.TIMED_OUT ||
+ status ==
RequestSender.GENERATED_REJECTED_OVERLOAD) {
+ if(!rejectedOverload) {
+ requestThrottle.requestRejectedOverload();
+ rejectedOverload = true;
+ }
+ } else {
+ if(status == RequestSender.DATA_NOT_FOUND ||
+ status == RequestSender.SUCCESS ||
+ status == RequestSender.ROUTE_NOT_FOUND
||
+ status == RequestSender.VERIFY_FAILURE)
{
+ long rtt = System.currentTimeMillis() -
startTime;
+ requestThrottle.requestCompleted(rtt);
+ }
+ }
+
+ if(rs.getStatus() == RequestSender.SUCCESS) {
+ try {
+ return new ClientSSKBlock(rs.getSSKBlock(),
key);
+ } catch (SSKVerifyException e) {
+ Logger.error(this, "Does not verify: "+e, e);
+ throw new
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
+ }
+ } else {
+ switch(rs.getStatus()) {
+ case RequestSender.NOT_FINISHED:
+ Logger.error(this, "RS still running in
getCHK!: "+rs);
+ throw new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+ case RequestSender.DATA_NOT_FOUND:
+ throw new
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND);
+ case RequestSender.ROUTE_NOT_FOUND:
+ throw new
LowLevelGetException(LowLevelGetException.ROUTE_NOT_FOUND);
+ case RequestSender.TRANSFER_FAILED:
+ Logger.error(this, "WTF? Transfer failed on an
SSK? on "+uid);
+ throw new
LowLevelGetException(LowLevelGetException.TRANSFER_FAILED);
+ case RequestSender.VERIFY_FAILURE:
+ throw new
LowLevelGetException(LowLevelGetException.VERIFY_FAILED);
+ case RequestSender.GENERATED_REJECTED_OVERLOAD:
+ case RequestSender.TIMED_OUT:
+ throw new
LowLevelGetException(LowLevelGetException.REJECTED_OVERLOAD);
+ default:
+ Logger.error(this, "Unknown RequestSender code
in getCHK: "+rs.getStatus()+" on "+rs);
+ throw new
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+ }
+ }
+ }
+ }
+
public void putKey(ClientKeyBlock block, RequestStarterClient client,
boolean cache) throws LowLevelPutException {
client.putKey(block, cache);
}
Modified: trunk/freenet/src/freenet/node/RequestHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestHandler.java 2006-01-12 00:44:06 UTC
(rev 7841)
+++ trunk/freenet/src/freenet/node/RequestHandler.java 2006-01-12 15:30:35 UTC
(rev 7842)
@@ -40,7 +40,7 @@
closestLoc = req.getDouble(DMT.NEAREST_LOCATION);
double myLoc = n.lm.getLocation().getValue();
// FIXME should be more generic when implement SSKs
- key = (NodeCHK) req.getObject(DMT.FREENET_ROUTING_KEY);
+ key = (Key) req.getObject(DMT.FREENET_ROUTING_KEY);
double keyLoc = key.toNormalizedDouble();
if(Math.abs(keyLoc - myLoc) < Math.abs(keyLoc - closestLoc))
closestLoc = myLoc;
Modified: trunk/freenet/src/freenet/node/RequestSender.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestSender.java 2006-01-12 00:44:06 UTC
(rev 7841)
+++ trunk/freenet/src/freenet/node/RequestSender.java 2006-01-12 15:30:35 UTC
(rev 7842)
@@ -55,6 +55,7 @@
private byte[] headers;
private byte[] sskData;
private boolean sentRequest;
+ private SSKBlock block;
// Terminal status
// Always set finished AFTER setting the reason flag
@@ -377,7 +378,7 @@
private void finishSSK(PeerNode next) {
try {
- SSKBlock block = new SSKBlock(sskData, headers,
(NodeSSK)key, false);
+ block = new SSKBlock(sskData, headers, (NodeSSK)key,
false);
node.store(block);
finish(SUCCESS, next);
} catch (SSKVerifyException e) {
@@ -497,4 +498,8 @@
final byte[] getSSKData() {
return sskData;
}
+
+ public SSKBlock getSSKBlock() {
+ return block;
+ }
}
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-01-12 00:44:06 UTC (rev
7841)
+++ trunk/freenet/src/freenet/node/Version.java 2006-01-12 15:30:35 UTC (rev
7842)
@@ -20,7 +20,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- public static final int buildNumber = 340;
+ public static final int buildNumber = 341;
/** Oldest build of Fred we will talk to */
public static final int lastGoodBuild = 340;