From f0cf825ca934b8d8ddbef499a7ef65808e29bc80 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Fri, 12 Aug 2011 12:57:23 +0200
Subject: [PATCH] Javadoc and unit test for SharedSecret.

---
 .../net/sf/briar/crypto/SharedSecret.java     | 37 ++++++++++++++++++
 .../net/sf/briar/crypto/SharedSecretTest.java | 38 +++++++++++++++++++
 2 files changed, 75 insertions(+)
 create mode 100644 test/net/sf/briar/crypto/SharedSecretTest.java

diff --git a/components/net/sf/briar/crypto/SharedSecret.java b/components/net/sf/briar/crypto/SharedSecret.java
index 4e9eb747e3..5c144dcc56 100644
--- a/components/net/sf/briar/crypto/SharedSecret.java
+++ b/components/net/sf/briar/crypto/SharedSecret.java
@@ -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;
+	}
 }
diff --git a/test/net/sf/briar/crypto/SharedSecretTest.java b/test/net/sf/briar/crypto/SharedSecretTest.java
new file mode 100644
index 0000000000..ebaa879976
--- /dev/null
+++ b/test/net/sf/briar/crypto/SharedSecretTest.java
@@ -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) {}
+	}
+}
-- 
GitLab