From ed1e705d355da6f73606d0738e89eabe6ec41277 Mon Sep 17 00:00:00 2001 From: zzz Date: Fri, 17 Jun 2022 10:34:34 -0400 Subject: [PATCH] Crypto: Fix equality checking of ECParameterSpecs in SigUtil.fromJavaKey() as the class does not define equals(). Affects Android family key loading where the class does not match our class. Tested via unit test to compare provider class sun.security.util.NamedCurve to our class java.security.spec.ECParameterSpec, untested on Android. Add conversion test to CertUtil loadcert CLI. ref: http://zzz.i2p/topics/3328 ref: i2p.android.base gitlab ticket #47 --- core/java/src/net/i2p/crypto/CertUtil.java | 5 ++++- core/java/src/net/i2p/crypto/ECConstants.java | 16 ++++++++++++++++ core/java/src/net/i2p/crypto/SigUtil.java | 8 ++++---- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/core/java/src/net/i2p/crypto/CertUtil.java b/core/java/src/net/i2p/crypto/CertUtil.java index cdbd8c76b..7d5289e06 100644 --- a/core/java/src/net/i2p/crypto/CertUtil.java +++ b/core/java/src/net/i2p/crypto/CertUtil.java @@ -42,6 +42,7 @@ import net.i2p.crypto.provider.I2PProvider; import net.i2p.data.Base64; import net.i2p.data.DataHelper; import net.i2p.data.SigningPrivateKey; +import net.i2p.data.SigningPublicKey; import net.i2p.util.Log; import net.i2p.util.FileSuffixFilter; import net.i2p.util.SecureFileOutputStream; @@ -583,7 +584,9 @@ public final class CertUtil { File f = new File(args[1]); if (args[0].equals("loadcert")) { X509Certificate cert = loadCert(f); - System.out.println(net.i2p.util.HexDump.dump(cert.getEncoded())); + PublicKey pub = cert.getPublicKey(); + SigningPublicKey spk = SigUtil.fromJavaKey(pub); + System.out.println("Loaded " + spk + ' ' + spk.toBase64()); } else if (args[0].equals("loadcrl")) { loadCRL(f); } else if (args[0].equals("loadcrldir")) { diff --git a/core/java/src/net/i2p/crypto/ECConstants.java b/core/java/src/net/i2p/crypto/ECConstants.java index 2518e34f9..1914f93fa 100644 --- a/core/java/src/net/i2p/crypto/ECConstants.java +++ b/core/java/src/net/i2p/crypto/ECConstants.java @@ -334,4 +334,20 @@ final class ECConstants { //public static final ECParameterSpec K571_SPEC = genSpec("sect571k1", "K-571", null); + /** + * There is no ECParameterSpec.equals(). + * Needed to load family keys on Android via SigUtil.fromJavaKey(). + * + * @since 0.9.55 + */ + public static boolean equals(ECParameterSpec s1, ECParameterSpec s2) { + if (s1 == s2) + return true; + // do this field by field, nothing has equals() + // but the BigIntegers, however they do have defined hashcodes + return s1.getCofactor() == s2.getCofactor() && // int + s1.getCurve().hashCode() == s2.getCurve().hashCode() && // EllipticCurve + s1.getGenerator().hashCode() == s2.getGenerator().hashCode() && // ECPoint + s1.getOrder().equals(s2.getOrder()); // BigInteger + } } diff --git a/core/java/src/net/i2p/crypto/SigUtil.java b/core/java/src/net/i2p/crypto/SigUtil.java index 20e707d11..e6f47aa8a 100644 --- a/core/java/src/net/i2p/crypto/SigUtil.java +++ b/core/java/src/net/i2p/crypto/SigUtil.java @@ -115,13 +115,13 @@ public final class SigUtil { } if (pk instanceof ECPublicKey) { ECPublicKey k = (ECPublicKey) pk; - AlgorithmParameterSpec spec = k.getParams(); + ECParameterSpec spec = k.getParams(); SigType type; - if (spec.equals(SigType.ECDSA_SHA256_P256.getParams())) + if (ECConstants.equals(spec, ECConstants.P256_SPEC)) type = SigType.ECDSA_SHA256_P256; - else if (spec.equals(SigType.ECDSA_SHA384_P384.getParams())) + else if (ECConstants.equals(spec, ECConstants.P384_SPEC)) type = SigType.ECDSA_SHA384_P384; - else if (spec.equals(SigType.ECDSA_SHA512_P521.getParams())) + else if (ECConstants.equals(spec, ECConstants.P521_SPEC)) type = SigType.ECDSA_SHA512_P521; else throw new InvalidKeyException("Unknown EC type");