From ee57bd7363460b1ad3d2fee51159e68a6a45ad14 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Sat, 13 Oct 2018 10:39:20 +0000 Subject: [PATCH] Data: Add encryption types for PublicKey, PrivateKey --- core/java/src/net/i2p/data/PrivateKey.java | 63 +++++++++++++++++++--- core/java/src/net/i2p/data/PublicKey.java | 59 +++++++++++++++++++- 2 files changed, 114 insertions(+), 8 deletions(-) diff --git a/core/java/src/net/i2p/data/PrivateKey.java b/core/java/src/net/i2p/data/PrivateKey.java index 163edcc3f5..5eafbbd8ae 100644 --- a/core/java/src/net/i2p/data/PrivateKey.java +++ b/core/java/src/net/i2p/data/PrivateKey.java @@ -11,6 +11,7 @@ package net.i2p.data; import java.util.Arrays; +import net.i2p.crypto.EncType; import net.i2p.crypto.KeyGenerator; /** @@ -18,20 +19,42 @@ import net.i2p.crypto.KeyGenerator; * A private key is 256byte Integer. The private key represents only the * exponent, not the primes, which are constant and defined in the crypto spec. * - * Note that we use short exponents, so all but the last 28.25 bytes are zero. - * See http://www.i2p2.i2p/how_cryptography for details. + * As of release 0.9.38, keys of arbitrary length and type are supported. + * See EncType. * * @author jrandom */ public class PrivateKey extends SimpleDataStructure { - public final static int KEYSIZE_BYTES = 256; + private static final EncType DEF_TYPE = EncType.ELGAMAL_2048; + public final static int KEYSIZE_BYTES = DEF_TYPE.getPrivkeyLen(); + + private final EncType _type; public PrivateKey() { + this(DEF_TYPE); + } + + /** + * @param type non-null + * @since 0.9.38 + */ + public PrivateKey(EncType type) { super(); + _type = type; } public PrivateKey(byte data[]) { + this(DEF_TYPE, data); + } + + /** + * @param type non-null + * @param data must be non-null + * @since 0.9.38 + */ + public PrivateKey(EncType type, byte data[]) { super(data); + _type = type; } /** constructs from base64 @@ -39,12 +62,20 @@ public class PrivateKey extends SimpleDataStructure { * on a prior instance of PrivateKey */ public PrivateKey(String base64Data) throws DataFormatException { - super(); + this(DEF_TYPE); fromBase64(base64Data); } public int length() { - return KEYSIZE_BYTES; + return _type.getPrivkeyLen(); + } + + /** + * @return non-null + * @since 0.9.38 + */ + public EncType getType() { + return _type; } /** derives a new PublicKey object derived from the secret contents @@ -56,6 +87,23 @@ public class PrivateKey extends SimpleDataStructure { return KeyGenerator.getPublicKey(this); } + /** + * @since 0.9.38 + */ + @Override + public String toString() { + StringBuilder buf = new StringBuilder(64); + buf.append("[PrivateKey ").append(_type).append(": "); + int length = length(); + if (_data == null) { + buf.append("null"); + } else { + buf.append("size: ").append(length); + } + buf.append(']'); + return buf.toString(); + } + /** * We assume the data has enough randomness in it, so use the last 4 bytes for speed. * Overridden since we use short exponents, so the first 227 bytes are all zero. @@ -64,6 +112,8 @@ public class PrivateKey extends SimpleDataStructure { public int hashCode() { if (_data == null) return 0; + if (_type != DEF_TYPE) + return DataHelper.hashCode(_data); int rv = _data[KEYSIZE_BYTES - 4]; for (int i = 1; i < 4; i++) rv ^= (_data[i + (KEYSIZE_BYTES - 4)] << (i*8)); @@ -74,6 +124,7 @@ public class PrivateKey extends SimpleDataStructure { public boolean equals(Object obj) { if (obj == this) return true; if ((obj == null) || !(obj instanceof PrivateKey)) return false; - return Arrays.equals(_data, ((PrivateKey) obj)._data); + PrivateKey p = (PrivateKey) obj; + return _type == p._type && Arrays.equals(_data, p._data); } } diff --git a/core/java/src/net/i2p/data/PublicKey.java b/core/java/src/net/i2p/data/PublicKey.java index 874e65e353..cf2bae7692 100644 --- a/core/java/src/net/i2p/data/PublicKey.java +++ b/core/java/src/net/i2p/data/PublicKey.java @@ -12,19 +12,27 @@ package net.i2p.data; import java.io.InputStream; import java.io.IOException; +import net.i2p.crypto.EncType; + /** * Defines the PublicKey as defined by the I2P data structure spec. * A public key is 256byte Integer. The public key represents only the * exponent, not the primes, which are constant and defined in the crypto spec. * + * As of release 0.9.38, keys of arbitrary length and type are supported. + * See EncType. + * * @author jrandom */ public class PublicKey extends SimpleDataStructure { - public final static int KEYSIZE_BYTES = 256; + private static final EncType DEF_TYPE = EncType.ELGAMAL_2048; + public final static int KEYSIZE_BYTES = DEF_TYPE.getPubkeyLen(); private static final int CACHE_SIZE = 1024; private static final SDSCache<PublicKey> _cache = new SDSCache<PublicKey>(PublicKey.class, KEYSIZE_BYTES, CACHE_SIZE); + private final EncType _type; + /** * Pull from cache or return new. * Deprecated - used only by deprecated Destination.readBytes(data, off) @@ -45,12 +53,31 @@ public class PublicKey extends SimpleDataStructure { } public PublicKey() { + this(DEF_TYPE); + } + + /** + * @param type if null, type is unknown + * @since 0.9.38 + */ + public PublicKey(EncType type) { super(); + _type = type; } /** @param data must be non-null */ public PublicKey(byte data[]) { + this(DEF_TYPE, data); + } + + /** + * @param type if null, type is unknown + * @param data must be non-null + * @since 0.9.38 + */ + public PublicKey(EncType type, byte data[]) { super(); + _type = type; if (data == null) throw new IllegalArgumentException("Data must be specified"); _data = data; @@ -61,18 +88,46 @@ public class PublicKey extends SimpleDataStructure { * on a prior instance of PublicKey */ public PublicKey(String base64Data) throws DataFormatException { - super(); + this(DEF_TYPE); fromBase64(base64Data); } public int length() { + if (_type != null) + return _type.getPubkeyLen(); + if (_data != null) + return _data.length; return KEYSIZE_BYTES; } + /** + * @return null if unknown + * @since 0.9.38 + */ + public EncType getType() { + return _type; + } + /** * @since 0.9.17 */ public static void clearCache() { _cache.clear(); } + + /** + * @since 0.9.38 + */ + @Override + public String toString() { + StringBuilder buf = new StringBuilder(64); + buf.append("[PublicKey ").append((_type != null) ? _type.toString() : "unknown type").append(' '); + if (_data == null) { + buf.append("null"); + } else { + buf.append("size: ").append(length()); + } + buf.append(']'); + return buf.toString(); + } } -- GitLab