summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSamuel Holland <samuel@sholland.org>2017-08-01 01:08:56 -0500
committerSamuel Holland <samuel@sholland.org>2017-08-01 01:08:56 -0500
commit19e8087642f3bb621d5c41db7f5f144345ab3c53 (patch)
tree0ed3c8dca6a5e983673c437f8a1916ae75cff60e
parent4208d524b1b39f9b86458263e85382c562b813ba (diff)
Keypair: Create class for generating/storing keys
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--app/src/main/java/com/wireguard/crypto/Keypair.java65
1 files changed, 65 insertions, 0 deletions
diff --git a/app/src/main/java/com/wireguard/crypto/Keypair.java b/app/src/main/java/com/wireguard/crypto/Keypair.java
new file mode 100644
index 00000000..ef2a4b31
--- /dev/null
+++ b/app/src/main/java/com/wireguard/crypto/Keypair.java
@@ -0,0 +1,65 @@
+package com.wireguard.crypto;
+
+import android.util.Base64;
+
+import java.security.SecureRandom;
+
+/**
+ * Represents a Curve25519 keypair as used by WireGuard.
+ */
+
+public class Keypair {
+ private static final int KEY_LENGTH = 32;
+ public static final int KEY_STRING_LENGTH = 44;
+
+ private static byte[] generatePrivateKey() {
+ final SecureRandom secureRandom = new SecureRandom();
+ final byte privateKey[] = new byte[KEY_LENGTH];
+ secureRandom.nextBytes(privateKey);
+ privateKey[0] &= 248;
+ privateKey[31] &= 127;
+ privateKey[31] |= 64;
+ return privateKey;
+ }
+
+ private static byte[] generatePublicKey(byte privateKey[]) {
+ final byte publicKey[] = new byte[KEY_LENGTH];
+ Curve25519.eval(publicKey, 0, privateKey, null);
+ return publicKey;
+ }
+
+ private static byte[] parseKey(String key) {
+ final byte keyBytes[] = Base64.decode(key, Base64.NO_WRAP);
+ if (keyBytes.length != KEY_LENGTH)
+ throw new IndexOutOfBoundsException("Key is not the correct length");
+ return keyBytes;
+ }
+
+ private static String unParseKey(byte keyBytes[]) {
+ return Base64.encodeToString(keyBytes, Base64.NO_WRAP);
+ }
+
+ private final byte privateKey[];
+ private final byte publicKey[];
+
+ public Keypair() {
+ this(generatePrivateKey());
+ }
+
+ private Keypair(byte privateKey[]) {
+ this.privateKey = privateKey;
+ publicKey = generatePublicKey(privateKey);
+ }
+
+ public Keypair(String privateKey) {
+ this(parseKey(privateKey));
+ }
+
+ public String getPrivateKey() {
+ return unParseKey(privateKey);
+ }
+
+ public String getPublicKey() {
+ return unParseKey(publicKey);
+ }
+}