- KeyPairGen: Catch ProviderException, fallback to BC provider

This commit is contained in:
zzz
2013-09-06 13:30:47 +00:00
parent 4d62f63c71
commit d27c465371
2 changed files with 46 additions and 3 deletions

View File

@@ -22,7 +22,7 @@ import net.i2p.util.NativeBigInteger;
*
* @since 0.9.9
*/
public class ECConstants {
class ECConstants {
private static final boolean DEBUG = true;
@@ -38,7 +38,10 @@ public class ECConstants {
}
}
private static final boolean BC_AVAILABLE;
static {
boolean loaded;
if (Security.getProvider("BC") == null) {
try {
Class cls = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
@@ -46,14 +49,19 @@ public class ECConstants {
Provider bc = (Provider)con.newInstance(new Object[0]);
Security.addProvider(bc);
log("Added BC provider");
loaded = true;
} catch (Exception e) {
log("Unable to add BC provider", e);
loaded = false;
}
} else {
log("BC provider already loaded");
loaded = true;
}
BC_AVAILABLE = true;
}
public static boolean isBCAvailable() { return BC_AVAILABLE; }
private static class ECParms {
public final String ps, ns, ss, bs, gxs, gys;

View File

@@ -14,6 +14,7 @@ import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.ProviderException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECPoint;
@@ -26,6 +27,7 @@ import net.i2p.data.SessionKey;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.data.SimpleDataStructure;
import net.i2p.util.Log;
import net.i2p.util.NativeBigInteger;
// main()
@@ -188,8 +190,41 @@ public class KeyGenerator {
if (type == SigType.DSA_SHA1)
return generateSigningKeys();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(type.getParams(), _context.random());
KeyPair kp = kpg.generateKeyPair();
KeyPair kp;
try {
kpg.initialize(type.getParams(), _context.random());
kp = kpg.generateKeyPair();
} catch (ProviderException pe) {
// This is a RuntimeException, thx Sun
// Fails for P-192 only, on Ubuntu
Log log = _context.logManager().getLog(KeyGenerator.class);
String pname = kpg.getProvider().getName();
if ("BC".equals(pname)) {
if (log.shouldLog(Log.WARN))
log.warn("BC KPG failed", pe);
throw new GeneralSecurityException("BC KPG", pe);
}
if (!ECConstants.isBCAvailable())
throw new GeneralSecurityException(pname + " KPG", pe);
if (log.shouldLog(Log.WARN))
log.warn(pname + " KPG failed, trying BC", pe);
try {
kpg = KeyPairGenerator.getInstance("EC", "BC");
kpg.initialize(type.getParams(), _context.random());
kp = kpg.generateKeyPair();
} catch (ProviderException pe2) {
if (log.shouldLog(Log.WARN))
log.warn("BC KPG failed too", pe2);
// throw original exception
throw new GeneralSecurityException(pname + " KPG", pe);
} catch (GeneralSecurityException gse) {
if (log.shouldLog(Log.WARN))
log.warn("BC KPG failed too", gse);
gse.printStackTrace();
// throw original exception
throw new GeneralSecurityException(pname + " KPG", pe);
}
}
ECPublicKey pubkey = (ECPublicKey) kp.getPublic();
ECPrivateKey privkey = (ECPrivateKey) kp.getPrivate();
SimpleDataStructure[] keys = new SimpleDataStructure[2];