forked from I2P_Developers/i2p.i2p
I2CP:
- 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:
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user