74b02f5
# HG changeset patch
74b02f5
# User andrew
74b02f5
# Date 1453866306 0
74b02f5
#      Wed Jan 27 03:45:06 2016 +0000
74b02f5
# Node ID 0ff7720931e8dbf7de25720bdc93b18527ab89e8
74b02f5
# Parent  48c15869ecd568263249af4b9a4e98d4e57f9a8f
74b02f5
PR2127: SunEC provider crashes when built using system NSS
74b02f5
Summary: Use NSS memory management functions
74b02f5
74b02f5
diff -r 48c15869ecd5 -r 0ff7720931e8 src/share/native/sun/security/ec/ECC_JNI.cpp
74b02f5
--- openjdk/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp	Wed Jan 27 02:54:06 2016 +0000
74b02f5
+++ openjdk/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp	Wed Jan 27 03:45:06 2016 +0000
74b02f5
@@ -32,6 +32,13 @@
74b02f5
 #define INVALID_PARAMETER_EXCEPTION \
74b02f5
         "java/security/InvalidParameterException"
74b02f5
 #define KEY_EXCEPTION   "java/security/KeyException"
74b02f5
+#define INTERNAL_ERROR "java/lang/InternalError"
74b02f5
+
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+#define SYSTEM_UNUSED(x) UNUSED(x)
74b02f5
+#else
74b02f5
+#define SYSTEM_UNUSED(x) x
74b02f5
+#endif
74b02f5
 
74b02f5
 extern "C" {
74b02f5
 
74b02f5
@@ -49,8 +56,13 @@
74b02f5
 /*
74b02f5
  * Deep free of the ECParams struct
74b02f5
  */
74b02f5
-void FreeECParams(ECParams *ecparams, jboolean freeStruct)
74b02f5
+void FreeECParams(ECParams *ecparams, jboolean SYSTEM_UNUSED(freeStruct))
74b02f5
 {
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+    // Needs to be freed using the matching method to the one
74b02f5
+    // that allocated it. PR_TRUE means the memory is zeroed.
74b02f5
+    PORT_FreeArena(ecparams->arena, PR_TRUE);
74b02f5
+#else
74b02f5
     // Use B_FALSE to free the SECItem->data element, but not the SECItem itself
74b02f5
     // Use B_TRUE to free both
74b02f5
 
74b02f5
@@ -64,6 +76,7 @@
74b02f5
     SECITEM_FreeItem(&ecparams->curveOID, B_FALSE);
74b02f5
     if (freeStruct)
74b02f5
         free(ecparams);
74b02f5
+#endif
74b02f5
 }
74b02f5
 
74b02f5
 jbyteArray getEncodedBytes(JNIEnv *env, SECItem *hSECItem)
74b02f5
@@ -108,6 +121,13 @@
74b02f5
         goto cleanup;
74b02f5
     }
74b02f5
 
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+    if (SECOID_Init() != SECSuccess) {
74b02f5
+	ThrowException(env, INTERNAL_ERROR);
74b02f5
+	goto cleanup;
74b02f5
+    }
74b02f5
+#endif
74b02f5
+
74b02f5
     // Fill a new ECParams using the supplied OID
74b02f5
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
74b02f5
         /* bad curve OID */
74b02f5
@@ -163,16 +183,26 @@
74b02f5
         if (params_item.data) {
74b02f5
             env->ReleaseByteArrayElements(encodedParams,
74b02f5
                 (jbyte *) params_item.data, JNI_ABORT);
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+	    if (SECOID_Shutdown() != SECSuccess) {
74b02f5
+		ThrowException(env, INTERNAL_ERROR);
74b02f5
+	    }
74b02f5
+#endif
74b02f5
         }
74b02f5
         if (ecparams) {
74b02f5
             FreeECParams(ecparams, true);
74b02f5
         }
