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 */
|
/** @since 0.9.12 */
|
||||||
public boolean isSigTypeAvailable(int code) {
|
public boolean isSigTypeAvailable(int code) {
|
||||||
SigType type = SigType.getByCode(code);
|
return SigType.isAvailable(code);
|
||||||
return type != null && type.isAvailable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 0.8.9 */
|
/** @since 0.8.9 */
|
||||||
|
@ -50,6 +50,7 @@ public class PrivateKey extends SimpleDataStructure {
|
|||||||
/** derives a new PublicKey object derived from the secret contents
|
/** derives a new PublicKey object derived from the secret contents
|
||||||
* of this PrivateKey
|
* of this PrivateKey
|
||||||
* @return a PublicKey object
|
* @return a PublicKey object
|
||||||
|
* @throws IllegalArgumentException on bad key
|
||||||
*/
|
*/
|
||||||
public PublicKey toPublic() {
|
public PublicKey toPublic() {
|
||||||
return KeyGenerator.getPublicKey(this);
|
return KeyGenerator.getPublicKey(this);
|
||||||
|
@ -30,6 +30,7 @@ import net.i2p.crypto.DSAEngine;
|
|||||||
import net.i2p.crypto.SHA1;
|
import net.i2p.crypto.SHA1;
|
||||||
import net.i2p.crypto.SHA1Hash;
|
import net.i2p.crypto.SHA1Hash;
|
||||||
import net.i2p.crypto.SHA256Generator;
|
import net.i2p.crypto.SHA256Generator;
|
||||||
|
import net.i2p.crypto.SigType;
|
||||||
import net.i2p.data.DatabaseEntry;
|
import net.i2p.data.DatabaseEntry;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
@ -532,10 +533,17 @@ public class RouterInfo extends DatabaseEntry {
|
|||||||
InputStream din;
|
InputStream din;
|
||||||
MessageDigest digest;
|
MessageDigest digest;
|
||||||
if (verifySig) {
|
if (verifySig) {
|
||||||
digest = _identity.getSigningPublicKey().getType().getDigestInstance();
|
SigType type = _identity.getSigningPublicKey().getType();
|
||||||
// TODO any better way?
|
if (type != SigType.EdDSA_SHA512_Ed25519) {
|
||||||
digest.update(_identity.toByteArray());
|
// This won't work for EdDSA
|
||||||
din = new DigestInputStream(in, digest);
|
digest = _identity.getSigningPublicKey().getType().getDigestInstance();
|
||||||
|
// TODO any better way?
|
||||||
|
digest.update(_identity.toByteArray());
|
||||||
|
din = new DigestInputStream(in, digest);
|
||||||
|
} else {
|
||||||
|
digest = null;
|
||||||
|
din = in;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
digest = null;
|
digest = null;
|
||||||
din = in;
|
din = in;
|
||||||
@ -569,10 +577,16 @@ public class RouterInfo extends DatabaseEntry {
|
|||||||
_signature.readBytes(in);
|
_signature.readBytes(in);
|
||||||
|
|
||||||
if (verifySig) {
|
if (verifySig) {
|
||||||
SimpleDataStructure hash = _identity.getSigningPublicKey().getType().getHashInstance();
|
SigType type = _identity.getSigningPublicKey().getType();
|
||||||
hash.setData(digest.digest());
|
if (type != SigType.EdDSA_SHA512_Ed25519) {
|
||||||
_isValid = DSAEngine.getInstance().verifySignature(_signature, hash, _identity.getSigningPublicKey());
|
// This won't work for EdDSA
|
||||||
_validated = true;
|
SimpleDataStructure hash = _identity.getSigningPublicKey().getType().getHashInstance();
|
||||||
|
hash.setData(digest.digest());
|
||||||
|
_isValid = DSAEngine.getInstance().verifySignature(_signature, hash, _identity.getSigningPublicKey());
|
||||||
|
_validated = true;
|
||||||
|
} else {
|
||||||
|
doValidate();
|
||||||
|
}
|
||||||
if (!_isValid) {
|
if (!_isValid) {
|
||||||
throw new DataFormatException("Bad sig");
|
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)
|
* Key with which a LeaseSet can be revoked (by republishing it with no Leases)
|
||||||
*
|
*
|
||||||
* @deprecated unused
|
* Deprecated, unused
|
||||||
*/
|
*/
|
||||||
public SigningPrivateKey getRevocationKey() { return _revocationKey; }
|
public SigningPrivateKey getRevocationKey() { return _revocationKey; }
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import java.util.Properties;
|
|||||||
|
|
||||||
import net.i2p.CoreVersion;
|
import net.i2p.CoreVersion;
|
||||||
import net.i2p.crypto.SigType;
|
import net.i2p.crypto.SigType;
|
||||||
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.data.Payload;
|
import net.i2p.data.Payload;
|
||||||
import net.i2p.data.i2cp.BandwidthLimitsMessage;
|
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.SessionStatusMessage;
|
||||||
import net.i2p.data.i2cp.SetDateMessage;
|
import net.i2p.data.i2cp.SetDateMessage;
|
||||||
import net.i2p.router.ClientTunnelSettings;
|
import net.i2p.router.ClientTunnelSettings;
|
||||||
|
import net.i2p.router.LeaseSetKeys;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.PasswordManager;
|
import net.i2p.util.PasswordManager;
|
||||||
@ -367,8 +369,31 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
|||||||
_runner.disconnectClient("Invalid CreateLeaseSetMessage");
|
_runner.disconnectClient("Invalid CreateLeaseSetMessage");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Destination dest = _runner.getConfig().getDestination();
|
||||||
_context.keyManager().registerKeys(message.getLeaseSet().getDestination(), message.getSigningPrivateKey(), message.getPrivateKey());
|
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 {
|
try {
|
||||||
_context.netDb().publish(message.getLeaseSet());
|
_context.netDb().publish(message.getLeaseSet());
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
|
@ -170,9 +170,12 @@ public class CreateRouterInfoJob extends JobImpl {
|
|||||||
String sstype = ctx.getProperty(PROP_ROUTER_SIGTYPE);
|
String sstype = ctx.getProperty(PROP_ROUTER_SIGTYPE);
|
||||||
if (sstype != null) {
|
if (sstype != null) {
|
||||||
SigType ntype = SigType.parseSigType(sstype);
|
SigType ntype = SigType.parseSigType(sstype);
|
||||||
if (ntype != null && ntype.isAvailable())
|
if (ntype != null)
|
||||||
cstype = ntype;
|
cstype = ntype;
|
||||||
}
|
}
|
||||||
|
// fallback?
|
||||||
|
if (cstype != SigType.DSA_SHA1 && !cstype.isAvailable())
|
||||||
|
cstype = SigType.DSA_SHA1;
|
||||||
return cstype;
|
return cstype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user