- Verify crypto key pair in LS
 - Verfiy same dest as before in LS
Router: Don't try to use an unavailable sig type for the router,
   even if it's the default
RouterInfo: Work around unsupported raw signatures for
   RI Ed25519 sig type
This commit is contained in:
zzz
2014-08-26 19:14:51 +00:00
parent 51f9d6d421
commit ed4fe56e7e
6 changed files with 56 additions and 14 deletions

View File

@ -188,8 +188,7 @@ public class EditBean extends IndexBean {
/** @since 0.9.12 */
public boolean isSigTypeAvailable(int code) {
SigType type = SigType.getByCode(code);
return type != null && type.isAvailable();
return SigType.isAvailable(code);
}
/** @since 0.8.9 */

View File

@ -50,6 +50,7 @@ public class PrivateKey extends SimpleDataStructure {
/** derives a new PublicKey object derived from the secret contents
* of this PrivateKey
* @return a PublicKey object
* @throws IllegalArgumentException on bad key
*/
public PublicKey toPublic() {
return KeyGenerator.getPublicKey(this);

View File

@ -30,6 +30,7 @@ import net.i2p.crypto.DSAEngine;
import net.i2p.crypto.SHA1;
import net.i2p.crypto.SHA1Hash;
import net.i2p.crypto.SHA256Generator;
import net.i2p.crypto.SigType;
import net.i2p.data.DatabaseEntry;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
@ -532,10 +533,17 @@ public class RouterInfo extends DatabaseEntry {
InputStream din;
MessageDigest digest;
if (verifySig) {
digest = _identity.getSigningPublicKey().getType().getDigestInstance();
// TODO any better way?
digest.update(_identity.toByteArray());
din = new DigestInputStream(in, digest);
SigType type = _identity.getSigningPublicKey().getType();
if (type != SigType.EdDSA_SHA512_Ed25519) {
// This won't work for EdDSA
digest = _identity.getSigningPublicKey().getType().getDigestInstance();
// TODO any better way?
digest.update(_identity.toByteArray());
din = new DigestInputStream(in, digest);
} else {
digest = null;
din = in;
}
} else {
digest = null;
din = in;
@ -569,10 +577,16 @@ public class RouterInfo extends DatabaseEntry {
_signature.readBytes(in);
if (verifySig) {
SimpleDataStructure hash = _identity.getSigningPublicKey().getType().getHashInstance();
hash.setData(digest.digest());
_isValid = DSAEngine.getInstance().verifySignature(_signature, hash, _identity.getSigningPublicKey());
_validated = true;
SigType type = _identity.getSigningPublicKey().getType();
if (type != SigType.EdDSA_SHA512_Ed25519) {
// This won't work for EdDSA
SimpleDataStructure hash = _identity.getSigningPublicKey().getType().getHashInstance();
hash.setData(digest.digest());
_isValid = DSAEngine.getInstance().verifySignature(_signature, hash, _identity.getSigningPublicKey());
_validated = true;
} else {
doValidate();
}
if (!_isValid) {
throw new DataFormatException("Bad sig");
}

View File

@ -40,7 +40,7 @@ public class LeaseSetKeys {
/**
* Key with which a LeaseSet can be revoked (by republishing it with no Leases)
*
* @deprecated unused
* Deprecated, unused
*/
public SigningPrivateKey getRevocationKey() { return _revocationKey; }

View File

@ -12,6 +12,7 @@ import java.util.Properties;
import net.i2p.CoreVersion;
import net.i2p.crypto.SigType;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.Payload;
import net.i2p.data.i2cp.BandwidthLimitsMessage;
@ -37,6 +38,7 @@ import net.i2p.data.i2cp.SessionId;
import net.i2p.data.i2cp.SessionStatusMessage;
import net.i2p.data.i2cp.SetDateMessage;
import net.i2p.router.ClientTunnelSettings;
import net.i2p.router.LeaseSetKeys;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
import net.i2p.util.PasswordManager;
@ -367,8 +369,31 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
_runner.disconnectClient("Invalid CreateLeaseSetMessage");
return;
}
_context.keyManager().registerKeys(message.getLeaseSet().getDestination(), message.getSigningPrivateKey(), message.getPrivateKey());
Destination dest = _runner.getConfig().getDestination();
Destination ndest = message.getLeaseSet().getDestination();
if (!dest.equals(ndest)) {
if (_log.shouldLog(Log.ERROR))
_log.error("Different destination in LS");
_runner.disconnectClient("Different destination in LS");
return;
}
LeaseSetKeys keys = _context.keyManager().getKeys(dest);
if (keys == null ||
!message.getPrivateKey().equals(keys.getDecryptionKey())) {
// Verify and register crypto keys if new or if changed
// Private crypto key should never change
if (!message.getPrivateKey().toPublic().equals(dest.getPublicKey())) {
if (_log.shouldLog(Log.ERROR))
_log.error("Private/public crypto key mismatch in LS");
_runner.disconnectClient("Private/public crypto key mismatch in LS");
return;
}
// just register new SPK, don't verify, unused
_context.keyManager().registerKeys(dest, message.getSigningPrivateKey(), message.getPrivateKey());
} else if (!message.getSigningPrivateKey().equals(keys.getRevocationKey())) {
// just register new SPK, don't verify, unused
_context.keyManager().registerKeys(dest, message.getSigningPrivateKey(), message.getPrivateKey());
}
try {
_context.netDb().publish(message.getLeaseSet());
} catch (IllegalArgumentException iae) {

View File

@ -170,9 +170,12 @@ public class CreateRouterInfoJob extends JobImpl {
String sstype = ctx.getProperty(PROP_ROUTER_SIGTYPE);
if (sstype != null) {
SigType ntype = SigType.parseSigType(sstype);
if (ntype != null && ntype.isAvailable())
if (ntype != null)
cstype = ntype;
}
// fallback?
if (cstype != SigType.DSA_SHA1 && !cstype.isAvailable())
cstype = SigType.DSA_SHA1;
return cstype;
}