Javadoc and unit test for SharedSecret.

This commit is contained in:
akwizgran
2011-08-12 12:57:23 +02:00
parent e896b2d86d
commit f0cf825ca9
2 changed files with 75 additions and 0 deletions

View File

@@ -4,6 +4,16 @@ import java.util.Arrays;
import javax.crypto.spec.IvParameterSpec;
/**
* An encrypted shared secret from which authentication and encryption keys can
* be derived. The encrypted secret carries an IV for encrypting and decrypting
* it and a flag indicating whether Alice's keys or Bob's keys should be
* derived from the secret.
* <p>
* When two parties agree on a shared secret, they must determine which of them
* will derive Alice's keys and which Bob's. Each party then encrypts the
* secret with an independent key and IV.
*/
class SharedSecret {
private static final int IV_BYTES = 16;
@@ -28,15 +38,42 @@ class SharedSecret {
ciphertext = Arrays.copyOfRange(secret, IV_BYTES + 1, secret.length);
}
SharedSecret(IvParameterSpec iv, boolean alice, byte[] ciphertext) {
if(iv.getIV().length != IV_BYTES) throw new IllegalArgumentException();
this.iv = iv;
this.alice = alice;
this.ciphertext = ciphertext;
}
/** Returns the IV used for encrypting and decrypting the secret. */
IvParameterSpec getIv() {
return iv;
}
/**
* Returns true if we should play the role of Alice in connections using
* this secret, or false if we should play the role of Bob.
*/
boolean getAlice() {
return alice;
}
/** Returns the encrypted shared secret. */
byte[] getCiphertext() {
return ciphertext;
}
/**
* Returns a raw representation of the encrypted shared secret, suitable
* for storing in the database.
*/
byte[] getBytes() {
byte[] b = new byte[IV_BYTES + 1 + ciphertext.length];
byte[] ivBytes = iv.getIV();
assert ivBytes.length == IV_BYTES;
System.arraycopy(ivBytes, 0, b, 0, IV_BYTES);
if(alice) b[IV_BYTES] = (byte) 1;
System.arraycopy(ciphertext, 0, b, IV_BYTES + 1, ciphertext.length);
return b;
}
}

View File

@@ -0,0 +1,38 @@
package net.sf.briar.crypto;
import java.util.Arrays;
import java.util.Random;
import junit.framework.TestCase;
import org.junit.Test;
public class SharedSecretTest extends TestCase {
@Test
public void testDecodeAndEncode() {
Random random = new Random();
byte[] secret = new byte[40];
random.nextBytes(secret);
secret[16] = (byte) 0;
SharedSecret s = new SharedSecret(secret);
assertTrue(Arrays.equals(secret, s.getBytes()));
secret[16] = (byte) 1;
s = new SharedSecret(secret);
assertTrue(Arrays.equals(secret, s.getBytes()));
// The Alice flag must be either 0 or 1
secret[16] = (byte) 2;
try {
s = new SharedSecret(secret);
fail();
} catch(IllegalArgumentException expected) {}
// The secret must be at least 18 bytes long
secret = new byte[17];
random.nextBytes(secret);
secret[16] = (byte) 0;
try {
s = new SharedSecret(secret);
fail();
} catch(IllegalArgumentException expected) {}
}
}