changeset 8237:9665966de2e7

PR2123: SunEC provider crashes when built using system NSS
author andrew
date Fri, 05 Dec 2014 02:53:29 +0000
parents 899ad74ad303
children 13bd267f397d
files src/share/native/sun/security/ec/ECC_JNI.cpp
diffstat 1 files changed, 71 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/native/sun/security/ec/ECC_JNI.cpp	Thu Dec 04 20:38:07 2014 +0000
+++ b/src/share/native/sun/security/ec/ECC_JNI.cpp	Fri Dec 05 02:53:29 2014 +0000
@@ -32,6 +32,13 @@
 #define INVALID_PARAMETER_EXCEPTION \
         "java/security/InvalidParameterException"
 #define KEY_EXCEPTION   "java/security/KeyException"
+#define INTERNAL_ERROR "java/lang/InternalError"
+
+#ifdef SYSTEM_NSS
+#define SYSTEM_UNUSED(x) UNUSED(x)
+#else
+#define SYSTEM_UNUSED(x) x
+#endif
 
 extern "C" {
 
@@ -47,8 +54,13 @@
 /*
  * Deep free of the ECParams struct
  */
-void FreeECParams(ECParams *ecparams, jboolean freeStruct)
+void FreeECParams(ECParams *ecparams, jboolean SYSTEM_UNUSED(freeStruct))
 {
+#ifdef SYSTEM_NSS
+    // Needs to be freed using the matching method to the one
+    // that allocated it. PR_TRUE means the memory is zeroed.
+    PORT_FreeArena(ecparams->arena, PR_TRUE);
+#else
     // Use B_FALSE to free the SECItem->data element, but not the SECItem itself
     // Use B_TRUE to free both
 
@@ -62,7 +74,7 @@
     SECITEM_FreeItem(&ecparams->curveOID, B_FALSE);
     if (freeStruct)
         free(ecparams);
-
+#endif
 }
 
 jbyteArray getEncodedBytes(JNIEnv *env, SECItem *hSECItem)
@@ -104,6 +116,13 @@
     params_item.data =
         (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
 
+#ifdef SYSTEM_NSS
+    if (SECOID_Init() != SECSuccess) {
+	ThrowException(env, INTERNAL_ERROR);
+	goto cleanup;
+    }
+#endif
+
     // Fill a new ECParams using the supplied OID
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
         /* bad curve OID */
@@ -159,6 +178,11 @@
         if (params_item.data) {
             env->ReleaseByteArrayElements(encodedParams,
                 (jbyte *) params_item.data, JNI_ABORT);
+#ifdef SYSTEM_NSS
+	    if (SECOID_Shutdown() != SECSuccess) {
+		ThrowException(env, INTERNAL_ERROR);
+	    }
+#endif
         }
 
         if (ecparams) {
@@ -167,10 +191,15 @@
 
         if (privKey) {
             FreeECParams(&privKey->ecParams, false);
+#ifndef SYSTEM_NSS
+	    // The entire ECPrivateKey is allocated in the arena
+	    // when using system NSS, so only the in-tree version
+	    // needs to clear these manually.
             SECITEM_FreeItem(&privKey->version, B_FALSE);
             SECITEM_FreeItem(&privKey->privateValue, B_FALSE);
             SECITEM_FreeItem(&privKey->publicValue, B_FALSE);
             free(privKey);
+#endif
         }
 
         if (pSeedBuffer) {
@@ -217,6 +246,13 @@
     params_item.data =
         (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
 
+#ifdef SYSTEM_NSS
+    if (SECOID_Init() != SECSuccess) {
+	ThrowException(env, INTERNAL_ERROR);
+	goto cleanup;
+    }
+#endif
+
     // Fill a new ECParams using the supplied OID
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
         /* bad curve OID */
@@ -258,6 +294,11 @@
         if (params_item.data) {
             env->ReleaseByteArrayElements(encodedParams,
                 (jbyte *) params_item.data, JNI_ABORT);
+#ifdef SYSTEM_NSS
+	    if (SECOID_Shutdown() != SECSuccess) {
+		ThrowException(env, INTERNAL_ERROR);
+	    }
+#endif
         }
 
         if (privKey.privateValue.data) {
@@ -326,6 +367,13 @@
     params_item.data =
         (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
 
+#ifdef SYSTEM_NSS
+    if (SECOID_Init() != SECSuccess) {
+	ThrowException(env, INTERNAL_ERROR);
+	goto cleanup;
+    }
+#endif
+
     // Fill a new ECParams using the supplied OID
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
         /* bad curve OID */
@@ -346,9 +394,15 @@
 
 cleanup:
     {
-        if (params_item.data)
+        if (params_item.data) {
             env->ReleaseByteArrayElements(encodedParams,
                 (jbyte *) params_item.data, JNI_ABORT);
+#ifdef SYSTEM_NSS
+	    if (SECOID_Shutdown() != SECSuccess) {
+		ThrowException(env, INTERNAL_ERROR);
+	    }
+#endif
+	}
 
         if (pubKey.publicValue.data)
             env->ReleaseByteArrayElements(publicKey,
@@ -397,6 +451,13 @@
     params_item.data =
         (unsigned char *) env->GetByteArrayElements(encodedParams, 0);
 
+#ifdef SYSTEM_NSS
+    if (SECOID_Init() != SECSuccess) {
+	ThrowException(env, INTERNAL_ERROR);
+	goto cleanup;
+    }
+#endif
+
     // Fill a new ECParams using the supplied OID
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
         /* bad curve OID */
@@ -435,9 +496,15 @@
             env->ReleaseByteArrayElements(publicKey,
                 (jbyte *) publicValue_item.data, JNI_ABORT);
 
-        if (params_item.data)
+        if (params_item.data) {
             env->ReleaseByteArrayElements(encodedParams,
                 (jbyte *) params_item.data, JNI_ABORT);
+#ifdef SYSTEM_NSS
+	    if (SECOID_Shutdown() != SECSuccess) {
+		ThrowException(env, INTERNAL_ERROR);
+	    }
+#endif
+	}
 
         if (ecparams)
             FreeECParams(ecparams, true);