changeset 7380:c084492f9e3d

8031340: Better TLS/EC management Reviewed-by: valeriep, coffeys, ahgross
author mbankal
date Wed, 05 Mar 2014 22:31:11 -0800
parents 1b21d26982d3
children 84bce1b3d28a
files make/sun/security/ec/mapfile-vers src/share/classes/sun/security/ec/ECKeyPairGenerator.java src/share/native/sun/security/ec/ECC_JNI.cpp
diffstat 3 files changed, 85 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/make/sun/security/ec/mapfile-vers	Wed Mar 05 20:56:53 2014 -0800
+++ b/make/sun/security/ec/mapfile-vers	Wed Mar 05 22:31:11 2014 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 SUNWprivate_1.1 {
         global:
                 Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair;
-                Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes;
 		Java_sun_security_ec_ECDSASignature_signDigest;
 		Java_sun_security_ec_ECDSASignature_verifySignedDigest;
 		Java_sun_security_ec_ECDHKeyAgreement_deriveKey;
--- a/src/share/classes/sun/security/ec/ECKeyPairGenerator.java	Wed Mar 05 20:56:53 2014 -0800
+++ b/src/share/classes/sun/security/ec/ECKeyPairGenerator.java	Wed Mar 05 22:31:11 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -123,19 +123,19 @@
 
         try {
 
-            long[] handles = generateECKeyPair(keySize, encodedParams, seed);
+            Object[] keyBytes = generateECKeyPair(keySize, encodedParams, seed);
 
             // The 'params' object supplied above is equivalent to the native
             // one so there is no need to fetch it.
 
-            // handles[0] points to the native private key
-            BigInteger s = new BigInteger(1, getEncodedBytes(handles[0]));
+            // keyBytes[0] is the encoding of the native private key
+            BigInteger s = new BigInteger(1, (byte[])keyBytes[0]);
 
             PrivateKey privateKey =
                 new ECPrivateKeyImpl(s, (ECParameterSpec)params);
 
-            // handles[1] points to the native public key
-            ECPoint w = ECParameters.decodePoint(getEncodedBytes(handles[1]),
+            // keyBytes[1] is the encoding of the native public key
+            ECPoint w = ECParameters.decodePoint((byte[])keyBytes[1],
                 ((ECParameterSpec)params).getCurve());
             PublicKey publicKey =
                 new ECPublicKeyImpl(w, (ECParameterSpec)params);
@@ -160,14 +160,9 @@
     }
 
     /*
-     * Generates the keypair and returns a 2-element array of handles.
-     * The first handle points to the private key, the second to the public key.
+     * Generates the keypair and returns a 2-element array of encoding bytes.
+     * The first one is for the private key, the second for the public key.
      */
-    private static native long[] generateECKeyPair(int keySize,
+    private static native Object[] generateECKeyPair(int keySize,
         byte[] encodedParams, byte[] seed) throws GeneralSecurityException;
-
-    /*
-     * Extracts the encoded key data using the supplied handle.
-     */
-    private static native byte[] getEncodedBytes(long handle);
 }
--- a/src/share/native/sun/security/ec/ECC_JNI.cpp	Wed Mar 05 20:56:53 2014 -0800
+++ b/src/share/native/sun/security/ec/ECC_JNI.cpp	Wed Mar 05 22:31:11 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,24 +62,42 @@
     SECITEM_FreeItem(&ecparams->curveOID, B_FALSE);
     if (freeStruct)
         free(ecparams);
+
+}
+
+jbyteArray getEncodedBytes(JNIEnv *env, SECItem *hSECItem)
+{
+    SECItem *s = (SECItem *)hSECItem;
+
+    jbyteArray jEncodedBytes = env->NewByteArray(s->len);
+    if (jEncodedBytes == NULL) {
+        return NULL;
+    }
+    // Copy bytes from a native SECItem buffer to java byte array
+    env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data);
+    if (env->ExceptionCheck()) { //should never happen
+        return NULL;
+    }
+    return jEncodedBytes;
 }
 
 /*
  * Class:     sun_security_ec_ECKeyPairGenerator
  * Method:    generateECKeyPair
- * Signature: (I[B[B)[J
+ * Signature: (I[B[B)[B
  */