74b02f5
         if (privKey) {
74b02f5
             FreeECParams(&privKey->ecParams, false);
74b02f5
+#ifndef SYSTEM_NSS
74b02f5
+	    // The entire ECPrivateKey is allocated in the arena
74b02f5
+	    // when using system NSS, so only the in-tree version
74b02f5
+	    // needs to clear these manually.
74b02f5
             SECITEM_FreeItem(&privKey->version, B_FALSE);
74b02f5
             SECITEM_FreeItem(&privKey->privateValue, B_FALSE);
74b02f5
             SECITEM_FreeItem(&privKey->publicValue, B_FALSE);
74b02f5
             free(privKey);
74b02f5
+#endif
74b02f5
         }
74b02f5
 
74b02f5
         if (pSeedBuffer) {
74b02f5
@@ -223,6 +253,13 @@
74b02f5
         goto cleanup;
74b02f5
     }
74b02f5
 
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+    if (SECOID_Init() != SECSuccess) {
74b02f5
+	ThrowException(env, INTERNAL_ERROR);
74b02f5
+	goto cleanup;
74b02f5
+    }
74b02f5
+#endif
74b02f5
+
74b02f5
     // Fill a new ECParams using the supplied OID
74b02f5
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
74b02f5
         /* bad curve OID */
74b02f5
@@ -270,6 +307,11 @@
74b02f5
         if (params_item.data) {
74b02f5
             env->ReleaseByteArrayElements(encodedParams,
74b02f5
                 (jbyte *) params_item.data, JNI_ABORT);
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+	    if (SECOID_Shutdown() != SECSuccess) {
74b02f5
+		ThrowException(env, INTERNAL_ERROR);
74b02f5
+	    }
74b02f5
+#endif
74b02f5
         }
74b02f5
         if (privKey.privateValue.data) {
74b02f5
             env->ReleaseByteArrayElements(privateKey,
74b02f5
@@ -336,6 +378,13 @@
74b02f5
         goto cleanup;
74b02f5
     }
74b02f5
 
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+    if (SECOID_Init() != SECSuccess) {
74b02f5
+	ThrowException(env, INTERNAL_ERROR);
74b02f5
+	goto cleanup;
74b02f5
+    }
74b02f5
+#endif
74b02f5
+
74b02f5
     // Fill a new ECParams using the supplied OID
74b02f5
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
74b02f5
         /* bad curve OID */
74b02f5
@@ -356,9 +405,15 @@
74b02f5
 
74b02f5
 cleanup:
74b02f5
     {
74b02f5
-        if (params_item.data)
74b02f5
+        if (params_item.data) {
74b02f5
             env->ReleaseByteArrayElements(encodedParams,
74b02f5
                 (jbyte *) params_item.data, JNI_ABORT);
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+	    if (SECOID_Shutdown() != SECSuccess) {
74b02f5
+		ThrowException(env, INTERNAL_ERROR);
74b02f5
+	    }
74b02f5
+#endif
74b02f5
+	}
74b02f5
 
74b02f5
         if (pubKey.publicValue.data)
74b02f5
             env->ReleaseByteArrayElements(publicKey,
74b02f5
@@ -419,6 +474,13 @@
74b02f5
         goto cleanup;
74b02f5
     }
74b02f5
 
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+    if (SECOID_Init() != SECSuccess) {
74b02f5
+	ThrowException(env, INTERNAL_ERROR);
74b02f5
+	goto cleanup;
74b02f5
+    }
74b02f5
+#endif
74b02f5
+
74b02f5
     // Fill a new ECParams using the supplied OID
74b02f5
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
74b02f5
         /* bad curve OID */
74b02f5
@@ -460,9 +522,15 @@
74b02f5
             env->ReleaseByteArrayElements(publicKey,
74b02f5
                 (jbyte *) publicValue_item.data, JNI_ABORT);
74b02f5
 
74b02f5
-        if (params_item.data)
74b02f5
+        if (params_item.data) {
74b02f5
             env->ReleaseByteArrayElements(encodedParams,
74b02f5
                 (jbyte *) params_item.data, JNI_ABORT);
74b02f5
+#ifdef SYSTEM_NSS
74b02f5
+	    if (SECOID_Shutdown() != SECSuccess) {
74b02f5
+		ThrowException(env, INTERNAL_ERROR);
74b02f5
+	    }
74b02f5
+#endif
74b02f5
+	}
74b02f5
 
74b02f5
         if (ecparams)
74b02f5
             FreeECParams(ecparams, true);