mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 03:39:05 +01:00
Replaced further JCE calls with direct instantiation of SC objects.
This commit is contained in:
@@ -5,8 +5,6 @@ import java.security.KeyPair;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Signature;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
public interface CryptoComponent {
|
||||
|
||||
ErasableKey generateSecretKey();
|
||||
@@ -82,18 +80,11 @@ public interface CryptoComponent {
|
||||
ErasableKey deriveFrameKey(byte[] secret, long connection, boolean alice,
|
||||
boolean initiator);
|
||||
|
||||
/**
|
||||
* Returns a cipher for generating the pseudo-random tags that are used to
|
||||
* recognise connections.
|
||||
*/
|
||||
Cipher getTagCipher();
|
||||
|
||||
/** Returns a cipher for encrypting and authenticating connections. */
|
||||
AuthenticatedCipher getFrameCipher();
|
||||
|
||||
/** Encodes the pseudo-random tag that is used to recognise a connection. */
|
||||
void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
|
||||
long connection);
|
||||
void encodeTag(byte[] tag, ErasableKey tagKey, long connection);
|
||||
|
||||
/**
|
||||
* Encrypts and authenticates the given plaintext so it can be written to
|
||||
|
||||
@@ -15,7 +15,6 @@ import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
@@ -30,10 +29,7 @@ import java.security.spec.EllipticCurve;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherSpi;
|
||||
import javax.crypto.KeyAgreement;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
import net.sf.briar.api.crypto.AuthenticatedCipher;
|
||||
import net.sf.briar.api.crypto.CryptoComponent;
|
||||
@@ -43,6 +39,7 @@ import net.sf.briar.api.crypto.MessageDigest;
|
||||
import net.sf.briar.api.crypto.PseudoRandom;
|
||||
import net.sf.briar.util.ByteUtils;
|
||||
|
||||
import org.spongycastle.crypto.BlockCipher;
|
||||
import org.spongycastle.crypto.CipherParameters;
|
||||
import org.spongycastle.crypto.engines.AESFastEngine;
|
||||
import org.spongycastle.crypto.generators.PKCS5S2ParametersGenerator;
|
||||
@@ -51,7 +48,6 @@ import org.spongycastle.crypto.modes.GCMBlockCipher;
|
||||
import org.spongycastle.crypto.params.KeyParameter;
|
||||
import org.spongycastle.jcajce.provider.asymmetric.ec.KeyPairGeneratorSpi;
|
||||
import org.spongycastle.jcajce.provider.digest.SHA384;
|
||||
import org.spongycastle.jcajce.provider.symmetric.AES;
|
||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
@@ -61,21 +57,19 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
Logger.getLogger(CryptoComponentImpl.class.getName());
|
||||
|
||||
private static final String PROVIDER = "SC"; // Spongy Castle
|
||||
private static final String SECRET_KEY_ALGO = "AES";
|
||||
private static final int SECRET_KEY_BYTES = 32; // 256 bits
|
||||
private static final String CIPHER_ALGO = "AES";
|
||||
private static final int CIPHER_BLOCK_BYTES = 16; // 128 bits
|
||||
private static final int CIPHER_KEY_BYTES = 32; // 256 bits
|
||||
private static final String AGREEMENT_ALGO = "ECDHC";
|
||||
private static final String AGREEMENT_KEY_PAIR_ALGO = "ECDH";
|
||||
private static final int AGREEMENT_KEY_PAIR_BITS = 384;
|
||||
private static final String SIGNATURE_ALGO = "ECDSA";
|
||||
private static final String SIGNATURE_KEY_PAIR_ALGO = "ECDSA";
|
||||
private static final int SIGNATURE_KEY_PAIR_BITS = 384;
|
||||
private static final String TAG_CIPHER_ALGO = "AES/ECB/NoPadding";
|
||||
private static final int GCM_MAC_BYTES = 16; // 128 bits
|
||||
private static final int STORAGE_IV_BYTES = 16; // 128 bits
|
||||
private static final int PBKDF_SALT_BYTES = 16; // 128 bits
|
||||
private static final int PBKDF_ITERATIONS = 1000;
|
||||
private static final String KEY_DERIVATION_ALGO = "AES/CTR/NoPadding";
|
||||
private static final int KEY_DERIVATION_IV_BYTES = 16; // 128 bits
|
||||
|
||||
// Labels for secret derivation
|
||||
private static final byte[] MASTER = { 'M', 'A', 'S', 'T', 'E', 'R', '\0' };
|
||||
@@ -96,11 +90,8 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
{ 'B', '_', 'F', 'R', 'A', 'M', 'E', '_', 'A', '\0' };
|
||||
private static final byte[] B_FRAME_B =
|
||||
{ 'B', '_', 'F', 'R', 'A', 'M', 'E', '_', 'B', '\0' };
|
||||
// Blank plaintext for key derivation
|
||||
private static final byte[] KEY_DERIVATION_BLANK_PLAINTEXT =
|
||||
new byte[SECRET_KEY_BYTES];
|
||||
// Blank secret for argument validation
|
||||
private static final byte[] BLANK_SECRET = new byte[SECRET_KEY_BYTES];
|
||||
private static final byte[] BLANK_SECRET = new byte[CIPHER_KEY_BYTES];
|
||||
|
||||
// Parameters for NIST elliptic curve P-384 - see "Suite B Implementer's
|
||||
// Guide to NIST SP 800-56A", section A.2
|
||||
@@ -137,38 +128,34 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
private static final ECParameterSpec P_384_PARAMS =
|
||||
new ECParameterSpec(P_384_CURVE, P_384_G, P_384_N, P_384_H);
|
||||
|
||||
private final Provider provider;
|
||||
private final KeyParser agreementKeyParser, signatureKeyParser;
|
||||
private final KeyPairGenerator agreementKeyPairGenerator;
|
||||
private final KeyPairGenerator signatureKeyPairGenerator;
|
||||
private final SecureRandom secureRandom;
|
||||
|
||||
CryptoComponentImpl() {
|
||||
provider = new BouncyCastleProvider();
|
||||
Security.addProvider(provider);
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
try {
|
||||
KeyFactory agreementKeyFactory = KeyFactory.getInstance(
|
||||
AGREEMENT_KEY_PAIR_ALGO, PROVIDER);
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
LOG.info("Agreement KeyFactory: "
|
||||
+ agreementKeyFactory.getClass().getName());
|
||||
}
|
||||
agreementKeyParser = new Sec1KeyParser(agreementKeyFactory,
|
||||
P_384_PARAMS, P_384_Q, AGREEMENT_KEY_PAIR_BITS);
|
||||
KeyFactory signatureKeyFactory = KeyFactory.getInstance(
|
||||
SIGNATURE_KEY_PAIR_ALGO, PROVIDER);
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
LOG.info("Signature KeyFactory: "
|
||||
+ signatureKeyFactory.getClass().getName());
|
||||
}
|
||||
signatureKeyParser = new Sec1KeyParser(signatureKeyFactory,
|
||||
P_384_PARAMS, P_384_Q, SIGNATURE_KEY_PAIR_BITS);
|
||||
agreementKeyPairGenerator = new KeyPairGeneratorSpi.ECDH();
|
||||
agreementKeyPairGenerator.initialize(AGREEMENT_KEY_PAIR_BITS);
|
||||
signatureKeyPairGenerator = new KeyPairGeneratorSpi.ECDSA();
|
||||
signatureKeyPairGenerator.initialize(SIGNATURE_KEY_PAIR_BITS);
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
LOG.info("Agreement KeyFactory: "
|
||||
+ agreementKeyFactory.getClass().getName());
|
||||
LOG.info("Signature KeyFactory: "
|
||||
+ signatureKeyFactory.getClass().getName());
|
||||
LOG.info("Agreement KeyPairGenerator: "
|
||||
+ agreementKeyPairGenerator.getClass().getName());
|
||||
LOG.info("Signature KeyPairGenerator: "
|
||||
+ signatureKeyPairGenerator.getClass().getName());
|
||||
}
|
||||
} catch(GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -176,9 +163,9 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public ErasableKey generateSecretKey() {
|
||||
byte[] b = new byte[SECRET_KEY_BYTES];
|
||||
byte[] b = new byte[CIPHER_KEY_BYTES];
|
||||
secureRandom.nextBytes(b);
|
||||
return new ErasableKeyImpl(b, SECRET_KEY_ALGO);
|
||||
return new ErasableKeyImpl(b, CIPHER_ALGO);
|
||||
}
|
||||
|
||||
public MessageDigest getMessageDigest() {
|
||||
@@ -243,7 +230,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public int[] deriveConfirmationCodes(byte[] secret) {
|
||||
if(secret.length != SECRET_KEY_BYTES)
|
||||
if(secret.length != CIPHER_KEY_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
if(Arrays.equals(secret, BLANK_SECRET))
|
||||
throw new IllegalArgumentException();
|
||||
@@ -258,7 +245,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public byte[][] deriveInvitationNonces(byte[] secret) {
|
||||
if(secret.length != SECRET_KEY_BYTES)
|
||||
if(secret.length != CIPHER_KEY_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
if(Arrays.equals(secret, BLANK_SECRET))
|
||||
throw new IllegalArgumentException();
|
||||
@@ -305,7 +292,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public byte[] deriveInitialSecret(byte[] secret, int transportIndex) {
|
||||
if(secret.length != SECRET_KEY_BYTES)
|
||||
if(secret.length != CIPHER_KEY_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
if(Arrays.equals(secret, BLANK_SECRET))
|
||||
throw new IllegalArgumentException();
|
||||
@@ -314,7 +301,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public byte[] deriveNextSecret(byte[] secret, long period) {
|
||||
if(secret.length != SECRET_KEY_BYTES)
|
||||
if(secret.length != CIPHER_KEY_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
if(Arrays.equals(secret, BLANK_SECRET))
|
||||
throw new IllegalArgumentException();
|
||||
@@ -324,7 +311,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
public ErasableKey deriveTagKey(byte[] secret, boolean alice) {
|
||||
if(secret.length != SECRET_KEY_BYTES)
|
||||
if(secret.length != CIPHER_KEY_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
if(Arrays.equals(secret, BLANK_SECRET))
|
||||
throw new IllegalArgumentException();
|
||||
@@ -334,7 +321,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
|
||||
public ErasableKey deriveFrameKey(byte[] secret, long connection,
|
||||
boolean alice, boolean initiator) {
|
||||
if(secret.length != SECRET_KEY_BYTES)
|
||||
if(secret.length != CIPHER_KEY_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
if(Arrays.equals(secret, BLANK_SECRET))
|
||||
throw new IllegalArgumentException();
|
||||
@@ -350,16 +337,12 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
}
|
||||
|
||||
private ErasableKey deriveKey(byte[] secret, byte[] label, long context) {
|
||||
if(secret.length != SECRET_KEY_BYTES)
|
||||
if(secret.length != CIPHER_KEY_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
if(Arrays.equals(secret, BLANK_SECRET))
|
||||
throw new IllegalArgumentException();
|
||||
byte[] key = counterModeKdf(secret, label, context);
|
||||
return new ErasableKeyImpl(key, SECRET_KEY_ALGO);
|
||||
}
|
||||
|
||||
public Cipher getTagCipher() {
|
||||
return new CipherFromSpi(new AES.ECB(), provider, TAG_CIPHER_ALGO);
|
||||
return new ErasableKeyImpl(key, CIPHER_ALGO);
|
||||
}
|
||||
|
||||
public AuthenticatedCipher getFrameCipher() {
|
||||
@@ -367,20 +350,15 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
return new AuthenticatedCipherImpl(cipher, GCM_MAC_BYTES);
|
||||
}
|
||||
|
||||
public void encodeTag(byte[] tag, Cipher tagCipher, ErasableKey tagKey,
|
||||
long connection) {
|
||||
public void encodeTag(byte[] tag, ErasableKey tagKey, long connection) {
|
||||
if(tag.length < TAG_LENGTH) throw new IllegalArgumentException();
|
||||
if(connection < 0 || connection > MAX_32_BIT_UNSIGNED)
|
||||
throw new IllegalArgumentException();
|
||||
for(int i = 0; i < TAG_LENGTH; i++) tag[i] = 0;
|
||||
ByteUtils.writeUint32(connection, tag, 0);
|
||||
try {
|
||||
tagCipher.init(ENCRYPT_MODE, tagKey);
|
||||
int encrypted = tagCipher.doFinal(tag, 0, TAG_LENGTH, tag);
|
||||
if(encrypted != TAG_LENGTH) throw new IllegalArgumentException();
|
||||
} catch(GeneralSecurityException e) {
|
||||
throw new IllegalArgumentException(e); // Unsuitable cipher or key
|
||||
}
|
||||
BlockCipher cipher = new AESFastEngine();
|
||||
cipher.init(true, new KeyParameter(tagKey.getEncoded()));
|
||||
cipher.processBlock(tag, 0, tag, 0);
|
||||
}
|
||||
|
||||
public byte[] encryptWithPassword(byte[] input, char[] password) {
|
||||
@@ -389,7 +367,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
secureRandom.nextBytes(salt);
|
||||
// Derive the key from the password
|
||||
byte[] keyBytes = pbkdf2(password, salt);
|
||||
ErasableKey key = new ErasableKeyImpl(keyBytes, SECRET_KEY_ALGO);
|
||||
ErasableKey key = new ErasableKeyImpl(keyBytes, CIPHER_ALGO);
|
||||
// Generate a random IV
|
||||
byte[] iv = new byte[STORAGE_IV_BYTES];
|
||||
secureRandom.nextBytes(iv);
|
||||
@@ -424,7 +402,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
System.arraycopy(input, salt.length, iv, 0, iv.length);
|
||||
// Derive the key from the password
|
||||
byte[] keyBytes = pbkdf2(password, salt);
|
||||
ErasableKey key = new ErasableKeyImpl(keyBytes, SECRET_KEY_ALGO);
|
||||
ErasableKey key = new ErasableKeyImpl(keyBytes, CIPHER_ALGO);
|
||||
// Initialise the cipher
|
||||
AuthenticatedCipher cipher;
|
||||
try {
|
||||
@@ -472,7 +450,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
byte[] initiatorInfo, byte[] responderInfo) {
|
||||
// The output of the hash function must be long enough to use as a key
|
||||
MessageDigest messageDigest = getMessageDigest();
|
||||
if(messageDigest.getDigestLength() < SECRET_KEY_BYTES)
|
||||
if(messageDigest.getDigestLength() < CIPHER_KEY_BYTES)
|
||||
throw new RuntimeException();
|
||||
// All fields are length-prefixed
|
||||
byte[] length = new byte[1];
|
||||
@@ -490,7 +468,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
messageDigest.update(responderInfo);
|
||||
byte[] hash = messageDigest.digest();
|
||||
// The secret is the first SECRET_KEY_BYTES bytes of the hash
|
||||
byte[] output = new byte[SECRET_KEY_BYTES];
|
||||
byte[] output = new byte[CIPHER_KEY_BYTES];
|
||||
System.arraycopy(hash, 0, output, 0, output.length);
|
||||
ByteUtils.erase(hash);
|
||||
return output;
|
||||
@@ -499,30 +477,24 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
// Key derivation function based on a block cipher in CTR mode - see
|
||||
// NIST SP 800-108, section 5.1
|
||||
private byte[] counterModeKdf(byte[] secret, byte[] label, long context) {
|
||||
if(secret.length != SECRET_KEY_BYTES)
|
||||
if(secret.length != CIPHER_KEY_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
if(Arrays.equals(secret, BLANK_SECRET))
|
||||
throw new IllegalArgumentException();
|
||||
// The label and context must leave a byte free for the counter
|
||||
if(label.length + 4 >= KEY_DERIVATION_IV_BYTES)
|
||||
if(label.length + 4 >= CIPHER_BLOCK_BYTES)
|
||||
throw new IllegalArgumentException();
|
||||
byte[] ivBytes = new byte[KEY_DERIVATION_IV_BYTES];
|
||||
System.arraycopy(label, 0, ivBytes, 0, label.length);
|
||||
ByteUtils.writeUint32(context, ivBytes, label.length);
|
||||
// Use the secret and the IV to encrypt a blank plaintext
|
||||
IvParameterSpec iv = new IvParameterSpec(ivBytes);
|
||||
ErasableKey key = new ErasableKeyImpl(secret, SECRET_KEY_ALGO);
|
||||
try {
|
||||
CipherSpi spi = new AES.ECB();
|
||||
Cipher cipher = new CipherFromSpi(spi, provider,
|
||||
KEY_DERIVATION_ALGO);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
|
||||
byte[] output = cipher.doFinal(KEY_DERIVATION_BLANK_PLAINTEXT);
|
||||
assert output.length == SECRET_KEY_BYTES;
|
||||
return output;
|
||||
} catch(GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
byte[] counter = new byte[CIPHER_BLOCK_BYTES];
|
||||
System.arraycopy(label, 0, counter, 0, label.length);
|
||||
ByteUtils.writeUint32(context, counter, label.length);
|
||||
BlockCipher cipher = new AESFastEngine();
|
||||
cipher.init(true, new KeyParameter(secret));
|
||||
byte[] output = new byte[CIPHER_KEY_BYTES];
|
||||
for(int i = 0; i * CIPHER_BLOCK_BYTES < output.length; i++) {
|
||||
counter[counter.length - 1] = (byte) i;
|
||||
cipher.processBlock(counter, 0, output, i * CIPHER_BLOCK_BYTES);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// Password-based key derivation function - see PKCS#5 v2.1, section 5.2
|
||||
@@ -532,7 +504,7 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
byte[] utf8 = toUtf8ByteArray(password);
|
||||
PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator();
|
||||
gen.init(utf8, salt, PBKDF_ITERATIONS);
|
||||
int keyLengthInBits = SECRET_KEY_BYTES * 8;
|
||||
int keyLengthInBits = CIPHER_KEY_BYTES * 8;
|
||||
CipherParameters p = gen.generateDerivedParameters(keyLengthInBits);
|
||||
ByteUtils.erase(utf8);
|
||||
return ((KeyParameter) p).getKey();
|
||||
@@ -551,12 +523,4 @@ class CryptoComponentImpl implements CryptoComponent {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CipherFromSpi extends Cipher {
|
||||
|
||||
private CipherFromSpi(CipherSpi spi, Provider provider,
|
||||
String transformation) {
|
||||
super(spi, provider, transformation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import static net.sf.briar.api.transport.TransportConstants.TAG_LENGTH;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import net.sf.briar.api.crypto.CryptoComponent;
|
||||
import net.sf.briar.api.crypto.ErasableKey;
|
||||
import net.sf.briar.api.transport.ConnectionContext;
|
||||
@@ -35,9 +33,8 @@ class ConnectionWriterFactoryImpl implements ConnectionWriterFactory {
|
||||
FrameWriter encryption;
|
||||
if(initiator) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
Cipher tagCipher = crypto.getTagCipher();
|
||||
ErasableKey tagKey = crypto.deriveTagKey(secret, initiatorIsAlice);
|
||||
crypto.encodeTag(tag, tagCipher, tagKey, connection);
|
||||
crypto.encodeTag(tag, tagKey, connection);
|
||||
tagKey.erase();
|
||||
encryption = new OutgoingEncryptionLayer(out, capacity,
|
||||
crypto.getFrameCipher(), frameKey, maxFrameLength, tag);
|
||||
|
||||
@@ -7,8 +7,6 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import net.sf.briar.api.Bytes;
|
||||
import net.sf.briar.api.ContactId;
|
||||
import net.sf.briar.api.TransportId;
|
||||
@@ -43,11 +41,10 @@ class TransportConnectionRecogniser {
|
||||
TagContext t = tagMap.remove(new Bytes(tag));
|
||||
if(t == null) return null; // The tag was not expected
|
||||
// Update the connection window and the expected tags
|
||||
Cipher cipher = crypto.getTagCipher();
|
||||
ErasableKey key = crypto.deriveTagKey(t.secret, !t.alice);
|
||||
for(long connection : t.window.setSeen(t.connection)) {
|
||||
byte[] tag1 = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag1, cipher, key, connection);
|
||||
crypto.encodeTag(tag1, key, connection);
|
||||
if(connection < t.connection) {
|
||||
TagContext removed = tagMap.remove(new Bytes(tag1));
|
||||
assert removed != null;
|
||||
@@ -75,12 +72,11 @@ class TransportConnectionRecogniser {
|
||||
long centre = s.getWindowCentre();
|
||||
byte[] bitmap = s.getWindowBitmap();
|
||||
// Create the connection window and the expected tags
|
||||
Cipher cipher = crypto.getTagCipher();
|
||||
ErasableKey key = crypto.deriveTagKey(secret, !alice);
|
||||
ConnectionWindow window = new ConnectionWindow(centre, bitmap);
|
||||
for(long connection : window.getUnseen()) {
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
crypto.encodeTag(tag, cipher, key, connection);
|
||||
crypto.encodeTag(tag, key, connection);
|
||||
TagContext added = new TagContext(contactId, alice, period,
|
||||
secret, window, connection);
|
||||
TagContext duplicate = tagMap.put(new Bytes(tag), added);
|
||||
@@ -102,11 +98,10 @@ class TransportConnectionRecogniser {
|
||||
// Locking: this
|
||||
private void removeSecret(RemovalContext r) {
|
||||
// Remove the expected tags
|
||||
Cipher cipher = crypto.getTagCipher();
|
||||
ErasableKey key = crypto.deriveTagKey(r.secret, !r.alice);
|
||||
byte[] tag = new byte[TAG_LENGTH];
|
||||
for(long connection : r.window.getUnseen()) {
|
||||
crypto.encodeTag(tag, cipher, key, connection);
|
||||
crypto.encodeTag(tag, key, connection);
|
||||
TagContext removed = tagMap.remove(new Bytes(tag));
|
||||
assert removed != null;
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@ import static org.junit.Assert.assertArrayEquals;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NullCipher;
|
||||
|
||||
import net.sf.briar.BriarTestCase;
|
||||
import net.sf.briar.TestUtils;
|
||||
import net.sf.briar.api.ContactId;
|
||||
@@ -45,7 +42,6 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
private final byte[] secret0, secret1, secret2, secret3, secret4;
|
||||
private final byte[] key0, key1, key2, key3, key4;
|
||||
private final byte[] initialSecret;
|
||||
private final Cipher cipher;
|
||||
|
||||
public KeyRotationIntegrationTest() {
|
||||
contactId = new ContactId(234);
|
||||
@@ -72,7 +68,6 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
for(int i = 0; i < key4.length; i++) key4[i] = 5;
|
||||
initialSecret = new byte[32];
|
||||
for(int i = 0; i < initialSecret.length; i++) initialSecret[i] = 123;
|
||||
cipher = new NullCipher();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -155,39 +150,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
will(returnValue(secret2.clone()));
|
||||
oneOf(db).addSecrets(Arrays.asList(s0, s1, s2));
|
||||
// The recogniser should derive the tags for period 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret0, false);
|
||||
will(returnValue(k0));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k0), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k0),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k0).getEncoded();
|
||||
will(returnValue(key0));
|
||||
}
|
||||
oneOf(k0).erase();
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
@@ -195,39 +184,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
oneOf(k2).erase();
|
||||
// stop()
|
||||
// The recogniser should derive the tags for period 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret0, false);
|
||||
will(returnValue(k0));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k0), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k0),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k0).getEncoded();
|
||||
will(returnValue(key0));
|
||||
}
|
||||
oneOf(k0).erase();
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
@@ -290,39 +273,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
will(returnValue(secret2.clone()));
|
||||
oneOf(db).addSecrets(Arrays.asList(s0, s1, s2));
|
||||
// The recogniser should derive the tags for period 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret0, false);
|
||||
will(returnValue(k0));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k0), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k0),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k0).getEncoded();
|
||||
will(returnValue(key0));
|
||||
}
|
||||
oneOf(k0).erase();
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
@@ -333,39 +310,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
will(returnValue(0L));
|
||||
// stop()
|
||||
// The recogniser should derive the tags for period 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret0, false);
|
||||
will(returnValue(k0));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k0), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k0),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k0).getEncoded();
|
||||
will(returnValue(key0));
|
||||
}
|
||||
oneOf(k0).erase();
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
@@ -436,50 +407,42 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
will(returnValue(secret2.clone()));
|
||||
oneOf(db).addSecrets(Arrays.asList(s0, s1, s2));
|
||||
// The recogniser should derive the tags for period 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret0, false);
|
||||
will(returnValue(k0));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k0), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k0),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k0).getEncoded();
|
||||
will(returnValue(key0));
|
||||
}
|
||||
oneOf(k0).erase();
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
}
|
||||
oneOf(k2).erase();
|
||||
// acceptConnection()
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(k2), with(16L));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
@@ -489,39 +452,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
oneOf(k2).erase();
|
||||
// stop()
|
||||
// The recogniser should derive the tags for period 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret0, false);
|
||||
will(returnValue(k0));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k0), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k0),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k0).getEncoded();
|
||||
will(returnValue(key0));
|
||||
}
|
||||
oneOf(k0).erase();
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the updated tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 1; i < 17; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
@@ -584,39 +541,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
oneOf(clock).currentTimeMillis();
|
||||
will(returnValue(EPOCH));
|
||||
// The recogniser should derive the tags for period 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret0, false);
|
||||
will(returnValue(k0));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k0), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k0),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k0).getEncoded();
|
||||
will(returnValue(key0));
|
||||
}
|
||||
oneOf(k0).erase();
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
@@ -627,39 +578,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
with(any(long.class)), with(any(long.class)));
|
||||
// stop()
|
||||
// The recogniser should remove the tags for period 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret0, false);
|
||||
will(returnValue(k0));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k0), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k0),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k0).getEncoded();
|
||||
will(returnValue(key0));
|
||||
}
|
||||
oneOf(k0).erase();
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
@@ -720,39 +665,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
will(returnValue(secret3.clone()));
|
||||
oneOf(db).addSecrets(Arrays.asList(s3));
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
}
|
||||
oneOf(k2).erase();
|
||||
// The recogniser should derive the tags for period 3
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret3, false);
|
||||
will(returnValue(k3));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k3), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k3),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k3).getEncoded();
|
||||
will(returnValue(key3));
|
||||
@@ -763,39 +702,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
with(any(long.class)), with(any(long.class)));
|
||||
// stop()
|
||||
// The recogniser should derive the tags for period 1
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret1, false);
|
||||
will(returnValue(k1));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k1), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k1),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k1).getEncoded();
|
||||
will(returnValue(key1));
|
||||
}
|
||||
oneOf(k1).erase();
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
}
|
||||
oneOf(k2).erase();
|
||||
// The recogniser should remove the tags for period 3
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret3, false);
|
||||
will(returnValue(k3));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k3), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k3),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k3).getEncoded();
|
||||
will(returnValue(key3));
|
||||
@@ -858,39 +791,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
// The new secrets should be stored
|
||||
oneOf(db).addSecrets(Arrays.asList(s3, s4));
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
}
|
||||
oneOf(k2).erase();
|
||||
// The recogniser should derive the tags for period 3
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret3, false);
|
||||
will(returnValue(k3));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k3), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k3),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k3).getEncoded();
|
||||
will(returnValue(key3));
|
||||
}
|
||||
oneOf(k3).erase();
|
||||
// The recogniser should derive the tags for period 4
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret4, false);
|
||||
will(returnValue(k4));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k4), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k4),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k4).getEncoded();
|
||||
will(returnValue(key4));
|
||||
@@ -901,39 +828,33 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
with(any(long.class)), with(any(long.class)));
|
||||
// stop()
|
||||
// The recogniser should derive the tags for period 2
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret2, false);
|
||||
will(returnValue(k2));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k2), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k2),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k2).getEncoded();
|
||||
will(returnValue(key2));
|
||||
}
|
||||
oneOf(k2).erase();
|
||||
// The recogniser should remove the tags for period 3
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret3, false);
|
||||
will(returnValue(k3));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k3), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k3),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k3).getEncoded();
|
||||
will(returnValue(key3));
|
||||
}
|
||||
oneOf(k3).erase();
|
||||
// The recogniser should derive the tags for period 4
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(cipher));
|
||||
oneOf(crypto).deriveTagKey(secret4, false);
|
||||
will(returnValue(k4));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(cipher),
|
||||
with(k4), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(k4),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
oneOf(k4).getEncoded();
|
||||
will(returnValue(key4));
|
||||
@@ -964,10 +885,9 @@ public class KeyRotationIntegrationTest extends BriarTestCase {
|
||||
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
byte[] tag = (byte[]) invocation.getParameter(0);
|
||||
ErasableKey key = (ErasableKey) invocation.getParameter(2);
|
||||
long connection = (Long) invocation.getParameter(3);
|
||||
byte[] rawKey = key.getEncoded();
|
||||
encodeTag(tag, rawKey, connection);
|
||||
ErasableKey key = (ErasableKey) invocation.getParameter(1);
|
||||
long connection = (Long) invocation.getParameter(2);
|
||||
encodeTag(tag, key.getEncoded(), connection);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,6 @@ import static org.junit.Assert.assertArrayEquals;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.NullCipher;
|
||||
|
||||
import net.sf.briar.BriarTestCase;
|
||||
import net.sf.briar.TestUtils;
|
||||
import net.sf.briar.api.ContactId;
|
||||
@@ -31,7 +28,6 @@ public class TransportConnectionRecogniserTest extends BriarTestCase {
|
||||
private final ContactId contactId = new ContactId(234);
|
||||
private final TransportId transportId =
|
||||
new TransportId(TestUtils.getRandomId());
|
||||
private final Cipher tagCipher = new NullCipher();
|
||||
|
||||
@Test
|
||||
public void testAddAndRemoveSecret() {
|
||||
@@ -44,24 +40,20 @@ public class TransportConnectionRecogniserTest extends BriarTestCase {
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Add secret
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(tagCipher));
|
||||
oneOf(crypto).deriveTagKey(secret, !alice);
|
||||
will(returnValue(tagKey));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagCipher), with(tagKey), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(tagKey),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
oneOf(tagKey).erase();
|
||||
// Remove secret
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(tagCipher));
|
||||
oneOf(crypto).deriveTagKey(secret, !alice);
|
||||
will(returnValue(tagKey));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagCipher), with(tagKey), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(tagKey),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
oneOf(tagKey).erase();
|
||||
@@ -86,24 +78,20 @@ public class TransportConnectionRecogniserTest extends BriarTestCase {
|
||||
final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
context.checking(new Expectations() {{
|
||||
// Add secret
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(tagCipher));
|
||||
oneOf(crypto).deriveTagKey(secret, !alice);
|
||||
will(returnValue(tagKey));
|
||||
for(int i = 0; i < 16; i++) {
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)),
|
||||
with(tagCipher), with(tagKey), with((long) i));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(tagKey),
|
||||
with((long) i));
|
||||
will(new EncodeTagAction());
|
||||
}
|
||||
oneOf(tagKey).erase();
|
||||
// Accept connection 0
|
||||
oneOf(crypto).getTagCipher();
|
||||
will(returnValue(tagCipher));
|
||||
oneOf(crypto).deriveTagKey(secret, !alice);
|
||||
will(returnValue(tagKey));
|
||||
// The window should slide to include connection 16
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(tagCipher),
|
||||
with(tagKey), with(16L));
|
||||
oneOf(crypto).encodeTag(with(any(byte[].class)), with(tagKey),
|
||||
with(16L));
|
||||
will(new EncodeTagAction());
|
||||
// The updated window should be stored
|
||||
oneOf(db).setConnectionWindow(contactId, transportId, 0, 1,
|
||||
@@ -136,7 +124,7 @@ public class TransportConnectionRecogniserTest extends BriarTestCase {
|
||||
|
||||
public Object invoke(Invocation invocation) throws Throwable {
|
||||
byte[] tag = (byte[]) invocation.getParameter(0);
|
||||
long connection = (Long) invocation.getParameter(3);
|
||||
long connection = (Long) invocation.getParameter(2);
|
||||
// Encode a fake tag based on the connection number
|
||||
ByteUtils.writeUint32(connection, tag, 0);
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user