Author: toad
Date: 2006-01-10 17:04:34 +0000 (Tue, 10 Jan 2006)
New Revision: 7834
Modified:
trunk/freenet/src/freenet/client/FileInserter.java
trunk/freenet/src/freenet/client/HighLevelSimpleClient.java
trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
trunk/freenet/src/freenet/client/events/SimpleBlockPutEvent.java
trunk/freenet/src/freenet/crypt/DSAPrivateKey.java
trunk/freenet/src/freenet/keys/ClientKey.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/keys/NodeSSK.java
trunk/freenet/src/freenet/keys/SSKBlock.java
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/NodeDispatcher.java
trunk/freenet/src/freenet/node/SSKInsertHandler.java
trunk/freenet/src/freenet/node/TextModeClientInterface.java
trunk/freenet/src/freenet/node/Version.java
Log:
338: (mandatory)
SSKs *almost* work.
Modified: trunk/freenet/src/freenet/client/FileInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/FileInserter.java 2006-01-10 14:28:22 UTC
(rev 7833)
+++ trunk/freenet/src/freenet/client/FileInserter.java 2006-01-10 17:04:34 UTC
(rev 7834)
@@ -1,6 +1,7 @@
package freenet.client;
import java.io.IOException;
+import java.net.MalformedURLException;
import freenet.client.events.BlockInsertErrorEvent;
import freenet.client.events.SimpleBlockPutEvent;
@@ -43,8 +44,12 @@
public FreenetURI run(InsertBlock block, boolean metadata, boolean
getCHKOnly, boolean noRetries) throws InserterException {
if(block.data == null)
throw new NullPointerException();
- if(!block.desiredURI.toString(false).equals("CHK@"))
+ if(block.desiredURI.getKeyType().equalsIgnoreCase("CHK")) {
+
if(!block.desiredURI.toString(false).equalsIgnoreCase("CHK@"))
+ throw new
InserterException(InserterException.INVALID_URI, null);
+ } else
if(!block.desiredURI.getKeyType().equalsIgnoreCase("SSK")) {
throw new
InserterException(InserterException.INVALID_URI, null);
+ }
// Insert the content.
// If we have reason to create a metadata document, include the
client metadata.
@@ -124,7 +129,11 @@
} else {
codec = bestCodec.codecNumberForMetadata();
}
- isk = InsertableClientSSK.create(block.desiredURI);
+ try {
+ isk =
InsertableClientSSK.create(block.desiredURI);
+ } catch (MalformedURLException e1) {
+ throw new
InserterException(InserterException.INVALID_URI, e1, null);
+ }
ClientSSKBlock ssk;
try {
ssk = isk.encode(data, metadata, true, codec,
data.size(), ctx.random);
Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClient.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClient.java 2006-01-10
14:28:22 UTC (rev 7833)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClient.java 2006-01-10
17:04:34 UTC (rev 7834)
@@ -23,10 +23,15 @@
public FetchResult fetch(FreenetURI uri) throws FetchException;
/**
- * Blocking insert of a URI
+ * Blocking insert.
* @throws InserterException If there is an error inserting the data
*/
public FreenetURI insert(InsertBlock insert, boolean getCHKOnly) throws
InserterException;
+
+ /**
+ * Blocking insert of a redirect.
+ */
+ public FreenetURI insertRedirect(FreenetURI insertURI, FreenetURI
target) throws InserterException;
/**
* Add a ClientEventListener.
Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2006-01-10 14:28:22 UTC (rev 7833)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
2006-01-10 17:04:34 UTC (rev 7834)
@@ -1,14 +1,22 @@
package freenet.client;
+import java.io.IOException;
+import java.net.MalformedURLException;
+
import freenet.client.events.ClientEventListener;
import freenet.client.events.ClientEventProducer;
import freenet.client.events.EventLogger;
import freenet.client.events.SimpleEventProducer;
import freenet.crypt.RandomSource;
+import freenet.keys.ClientCHK;
+import freenet.keys.ClientKey;
import freenet.keys.FreenetURI;
+import freenet.keys.InsertableClientSSK;
import freenet.node.RequestStarterClient;
import freenet.node.SimpleLowLevelClient;
+import freenet.support.Bucket;
import freenet.support.BucketFactory;
+import freenet.support.BucketTools;
import freenet.support.Logger;
public class HighLevelSimpleClientImpl implements HighLevelSimpleClient {
@@ -109,6 +117,23 @@
FileInserter i = new FileInserter(context);
return i.run(insert, metadata, getCHKOnly, false);
}
+
+ public FreenetURI insertRedirect(FreenetURI insertURI, FreenetURI
targetURI) throws InserterException {
+ Metadata m = new Metadata(Metadata.SIMPLE_REDIRECT, targetURI,
new ClientMetadata());
+ Bucket b;
+ try {
+ b = BucketTools.makeImmutableBucket(bucketFactory,
m.writeToByteArray());
+ } catch (IOException e) {
+ Logger.error(this, "Bucket error: "+e);
+ throw new
InserterException(InserterException.INTERNAL_ERROR, e, null);
+ }
+ ClientKey k;
+ InsertBlock block = new InsertBlock(b, new ClientMetadata(),
insertURI);
+ InserterContext context = new InserterContext(client,
bucketFactory, random, INSERT_RETRIES, CONSECUTIVE_RNFS_ASSUME_SUCCESS,
+ SPLITFILE_INSERT_THREADS,
SPLITFILE_BLOCKS_PER_SEGMENT, SPLITFILE_CHECK_BLOCKS_PER_SEGMENT,
globalEventProducer, insertStarter, cacheLocalRequests);
+ FileInserter i = new FileInserter(context);
+ return i.run(block, true, false, false);
+ }
public void addGlobalHook(ClientEventListener listener) {
globalEventProducer.addEventListener(listener);
Modified: trunk/freenet/src/freenet/client/events/SimpleBlockPutEvent.java
===================================================================
--- trunk/freenet/src/freenet/client/events/SimpleBlockPutEvent.java
2006-01-10 14:28:22 UTC (rev 7833)
+++ trunk/freenet/src/freenet/client/events/SimpleBlockPutEvent.java
2006-01-10 17:04:34 UTC (rev 7834)
@@ -14,7 +14,7 @@
}
public String getDescription() {
- return "Inserting simple CHK: "+key.getURI();
+ return "Inserting simple key: "+key.getURI();
}
public int getCode() {
Modified: trunk/freenet/src/freenet/crypt/DSAPrivateKey.java
===================================================================
--- trunk/freenet/src/freenet/crypt/DSAPrivateKey.java 2006-01-10 14:28:22 UTC
(rev 7833)
+++ trunk/freenet/src/freenet/crypt/DSAPrivateKey.java 2006-01-10 17:04:34 UTC
(rev 7834)
@@ -25,7 +25,7 @@
public DSAPrivateKey(DSAGroup g, Random r) {
BigInteger x;
do {
- x = new NativeBigInteger(160, r);
+ x = new NativeBigInteger(256, r);
} while (x.compareTo(g.getQ()) > -1);
this.x = x;
}
Modified: trunk/freenet/src/freenet/keys/ClientKey.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientKey.java 2006-01-10 14:28:22 UTC
(rev 7833)
+++ trunk/freenet/src/freenet/keys/ClientKey.java 2006-01-10 17:04:34 UTC
(rev 7834)
@@ -11,6 +11,8 @@
public static ClientKey getBaseKey(FreenetURI origURI) throws
MalformedURLException {
if(origURI.getKeyType().equals("CHK"))
return new ClientCHK(origURI);
+ if(origURI.getKeyType().equals("SSK"))
+ return new ClientSSK(origURI);
throw new UnsupportedOperationException("Unknown keytype from
"+origURI);
}
Modified: trunk/freenet/src/freenet/keys/ClientSSK.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientSSK.java 2006-01-10 14:28:22 UTC
(rev 7833)
+++ trunk/freenet/src/freenet/keys/ClientSSK.java 2006-01-10 17:04:34 UTC
(rev 7834)
@@ -1,6 +1,7 @@
package freenet.keys;
import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -52,12 +53,18 @@
}
}
+ public ClientSSK(FreenetURI origURI) throws MalformedURLException {
+ this(origURI.getDocName(), null, origURI.getCryptoKey());
+ if(!origURI.getKeyType().equalsIgnoreCase("SSK"))
+ throw new MalformedURLException();
+ }
+
public FreenetURI getURI() {
return new FreenetURI("SSK", docName, pubKeyHash, cryptoKey,
null);
}
public Key getNodeKey() {
- return new NodeSSK(pubKeyHash, ehDocname);
+ return new NodeSSK(pubKeyHash, ehDocname, pubKey);
}
}
Modified: trunk/freenet/src/freenet/keys/ClientSSKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientSSKBlock.java 2006-01-10 14:28:22 UTC
(rev 7833)
+++ trunk/freenet/src/freenet/keys/ClientSSKBlock.java 2006-01-10 17:04:34 UTC
(rev 7834)
@@ -23,6 +23,7 @@
public ClientSSKBlock(byte[] data, byte[] headers, ClientSSK key,
boolean dontVerify) throws SSKVerifyException {
super(data, headers, (NodeSSK) key.getNodeKey(), dontVerify);
+ this.key = key;
}
/**
Modified: trunk/freenet/src/freenet/keys/InsertableClientSSK.java
===================================================================
--- trunk/freenet/src/freenet/keys/InsertableClientSSK.java 2006-01-10
14:28:22 UTC (rev 7833)
+++ trunk/freenet/src/freenet/keys/InsertableClientSSK.java 2006-01-10
17:04:34 UTC (rev 7834)
@@ -1,6 +1,7 @@
package freenet.keys;
import java.io.IOException;
+import java.net.MalformedURLException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -27,10 +28,13 @@
public InsertableClientSSK(String docName, DSAPublicKey pubKey,
DSAPrivateKey privKey, byte[] cryptoKey) {
super(docName, pubKey, cryptoKey);
+ if(pubKey == null) throw new NullPointerException();
this.privKey = privKey;
}
- public static InsertableClientSSK create(FreenetURI uri) {
+ public static InsertableClientSSK create(FreenetURI uri) throws
MalformedURLException {
+ if(!uri.getKeyType().equalsIgnoreCase("SSK"))
+ throw new MalformedURLException();
DSAGroup g = Global.DSAgroupBigA;
DSAPrivateKey privKey = new DSAPrivateKey(new
NativeBigInteger(1, uri.getKeyVal()));
DSAPublicKey pubKey = new DSAPublicKey(g, privKey);
@@ -145,7 +149,7 @@
try {
return new ClientSSKBlock(data, headers, this, false);
// FIXME set last arg to true to not verify
} catch (SSKVerifyException e) {
- throw new IllegalStateException("Impossible encoding
error: "+e.getMessage()+e);
+ throw new IllegalStateException("Impossible encoding
error: "+e.getMessage(), e);
}
}
@@ -162,7 +166,7 @@
throw new IllegalStateException("Cannot
truncate");
}
byte[] buf = new byte[len];
- System.arraycopy(bs, 0, buf, (bs.length-len),
buf.length);
+ System.arraycopy(bs, (bs.length-len), buf, 0, len);
return buf;
}
}
Modified: trunk/freenet/src/freenet/keys/NodeSSK.java
===================================================================
--- trunk/freenet/src/freenet/keys/NodeSSK.java 2006-01-10 14:28:22 UTC (rev
7833)
+++ trunk/freenet/src/freenet/keys/NodeSSK.java 2006-01-10 17:04:34 UTC (rev
7834)
@@ -30,10 +30,11 @@
static final int PUBKEY_HASH_SIZE = 32;
static final int E_H_DOCNAME_SIZE = 32;
- public NodeSSK(byte[] pkHash, byte[] ehDocname) {
+ public NodeSSK(byte[] pkHash, byte[] ehDocname, DSAPublicKey pubKey) {
super(makeRoutingKey(pkHash, ehDocname));
this.encryptedHashedDocname = ehDocname;
this.pubKeyHash = pkHash;
+ this.pubKey = pubKey;
}
// routingKey = H( E(H(docname)) + H(pubkey) )
@@ -63,7 +64,7 @@
raf.readFully(buf);
byte[] buf2 = new byte[PUBKEY_HASH_SIZE];
raf.readFully(buf2);
- return new NodeSSK(buf, buf2);
+ return new NodeSSK(buf, buf2, null);
}
public short getType() {
@@ -92,4 +93,10 @@
return pubKeyHash;
}
+ public void setPubKey(DSAPublicKey pubKey2) {
+ if(pubKey == pubKey2) return;
+ if(pubKey != null) throw new IllegalStateException("Already
assigned pubkey to different value! Old="+pubKey.writeAsField()+",
new="+pubKey2.writeAsField());
+ this.pubKey = pubKey2;
+ }
+
}
Modified: trunk/freenet/src/freenet/keys/SSKBlock.java
===================================================================
--- trunk/freenet/src/freenet/keys/SSKBlock.java 2006-01-10 14:28:22 UTC
(rev 7833)
+++ trunk/freenet/src/freenet/keys/SSKBlock.java 2006-01-10 17:04:34 UTC
(rev 7834)
@@ -27,8 +27,8 @@
* 32 bytes - H(decrypted data), = data decryption key
* 2 bytes - data length + metadata flag
* 2 bytes - data compression algorithm or -1
- * IMPLICIT - hash of remaining fields, including the implicit hash of
data
* IMPLICIT - hash of data
+ * IMPLICIT - hash of remaining fields, including the implicit hash of
data
*
* SIGNATURE ON THE ABOVE HASH:
* 32 bytes - signature: R (unsigned bytes)
@@ -86,6 +86,7 @@
System.arraycopy(headers, x, ehDocname, 0, ehDocname.length);
x+=E_H_DOCNAME_LENGTH;
headersOffset = x; // is index to start of encrypted headers
+ x += ENCRYPTED_HEADERS_LENGTH;
// Extract the signature
byte[] bufR = new byte[SIG_R_LENGTH];
byte[] bufS = new byte[SIG_S_LENGTH];
@@ -102,7 +103,7 @@
md.update(data);
byte[] dataHash = md.digest();
// All headers up to and not including the signature
- md.update(headers, 0, headersOffset);
+ md.update(headers, 0, headersOffset +
ENCRYPTED_HEADERS_LENGTH);
// Then the implicit data hash
md.update(dataHash);
// Makes the implicit overall hash
@@ -113,8 +114,6 @@
if(!DSA.verify(pubKey, new DSASignature(r, s), new
NativeBigInteger(1, overallHash))) {
throw new SSKVerifyException("Signature
verification failed for node-level SSK");
}
- if(headers.length < x+2+E_H_DOCNAME_LENGTH)
- throw new SSKVerifyException("Headers too short
after sig verification: "+headers.length+" should be "+x+2+E_H_DOCNAME_LENGTH);
}
if(!Arrays.equals(ehDocname, nodeKey.encryptedHashedDocname))
throw new SSKVerifyException("E(H(docname)) wrong -
wrong key??");
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-01-10 14:28:22 UTC (rev
7833)
+++ trunk/freenet/src/freenet/node/Node.java 2006-01-10 17:04:34 UTC (rev
7834)
@@ -21,7 +21,6 @@
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Hashtable;
import java.util.Iterator;
import freenet.client.ArchiveManager;
@@ -672,7 +671,6 @@
public void realPutSSK(ClientSSKBlock block, boolean cache) throws
LowLevelPutException {
byte[] data = block.getRawData();
byte[] headers = block.getRawHeaders();
- PartiallyReceivedBlock prb = new
PartiallyReceivedBlock(PACKETS_IN_BLOCK, PACKET_SIZE, data);
SSKInsertSender is;
long uid = random.nextLong();
if(!lockUID(uid)) {
Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java 2006-01-10 14:28:22 UTC
(rev 7833)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java 2006-01-10 17:04:34 UTC
(rev 7834)
@@ -72,7 +72,7 @@
return handleRoutedRejected(m);
} else if(spec == DMT.FNPCHKDataRequest || spec ==
DMT.FNPSSKDataRequest) {
return handleDataRequest(m);
- } else if(spec == DMT.FNPInsertRequest) {
+ } else if(spec == DMT.FNPInsertRequest || spec ==
DMT.FNPSSKInsertRequest) {
return handleInsertRequest(m);
} else if(spec == DMT.FNPLinkPing) {
long id = m.getLong(DMT.PING_SEQNO);
@@ -169,10 +169,17 @@
}
return true;
}
- InsertHandler rh = new InsertHandler(m, id, node, now);
- Thread t = new Thread(rh, "InsertHandler for "+id+" on
"+node.portNumber);
- t.setDaemon(true);
- t.start();
+ if(m.getSpec().equals(DMT.FNPSSKInsertRequest)) {
+ SSKInsertHandler rh = new SSKInsertHandler(m, id, node, now);
+ Thread t = new Thread(rh, "InsertHandler for "+id+" on
"+node.portNumber);
+ t.setDaemon(true);
+ t.start();
+ } else {
+ InsertHandler rh = new InsertHandler(m, id, node, now);
+ Thread t = new Thread(rh, "InsertHandler for "+id+" on
"+node.portNumber);
+ t.setDaemon(true);
+ t.start();
+ }
Logger.minor(this, "Started InsertHandler for "+id);
return true;
}
Modified: trunk/freenet/src/freenet/node/SSKInsertHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/SSKInsertHandler.java 2006-01-10
14:28:22 UTC (rev 7833)
+++ trunk/freenet/src/freenet/node/SSKInsertHandler.java 2006-01-10
17:04:34 UTC (rev 7834)
@@ -9,7 +9,6 @@
import freenet.io.comm.MessageFilter;
import freenet.io.comm.NotConnectedException;
import freenet.io.xfer.BlockReceiver;
-import freenet.keys.NodeCHK;
import freenet.keys.NodeSSK;
import freenet.keys.SSKBlock;
import freenet.keys.SSKVerifyException;
@@ -92,6 +91,7 @@
if(pubKey == null) {
// Wait for pub key
+ Logger.minor(this, "Waiting for pubkey on "+uid);
MessageFilter mfPK =
MessageFilter.create().setType(DMT.FNPSSKPubKey).setField(DMT.UID,
uid).setSource(source).setTimeout(PUBKEY_TIMEOUT);
@@ -104,6 +104,7 @@
byte[] pubkeyAsBytes =
((ShortBuffer)pk.getObject(DMT.PUBKEY_AS_BYTES)).getData();
try {
pubKey = new
DSAPublicKey(pubkeyAsBytes);
+ Logger.minor(this, "Got pubkey on
"+uid);
} catch (IOException e) {
Logger.error(this, "Invalid pubkey from
"+source+" on "+uid);
Message msg =
DMT.createFNPDataInsertRejected(uid, DMT.DATA_INSERT_REJECTED_SSK_ERROR);
@@ -123,9 +124,10 @@
// Now we have the data, the headers and the pubkey. Commit it.
try {
+ key.setPubKey(pubKey);
block = new SSKBlock(data, headers, key, false);
} catch (SSKVerifyException e1) {
- Logger.error(this, "Invalid SSK from "+source);
+ Logger.error(this, "Invalid SSK from "+source, e1);
Message msg = DMT.createFNPDataInsertRejected(uid,
DMT.DATA_INSERT_REJECTED_SSK_ERROR);
try {
source.send(msg);
Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-01-10
14:28:22 UTC (rev 7833)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-01-10
17:04:34 UTC (rev 7834)
@@ -101,7 +101,7 @@
System.out.println("PUTDIR:<path>[#<defaultfile>] - Put the entire
directory from disk.");
System.out.println("GETCHKDIR:<path>[#<defaultfile>] - Get the key
that would be returned if we'd put the entire directory from disk.");
System.out.println("MAKESSK - Create an SSK keypair.");
- System.out.println("PUTSSK:<insert uri>:<url to redirect to> - Insert
an SSK redirect to a file already inserted.");
+ System.out.println("PUTSSK:<insert uri>;<url to redirect to> - Insert
an SSK redirect to a file already inserted.");
// System.out.println("PUBLISH:<name> - create a publish/subscribe
stream called <name>");
// System.out.println("PUSH:<name>:<text> - publish a single line of
text to the stream named");
// System.out.println("SUBSCRIBE:<key> - subscribe to a
publish/subscribe stream by key");
@@ -399,6 +399,33 @@
InsertableClientSSK key = InsertableClientSSK.createRandom(r);
System.out.println("Insert URI:
"+key.getInsertURI().toString(false));
System.out.println("Request URI:
"+key.getURI().toString(false));
+ } else if(uline.startsWith("PUTSSK:")) {
+ String cmd = line.substring("PUTSSK:".length());
+ cmd = cmd.trim();
+ if(cmd.indexOf(';') <= 0) {
+ System.out.println("No target URI provided.");
+ System.out.println("PUTSSK:<insert uri>;<url to
redirect to>");
+ return;
+ }
+ String[] split = cmd.split(";");
+ String insertURI = split[0];
+ String targetURI = split[1];
+ System.out.println("Insert URI: "+insertURI);
+ System.out.println("Target URI: "+targetURI);
+ FreenetURI insert = new FreenetURI(insertURI);
+ FreenetURI target = new FreenetURI(targetURI);
+ InsertableClientSSK key = InsertableClientSSK.create(insert);
+ System.out.println("Fetch URI: "+key.getURI());
+ try {
+ FreenetURI result =
client.insertRedirect(insert, target);
+ System.out.println("Successfully inserted to
fetch URI: "+key.getURI());
+ } catch (InserterException e) {
+ System.out.println("Finished insert but: "+e.getMessage());
+ if(e.uri != null) {
+ System.out.println("URI would have been: "+e.uri);
+ }
+ }
+
} else if(uline.startsWith("STATUS")) {
SimpleFieldSet fs = n.exportFieldSet();
System.out.println(fs.toString());
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-01-10 14:28:22 UTC (rev
7833)
+++ trunk/freenet/src/freenet/node/Version.java 2006-01-10 17:04:34 UTC (rev
7834)
@@ -20,10 +20,10 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- public static final int buildNumber = 337;
+ public static final int buildNumber = 338;
/** Oldest build of Fred we will talk to */
- public static final int lastGoodBuild = 337;
+ public static final int lastGoodBuild = 338;
/** The highest reported build of fred */
public static int highestSeenBuild = buildNumber;