-JNIEXPORT jlongArray
+JNIEXPORT jobjectArray
 JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair
   (JNIEnv *env, jclass clazz, jint keySize, jbyteArray encodedParams, jbyteArray seed)
 {
-    ECPrivateKey *privKey;      /* contains both public and private values */
+    ECPrivateKey *privKey = NULL;      /* contains both public and private values */
     ECParams *ecparams = NULL;
     SECKEYECParams params_item;
     jint jSeedLength;
     jbyte* pSeedBuffer = NULL;
-    jlongArray result = NULL;
-    jlong* resultElements = NULL;
+    jobjectArray result = NULL;
+    jclass baCls = NULL;
+    jbyteArray jba;
 
     // Initialize the ECParams struct
     params_item.len = env->GetArrayLength(encodedParams);
@@ -106,61 +124,64 @@
     }
 
     jboolean isCopy;
-    result = env->NewLongArray(2);
-    resultElements = env->GetLongArrayElements(result, &isCopy);
+    baCls = env->FindClass("[B");
+    if (baCls == NULL) {
+        goto cleanup;
+    }
+    result = env->NewObjectArray(2, baCls, NULL);
+    if (result == NULL) {
+        goto cleanup;
+    }
+    jba = getEncodedBytes(env, &(privKey->privateValue));
+    if (jba == NULL) {
+        result = NULL;
+        goto cleanup;
+    }
+    env->SetObjectArrayElement(result, 0, jba); // big integer
+    if (env->ExceptionCheck()) { // should never happen
+        result = NULL;
+        goto cleanup;
+    }
 
-    resultElements[0] = (jlong) &(privKey->privateValue); // private big integer
-    resultElements[1] = (jlong) &(privKey->publicValue); // encoded ec point
-
-    // If the array is a copy then we must write back our changes
-    if (isCopy == JNI_TRUE) {
-        env->ReleaseLongArrayElements(result, resultElements, 0);
+    jba = getEncodedBytes(env, &(privKey->publicValue));
+    if (jba == NULL) {
+        result = NULL;
+        goto cleanup;
+    }
+    env->SetObjectArrayElement(result, 1, jba); // encoded ec point
+    if (env->ExceptionCheck()) { // should never happen
+        result = NULL;
+        goto cleanup;
     }
 
 cleanup:
     {
-        if (params_item.data)
+        if (params_item.data) {
             env->ReleaseByteArrayElements(encodedParams,
                 (jbyte *) params_item.data, JNI_ABORT);
+        }
 
-        if (ecparams)
+        if (ecparams) {
             FreeECParams(ecparams, true);
+        }
 
         if (privKey) {
             FreeECParams(&privKey->ecParams, false);
             SECITEM_FreeItem(&privKey->version, B_FALSE);
-            // Don't free privKey->privateValue and privKey->publicValue
+            SECITEM_FreeItem(&privKey->privateValue, B_FALSE);
+            SECITEM_FreeItem(&privKey->publicValue, B_FALSE);
+            free(privKey);
         }
 
-        if (pSeedBuffer)
+        if (pSeedBuffer) {
             delete [] pSeedBuffer;
+        }
     }
 
     return result;
 }
 
 /*
- * Class:     sun_security_ec_ECKeyPairGenerator
- * Method:    getEncodedBytes
- * Signature: (J)[B
- */
-JNIEXPORT jbyteArray
-JNICALL Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes
-  (JNIEnv *env, jclass clazz, jlong hSECItem)
-{
-    SECItem *s = (SECItem *)hSECItem;
-    jbyteArray jEncodedBytes = env->NewByteArray(s->len);
-
-    // Copy bytes from a native SECItem buffer to Java byte array
-    env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data);
-
-    // Use B_FALSE to free only the SECItem->data
-    SECITEM_FreeItem(s, B_FALSE);
-
-    return jEncodedBytes;
-}
-
-/*
  * Class:     sun_security_ec_ECDSASignature
  * Method:    signDigest
  * Signature: ([B[B[B[B)[B
@@ -234,21 +255,31 @@
 
 cleanup:
     {
-        if (params_item.data)
+        if (params_item.data) {
             env->ReleaseByteArrayElements(encodedParams,
                 (jbyte *) params_item.data, JNI_ABORT);
+        }
 
-        if (pDigestBuffer)
+        if (privKey.privateValue.data) {
+            env->ReleaseByteArrayElements(privateKey,
+                (jbyte *) privKey.privateValue.data, JNI_ABORT);
+        }
+
+        if (pDigestBuffer) {
             delete [] pDigestBuffer;
+        }
 
-        if (pSignedDigestBuffer)
+        if (pSignedDigestBuffer) {
             delete [] pSignedDigestBuffer;
+        }
 
-        if (pSeedBuffer)
+        if (pSeedBuffer) {
             delete [] pSeedBuffer;
+        }
 
-        if (ecparams)
+        if (ecparams) {
             FreeECParams(ecparams, true);
+        }
     }
 
     return jSignedDigest;