forked from I2P_Developers/i2p.i2p
@ -548,6 +548,7 @@ public class HandshakeState implements Destroyable, Cloneable {
|
|||||||
// Format the message.
|
// Format the message.
|
||||||
try {
|
try {
|
||||||
// Process tokens until the direction changes or the patten ends.
|
// Process tokens until the direction changes or the patten ends.
|
||||||
|
loop:
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (patternIndex >= pattern.length) {
|
if (patternIndex >= pattern.length) {
|
||||||
// The pattern has finished, so the next action is "split".
|
// The pattern has finished, so the next action is "split".
|
||||||
@ -627,6 +628,11 @@ public class HandshakeState implements Destroyable, Cloneable {
|
|||||||
|
|
||||||
case Pattern.SS:
|
case Pattern.SS:
|
||||||
{
|
{
|
||||||
|
// I2P N extension to IK
|
||||||
|
if (patternId.equals(PATTERN_ID_IK) &&
|
||||||
|
localKeyPair.isNullPublicKey()) {
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
// DH operation with initiator and responder static keys.
|
// DH operation with initiator and responder static keys.
|
||||||
mixDH(localKeyPair, remotePublicKey);
|
mixDH(localKeyPair, remotePublicKey);
|
||||||
}
|
}
|
||||||
@ -702,6 +708,7 @@ public class HandshakeState implements Destroyable, Cloneable {
|
|||||||
// Process the message.
|
// Process the message.
|
||||||
try {
|
try {
|
||||||
// Process tokens until the direction changes or the patten ends.
|
// Process tokens until the direction changes or the patten ends.
|
||||||
|
loop:
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (patternIndex >= pattern.length) {
|
if (patternIndex >= pattern.length) {
|
||||||
// The pattern has finished, so the next action is "split".
|
// The pattern has finished, so the next action is "split".
|
||||||
@ -792,6 +799,11 @@ public class HandshakeState implements Destroyable, Cloneable {
|
|||||||
|
|
||||||
case Pattern.SS:
|
case Pattern.SS:
|
||||||
{
|
{
|
||||||
|
// I2P N extension to IK
|
||||||
|
if (patternId.equals(PATTERN_ID_IK) &&
|
||||||
|
remotePublicKey.isNullPublicKey()) {
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
// DH operation with initiator and responder static keys.
|
// DH operation with initiator and responder static keys.
|
||||||
mixDH(localKeyPair, remotePublicKey);
|
mixDH(localKeyPair, remotePublicKey);
|
||||||
}
|
}
|
||||||
|
@ -401,19 +401,6 @@ public final class ECIESAEADEngine {
|
|||||||
if (keyManager.isDuplicate(pk)) {
|
if (keyManager.isDuplicate(pk)) {
|
||||||
if (_log.shouldWarn())
|
if (_log.shouldWarn())
|
||||||
_log.warn("Dup eph. key in IB NS: " + pk);
|
_log.warn("Dup eph. key in IB NS: " + pk);
|
||||||
return NO_CLOVES;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] alicePK = new byte[KEYLEN];
|
|
||||||
state.getRemotePublicKey().getPublicKey(alicePK, 0);
|
|
||||||
if (_log.shouldDebug()) {
|
|
||||||
_log.debug("NS decrypt success from PK " + Base64.encode(alicePK));
|
|
||||||
_log.debug("State after decrypt new session: " + state);
|
|
||||||
}
|
|
||||||
if (Arrays.equals(alicePK, NULLPK)) {
|
|
||||||
// TODO
|
|
||||||
if (_log.shouldWarn())
|
|
||||||
_log.warn("Zero static key in IB NS");
|
|
||||||
state.destroy();
|
state.destroy();
|
||||||
return NO_CLOVES;
|
return NO_CLOVES;
|
||||||
}
|
}
|
||||||
@ -447,10 +434,6 @@ public final class ECIESAEADEngine {
|
|||||||
return NO_CLOVES;
|
return NO_CLOVES;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tell the SKM
|
|
||||||
PublicKey alice = new PublicKey(EncType.ECIES_X25519, alicePK);
|
|
||||||
keyManager.createSession(alice, null, state, null);
|
|
||||||
|
|
||||||
if (pc.cloveSet.isEmpty()) {
|
if (pc.cloveSet.isEmpty()) {
|
||||||
// this is legal
|
// this is legal
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
@ -458,11 +441,26 @@ public final class ECIESAEADEngine {
|
|||||||
state.destroy();
|
state.destroy();
|
||||||
return NO_CLOVES;
|
return NO_CLOVES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] alicePK = new byte[KEYLEN];
|
||||||
|
state.getRemotePublicKey().getPublicKey(alicePK, 0);
|
||||||
|
if (_log.shouldDebug()) {
|
||||||
|
_log.debug("NS decrypt success from PK " + Base64.encode(alicePK));
|
||||||
|
_log.debug("State after decrypt new session: " + state);
|
||||||
|
}
|
||||||
|
if (Arrays.equals(alicePK, NULLPK)) {
|
||||||
|
state.destroy();
|
||||||
|
} else {
|
||||||
|
// tell the SKM
|
||||||
|
PublicKey alice = new PublicKey(EncType.ECIES_X25519, alicePK);
|
||||||
|
keyManager.createSession(alice, null, state, null);
|
||||||
|
setResponseTimerNS(alice, pc.cloveSet, keyManager);
|
||||||
|
}
|
||||||
|
|
||||||
int num = pc.cloveSet.size();
|
int num = pc.cloveSet.size();
|
||||||
GarlicClove[] arr = new GarlicClove[num];
|
GarlicClove[] arr = new GarlicClove[num];
|
||||||
// msg id and expiration not checked in GarlicMessageReceiver
|
// msg id and expiration not checked in GarlicMessageReceiver
|
||||||
CloveSet rv = new CloveSet(pc.cloveSet.toArray(arr), Certificate.NULL_CERT, 0, pc.datetime);
|
CloveSet rv = new CloveSet(pc.cloveSet.toArray(arr), Certificate.NULL_CERT, 0, pc.datetime);
|
||||||
setResponseTimerNS(alice, pc.cloveSet, keyManager);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -713,8 +711,12 @@ public final class ECIESAEADEngine {
|
|||||||
* This is the one called from GarlicMessageBuilder and is the primary entry point.
|
* This is the one called from GarlicMessageBuilder and is the primary entry point.
|
||||||
*
|
*
|
||||||
* @param target public key to which the data should be encrypted.
|
* @param target public key to which the data should be encrypted.
|
||||||
|
* @param to ignored if priv is null
|
||||||
* @param priv local private key to encrypt with, from the leaseset
|
* @param priv local private key to encrypt with, from the leaseset
|
||||||
* @param callback may be null, if non-null an ack will be requested (except NS/NSR)
|
* may be null for anonymous (N-in-IK)
|
||||||
|
* @param keyManager ignored if priv is null
|
||||||
|
* @param callback may be null, if non-null an ack will be requested (except NS/NSR),
|
||||||
|
* ignored if priv is null
|
||||||
* @return encrypted data or null on failure
|
* @return encrypted data or null on failure
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -729,17 +731,28 @@ public final class ECIESAEADEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param to ignored if priv is null
|
||||||
|
* @param priv local private key to encrypt with, from the leaseset
|
||||||
|
* may be null for anonymous (N-in-IK)
|
||||||
|
* @param keyManager ignored if priv is null
|
||||||
|
* @param callback may be null, ignored if priv is null
|
||||||
|
*/
|
||||||
private byte[] x_encrypt(CloveSet cloves, PublicKey target, Destination to, PrivateKey priv,
|
private byte[] x_encrypt(CloveSet cloves, PublicKey target, Destination to, PrivateKey priv,
|
||||||
RatchetSKM keyManager,
|
RatchetSKM keyManager,
|
||||||
ReplyCallback callback) {
|
ReplyCallback callback) {
|
||||||
if (target.getType() != EncType.ECIES_X25519)
|
if (target.getType() != EncType.ECIES_X25519)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
if (Arrays.equals(target.getData(), NULLPK)) {
|
if (Arrays.equals(target.getData(), NULLPK)) {
|
||||||
// TODO
|
|
||||||
if (_log.shouldWarn())
|
if (_log.shouldWarn())
|
||||||
_log.warn("Zero static key target");
|
_log.warn("Zero static key target");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (priv == null) {
|
||||||
|
if (_log.shouldDebug())
|
||||||
|
_log.debug("Encrypting as NS zero-key to " + target);
|
||||||
|
return encryptNewSession(cloves, target, null, null, null, null);
|
||||||
|
}
|
||||||
RatchetEntry re = keyManager.consumeNextAvailableTag(target);
|
RatchetEntry re = keyManager.consumeNextAvailableTag(target);
|
||||||
if (re == null) {
|
if (re == null) {
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
@ -781,7 +794,11 @@ public final class ECIESAEADEngine {
|
|||||||
* - 16 byte MAC
|
* - 16 byte MAC
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param callback may be null
|
* @param to ignored if priv is null
|
||||||
|
* @param priv local private key to encrypt with, from the leaseset
|
||||||
|
* may be null for anonymous (N-in-IK)
|
||||||
|
* @param keyManager ignored if priv is null
|
||||||
|
* @param callback may be null, ignored if priv is null
|
||||||
* @return encrypted data or null on failure
|
* @return encrypted data or null on failure
|
||||||
*/
|
*/
|
||||||
private byte[] encryptNewSession(CloveSet cloves, PublicKey target, Destination to, PrivateKey priv,
|
private byte[] encryptNewSession(CloveSet cloves, PublicKey target, Destination to, PrivateKey priv,
|
||||||
@ -794,8 +811,12 @@ public final class ECIESAEADEngine {
|
|||||||
throw new IllegalStateException("bad proto", gse);
|
throw new IllegalStateException("bad proto", gse);
|
||||||
}
|
}
|
||||||
state.getRemotePublicKey().setPublicKey(target.getData(), 0);
|
state.getRemotePublicKey().setPublicKey(target.getData(), 0);
|
||||||
state.getLocalKeyPair().setKeys(priv.getData(), 0,
|
if (priv != null) {
|
||||||
priv.toPublic().getData(), 0);
|
state.getLocalKeyPair().setKeys(priv.getData(), 0,
|
||||||
|
priv.toPublic().getData(), 0);
|
||||||
|
} else {
|
||||||
|
state.getLocalKeyPair().setKeys(NULLPK, 0, NULLPK, 0);
|
||||||
|
}
|
||||||
state.start();
|
state.start();
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("State before encrypt new session: " + state);
|
_log.debug("State before encrypt new session: " + state);
|
||||||
@ -826,8 +847,12 @@ public final class ECIESAEADEngine {
|
|||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("Elligator2 encoded eph. key: " + Base64.encode(enc, 0, 32));
|
_log.debug("Elligator2 encoded eph. key: " + Base64.encode(enc, 0, 32));
|
||||||
|
|
||||||
// tell the SKM
|
if (priv != null) {
|
||||||
keyManager.createSession(target, to, state, callback);
|
// tell the SKM
|
||||||
|
keyManager.createSession(target, to, state, callback);
|
||||||
|
} else {
|
||||||
|
state.destroy();
|
||||||
|
}
|
||||||
return enc;
|
return enc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -963,6 +988,19 @@ public final class ECIESAEADEngine {
|
|||||||
return encr;
|
return encr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt the data to the target using the given key from an anonymous source,
|
||||||
|
* for netdb lookups.
|
||||||
|
* Called from MessageWrapper.
|
||||||
|
*
|
||||||
|
* @param target public key to which the data should be encrypted.
|
||||||
|
* @return encrypted data or null on failure
|
||||||
|
* @since 0.9.48
|
||||||
|
*/
|
||||||
|
public byte[] encrypt(CloveSet cloves, PublicKey target) {
|
||||||
|
return encrypt(cloves, target, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No ad
|
* No ad
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user