From 23534b31c6c7ba65a9eaa0bd3f6c27d6af19343f Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 14 Dec 2014 17:52:23 +0000 Subject: [PATCH] SU3File: Infer SigType from private key when signing, Change default to RSA 4096 SigUtil: Add conversion methods for Java keys with unknown types --- core/java/src/net/i2p/crypto/SU3File.java | 7 +- core/java/src/net/i2p/crypto/SigUtil.java | 99 +++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/core/java/src/net/i2p/crypto/SU3File.java b/core/java/src/net/i2p/crypto/SU3File.java index bd9281b2b..0f0b6efd3 100644 --- a/core/java/src/net/i2p/crypto/SU3File.java +++ b/core/java/src/net/i2p/crypto/SU3File.java @@ -126,7 +126,7 @@ public class SU3File { private static final ContentType DEFAULT_CONTENT_TYPE = ContentType.UNKNOWN; // avoid early ctx init //private static final SigType DEFAULT_SIG_TYPE = SigType.DSA_SHA1; - private static final int DEFAULT_SIG_CODE = 0; + private static final int DEFAULT_SIG_CODE = 6; /** * @@ -826,6 +826,11 @@ public class SU3File { System.out.println("Private key for " + signerName + " not found in keystore " + privateKeyFile); return false; } + // now fix the sig type based on the private key + SigType oldType = type; + type = SigUtil.fromJavaKey(pk).getType(); + if (oldType != type) + System.out.println("Warning: Using private key type " + type + ", ignoring specified type " + oldType); SU3File file = new SU3File(signedFile); file.write(new File(inputFile), ftype, ctype.getCode(), version, signerName, pk, type); System.out.println("Input file '" + inputFile + "' signed and written to '" + signedFile + "'"); diff --git a/core/java/src/net/i2p/crypto/SigUtil.java b/core/java/src/net/i2p/crypto/SigUtil.java index c492dc663..d04abb438 100644 --- a/core/java/src/net/i2p/crypto/SigUtil.java +++ b/core/java/src/net/i2p/crypto/SigUtil.java @@ -18,6 +18,7 @@ import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; +import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.ECParameterSpec; @@ -97,6 +98,55 @@ public class SigUtil { } /** + * Use if SigType is unknown. + * For efficiency, use fromJavakey(pk, type) if type is known. + * + * @param pk JAVA key! + * @throws IllegalArgumentException on unknown type + * @since 0.9.18 + */ + public static SigningPublicKey fromJavaKey(PublicKey pk) + throws GeneralSecurityException { + if (pk instanceof DSAPublicKey) { + return fromJavaKey((DSAPublicKey) pk); + } + if (pk instanceof ECPublicKey) { + ECPublicKey k = (ECPublicKey) pk; + AlgorithmParameterSpec spec = k.getParams(); + SigType type; + if (spec.equals(SigType.ECDSA_SHA256_P256.getParams())) + type = SigType.ECDSA_SHA256_P256; + else if (spec.equals(SigType.ECDSA_SHA384_P384.getParams())) + type = SigType.ECDSA_SHA384_P384; + else if (spec.equals(SigType.ECDSA_SHA512_P521.getParams())) + type = SigType.ECDSA_SHA512_P521; + else + throw new IllegalArgumentException("Unknown EC type"); + return fromJavaKey(k, type); + } + if (pk instanceof EdDSAPublicKey) { + return fromJavaKey((EdDSAPublicKey) pk, SigType.EdDSA_SHA512_Ed25519); + } + if (pk instanceof RSAPublicKey) { + RSAPublicKey k = (RSAPublicKey) pk; + int sz = k.getModulus().bitLength(); + SigType type; + if (sz <= ((RSAKeyGenParameterSpec) SigType.RSA_SHA256_2048.getParams()).getKeysize()) + type = SigType.RSA_SHA256_2048; + else if (sz <= ((RSAKeyGenParameterSpec) SigType.RSA_SHA384_3072.getParams()).getKeysize()) + type = SigType.RSA_SHA384_3072; + else if (sz <= ((RSAKeyGenParameterSpec) SigType.RSA_SHA512_4096.getParams()).getKeysize()) + type = SigType.RSA_SHA512_4096; + else + throw new IllegalArgumentException("Unknown RSA type"); + return fromJavaKey(k, type); + } + throw new IllegalArgumentException("Unknown type"); + } + + /** + * Use if SigType is known. + * * @param pk JAVA key! */ public static SigningPublicKey fromJavaKey(PublicKey pk, SigType type) @@ -116,6 +166,55 @@ public class SigUtil { } /** + * Use if SigType is unknown. + * For efficiency, use fromJavakey(pk, type) if type is known. + * + * @param pk JAVA key! + * @throws IllegalArgumentException on unknown type + * @since 0.9.18 + */ + public static SigningPrivateKey fromJavaKey(PrivateKey pk) + throws GeneralSecurityException { + if (pk instanceof DSAPrivateKey) { + return fromJavaKey((DSAPrivateKey) pk); + } + if (pk instanceof ECPrivateKey) { + ECPrivateKey k = (ECPrivateKey) pk; + AlgorithmParameterSpec spec = k.getParams(); + SigType type; + if (spec.equals(SigType.ECDSA_SHA256_P256.getParams())) + type = SigType.ECDSA_SHA256_P256; + else if (spec.equals(SigType.ECDSA_SHA384_P384.getParams())) + type = SigType.ECDSA_SHA384_P384; + else if (spec.equals(SigType.ECDSA_SHA512_P521.getParams())) + type = SigType.ECDSA_SHA512_P521; + else + throw new IllegalArgumentException("Unknown EC type"); + return fromJavaKey(k, type); + } + if (pk instanceof EdDSAPrivateKey) { + return fromJavaKey((EdDSAPrivateKey) pk, SigType.EdDSA_SHA512_Ed25519); + } + if (pk instanceof RSAPrivateKey) { + RSAPrivateKey k = (RSAPrivateKey) pk; + int sz = k.getModulus().bitLength(); + SigType type; + if (sz <= ((RSAKeyGenParameterSpec) SigType.RSA_SHA256_2048.getParams()).getKeysize()) + type = SigType.RSA_SHA256_2048; + else if (sz <= ((RSAKeyGenParameterSpec) SigType.RSA_SHA384_3072.getParams()).getKeysize()) + type = SigType.RSA_SHA384_3072; + else if (sz <= ((RSAKeyGenParameterSpec) SigType.RSA_SHA512_4096.getParams()).getKeysize()) + type = SigType.RSA_SHA512_4096; + else + throw new IllegalArgumentException("Unknown RSA type"); + return fromJavaKey(k, type); + } + throw new IllegalArgumentException("Unknown type"); + } + + /** + * Use if SigType is known. + * * @param pk JAVA key! */ public static SigningPrivateKey fromJavaKey(PrivateKey pk, SigType type)