I2CP: Remove revocation private key from CreateLeaseset2 message

Use correct key to sign SessionConfig with offline keys
LeaseSetKeys cleanups
This commit is contained in:
zzz
2019-02-03 12:59:53 +00:00
parent d7808cd16d
commit 7d11fb269e
9 changed files with 48 additions and 35 deletions

View File

@ -362,6 +362,7 @@ class I2CPMessageProducer {
* This method is misnamed, it does not create the LeaseSet,
* the caller does that.
*
* @param signingPriv ignored for LS2
*/
public void createLeaseSet(I2PSessionImpl session, LeaseSet leaseSet, SigningPrivateKey signingPriv,
List<PrivateKey> privs) throws I2PSessionException {
@ -370,6 +371,7 @@ class I2CPMessageProducer {
if (type == DatabaseEntry.KEY_TYPE_LEASESET) {
msg = new CreateLeaseSetMessage();
msg.setPrivateKey(privs.get(0));
msg.setSigningPrivateKey(signingPriv);
} else {
CreateLeaseSet2Message msg2 = new CreateLeaseSet2Message();
for (PrivateKey priv : privs) {
@ -378,7 +380,6 @@ class I2CPMessageProducer {
msg = msg2;
}
msg.setLeaseSet(leaseSet);
msg.setSigningPrivateKey(signingPriv);
SessionId sid = session.getSessionId();
if (sid == null) {
_log.error(session.toString() + " create LS w/o session", new Exception());

View File

@ -304,16 +304,20 @@ class RequestLeaseSetMessageHandler extends HandlerImpl {
}
try {
leaseSet.sign(session.getPrivateKey());
// Workaround for unparsable serialized signing private key for revocation
// Send him a dummy DSA_SHA1 private key since it's unused anyway
// See CreateLeaseSetMessage.doReadMessage()
// For LS1 only
SigningPrivateKey spk = li.getSigningPrivateKey();
if (!_context.isRouterContext() && spk.getType() != SigType.DSA_SHA1 &&
!(leaseSet instanceof LeaseSet2)) {
if (isLS2) {
// no revocation key in LS2
spk = null;
} else if (!_context.isRouterContext() && spk.getType() != SigType.DSA_SHA1) {
// Workaround for unparsable serialized signing private key for revocation
// Send him a dummy DSA_SHA1 private key since it's unused anyway
// See CreateLeaseSetMessage.doReadMessage()
// For LS1 only
byte[] dummy = new byte[SigningPrivateKey.KEYSIZE_BYTES];
_context.random().nextBytes(dummy);
spk = new SigningPrivateKey(dummy);
if (_log.shouldDebug())
_log.debug("Generated random dummy SPK " + spk);
}
session.getProducer().createLeaseSet(session, leaseSet, spk, li.getPrivateKeys());
session.setLeaseSet(leaseSet);

View File

@ -18,20 +18,21 @@ import net.i2p.data.LeaseSet2;
import net.i2p.data.MetaLeaseSet;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.data.SigningPrivateKey;
/**
* Like CreateLeaseSetMessage, but supports both old
* and new LeaseSet types, including LS2, Meta, and Encrypted.
* Revocation keys are not present.
* Multiple public/private encryption keys are possible.
*
* For LS2:
* Same as CreateLeaseSetMessage, but has a netdb type before
* the LeaseSet. SigningPrivateKey and PrivateKey(s) are
* the LeaseSet. PrivateKeys are
* serialized after the LeaseSet, not before, so we can
* infer the types from the LeaseSet.
*
* For Meta LS:
* SigningPrivateKey and PrivateKey are not present.
* PrivateKeys are not present.
*
* For Encrypted LS:
* TODO
@ -105,8 +106,6 @@ public class CreateLeaseSet2Message extends CreateLeaseSetMessage {
SigType stype = _leaseSet.getSignature().getType();
if (stype == null)
throw new I2CPMessageException("Unsupported sig type");
_signingPrivateKey = new SigningPrivateKey(stype);
_signingPrivateKey.readBytes(in);
if (type == DatabaseEntry.KEY_TYPE_LS2 ||
type == DatabaseEntry.KEY_TYPE_ENCRYPTED_LS2) {
LeaseSet2 ls2 = (LeaseSet2) _leaseSet;
@ -140,20 +139,22 @@ public class CreateLeaseSet2Message extends CreateLeaseSetMessage {
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
int type = _leaseSet.getType();
if (_sessionId == null || _leaseSet == null ||
(type != DatabaseEntry.KEY_TYPE_META_LS2 && (_signingPrivateKey == null || _privateKey == null)))
(type != DatabaseEntry.KEY_TYPE_META_LS2 && _privateKey == null))
throw new I2CPMessageException("Unable to write out the message as there is not enough data");
int size = 4 // sessionId
+ 1 // type
+ _leaseSet.size()
+ _signingPrivateKey.length()
+ _privateKey.length();
+ _leaseSet.size();
if (type != DatabaseEntry.KEY_TYPE_META_LS2) {
for (PrivateKey pk : getPrivateKeys()) {
size += pk.length();
}
}
ByteArrayOutputStream os = new ByteArrayOutputStream(size);
try {
_sessionId.writeBytes(os);
os.write(_leaseSet.getType());
_leaseSet.writeBytes(os);
if (type != DatabaseEntry.KEY_TYPE_META_LS2) {
_signingPrivateKey.writeBytes(os);
for (PrivateKey pk : getPrivateKeys()) {
pk.writeBytes(os);
}
@ -173,9 +174,12 @@ public class CreateLeaseSet2Message extends CreateLeaseSetMessage {
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("[CreateLeaseSet2Message: ");
buf.append("\n\tLeaseSet: ").append(getLeaseSet());
buf.append("\n\tSigningPrivateKey: ").append(getSigningPrivateKey());
buf.append("\n\tPrivateKey: ").append(getPrivateKey());
buf.append("\n\tLeaseSet: ").append(_leaseSet);
if (_leaseSet.getType() != DatabaseEntry.KEY_TYPE_META_LS2) {
for (PrivateKey pk : getPrivateKeys()) {
buf.append("\n\tPrivateKey: ").append(pk);
}
}
buf.append("\n\tSessionId: ").append(getSessionId());
buf.append("]");
return buf.toString();

View File

@ -28,7 +28,7 @@ public class CreateLeaseSetMessage extends I2CPMessageImpl {
public final static int MESSAGE_TYPE = 4;
protected SessionId _sessionId;
protected LeaseSet _leaseSet;
protected SigningPrivateKey _signingPrivateKey;
private SigningPrivateKey _signingPrivateKey;
protected PrivateKey _privateKey;
public CreateLeaseSetMessage() {

View File

@ -346,7 +346,10 @@ public class SessionConfig extends DataStructureImpl {
_destination = Destination.create(rawConfig);
_options = DataHelper.readProperties(rawConfig);
_creationDate = DataHelper.readDate(rawConfig);
_signature = new Signature(_destination.getSigningPublicKey().getType());
SigningPublicKey spk = getTransientSigningPublicKey();
if (spk == null)
spk = _destination.getSigningPublicKey();
_signature = new Signature(spk.getType());
_signature.readBytes(rawConfig);
}

View File

@ -109,7 +109,10 @@ public class KeyManager {
*/
public synchronized SigningPublicKey getSigningPublicKey() { return _signingPublicKey; }
/** client */
/**
* client
* @param leaseRevocationPrivateKey unused, may be null
*/
public void registerKeys(Destination dest, SigningPrivateKey leaseRevocationPrivateKey, PrivateKey endpointDecryptionKey) {
if (_log.shouldLog(Log.INFO))
_log.info("Registering keys for destination " + dest.calculateHash().toBase64());

View File

@ -8,20 +8,13 @@ package net.i2p.router;
*
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.DataStructureImpl;
import net.i2p.data.Destination;
import net.i2p.data.PrivateKey;
import net.i2p.data.SigningPrivateKey;
/**
* Wrap up the keys given to the router when a destination connects to it.
* Used only by KeyManager.
* Used by KeyManager, ClientMessageEventListener, GarlicMessageReceiver.
*/
public class LeaseSetKeys {
private final SigningPrivateKey _revocationKey;
@ -29,7 +22,7 @@ public class LeaseSetKeys {
/**
* @param dest unused
* @param revocationKey unused
* @param revocationKey unused, may be null
* @param decryptionKey non-null
*/
public LeaseSetKeys(Destination dest, SigningPrivateKey revocationKey, PrivateKey decryptionKey) {

View File

@ -508,8 +508,14 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
return;
}
int type = ls.getType();
if (type != DatabaseEntry.KEY_TYPE_META_LS2 &&
(message.getPrivateKey() == null || message.getSigningPrivateKey() == null)) {
if (type != DatabaseEntry.KEY_TYPE_META_LS2 && message.getPrivateKey() == null) {
if (_log.shouldLog(Log.ERROR))
_log.error("Null private keys: " + message);
_runner.disconnectClient("Invalid CreateLeaseSetMessage - null private keys");
return;
}
if (type == DatabaseEntry.KEY_TYPE_LEASESET && message.getSigningPrivateKey() == null) {
// revocation keys only in LS1
if (_log.shouldLog(Log.ERROR))
_log.error("Null private keys: " + message);
_runner.disconnectClient("Invalid CreateLeaseSetMessage - null private keys");

View File

@ -10,7 +10,6 @@ package net.i2p.router.client;
import net.i2p.data.LeaseSet;
import net.i2p.data.PrivateKey;
import net.i2p.data.SigningPrivateKey;
import net.i2p.router.Job;
/**