diff --git a/core/java/src/net/i2p/crypto/KeyStoreUtil.java b/core/java/src/net/i2p/crypto/KeyStoreUtil.java index 19530cdcee..95e0c41b20 100644 --- a/core/java/src/net/i2p/crypto/KeyStoreUtil.java +++ b/core/java/src/net/i2p/crypto/KeyStoreUtil.java @@ -315,10 +315,11 @@ public class KeyStoreUtil { "-dname", "CN=" + cname + ",OU=" + ou + ",O=I2P Anonymous Network,L=XX,ST=XX,C=XX", "-validity", Integer.toString(validDays), // 10 years "-keyalg", keyAlg, + "-sigalg", getSigAlg(keySize, keyAlg), "-keysize", Integer.toString(keySize), "-keypass", keyPW }; - boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 30); // 30 secs + boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 240); if (success) { success = ks.exists(); } @@ -335,6 +336,30 @@ public class KeyStoreUtil { return success; } + private static String getSigAlg(int size, String keyalg) { + if (keyalg.equals("EC")) + keyalg = "ECDSA"; + String hash; + if (keyalg.equals("ECDSA")) { + if (size <= 256) + hash = "SHA256"; + else if (size <= 384) + hash = "SHA384"; + else + hash = "SHA512"; + } else { + if (size <= 1024) + hash = "SHA1"; + else if (size <= 2048) + hash = "SHA256"; + else if (size <= 3072) + hash = "SHA384"; + else + hash = "SHA512"; + } + return hash + "with" + keyalg; + } + /** * Get a private key out of a keystore * diff --git a/core/java/src/net/i2p/crypto/RSAConstants.java b/core/java/src/net/i2p/crypto/RSAConstants.java new file mode 100644 index 0000000000..3f77d09f19 --- /dev/null +++ b/core/java/src/net/i2p/crypto/RSAConstants.java @@ -0,0 +1,29 @@ +package net.i2p.crypto; + +import java.math.BigInteger; +import java.security.spec.RSAKeyGenParameterSpec; + +import net.i2p.util.NativeBigInteger; + +/** + * Constants for RSA + * + * @since 0.9.9 + */ +class RSAConstants { + + /** + * Generate a spec + */ + private static RSAKeyGenParameterSpec genSpec(int size, BigInteger exp) { + return new RSAKeyGenParameterSpec(size, exp); + } + + private static final BigInteger F4 = new NativeBigInteger(RSAKeyGenParameterSpec.F4); + + // standard specs + public static final RSAKeyGenParameterSpec F4_1024_SPEC = genSpec(1024, F4); + public static final RSAKeyGenParameterSpec F4_2048_SPEC = genSpec(2048, F4); + public static final RSAKeyGenParameterSpec F4_3072_SPEC = genSpec(3072, F4); + public static final RSAKeyGenParameterSpec F4_4096_SPEC = genSpec(4096, F4); +} diff --git a/core/java/src/net/i2p/crypto/SU3File.java b/core/java/src/net/i2p/crypto/SU3File.java index f5e25f1b08..630ca2a038 100644 --- a/core/java/src/net/i2p/crypto/SU3File.java +++ b/core/java/src/net/i2p/crypto/SU3File.java @@ -385,6 +385,8 @@ public class SU3File { SimpleDataStructure hash = sigType.getHashInstance(); hash.setData(sha); Signature signature = _context.dsa().sign(hash, privkey, sigType); + if (signature == null) + throw new IOException("sig fail"); //System.out.println("hash\n" + HexDump.dump(sha)); //System.out.println("sig\n" + HexDump.dump(signature.getData())); signature.writeBytes(out); diff --git a/core/java/src/net/i2p/crypto/SigType.java b/core/java/src/net/i2p/crypto/SigType.java index 94f726da06..82ba8c4bd7 100644 --- a/core/java/src/net/i2p/crypto/SigType.java +++ b/core/java/src/net/i2p/crypto/SigType.java @@ -54,6 +54,11 @@ public enum SigType { ECDSA_SHA256_K409(15, 104, 52, 32, 104, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.K409_SPEC), ECDSA_SHA256_K571(16, 144, 72, 32, 144, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.K571_SPEC), + RSA_SHA1(17, 128, 256, 20, 128, SigAlgo.RSA, "SHA-1", "SHA1withRSA", RSAConstants.F4_1024_SPEC), + RSA_SHA256(18, 256, 512, 32, 256, SigAlgo.RSA, "SHA-256", "SHA256withRSA", RSAConstants.F4_2048_SPEC), + RSA_SHA384(19, 384, 768, 48, 384, SigAlgo.RSA, "SHA-384", "SHA2384ithRSA", RSAConstants.F4_3072_SPEC), + RSA_SHA512(20, 512, 1024, 64, 512, SigAlgo.RSA, "SHA-512", "SHA512withRSA", RSAConstants.F4_4096_SPEC), + //MD5 //ELGAMAL_SHA256 //RSA_SHA1 diff --git a/core/java/src/net/i2p/crypto/SigUtil.java b/core/java/src/net/i2p/crypto/SigUtil.java index 99525c7f96..58471376e6 100644 --- a/core/java/src/net/i2p/crypto/SigUtil.java +++ b/core/java/src/net/i2p/crypto/SigUtil.java @@ -31,6 +31,7 @@ import java.security.spec.ECPoint; import java.security.spec.EllipticCurve; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; @@ -169,8 +170,8 @@ class SigUtil { byte[] by = new byte[sublen]; System.arraycopy(b, 0, bx, 0, sublen); System.arraycopy(b, sublen, by, 0, sublen); - BigInteger x = new BigInteger(1, bx); - BigInteger y = new BigInteger(1, by); + BigInteger x = new NativeBigInteger(1, bx); + BigInteger y = new NativeBigInteger(1, by); ECPoint w = new ECPoint(x, y); // see ECConstants re: casting ECPublicKeySpec ks = new ECPublicKeySpec(w, (ECParameterSpec) type.getParams()); @@ -184,7 +185,7 @@ class SigUtil { int len = type.getPubkeyLen(); int sublen = len / 2; byte[] b = pk.getData(); - BigInteger s = new BigInteger(1, b); + BigInteger s = new NativeBigInteger(1, b); // see ECConstants re: casting ECPrivateKeySpec ks = new ECPrivateKeySpec(s, (ECParameterSpec) type.getParams()); KeyFactory kf = KeyFactory.getInstance("EC"); @@ -254,42 +255,71 @@ class SigUtil { return new SigningPrivateKey(type, bx); } + /** + * @deprecated unused + */ public static RSAPublicKey toJavaRSAKey(SigningPublicKey pk) throws GeneralSecurityException { + SigType type = pk.getType(); KeyFactory kf = KeyFactory.getInstance("RSA"); + BigInteger n = new NativeBigInteger(1, pk.getData()); + BigInteger e = ((RSAKeyGenParameterSpec)type.getParams()).getPublicExponent(); // modulus exponent - KeySpec ks = new RSAPublicKeySpec(null, null); // FIXME + KeySpec ks = new RSAPublicKeySpec(n, e); return (RSAPublicKey) kf.generatePublic(ks); } + /** + * @deprecated unimplemented, unused + */ public static RSAPrivateKey toJavaRSAKey(SigningPrivateKey pk) throws GeneralSecurityException { + /* KeyFactory kf = KeyFactory.getInstance("RSA"); + // private key is modulus (pubkey) + exponent + // get each part like in EC + BigInteger n = new NativeBigInteger(1, ...); + BigInteger d = new NativeBigInteger(1, ...); // modulus exponent - KeySpec ks = new RSAPrivateKeySpec(null, null); // FIXME + KeySpec ks = new RSAPrivateKeySpec(n, d); // 65537 0x10001 return (RSAPrivateKey) kf.generatePrivate(ks); + */ + throw new UnsupportedOperationException(); } + /** + * @deprecated unused + */ public static SigningPublicKey fromJavaKey(RSAPublicKey pk, SigType type) throws GeneralSecurityException { - BigInteger y = pk.getPublicExponent(); + BigInteger n = pk.getModulus(); int len = type.getPubkeyLen(); - byte[] by = rectify(y, len); - return new SigningPublicKey(type, by); + byte[] bn = rectify(n, len); + return new SigningPublicKey(type, bn); } + /** + * @deprecated unimplemented, unused + */ public static SigningPrivateKey fromJavaKey(RSAPrivateKey pk, SigType type) throws GeneralSecurityException { - BigInteger x = pk.getPrivateExponent(); - int len = type.getPrivkeyLen(); - byte[] bx = rectify(x, len); + /* + // private key is modulus (pubkey) + exponent + BigInteger n = pk.getModulus(); + BigInteger d = pk.getPrivateExponent(); + // put them together like in EC return new SigningPrivateKey(type, bx); + */ + throw new UnsupportedOperationException(); } /** * @return ASN.1 representation */ public static byte[] toJavaSig(Signature sig) { + // RSA sigs are not ASN encoded + if (sig.getType().getBaseAlgorithm() == SigAlgo.RSA) + return sig.getData(); return sigBytesToASN1(sig.getData()); } @@ -299,6 +329,9 @@ class SigUtil { */ public static Signature fromJavaSig(byte[] asn, SigType type) throws SignatureException { + // RSA sigs are not ASN encoded + if (type.getBaseAlgorithm() == SigAlgo.RSA) + return new Signature(type, asn); return new Signature(type, aSN1ToSigBytes(asn, type.getSigLen())); }