diff --git a/core/java/src/net/i2p/crypto/KeyGenerator.java b/core/java/src/net/i2p/crypto/KeyGenerator.java index 957b6120a..4297fcae2 100644 --- a/core/java/src/net/i2p/crypto/KeyGenerator.java +++ b/core/java/src/net/i2p/crypto/KeyGenerator.java @@ -34,6 +34,7 @@ import net.i2p.I2PAppContext; import net.i2p.crypto.eddsa.EdDSAPrivateKey; import net.i2p.crypto.eddsa.EdDSAPublicKey; import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec; +import net.i2p.crypto.provider.I2PProvider; import net.i2p.data.Hash; import net.i2p.data.PrivateKey; import net.i2p.data.PublicKey; @@ -58,6 +59,10 @@ import net.i2p.util.RandomSource; public final class KeyGenerator { private final I2PAppContext _context; + static { + I2PProvider.addProvider(); + } + public KeyGenerator(I2PAppContext context) { _context = context; } diff --git a/core/java/src/net/i2p/crypto/KeyStoreUtil.java b/core/java/src/net/i2p/crypto/KeyStoreUtil.java index 40e597b93..1de4687de 100644 --- a/core/java/src/net/i2p/crypto/KeyStoreUtil.java +++ b/core/java/src/net/i2p/crypto/KeyStoreUtil.java @@ -9,7 +9,6 @@ import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.PrivateKey; -import java.security.Security; import java.security.cert.Certificate; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; @@ -43,11 +42,7 @@ public final class KeyStoreUtil { private static final int DEFAULT_KEY_VALID_DAYS = 3652; // 10 years static { - try { - Security.addProvider(new I2PProvider()); - } catch (SecurityException se) { - System.out.println("WARN: Could not install I2P provider: " + se); - } + I2PProvider.addProvider(); } /** @@ -490,7 +485,7 @@ public final class KeyStoreUtil { a.add("-sigalg"); a.add(getSigAlg(keySize, keyAlg)); a.add("-keysize"); a.add(Integer.toString(keySize)); a.add("-keypass"); a.add(keyPW); - if (keyAlg.equals("Ed") || keyAlg.equals("EdDSA")) { + if (keyAlg.equals("Ed") || keyAlg.equals("EdDSA") || keyAlg.equals("ElGamal")) { File f = I2PAppContext.getGlobalContext().getBaseDir(); f = new File(f, "lib"); f = new File(f, "i2p.jar"); @@ -838,13 +833,15 @@ public final class KeyStoreUtil { String alias = args[2]; String pw = args[3]; boolean ok = createKeys(ksf, DEFAULT_KEYSTORE_PASSWORD, alias, "test cname", "test ou", - DEFAULT_KEY_VALID_DAYS, "EdDSA", 256, pw); + //DEFAULT_KEY_VALID_DAYS, "EdDSA", 256, pw); + DEFAULT_KEY_VALID_DAYS, "ElGamal", 2048, pw); System.out.println("genkey ok? " + ok); } private static void testKeygen2(String[] args) throws Exception { // keygen test using the I2PProvider - SigType type = SigType.EdDSA_SHA512_Ed25519; + //SigType type = SigType.EdDSA_SHA512_Ed25519; + SigType type = SigType.ElGamal_SHA256_MODP2048; java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName()); kpg.initialize(type.getParams()); java.security.KeyPair kp = kpg.generateKeyPair(); @@ -856,10 +853,20 @@ public final class KeyStoreUtil { System.out.println("Encoded public key:"); System.out.println(net.i2p.util.HexDump.dump(jpub.getEncoded())); - java.security.Signature jsig = java.security.Signature.getInstance("SHA512withEdDSA"); + java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName()); jsig.initSign(jpriv); - jsig.update(new byte[111]); - net.i2p.data.Signature sig = SigUtil.fromJavaSig(jsig.sign(), type); + byte[] data = new byte[111]; + net.i2p.util.RandomSource.getInstance().nextBytes(data); + jsig.update(data); + byte[] bsig = jsig.sign(); + System.out.println("Encoded signature:"); + System.out.println(net.i2p.util.HexDump.dump(bsig)); + jsig.initVerify(jpub); + jsig.update(data); + boolean ok = jsig.verify(bsig); + System.out.println("verify passed? " + ok); + + net.i2p.data.Signature sig = SigUtil.fromJavaSig(bsig, type); System.out.println("Signature test: " + sig); } ****/ diff --git a/core/java/src/net/i2p/crypto/SigAlgo.java b/core/java/src/net/i2p/crypto/SigAlgo.java index 8e0523c1b..1195df148 100644 --- a/core/java/src/net/i2p/crypto/SigAlgo.java +++ b/core/java/src/net/i2p/crypto/SigAlgo.java @@ -10,7 +10,15 @@ public enum SigAlgo { DSA("DSA"), EC("EC"), EdDSA("EdDSA"), - RSA("RSA") + /** + * For local use only, not for use in the network. + */ + RSA("RSA"), + /** + * For local use only, not for use in the network. + * @since 0.9.25 + */ + ElGamal("ElGamal") ; private final String name; diff --git a/core/java/src/net/i2p/crypto/provider/I2PProvider.java b/core/java/src/net/i2p/crypto/provider/I2PProvider.java index e64bb1d43..f60284a3e 100644 --- a/core/java/src/net/i2p/crypto/provider/I2PProvider.java +++ b/core/java/src/net/i2p/crypto/provider/I2PProvider.java @@ -3,6 +3,7 @@ package net.i2p.crypto.provider; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.Provider; +import java.security.Security; /** * @since 0.9.15 @@ -11,6 +12,7 @@ public final class I2PProvider extends Provider { public static final String PROVIDER_NAME = "I2P"; private static final String INFO = "I2P Security Provider v0.1, implementing" + "several algorithms used by I2P."; + private static boolean _installed; /** * Construct a new provider. This should only be required when @@ -78,4 +80,33 @@ public final class I2PProvider extends Provider { put("Alg.Alias.Signature.1.3.14.7.2.1.1", "SHA256withElGamal"); put("Alg.Alias.Signature.OID.1.3.14.7.2.1.1", "SHA256withElGamal"); } + + /** + * Install the I2PProvider. + * Harmless to call multiple times. + * @since 0.9.25 + */ + public static void addProvider() { + synchronized(I2PProvider.class) { + if (!_installed) { + try { + Provider us = new I2PProvider(); + // put ours ahead of BC, if installed, because our ElGamal + // implementation may not be fully compatible with BC + Provider[] provs = Security.getProviders(); + for (int i = 0; i < provs.length; i++) { + if (provs[i].getName().equals("BC")) { + Security.insertProviderAt(us, i); + _installed = true; + return; + } + } + Security.addProvider(us); + _installed = true; + } catch (SecurityException se) { + System.out.println("WARN: Could not install I2P provider: " + se); + } + } + } + } }