forked from I2P_Developers/i2p.i2p
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:
@ -29,7 +29,7 @@ import com.southernstorm.noise.protocol.Destroyable;
|
||||
/**
|
||||
* 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.
|
||||
private final byte[] nonce;
|
||||
@ -324,4 +324,13 @@ public final class Poly1305 implements Destroyable {
|
||||
Arrays.fill(c, 0);
|
||||
Arrays.fill(t, (long)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P
|
||||
* @since 0.9.44
|
||||
*/
|
||||
@Override
|
||||
public Poly1305 clone() throws CloneNotSupportedException {
|
||||
return (Poly1305) super.clone();
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,10 @@ public class ChaChaPolyCipherState implements CipherState {
|
||||
private final byte[] polyKey;
|
||||
private long n;
|
||||
private boolean haskey;
|
||||
// Debug only
|
||||
private byte[] initialKey;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* Constructs a new cipher state for the "ChaChaPoly" algorithm.
|
||||
@ -55,6 +59,20 @@ public class ChaChaPolyCipherState implements CipherState {
|
||||
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
|
||||
public void destroy() {
|
||||
poly.destroy();
|
||||
@ -80,6 +98,10 @@ public class ChaChaPolyCipherState implements CipherState {
|
||||
|
||||
@Override
|
||||
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);
|
||||
n = 0;
|
||||
haskey = true;
|
||||
@ -249,6 +271,15 @@ public class ChaChaPolyCipherState implements CipherState {
|
||||
n = nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P
|
||||
* @since 0.9.44
|
||||
*/
|
||||
@Override
|
||||
public ChaChaPolyCipherState clone() throws CloneNotSupportedException {
|
||||
return new ChaChaPolyCipherState(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P debug
|
||||
*/
|
||||
@ -258,6 +289,15 @@ public class ChaChaPolyCipherState implements CipherState {
|
||||
buf.append(" Cipher State:\n" +
|
||||
" nonce: ");
|
||||
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: ");
|
||||
if (haskey)
|
||||
buf.append(net.i2p.data.Base64.encode(polyKey));
|
||||
|
@ -33,7 +33,7 @@ import javax.crypto.ShortBufferException;
|
||||
* will create two CipherState objects for encrypting packets sent to
|
||||
* 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.
|
||||
@ -155,4 +155,10 @@ public interface CipherState extends Destroyable {
|
||||
* value goes backwards then security may be compromised.
|
||||
*/
|
||||
void setNonce(long nonce);
|
||||
|
||||
/**
|
||||
* I2P
|
||||
* @since 0.9.44
|
||||
*/
|
||||
public CipherState clone() throws CloneNotSupportedException;
|
||||
}
|
||||
|
@ -26,23 +26,25 @@ import java.util.Arrays;
|
||||
|
||||
import com.southernstorm.noise.crypto.x25519.Curve25519;
|
||||
|
||||
import net.i2p.crypto.KeyFactory;
|
||||
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.
|
||||
*/
|
||||
class Curve25519DHState implements DHState {
|
||||
class Curve25519DHState implements DHState, Cloneable {
|
||||
|
||||
private final byte[] publicKey;
|
||||
private final byte[] privateKey;
|
||||
private int mode;
|
||||
private final X25519KeyFactory _xdh;
|
||||
private final KeyFactory _xdh;
|
||||
private byte[] encodedPublicKey;
|
||||
|
||||
/**
|
||||
* Constructs a new Diffie-Hellman object for Curve25519.
|
||||
*/
|
||||
public Curve25519DHState(X25519KeyFactory xdh)
|
||||
public Curve25519DHState(KeyFactory xdh)
|
||||
{
|
||||
publicKey = new byte [32];
|
||||
privateKey = new byte [32];
|
||||
@ -80,6 +82,11 @@ class Curve25519DHState implements DHState {
|
||||
KeyPair kp = _xdh.getKeys();
|
||||
System.arraycopy(kp.getPrivate().getData(), 0, privateKey, 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;
|
||||
}
|
||||
|
||||
@ -111,6 +118,10 @@ class Curve25519DHState implements DHState {
|
||||
public void setToNullPublicKey() {
|
||||
Arrays.fill(publicKey, (byte)0);
|
||||
Arrays.fill(privateKey, (byte)0);
|
||||
if (encodedPublicKey != null) {
|
||||
Arrays.fill(encodedPublicKey, (byte)0);
|
||||
encodedPublicKey = null;
|
||||
}
|
||||
mode = 0x01;
|
||||
}
|
||||
|
||||
@ -118,6 +129,10 @@ class Curve25519DHState implements DHState {
|
||||
public void clearKey() {
|
||||
Noise.destroy(publicKey);
|
||||
Noise.destroy(privateKey);
|
||||
if (encodedPublicKey != null) {
|
||||
Noise.destroy(encodedPublicKey);
|
||||
encodedPublicKey = null;
|
||||
}
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
@ -141,6 +156,26 @@ class Curve25519DHState implements DHState {
|
||||
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
|
||||
public void calculate(byte[] sharedKey, int offset, DHState publicDH) {
|
||||
if (!(publicDH instanceof Curve25519DHState))
|
||||
@ -159,4 +194,13 @@ class Curve25519DHState implements DHState {
|
||||
System.arraycopy(dh.publicKey, 0, publicKey, 0, 32);
|
||||
mode = dh.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P
|
||||
* @since 0.9.44
|
||||
*/
|
||||
@Override
|
||||
public Curve25519DHState clone() throws CloneNotSupportedException {
|
||||
return (Curve25519DHState) super.clone();
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ package com.southernstorm.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.
|
||||
@ -132,6 +132,26 @@ public interface DHState extends Destroyable {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -153,4 +173,10 @@ public interface DHState extends Destroyable {
|
||||
* the same type as this object.
|
||||
*/
|
||||
void copyFrom(DHState other);
|
||||
|
||||
/**
|
||||
* I2P
|
||||
* @since 0.9.44
|
||||
*/
|
||||
public DHState clone() throws CloneNotSupportedException;
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ import java.util.Arrays;
|
||||
import javax.crypto.BadPaddingException;
|
||||
import javax.crypto.ShortBufferException;
|
||||
|
||||
import net.i2p.router.transport.crypto.X25519KeyFactory;
|
||||
import net.i2p.crypto.KeyFactory;
|
||||
|
||||
/**
|
||||
* Interface to a Noise handshake.
|
||||
*/
|
||||
public class HandshakeState implements Destroyable {
|
||||
public class HandshakeState implements Destroyable, Cloneable {
|
||||
|
||||
private final SymmetricState symmetric;
|
||||
private final boolean isInitiator;
|
||||
@ -128,36 +128,53 @@ public class HandshakeState implements Destroyable {
|
||||
private static final int FALLBACK_POSSIBLE = 0x40;
|
||||
|
||||
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 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 final String cipher;
|
||||
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 {
|
||||
// Parse the protocol name into its components.
|
||||
// XK
|
||||
String[] components = protocolName.split("_");
|
||||
if (components.length != 5)
|
||||
throw new IllegalArgumentException("Protocol name must have 5 components");
|
||||
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];
|
||||
cipher = components[3];
|
||||
hash = components[4];
|
||||
if (!prefix.equals("Noise") && !prefix.equals("NoisePSK"))
|
||||
throw new IllegalArgumentException("Prefix must be Noise or NoisePSK");
|
||||
pattern = Pattern.lookup(patternId);
|
||||
if (pattern == null)
|
||||
PATTERN_XK = Pattern.lookup(id);
|
||||
if (PATTERN_XK == null)
|
||||
throw new IllegalArgumentException("Handshake pattern is not recognized");
|
||||
if (!dh.equals("25519"))
|
||||
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.
|
||||
* Noise protocol name is hardcoded.
|
||||
*
|
||||
* @param patternId XK or IK
|
||||
* @param role The role, HandshakeState.INITIATOR or HandshakeState.RESPONDER.
|
||||
* @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
|
||||
* 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];
|
||||
int extraReqs = 0;
|
||||
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");
|
||||
|
||||
// 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);
|
||||
action = NO_ACTION;
|
||||
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.
|
||||
*
|
||||
@ -231,6 +276,19 @@ public class HandshakeState implements Destroyable {
|
||||
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.
|
||||
*
|
||||
@ -534,6 +592,13 @@ public class HandshakeState implements Destroyable {
|
||||
}
|
||||
break;
|
||||
|
||||
case Pattern.SS:
|
||||
{
|
||||
// DH operation with initiator and responder static keys.
|
||||
mixDH(localKeyPair, remotePublicKey);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// Unknown token code. Abort.
|
||||
@ -692,6 +757,13 @@ public class HandshakeState implements Destroyable {
|
||||
}
|
||||
break;
|
||||
|
||||
case Pattern.SS:
|
||||
{
|
||||
// DH operation with initiator and responder static keys.
|
||||
mixDH(localKeyPair, remotePublicKey);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// Unknown token code. Abort.
|
||||
@ -844,13 +916,25 @@ public class HandshakeState implements Destroyable {
|
||||
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
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("Handshake State:\n");
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
buf.append(patternId);
|
||||
buf.append(" Handshake State:\n");
|
||||
buf.append(symmetric.toString());
|
||||
|
||||
byte[] tmp = new byte[32];
|
||||
|
@ -71,6 +71,23 @@ class Pattern {
|
||||
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.
|
||||
*
|
||||
@ -81,6 +98,8 @@ class Pattern {
|
||||
{
|
||||
if (name.equals("XK"))
|
||||
return noise_pattern_XK;
|
||||
else if (name.equals("IK"))
|
||||
return noise_pattern_IK;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -34,32 +34,42 @@ import javax.crypto.ShortBufferException;
|
||||
/**
|
||||
* Symmetric state for helping manage a Noise handshake.
|
||||
*/
|
||||
class SymmetricState implements Destroyable {
|
||||
class SymmetricState implements Destroyable, Cloneable {
|
||||
|
||||
// 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 {
|
||||
INIT_HASH_XK = initHash(HandshakeState.protocolName);
|
||||
INIT_HASH_IK = initHash(HandshakeState.protocolName2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.44
|
||||
*/
|
||||
private static byte[] initHash(String protocolName) {
|
||||
byte[] protocolNameBytes;
|
||||
try {
|
||||
protocolNameBytes = HandshakeState.protocolName.getBytes("UTF-8");
|
||||
protocolNameBytes = protocolName.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// If UTF-8 is not supported, then we are definitely in trouble!
|
||||
throw new UnsupportedOperationException("UTF-8 encoding is not supported");
|
||||
}
|
||||
INIT_HASH = new byte[32];
|
||||
byte[] rv = new byte[32];
|
||||
if (protocolNameBytes.length <= 32) {
|
||||
System.arraycopy(protocolNameBytes, 0, INIT_HASH, 0, protocolNameBytes.length);
|
||||
Arrays.fill(INIT_HASH, protocolNameBytes.length, 32, (byte)0);
|
||||
System.arraycopy(protocolNameBytes, 0, rv, 0, protocolNameBytes.length);
|
||||
Arrays.fill(rv, protocolNameBytes.length, 32, (byte)0);
|
||||
} else {
|
||||
try {
|
||||
MessageDigest hash = Noise.createHash("SHA256");
|
||||
hash.update(protocolNameBytes, 0, protocolNameBytes.length);
|
||||
hash.digest(INIT_HASH, 0, 32);
|
||||
hash.digest(rv, 0, 32);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private final CipherState cipher;
|
||||
@ -78,7 +88,7 @@ class SymmetricState implements Destroyable {
|
||||
* @throws NoSuchAlgorithmException The cipher or hash algorithm in the
|
||||
* 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);
|
||||
hash = Noise.createHash(hashName);
|
||||
@ -87,10 +97,29 @@ class SymmetricState implements Destroyable {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@ -482,6 +511,15 @@ class SymmetricState implements Destroyable {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P
|
||||
* @since 0.9.44
|
||||
*/
|
||||
@Override
|
||||
public SymmetricState clone() throws CloneNotSupportedException {
|
||||
return new SymmetricState(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* I2P debug
|
||||
*/
|
||||
|
@ -4,6 +4,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.crypto.EncType;
|
||||
import net.i2p.crypto.KeyFactory;
|
||||
import net.i2p.crypto.KeyPair;
|
||||
import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.PublicKey;
|
||||
@ -19,7 +20,7 @@ import net.i2p.util.SystemVersion;
|
||||
*
|
||||
* @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 Log _log;
|
||||
|
@ -682,7 +682,7 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
|
||||
}
|
||||
|
||||
try {
|
||||
_handshakeState = new HandshakeState(HandshakeState.RESPONDER, _transport.getXDHFactory());
|
||||
_handshakeState = new HandshakeState(HandshakeState.PATTERN_ID_XK, HandshakeState.RESPONDER, _transport.getXDHFactory());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
throw new IllegalStateException("bad proto", gse);
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ class OutboundNTCP2State implements EstablishState {
|
||||
_state = State.OB_INIT;
|
||||
_tmp = new byte[TOTAL1_MAX];
|
||||
try {
|
||||
_handshakeState = new HandshakeState(HandshakeState.INITIATOR, _transport.getXDHFactory());
|
||||
_handshakeState = new HandshakeState(HandshakeState.PATTERN_ID_XK, HandshakeState.INITIATOR, _transport.getXDHFactory());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
throw new IllegalStateException("bad proto", gse);
|
||||
}
|
||||
|
Reference in New Issue
Block a user