Crypto: Noise modifications to support ratchet:

- Add IK support
- Add generic key factory support
- Add method to get ephemeral key
- Add method to get encoded ephemeral key
- Add clone() support
- Add back ChaCha debug support
This commit is contained in:
zzz
2019-10-23 13:02:00 +00:00
parent 236354e5a8
commit 2c2f90089b
11 changed files with 297 additions and 30 deletions

View File

@ -29,7 +29,7 @@ import com.southernstorm.noise.protocol.Destroyable;
/** /**
* Simple implementation of the Poly1305 message authenticator. * Simple implementation of the Poly1305 message authenticator.
*/ */
public final class Poly1305 implements Destroyable { public final class Poly1305 implements Destroyable, Cloneable {
// The 130-bit intermediate values are broken up into five 26-bit words. // The 130-bit intermediate values are broken up into five 26-bit words.
private final byte[] nonce; private final byte[] nonce;
@ -324,4 +324,13 @@ public final class Poly1305 implements Destroyable {
Arrays.fill(c, 0); Arrays.fill(c, 0);
Arrays.fill(t, (long)0); Arrays.fill(t, (long)0);
} }
/**
* I2P
* @since 0.9.44
*/
@Override
public Poly1305 clone() throws CloneNotSupportedException {
return (Poly1305) super.clone();
}
} }

View File

