diff options
author | Samuel Holland <samuel@sholland.org> | 2018-12-13 21:30:38 -0600 |
---|---|---|
committer | Samuel Holland <samuel@sholland.org> | 2018-12-15 14:46:23 -0600 |
commit | dcb0e9b3e8643bc73a67c874b9add72cc0ee8f6e (patch) | |
tree | e0f720a7315a60827d19daa8ee155f09eab61586 /app/src/main/java/com/wireguard/crypto | |
parent | 3497882ea6ae74ef6da0984a21398963624e9561 (diff) |
Provide semantically meaningful exceptions for translation
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'app/src/main/java/com/wireguard/crypto')
-rw-r--r-- | app/src/main/java/com/wireguard/crypto/Key.java | 62 | ||||
-rw-r--r-- | app/src/main/java/com/wireguard/crypto/KeyFormatException.java | 34 | ||||
-rw-r--r-- | app/src/main/java/com/wireguard/crypto/KeyPair.java | 34 |
3 files changed, 74 insertions, 56 deletions
diff --git a/app/src/main/java/com/wireguard/crypto/Key.java b/app/src/main/java/com/wireguard/crypto/Key.java index 85146794..ded9941e 100644 --- a/app/src/main/java/com/wireguard/crypto/Key.java +++ b/app/src/main/java/com/wireguard/crypto/Key.java @@ -5,6 +5,9 @@ package com.wireguard.crypto; +import com.wireguard.crypto.KeyFormatException.Type; + +import java.security.SecureRandom; import java.util.Arrays; /** @@ -83,10 +86,10 @@ public final class Key { * @param str the base64 string representation of a WireGuard key * @return the decoded key encapsulated in an immutable container */ - public static Key fromBase64(final String str) { + public static Key fromBase64(final String str) throws KeyFormatException { final char[] input = str.toCharArray(); if (input.length != Format.BASE64.length || input[Format.BASE64.length - 1] != '=') - throw new KeyFormatException(Format.BASE64); + throw new KeyFormatException(Format.BASE64, Type.LENGTH); final byte[] key = new byte[Format.BINARY.length]; int i; int ret = 0; @@ -109,7 +112,7 @@ public final class Key { key[i * 3 + 1] = (byte) ((val >>> 8) & 0xff); if (ret != 0) - throw new KeyFormatException(Format.BASE64); + throw new KeyFormatException(Format.BASE64, Type.CONTENTS); return new Key(key); } @@ -120,9 +123,9 @@ public final class Key { * @param bytes an array of bytes containing a WireGuard key in binary format * @return the key encapsulated in an immutable container */ - public static Key fromBytes(final byte[] bytes) { + public static Key fromBytes(final byte[] bytes) throws KeyFormatException { if (bytes.length != Format.BINARY.length) - throw new KeyFormatException(Format.BINARY); + throw new KeyFormatException(Format.BINARY, Type.LENGTH); return new Key(bytes); } @@ -133,10 +136,10 @@ public final class Key { * @param str the hexadecimal string representation of a WireGuard key * @return the decoded key encapsulated in an immutable container */ - public static Key fromHex(final String str) { + public static Key fromHex(final String str) throws KeyFormatException { final char[] input = str.toCharArray(); if (input.length != Format.HEX.length) - throw new KeyFormatException(Format.HEX); + throw new KeyFormatException(Format.HEX, Type.LENGTH); final byte[] key = new byte[Format.BINARY.length]; int ret = 0; for (int i = 0; i < key.length; ++i) { @@ -167,11 +170,38 @@ public final class Key { key[i] = (byte) (cAcc | cVal); } if (ret != 0) - throw new KeyFormatException(Format.HEX); + throw new KeyFormatException(Format.HEX, Type.CONTENTS); return new Key(key); } /** + * Generates a private key using the system's {@link SecureRandom} number generator. + * + * @return a well-formed random private key + */ + static Key generatePrivateKey() { + final SecureRandom secureRandom = new SecureRandom(); + final byte[] privateKey = new byte[Format.BINARY.getLength()]; + secureRandom.nextBytes(privateKey); + privateKey[0] &= 248; + privateKey[31] &= 127; + privateKey[31] |= 64; + return new Key(privateKey); + } + + /** + * Generates a public key from an existing private key. + * + * @param privateKey a private key + * @return a well-formed public key that corresponds to the supplied private key + */ + static Key generatePublicKey(final Key privateKey) { + final byte[] publicKey = new byte[Format.BINARY.getLength()]; + Curve25519.eval(publicKey, 0, privateKey.getBytes(), null); + return new Key(publicKey); + } + + /** * Returns the key as an array of bytes. * * @return an array of bytes containing the raw binary key @@ -236,20 +266,4 @@ public final class Key { } } - /** - * An exception thrown when attempting to parse an invalid key (too short, too long, or byte - * data inappropriate for the format). The format being parsed can be accessed with the - * {@link #getFormat} method. - */ - public static final class KeyFormatException extends RuntimeException { - private final Format format; - - private KeyFormatException(final Format format) { - this.format = format; - } - - public Format getFormat() { - return format; - } - } } diff --git a/app/src/main/java/com/wireguard/crypto/KeyFormatException.java b/app/src/main/java/com/wireguard/crypto/KeyFormatException.java new file mode 100644 index 00000000..b44297d1 --- /dev/null +++ b/app/src/main/java/com/wireguard/crypto/KeyFormatException.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2018 WireGuard LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.wireguard.crypto; + +/** + * An exception thrown when attempting to parse an invalid key (too short, too long, or byte + * data inappropriate for the format). The format being parsed can be accessed with the + * {@link #getFormat} method. + */ +public final class KeyFormatException extends Exception { + private final Key.Format format; + private final Type type; + + KeyFormatException(final Key.Format format, final Type type) { + this.format = format; + this.type = type; + } + + public Key.Format getFormat() { + return format; + } + + public Type getType() { + return type; + } + + public enum Type { + CONTENTS, + LENGTH + } +} diff --git a/app/src/main/java/com/wireguard/crypto/KeyPair.java b/app/src/main/java/com/wireguard/crypto/KeyPair.java index 2b2bf564..2e771edc 100644 --- a/app/src/main/java/com/wireguard/crypto/KeyPair.java +++ b/app/src/main/java/com/wireguard/crypto/KeyPair.java @@ -5,8 +5,6 @@ package com.wireguard.crypto; -import java.security.SecureRandom; - /** * Represents a Curve25519 key pair as used by WireGuard. * <p> @@ -20,7 +18,7 @@ public class KeyPair { * Creates a key pair using a newly-generated private key. */ public KeyPair() { - this(generatePrivateKey()); + this(Key.generatePrivateKey()); } /** @@ -30,35 +28,7 @@ public class KeyPair { */ public KeyPair(final Key privateKey) { this.privateKey = privateKey; - publicKey = generatePublicKey(privateKey); - } - - /** - * Generates a private key using the system's {@link SecureRandom} number generator. - * - * @return a well-formed random private key - */ - @SuppressWarnings("MagicNumber") - private static Key generatePrivateKey() { - final SecureRandom secureRandom = new SecureRandom(); - final byte[] privateKey = new byte[Key.Format.BINARY.getLength()]; - secureRandom.nextBytes(privateKey); - privateKey[0] &= 248; - privateKey[31] &= 127; - privateKey[31] |= 64; - return Key.fromBytes(privateKey); - } - - /** - * Generates a public key from an existing private key. - * - * @param privateKey a private key - * @return a well-formed public key that corresponds to the supplied private key - */ - private static Key generatePublicKey(final Key privateKey) { - final byte[] publicKey = new byte[Key.Format.BINARY.getLength()]; - Curve25519.eval(publicKey, 0, privateKey.getBytes(), null); - return Key.fromBytes(publicKey); + publicKey = Key.generatePublicKey(privateKey); } /** |