forked from I2P_Developers/i2p.i2p
i2ptunnel: New CLI BlindingInfo test
I2CP: Fix BlindingInfo serialization
This commit is contained in:
@ -66,10 +66,14 @@ import net.i2p.client.I2PSession;
|
|||||||
import net.i2p.client.I2PSessionException;
|
import net.i2p.client.I2PSessionException;
|
||||||
import net.i2p.client.I2PSimpleClient;
|
import net.i2p.client.I2PSimpleClient;
|
||||||
import net.i2p.client.naming.NamingService;
|
import net.i2p.client.naming.NamingService;
|
||||||
|
import net.i2p.crypto.Blinding;
|
||||||
|
import net.i2p.crypto.EncType;
|
||||||
import net.i2p.data.Base64;
|
import net.i2p.data.Base64;
|
||||||
|
import net.i2p.data.BlindData;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
|
import net.i2p.data.PrivateKey;
|
||||||
import net.i2p.i2ptunnel.socks.I2PSOCKSIRCTunnel;
|
import net.i2p.i2ptunnel.socks.I2PSOCKSIRCTunnel;
|
||||||
import net.i2p.i2ptunnel.socks.I2PSOCKSTunnel;
|
import net.i2p.i2ptunnel.socks.I2PSOCKSTunnel;
|
||||||
import net.i2p.i2ptunnel.streamr.StreamrConsumer;
|
import net.i2p.i2ptunnel.streamr.StreamrConsumer;
|
||||||
@ -448,6 +452,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
|||||||
runOwnDest(args, l);
|
runOwnDest(args, l);
|
||||||
} else if (cmdname.equals("auth")) {
|
} else if (cmdname.equals("auth")) {
|
||||||
runAuth(args, l);
|
runAuth(args, l);
|
||||||
|
} else if (cmdname.equals("blinding")) {
|
||||||
|
runBlinding(args, l);
|
||||||
} else {
|
} else {
|
||||||
l.log("Unknown command [" + cmdname + "]");
|
l.log("Unknown command [" + cmdname + "]");
|
||||||
}
|
}
|
||||||
@ -464,6 +470,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
|||||||
l.log("Command list:\n" +
|
l.log("Command list:\n" +
|
||||||
// alphabetical please...
|
// alphabetical please...
|
||||||
" auth <username> <password>\n" +
|
" auth <username> <password>\n" +
|
||||||
|
" blinding [-d|p] [-k key] [-s password] [-e expires] xxx.b32.i2p\n" +
|
||||||
" client <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]\n" +
|
" client <port> <pubkey>[,<pubkey,...]|file:<pubkeyfile> [<sharedClient>]\n" +
|
||||||
" clientoptions [-acx] [key=value ]*\n" +
|
" clientoptions [-acx] [key=value ]*\n" +
|
||||||
" close [forced|destroy] <jobnumber>|all\n" +
|
" close [forced|destroy] <jobnumber>|all\n" +
|
||||||
@ -1694,6 +1701,110 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a BlindingInfo message, just for testing
|
||||||
|
* @since 0.9.43
|
||||||
|
*/
|
||||||
|
private void runBlinding(String[] argv, Logging l) {
|
||||||
|
// blinding [-d|p] [-k key] [-s password] [-e expires] xxx.b32.i2p // -d for DH; -p for PSK; expires in days
|
||||||
|
Getopt g = new Getopt("blinding", argv, "dpk:s:e:");
|
||||||
|
boolean error = false;
|
||||||
|
boolean dh = false;
|
||||||
|
boolean psk = false;
|
||||||
|
String key = null;
|
||||||
|
String pw = null;
|
||||||
|
long expires = 0;
|
||||||
|
int c;
|
||||||
|
while ((c = g.getopt()) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'd':
|
||||||
|
dh = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
psk = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'k':
|
||||||
|
key = g.getOptarg();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
pw = g.getOptarg();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'e':
|
||||||
|
expires = Long.parseLong(g.getOptarg());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
case ':':
|
||||||
|
default:
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int remaining = argv.length - g.getOptind();
|
||||||
|
if (error || remaining != 1 || (dh && psk) || ((dh || psk) && key == null)) {
|
||||||
|
System.out.println("Usage: blinding [-d|p] [-k key] [-s password] [-e expires] xxx.b32.i2p // -d for DH; -p for PSK; expires in days");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String name = argv[g.getOptind()];
|
||||||
|
BlindData bd;
|
||||||
|
try {
|
||||||
|
int auth = BlindData.AUTH_NONE;
|
||||||
|
PrivateKey pk = null;
|
||||||
|
if (key != null) {
|
||||||
|
byte[] data = Base64.decode(key);
|
||||||
|
if (data == null || data.length != 32) {
|
||||||
|
System.out.println("Invalid private key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pk = new PrivateKey(EncType.ECIES_X25519, data);
|
||||||
|
auth = dh ? BlindData.AUTH_DH : BlindData.AUTH_PSK;
|
||||||
|
}
|
||||||
|
// basic check and decode
|
||||||
|
bd = Blinding.decode(_context, name);
|
||||||
|
// fill in key and secret
|
||||||
|
bd = new BlindData(_context, bd.getUnblindedPubKey(), bd.getBlindedSigType(), pw, auth, pk);
|
||||||
|
long now = _context.clock().now();
|
||||||
|
bd.setDate(now);
|
||||||
|
if (expires > 0) {
|
||||||
|
expires *= 24*60*60*1000L;
|
||||||
|
expires += now;
|
||||||
|
bd.setExpiration(expires);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
System.out.println("Invalid b32 " + name + " - " + iae);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean ssl = Boolean.parseBoolean(_clientOptions.getProperty("i2cp.SSL"));
|
||||||
|
String user = _clientOptions.getProperty("i2cp.username");
|
||||||
|
String ipw = _clientOptions.getProperty("i2cp.password");
|
||||||
|
I2PClient client = new I2PSimpleClient();
|
||||||
|
Properties opts = new Properties();
|
||||||
|
opts.put(I2PClient.PROP_TCP_HOST, host);
|
||||||
|
opts.put(I2PClient.PROP_TCP_PORT, port);
|
||||||
|
opts.put("i2cp.SSL", Boolean.toString(ssl));
|
||||||
|
if (user != null)
|
||||||
|
opts.put("i2cp.username", user);
|
||||||
|
if (ipw != null)
|
||||||
|
opts.put("i2cp.password", ipw);
|
||||||
|
I2PSession session = null;
|
||||||
|
try {
|
||||||
|
session = client.createSession(null, opts);
|
||||||
|
session.connect();
|
||||||
|
System.out.println("Sending: " + bd);
|
||||||
|
session.sendBlindingInfo(bd);
|
||||||
|
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||||
|
} catch (I2PSessionException ise) {
|
||||||
|
System.out.println("Send blinding info failed: " + ise);
|
||||||
|
} finally {
|
||||||
|
if (session != null) {
|
||||||
|
try { session.destroySession(); } catch (I2PSessionException ise) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to actually close the given task number (optionally forcing
|
* Helper method to actually close the given task number (optionally forcing
|
||||||
* closure)
|
* closure)
|
||||||
|
@ -337,6 +337,8 @@ public class BlindingInfoMessage extends I2CPMessageImpl {
|
|||||||
try {
|
try {
|
||||||
_sessionId.writeBytes(os);
|
_sessionId.writeBytes(os);
|
||||||
byte flags = (byte) _authType;
|
byte flags = (byte) _authType;
|
||||||
|
if (_privkey != null)
|
||||||
|
flags |= FLAG_AUTH;
|
||||||
if (_secret != null)
|
if (_secret != null)
|
||||||
flags |= FLAG_SECRET;
|
flags |= FLAG_SECRET;
|
||||||
os.write(flags);
|
os.write(flags);
|
||||||
@ -349,10 +351,13 @@ public class BlindingInfoMessage extends I2CPMessageImpl {
|
|||||||
DataHelper.writeString(os, _host);
|
DataHelper.writeString(os, _host);
|
||||||
} else if (_endpointType == TYPE_DEST) {
|
} else if (_endpointType == TYPE_DEST) {
|
||||||
_dest.writeBytes(os);
|
_dest.writeBytes(os);
|
||||||
} else {
|
} else { // TYPE_KEY
|
||||||
|
DataHelper.writeLong(os, 2, _pubkey.getType().getCode());
|
||||||
|
os.write(_pubkey.getData());
|
||||||
|
}
|
||||||
|
if (_privkey != null) {
|
||||||
DataHelper.writeLong(os, 2, _privkey.getType().getCode());
|
DataHelper.writeLong(os, 2, _privkey.getType().getCode());
|
||||||
os.write(_privkey.getData());
|
os.write(_privkey.getData());
|
||||||
DataHelper.writeString(os, _host);
|
|
||||||
}
|
}
|
||||||
if (_secret != null)
|
if (_secret != null)
|
||||||
DataHelper.writeString(os, _secret);
|
DataHelper.writeString(os, _secret);
|
||||||
|
Reference in New Issue
Block a user