@ -41,6 +41,10 @@ public class ChaChaPolyCipherState implements CipherState {
private final byte[] polyKey; private final byte[] polyKey;
private long n; private long n;
private boolean haskey; private boolean haskey;
// Debug only
private byte[] initialKey;
private static final boolean DEBUG = false;
/** /**
* Constructs a new cipher state for the "ChaChaPoly" algorithm. * Constructs a new cipher state for the "ChaChaPoly" algorithm.
@ -55,6 +59,20 @@ public class ChaChaPolyCipherState implements CipherState {
haskey = false; haskey = false;
} }
/**
* Copy constructor for cloning
* @since 0.9.44
*/
protected ChaChaPolyCipherState(ChaChaPolyCipherState o) throws CloneNotSupportedException {
poly = o.poly.clone();
input = Arrays.copyOf(o.input, o.input.length);
output = Arrays.copyOf(o.output, o.output.length);
polyKey = Arrays.copyOf(o.polyKey, o.polyKey.length);
n = o.n;
haskey = o.haskey;
initialKey = o.initialKey;
}
@Override @Override
public void destroy() { public void destroy() {
poly.destroy(); poly.destroy();
@ -80,6 +98,10 @@ public class ChaChaPolyCipherState implements CipherState {
@Override @Override
public void initializeKey(byte[] key, int offset) { public void initializeKey(byte[] key, int offset) {
if (DEBUG) {
initialKey = new byte[32];
System.arraycopy(key, 0, initialKey, 0, 32);
}
ChaChaCore.initKey256(input, key, offset); ChaChaCore.initKey256(input, key, offset);
n = 0; n = 0;
haskey = true; haskey = true;
@ -249,6 +271,15 @@ public class ChaChaPolyCipherState implements CipherState {
n = nonce; n = nonce;
} }
/**
* I2P
* @since 0.9.44
*/
@Override
public ChaChaPolyCipherState clone() throws CloneNotSupportedException {
return new ChaChaPolyCipherState(this);
}
/** /**
* I2P debug * I2P debug
*/ */
@ -258,6 +289,15 @@ public class ChaChaPolyCipherState implements CipherState {
buf.append(" Cipher State:\n" + buf.append(" Cipher State:\n" +
" nonce: "); " nonce: ");
buf.append(n); buf.append(n);
// I2P debug
if (DEBUG) {
buf.append("\n" +
" init key: ");
if (haskey)
buf.append(net.i2p.data.Base64.encode(initialKey));
else
buf.append("null");
}
buf.append("\n poly key: "); buf.append("\n poly key: ");
if (haskey) if (haskey)
buf.append(net.i2p.data.Base64.encode(polyKey)); buf.append(net.i2p.data.Base64.encode(polyKey));

View File

@ -33,7 +33,7 @@ import javax.crypto.ShortBufferException;
* will create two CipherState objects for encrypting packets sent to * will create two CipherState objects for encrypting packets sent to
* the other party, and decrypting packets received from the other party. * the other party, and decrypting packets received from the other party.
*/ */
public interface CipherState extends Destroyable { public interface CipherState extends Destroyable, Cloneable {
/** /**
* Gets the Noise protocol name for this cipher. * Gets the Noise protocol name for this cipher.
@ -155,4 +155,10 @@ public interface CipherState extends Destroyable {
* value goes backwards then security may be compromised. * value goes backwards then security may be compromised.
*/ */
void setNonce(long nonce); void setNonce(long nonce);
/**
* I2P
* @since 0.9.44
*/
public CipherState clone() throws CloneNotSupportedException;
} }

View File

@ -26,23 +26,25 @@ import java.util.Arrays;
import com.southernstorm.noise.crypto.x25519.Curve25519; import com.southernstorm.noise.crypto.x25519.Curve25519;
import net.i2p.crypto.KeyFactory;
import net.i2p.crypto.KeyPair; import net.i2p.crypto.KeyPair;
import net.i2p.router.transport.crypto.X25519KeyFactory; import net.i2p.router.crypto.ratchet.Elg2KeyPair;
/** /**
* Implementation of the Curve25519 algorithm for the Noise protocol. * Implementation of the Curve25519 algorithm for the Noise protocol.
*/ */
class Curve25519DHState implements DHState { class Curve25519DHState implements DHState, Cloneable {
private final byte[] publicKey; private final byte[] publicKey;
private final byte[] privateKey; private final byte[] privateKey;
private int mode; private int mode;
private final X25519KeyFactory _xdh; private final KeyFactory _xdh;
private byte[] encodedPublicKey;
/** /**
* Constructs a new Diffie-Hellman object for Curve25519. * Constructs a new Diffie-Hellman object for Curve25519.
*/ */
public Curve25519DHState(X25519KeyFactory xdh) public Curve25519DHState(KeyFactory xdh)
{ {
publicKey = new byte [32]; publicKey = new byte [32];
privateKey = new byte [32]; privateKey = new byte [32];
@ -80,6 +82,11 @@ class Curve25519DHState implements DHState {
KeyPair kp = _xdh.getKeys(); KeyPair kp = _xdh.getKeys();
System.arraycopy(kp.getPrivate().getData(), 0, privateKey, 0, 32); System.arraycopy(kp.getPrivate().getData(), 0, privateKey, 0, 32);
System.arraycopy(kp.getPublic().getData(), 0, publicKey, 0, 32); System.arraycopy(kp.getPublic().getData(), 0, publicKey, 0, 32);
if (kp instanceof Elg2KeyPair) {
Elg2KeyPair ekp = (Elg2KeyPair) kp;
encodedPublicKey = new byte[32];
System.arraycopy(ekp.getEncoded(), 0, encodedPublicKey, 0, 32);
}
mode = 0x03; mode = 0x03;
} }
@ -111,6 +118,10 @@ class Curve25519DHState implements DHState {
public void setToNullPublicKey() { public void setToNullPublicKey() {
Arrays.fill(publicKey, (byte)0); Arrays.fill(publicKey, (byte)0);
Arrays.fill(privateKey, (byte)0); Arrays.fill(privateKey, (byte)0);
if (encodedPublicKey != null) {
Arrays.fill(encodedPublicKey, (byte)0);
encodedPublicKey = null;
}
mode = 0x01; mode = 0x01;
} }
@ -118,6 +129,10 @@ class Curve25519DHState implements DHState {
public void clearKey() { public void clearKey() {
Noise.destroy(publicKey); Noise.destroy(publicKey);
Noise.destroy(privateKey); Noise.destroy(privateKey);
if (encodedPublicKey != null) {
Noise.destroy(encodedPublicKey);
encodedPublicKey = null;
}
mode = 0; mode = 0;
} }
@ -141,6 +156,26 @@ class Curve25519DHState implements DHState {
return temp == 0; return temp == 0;
} }
/**
* I2P
* @since 0.9.44
*/
@Override
public boolean hasEncodedPublicKey() {
return encodedPublicKey != null;
}
/**
* I2P
* @since 0.9.44
*/
@Override
public void getEncodedPublicKey(byte[] key, int offset) {
if (encodedPublicKey == null)
throw new IllegalStateException();
System.arraycopy(encodedPublicKey, 0, key, offset, 32);
}
@Override @Override
public void calculate(byte[] sharedKey, int offset, DHState publicDH) { public void calculate(byte[] sharedKey, int offset, DHState publicDH) {
if (!(publicDH instanceof Curve25519DHState)) if (!(publicDH instanceof Curve25519DHState))
@ -159,4 +194,13 @@ class Curve25519DHState implements DHState {
System.arraycopy(dh.publicKey, 0, publicKey, 0, 32); System.arraycopy(dh.publicKey, 0, publicKey, 0, 32);
mode = dh.mode; mode = dh.mode;
} }
/**
* I2P
* @since 0.9.44
*/
@Override
public Curve25519DHState clone() throws CloneNotSupportedException {
return (Curve25519DHState) super.clone();
}
} }

View File

@ -25,7 +25,7 @@ package com.southernstorm.noise.protocol;
/** /**
* Interface to a Diffie-Hellman algorithm for the Noise protocol. * Interface to a Diffie-Hellman algorithm for the Noise protocol.
*/ */
public interface DHState extends Destroyable { public interface DHState extends Destroyable, Cloneable {
/** /**
* Gets the Noise protocol name for this Diffie-Hellman algorithm. * Gets the Noise protocol name for this Diffie-Hellman algorithm.
@ -132,6 +132,26 @@ public interface DHState extends Destroyable {
*/ */
boolean isNullPublicKey(); boolean isNullPublicKey();
/**
* Determine if this object contains an optional encoded public key.
*
* @return Returns true if this object contains an encoded public key,
* or false if the public key has not yet been set.
*
* @since 0.9.44
*/
boolean hasEncodedPublicKey();
/**
* Gets the public key associated with this object.
*
* @param key The buffer to copy the public key to.
* @param offset The first offset in the key buffer to copy to.
*
* @since 0.9.44
*/
void getEncodedPublicKey(byte[] key, int offset);
/** /**
* Performs a Diffie-Hellman calculation with this object as the private key. * Performs a Diffie-Hellman calculation with this object as the private key.
* *
@ -153,4 +173,10 @@ public interface DHState extends Destroyable {
* the same type as this object. * the same type as this object.
*/ */
void copyFrom(DHState other); void copyFrom(DHState other);
/**
* I2P
* @since 0.9.44
*/
public DHState clone() throws CloneNotSupportedException;
} }

View File

@ -28,12 +28,12 @@ import java.util.Arrays;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.ShortBufferException; import javax.crypto.ShortBufferException;
import net.i2p.router.transport.crypto.X25519KeyFactory; import net.i2p.crypto.KeyFactory;
/** /**
* Interface to a Noise handshake. * Interface to a Noise handshake.
*/ */
public class HandshakeState implements Destroyable { public class HandshakeState implements Destroyable, Cloneable {
private final SymmetricState symmetric; private final SymmetricState symmetric;
private final boolean isInitiator; private final boolean isInitiator;
@ -128,36 +128,53 @@ public class HandshakeState implements Destroyable {
private static final int FALLBACK_POSSIBLE = 0x40; private static final int FALLBACK_POSSIBLE = 0x40;
public static final String protocolName = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256"; public static final String protocolName = "Noise_XKaesobfse+hs2+hs3_25519_ChaChaPoly_SHA256";
public static final String protocolName2 = "Noise_IKelg2+hs2_25519_ChaChaPoly_SHA256";
private static final String prefix; private static final String prefix;
private static final String patternId; private final String patternId;
public static final String PATTERN_ID_XK = "XK";
public static final String PATTERN_ID_IK = "IK";
private static String dh; private static String dh;
private static final String cipher; private static final String cipher;
private static final String hash; private static final String hash;
private static final short[] pattern; private final short[] pattern;
private static final short[] PATTERN_XK;
private static final short[] PATTERN_IK;
static { static {
// Parse the protocol name into its components. // Parse the protocol name into its components.
// XK
String[] components = protocolName.split("_"); String[] components = protocolName.split("_");
if (components.length != 5) if (components.length != 5)
throw new IllegalArgumentException("Protocol name must have 5 components"); throw new IllegalArgumentException("Protocol name must have 5 components");
prefix = components[0]; prefix = components[0];
patternId = components[1].substring(0, 2); String id = components[1].substring(0, 2);
if (!PATTERN_ID_XK.equals(id))
throw new IllegalArgumentException();
dh = components[2]; dh = components[2];
cipher = components[3]; cipher = components[3];
hash = components[4]; hash = components[4];
if (!prefix.equals("Noise") && !prefix.equals("NoisePSK")) if (!prefix.equals("Noise") && !prefix.equals("NoisePSK"))
throw new IllegalArgumentException("Prefix must be Noise or NoisePSK"); throw new IllegalArgumentException("Prefix must be Noise or NoisePSK");
pattern = Pattern.lookup(patternId); PATTERN_XK = Pattern.lookup(id);
if (pattern == null) if (PATTERN_XK == null)
throw new IllegalArgumentException("Handshake pattern is not recognized"); throw new IllegalArgumentException("Handshake pattern is not recognized");
if (!dh.equals("25519")) if (!dh.equals("25519"))
throw new IllegalArgumentException("Unknown Noise DH algorithm name: " + dh); throw new IllegalArgumentException("Unknown Noise DH algorithm name: " + dh);
// IK
components = protocolName2.split("_");
id = components[1].substring(0, 2);
if (!PATTERN_ID_IK.equals(id))
throw new IllegalArgumentException();
PATTERN_IK = Pattern.lookup(id);
if (PATTERN_IK == null)
throw new IllegalArgumentException("Handshake pattern is not recognized");
} }
/** /**
* Creates a new Noise handshake. * Creates a new Noise handshake.
* Noise protocol name is hardcoded. * Noise protocol name is hardcoded.
* *
* @param patternId XK or IK
* @param role The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER. * @param role The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.
* @param xdh The key pair factory for ephemeral keys * @param xdh The key pair factory for ephemeral keys
* *
@ -167,8 +184,15 @@ public class HandshakeState implements Destroyable {
* @throws NoSuchAlgorithmException One of the cryptographic algorithms * @throws NoSuchAlgorithmException One of the cryptographic algorithms
* that is specified in the protocolName is not supported. * that is specified in the protocolName is not supported.
*/ */
public HandshakeState(int role, X25519KeyFactory xdh) throws NoSuchAlgorithmException public HandshakeState(String patternId, int role, KeyFactory xdh) throws NoSuchAlgorithmException
{ {
this.patternId = patternId;
if (patternId.equals(PATTERN_ID_XK))
pattern = PATTERN_XK;
else if (patternId.equals(PATTERN_ID_IK))
pattern = PATTERN_IK;
else
throw new IllegalArgumentException("Handshake pattern is not recognized");
short flags = pattern[0]; short flags = pattern[0];
int extraReqs = 0; int extraReqs = 0;
if ((flags & Pattern.FLAG_REMOTE_REQUIRED) != 0 && patternId.length() > 1) if ((flags & Pattern.FLAG_REMOTE_REQUIRED) != 0 && patternId.length() > 1)
@ -183,7 +207,7 @@ public class HandshakeState implements Destroyable {
throw new IllegalArgumentException("Role must be initiator or responder"); throw new IllegalArgumentException("Role must be initiator or responder");
// Initialize this object. This will also create the cipher and hash objects. // Initialize this object. This will also create the cipher and hash objects.
symmetric = new SymmetricState(cipher, hash); symmetric = new SymmetricState(cipher, hash, patternId);
isInitiator = (role == INITIATOR); isInitiator = (role == INITIATOR);
action = NO_ACTION; action = NO_ACTION;
requirements = extraReqs | computeRequirements(flags, prefix, role, false); requirements = extraReqs | computeRequirements(flags, prefix, role, false);
@ -201,6 +225,27 @@ public class HandshakeState implements Destroyable {
} }
/**
* Copy constructor for cloning
* @since 0.9.44
*/
protected HandshakeState(HandshakeState o) throws CloneNotSupportedException {
// everything is shallow copied except for symmetric state
symmetric = o.symmetric.clone();
isInitiator = o.isInitiator;
localKeyPair = o.localKeyPair;
localEphemeral = o.localEphemeral;
remotePublicKey = o.remotePublicKey;
remoteEphemeral = o.remoteEphemeral;
action = o.action;
if (action == SPLIT || action == COMPLETE)
throw new CloneNotSupportedException("clone after NSR");
requirements = o.requirements;
patternIndex = o.patternIndex;
patternId = o.patternId;
pattern = o.pattern;
}
/** /**
* Gets the name of the Noise protocol. * Gets the name of the Noise protocol.
* *
@ -231,6 +276,19 @@ public class HandshakeState implements Destroyable {
return localKeyPair; return localKeyPair;
} }
/**
* Gets the keypair object for the local ephemeral key.
*
* I2P
*
* @return The keypair, or null if a local ephemeral key is not required or has not been generated.
* @since 0.9.44
*/
public DHState getLocalEphemeralKeyPair()
{
return localEphemeral;
}
/** /**
* Determine if this handshake requires a local static key. * Determine if this handshake requires a local static key.
* *
@ -534,6 +592,13 @@ public class HandshakeState implements Destroyable {
} }
break; break;
case Pattern.SS:
{
// DH operation with initiator and responder static keys.
mixDH(localKeyPair, remotePublicKey);
}
break;
default: default:
{ {
// Unknown token code. Abort. // Unknown token code. Abort.
@ -692,6 +757,13 @@ public class HandshakeState implements Destroyable {
} }
break; break;
case Pattern.SS:
{
// DH operation with initiator and responder static keys.
mixDH(localKeyPair, remotePublicKey);
}
break;
default: default:
{ {
// Unknown token code. Abort. // Unknown token code. Abort.
@ -844,13 +916,25 @@ public class HandshakeState implements Destroyable {
return symmetric.getChainingKey(); return symmetric.getChainingKey();
} }
/**
* I2P
* Must be called before both eph. keys set.
* @since 0.9.44
*/
@Override
public synchronized HandshakeState clone() throws CloneNotSupportedException {
return new HandshakeState(this);
}
/** /**
* I2P debug * I2P debug
*/ */
@Override @Override
public String toString() { public String toString() {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder(256);
buf.append("Handshake State:\n"); buf.append(patternId);
buf.append(" Handshake State:\n");
buf.append(symmetric.toString()); buf.append(symmetric.toString());
byte[] tmp = new byte[32]; byte[] tmp = new byte[32];

View File

@ -71,6 +71,23 @@ class Pattern {
SE SE
}; };
private static final short[] noise_pattern_IK = {
FLAG_LOCAL_STATIC |
FLAG_LOCAL_EPHEMERAL |
FLAG_REMOTE_STATIC |
FLAG_REMOTE_EPHEMERAL |
FLAG_REMOTE_REQUIRED,
E,
ES,
S,
SS,
FLIP_DIR,
E,
EE,
SE
};
/** /**
* Look up the description information for a pattern. * Look up the description information for a pattern.
* *
@ -81,6 +98,8 @@ class Pattern {
{ {
if (name.equals("XK")) if (name.equals("XK"))
return noise_pattern_XK; return noise_pattern_XK;
else if (name.equals("IK"))
return noise_pattern_IK;
return null; return null;
} }

View File

@ -34,32 +34,42 @@ import javax.crypto.ShortBufferException;
/** /**
* Symmetric state for helping manage a Noise handshake. * Symmetric state for helping manage a Noise handshake.
*/ */
class SymmetricState implements Destroyable { class SymmetricState implements Destroyable, Cloneable {
// precalculated hash of the Noise name // precalculated hash of the Noise name
private static final byte[] INIT_HASH; private static final byte[] INIT_HASH_XK;
private static final byte[] INIT_HASH_IK;
static { static {
INIT_HASH_XK = initHash(HandshakeState.protocolName);
INIT_HASH_IK = initHash(HandshakeState.protocolName2);
}
/**
* @since 0.9.44
*/
private static byte[] initHash(String protocolName) {
byte[] protocolNameBytes; byte[] protocolNameBytes;
try { try {
protocolNameBytes = HandshakeState.protocolName.getBytes("UTF-8"); protocolNameBytes = protocolName.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
// If UTF-8 is not supported, then we are definitely in trouble! // If UTF-8 is not supported, then we are definitely in trouble!
throw new UnsupportedOperationException("UTF-8 encoding is not supported"); throw new UnsupportedOperationException("UTF-8 encoding is not supported");
} }
INIT_HASH = new byte[32]; byte[] rv = new byte[32];
if (protocolNameBytes.length <= 32) { if (protocolNameBytes.length <= 32) {
System.arraycopy(protocolNameBytes, 0, INIT_HASH, 0, protocolNameBytes.length); System.arraycopy(protocolNameBytes, 0, rv, 0, protocolNameBytes.length);
Arrays.fill(INIT_HASH, protocolNameBytes.length, 32, (byte)0); Arrays.fill(rv, protocolNameBytes.length, 32, (byte)0);
} else { } else {
try { try {
MessageDigest hash = Noise.createHash("SHA256"); MessageDigest hash = Noise.createHash("SHA256");
hash.update(protocolNameBytes, 0, protocolNameBytes.length); hash.update(protocolNameBytes, 0, protocolNameBytes.length);
hash.digest(INIT_HASH, 0, 32); hash.digest(rv, 0, 32);
} catch (Exception e) { } catch (Exception e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
} }
return rv;
} }
private final CipherState cipher; private final CipherState cipher;
@ -78,7 +88,7 @@ class SymmetricState implements Destroyable {
* @throws NoSuchAlgorithmException The cipher or hash algorithm in the * @throws NoSuchAlgorithmException The cipher or hash algorithm in the
* protocol name is not supported. * protocol name is not supported.
*/ */
public SymmetricState(String cipherName, String hashName) throws NoSuchAlgorithmException public SymmetricState(String cipherName, String hashName, String patternId) throws NoSuchAlgorithmException
{ {
cipher = Noise.createCipher(cipherName); cipher = Noise.createCipher(cipherName);
hash = Noise.createHash(hashName); hash = Noise.createHash(hashName);
@ -87,10 +97,29 @@ class SymmetricState implements Destroyable {
h = new byte [hashLength]; h = new byte [hashLength];
prev_h = new byte [hashLength]; prev_h = new byte [hashLength];
System.arraycopy(INIT_HASH, 0, h, 0, hashLength); byte[] initHash;
if (patternId.equals(HandshakeState.PATTERN_ID_XK))
initHash = INIT_HASH_XK;
else if (patternId.equals(HandshakeState.PATTERN_ID_IK))
initHash = INIT_HASH_IK;
else
throw new IllegalArgumentException("Handshake pattern is not recognized");
System.arraycopy(initHash, 0, h, 0, hashLength);
System.arraycopy(h, 0, ck, 0, hashLength); System.arraycopy(h, 0, ck, 0, hashLength);
} }
/**
* Copy constructor for cloning
* @since 0.9.44
*/
protected SymmetricState(SymmetricState o) throws CloneNotSupportedException {
cipher = o.cipher.clone();
hash = (MessageDigest) o.hash.clone();
ck = Arrays.copyOf(o.ck, o.ck.length);
h = Arrays.copyOf(o.h, o.h.length);
prev_h = Arrays.copyOf(o.prev_h, o.prev_h.length);
}
/** /**
* Gets the name of the Noise protocol. * Gets the name of the Noise protocol.
* *
@ -482,6 +511,15 @@ class SymmetricState implements Destroyable {
return rv; return rv;
} }
/**
* I2P
* @since 0.9.44
*/
@Override
public SymmetricState clone() throws CloneNotSupportedException {
return new SymmetricState(this);
}
/** /**
* I2P debug * I2P debug
*/ */

View File

@ -4,6 +4,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.crypto.EncType; import net.i2p.crypto.EncType;
import net.i2p.crypto.KeyFactory;
import net.i2p.crypto.KeyPair; import net.i2p.crypto.KeyPair;
import net.i2p.data.PrivateKey; import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey; import net.i2p.data.PublicKey;
@ -19,7 +20,7 @@ import net.i2p.util.SystemVersion;
* *
* @since 0.9.36 from DHSessionKeyFactory.PrecalcRunner * @since 0.9.36 from DHSessionKeyFactory.PrecalcRunner
*/ */
public class X25519KeyFactory extends I2PThread { public class X25519KeyFactory extends I2PThread implements KeyFactory {
private final I2PAppContext _context; private final I2PAppContext _context;
private final Log _log; private final Log _log;

View File

@ -682,7 +682,7 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
} }
try { try {
_handshakeState = new HandshakeState(HandshakeState.RESPONDER, _transport.getXDHFactory()); _handshakeState = new HandshakeState(HandshakeState.PATTERN_ID_XK, HandshakeState.RESPONDER, _transport.getXDHFactory());
} catch (GeneralSecurityException gse) { } catch (GeneralSecurityException gse) {
throw new IllegalStateException("bad proto", gse); throw new IllegalStateException("bad proto", gse);
} }

View File

@ -106,7 +106,7 @@ class OutboundNTCP2State implements EstablishState {
_state = State.OB_INIT; _state = State.OB_INIT;
_tmp = new byte[TOTAL1_MAX]; _tmp = new byte[TOTAL1_MAX];
try { try {
_handshakeState = new HandshakeState(HandshakeState.INITIATOR, _transport.getXDHFactory()); _handshakeState = new HandshakeState(HandshakeState.PATTERN_ID_XK, HandshakeState.INITIATOR, _transport.getXDHFactory());
} catch (GeneralSecurityException gse) { } catch (GeneralSecurityException gse) {
throw new IllegalStateException("bad proto", gse); throw new IllegalStateException("bad proto", gse);
} }