diff options
author | Alex Klyubin <klyubin@google.com> | 2013-03-29 11:30:17 -0700 |
---|---|---|
committer | Alex Klyubin <klyubin@google.com> | 2013-03-29 13:29:20 -0700 |
commit | 0469e3a6a9b5e854b8b985039de8ba4f6e6037bd (patch) | |
tree | 7a259856e913fee1e4c3908ccce7b9ca8b5c0d9c /luni | |
parent | 589d6f45d4c38c1d74ea970284c32ed013422eef (diff) | |
download | libcore-0469e3a6a9b5e854b8b985039de8ba4f6e6037bd.zip libcore-0469e3a6a9b5e854b8b985039de8ba4f6e6037bd.tar.gz libcore-0469e3a6a9b5e854b8b985039de8ba4f6e6037bd.tar.bz2 |
Switch OpenSSLECDHKeyAgreement to KeyFactory.translateKey.
OpenSSL KeyFactory.translateKey encapsulates all the functionality
for translating arbitrary Key instances to OpenSSL-backed Key
instances. Thus, there's no need to replicate that functionality
elsewhere.
Change-Id: I4caa0021e51a83be6932617117275fd033b6d5f7
Diffstat (limited to 'luni')
3 files changed, 43 insertions, 56 deletions
diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java index b24ad0e..dfc512f 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java @@ -206,6 +206,8 @@ public final class NativeCrypto { public static native byte[] EC_GROUP_get_order(long groupCtx); + public static native int EC_GROUP_get_degree(long groupCtx); + public static native byte[] EC_GROUP_get_cofactor(long groupCtx); public static native long EC_POINT_new(long groupRef); diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECDHKeyAgreement.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECDHKeyAgreement.java index 096e300..5146156 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECDHKeyAgreement.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLECDHKeyAgreement.java @@ -19,9 +19,10 @@ package org.apache.harmony.xnet.provider.jsse; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; +import java.security.KeyFactory; +import java.security.PrivateKey; +import java.security.PublicKey; import java.security.SecureRandom; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.KeyAgreementSpi; @@ -54,36 +55,14 @@ public final class OpenSSLECDHKeyAgreement extends KeyAgreementSpi { if (!lastPhase) { throw new IllegalStateException("ECDH only has one phase"); } + if (key == null) { throw new InvalidKeyException("key == null"); } - if (!(key instanceof ECPublicKey)) { - throw new InvalidKeyException("This phase requires an ECPublicKey. Actual key type: " - + key.getClass()); - } - ECPublicKey publicKey = (ECPublicKey) key; - - OpenSSLKey openSslPublicKey; - if (publicKey instanceof OpenSSLECPublicKey) { - // OpenSSL-backed key - openSslPublicKey = ((OpenSSLECPublicKey) publicKey).getOpenSSLKey(); - } else { - // Not an OpenSSL-backed key -- create an OpenSSL-backed key from its X.509 encoding - if (!"X.509".equals(publicKey.getFormat())) { - throw new InvalidKeyException("Non-OpenSSL public key (" + publicKey.getClass() - + ") offers unsupported encoding format: " + publicKey.getFormat()); - } - byte[] encoded = publicKey.getEncoded(); - if (encoded == null) { - throw new InvalidKeyException("Non-OpenSSL public key (" + publicKey.getClass() - + ") does not provide encoded form"); - } - try { - openSslPublicKey = new OpenSSLKey(NativeCrypto.d2i_PUBKEY(encoded)); - } catch (Exception e) { - throw new InvalidKeyException("Failed to decode X.509 encoded public key", e); - } + if (!(key instanceof PublicKey)) { + throw new InvalidKeyException("Not a public key: " + key.getClass()); } + OpenSSLKey openSslPublicKey = translateKeyToEcOpenSSLKey(key); byte[] buffer = new byte[mExpectedResultLength]; int actualResultLength = NativeCrypto.ECDH_compute_key( @@ -142,35 +121,15 @@ public final class OpenSSLECDHKeyAgreement extends KeyAgreementSpi { if (key == null) { throw new InvalidKeyException("key == null"); } - if (!(key instanceof ECPrivateKey)) { - throw new InvalidKeyException("Not an EC private key: " + key.getClass()); - } - ECPrivateKey privateKey = (ECPrivateKey) key; - mExpectedResultLength = - (privateKey.getParams().getCurve().getField().getFieldSize() + 7) / 8; - - OpenSSLKey openSslPrivateKey; - if (privateKey instanceof OpenSSLECPrivateKey) { - // OpenSSL-backed key - openSslPrivateKey = ((OpenSSLECPrivateKey) privateKey).getOpenSSLKey(); - } else { - // Not an OpenSSL-backed key -- create an OpenSSL-backed key from its PKCS#8 encoding - if (!"PKCS#8".equals(privateKey.getFormat())) { - throw new InvalidKeyException("Non-OpenSSL private key (" + privateKey.getClass() - + ") offers unsupported encoding format: " + privateKey.getFormat()); - } - byte[] encoded = privateKey.getEncoded(); - if (encoded == null) { - throw new InvalidKeyException("Non-OpenSSL private key (" + privateKey.getClass() - + ") does not provide encoded form"); - } - try { - openSslPrivateKey = new OpenSSLKey(NativeCrypto.d2i_PKCS8_PRIV_KEY_INFO(encoded)); - } catch (Exception e) { - throw new InvalidKeyException("Failed to decode PKCS#8 encoded private key", e); - } + if (!(key instanceof PrivateKey)) { + throw new InvalidKeyException("Not a private key: " + key.getClass()); } - mOpenSslPrivateKey = openSslPrivateKey; + + OpenSSLKey openSslKey = translateKeyToEcOpenSSLKey(key); + int fieldSizeBits = NativeCrypto.EC_GROUP_get_degree(NativeCrypto.EC_KEY_get0_group( + openSslKey.getPkeyContext())); + mExpectedResultLength = (fieldSizeBits + 7) / 8; + mOpenSslPrivateKey = openSslKey; } @Override @@ -188,4 +147,13 @@ public final class OpenSSLECDHKeyAgreement extends KeyAgreementSpi { throw new IllegalStateException("Key agreement not completed"); } } + + private static OpenSSLKey translateKeyToEcOpenSSLKey(Key key) throws InvalidKeyException { + try { + return ((OpenSSLKeyHolder) KeyFactory.getInstance( + "EC", OpenSSLProvider.PROVIDER_NAME).translateKey(key)).getOpenSSLKey(); + } catch (Exception e) { + throw new InvalidKeyException("Failed to translate key to OpenSSL EC key", e); + } + } } diff --git a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp index ee6a57e..0921d8b 100644 --- a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp +++ b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp @@ -2360,6 +2360,22 @@ static jbyteArray NativeCrypto_EC_GROUP_get_order(JNIEnv* env, jclass, jlong gro return orderArray; } +static jint NativeCrypto_EC_GROUP_get_degree(JNIEnv* env, jclass, jlong groupRef) +{ + const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef); + JNI_TRACE("EC_GROUP_get_degree(%p)", group); + + jint degree = EC_GROUP_get_degree(group); + if (degree == 0) { + JNI_TRACE("EC_GROUP_get_degree(%p) => unsupported", group); + jniThrowRuntimeException(env, "not supported"); + return 0; + } + + JNI_TRACE("EC_GROUP_get_degree(%p) => %d", group, degree); + return degree; +} + static jbyteArray NativeCrypto_EC_GROUP_get_cofactor(JNIEnv* env, jclass, jlong groupRef) { const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef); @@ -7821,6 +7837,7 @@ static JNINativeMethod sNativeCryptoMethods[] = { NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve_name, "(J)Ljava/lang/String;"), NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve, "(J)[[B"), NATIVE_METHOD(NativeCrypto, EC_GROUP_get_order, "(J)[B"), + NATIVE_METHOD(NativeCrypto, EC_GROUP_get_degree, "(J)I"), NATIVE_METHOD(NativeCrypto, EC_GROUP_get_cofactor, "(J)[B"), NATIVE_METHOD(NativeCrypto, EC_GROUP_clear_free, "(J)V"), NATIVE_METHOD(NativeCrypto, EC_GROUP_cmp, "(JJ)Z"), |