0b99e16
# HG changeset patch
0b99e16
# User andrew
0b99e16
# Date 1453867347 0
0b99e16
#      Wed Jan 27 04:02:27 2016 +0000
0b99e16
# Node ID 26e2e029ee256e9815fdc324831a03d8582255e1
0b99e16
# Parent  0ff7720931e8dbf7de25720bdc93b18527ab89e8
0b99e16
PR2815: Race condition in SunEC provider with system NSS
0b99e16
Summary: Perform initialisation and shutdown only when library is loaded or SunEC is finalized respectively
0b99e16
0b99e16
diff -r 0ff7720931e8 -r 26e2e029ee25 make/mapfiles/libsunec/mapfile-vers
0b99e16
--- openjdk/jdk/make/mapfiles/libsunec/mapfile-vers	Wed Jan 27 03:45:06 2016 +0000
0b99e16
+++ openjdk/jdk/make/mapfiles/libsunec/mapfile-vers	Wed Jan 27 04:02:27 2016 +0000
0b99e16
@@ -31,6 +31,8 @@
0b99e16
                 Java_sun_security_ec_ECDSASignature_signDigest;
0b99e16
                 Java_sun_security_ec_ECDSASignature_verifySignedDigest;
0b99e16
                 Java_sun_security_ec_ECDHKeyAgreement_deriveKey;
0b99e16
+		Java_sun_security_ec_SunEC_initialize;
0b99e16
+		Java_sun_security_ec_SunEC_cleanup;
0b99e16
         local:
0b99e16
                 *;
0b99e16
 };
0b99e16
diff -r 0ff7720931e8 -r 26e2e029ee25 src/share/classes/sun/security/ec/SunEC.java
0b99e16
--- openjdk/jdk/src/share/classes/sun/security/ec/SunEC.java	Wed Jan 27 03:45:06 2016 +0000
0b99e16
+++ openjdk/jdk/src/share/classes/sun/security/ec/SunEC.java	Wed Jan 27 04:02:27 2016 +0000
0b99e16
@@ -58,6 +58,7 @@
0b99e16
             AccessController.doPrivileged(new PrivilegedAction<Void>() {
0b99e16
                 public Void run() {
0b99e16
                     System.loadLibrary("sunec"); // check for native library
0b99e16
+                    initialize();
0b99e16
                     return null;
0b99e16
                 }
0b99e16
             });
0b99e16
@@ -81,4 +82,22 @@
0b99e16
         }
0b99e16
     }
0b99e16
 
0b99e16
+    /**
0b99e16
+     * Cleanup native resources during finalisation.
0b99e16
+     */
0b99e16
+    @Override
0b99e16
+    protected void finalize() {
0b99e16
+        cleanup();
0b99e16
+    }
0b99e16
+
0b99e16
+    /**
0b99e16
+     * Initialize the native code.
0b99e16
+     */
0b99e16
+    private static native void initialize();
0b99e16
+
0b99e16
+    /**
0b99e16
+     * Cleanup in the native layer.
0b99e16
+     */
0b99e16
+    private static native void cleanup();
0b99e16
+
0b99e16
 }
0b99e16
diff -r 0ff7720931e8 -r 26e2e029ee25 src/share/native/sun/security/ec/ECC_JNI.cpp
0b99e16
--- openjdk/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp	Wed Jan 27 03:45:06 2016 +0000
0b99e16
+++ openjdk/jdk/src/share/native/sun/security/ec/ECC_JNI.cpp	Wed Jan 27 04:02:27 2016 +0000
0b99e16
@@ -121,13 +121,6 @@
0b99e16
         goto cleanup;
0b99e16
     }
0b99e16
 
0b99e16
-#ifdef SYSTEM_NSS
0b99e16
-    if (SECOID_Init() != SECSuccess) {
0b99e16
-	ThrowException(env, INTERNAL_ERROR);
0b99e16
-	goto cleanup;
0b99e16
-    }
0b99e16
-#endif
0b99e16
-
0b99e16
     // Fill a new ECParams using the supplied OID
0b99e16
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
0b99e16
         /* bad curve OID */
0b99e16
@@ -183,11 +176,6 @@
0b99e16
         if (params_item.data) {
0b99e16
             env->ReleaseByteArrayElements(encodedParams,
0b99e16
                 (jbyte *) params_item.data, JNI_ABORT);
0b99e16
-#ifdef SYSTEM_NSS
0b99e16
-	    if (SECOID_Shutdown() != SECSuccess) {
0b99e16
-		ThrowException(env, INTERNAL_ERROR);
0b99e16
-	    }
0b99e16
-#endif
0b99e16
         }
0b99e16
         if (ecparams) {
0b99e16
             FreeECParams(ecparams, true);
0b99e16
@@ -253,13 +241,6 @@
0b99e16
         goto cleanup;
0b99e16
     }
0b99e16
 
0b99e16
-#ifdef SYSTEM_NSS
0b99e16
-    if (SECOID_Init() != SECSuccess) {
0b99e16
-	ThrowException(env, INTERNAL_ERROR);
0b99e16
-	goto cleanup;
0b99e16
-    }
0b99e16
-#endif
0b99e16
-
0b99e16
     // Fill a new ECParams using the supplied OID
0b99e16
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
0b99e16
         /* bad curve OID */
0b99e16
@@ -307,11 +288,6 @@
0b99e16
         if (params_item.data) {
0b99e16
             env->ReleaseByteArrayElements(encodedParams,
0b99e16
                 (jbyte *) params_item.data, JNI_ABORT);
0b99e16
-#ifdef SYSTEM_NSS
0b99e16
-	    if (SECOID_Shutdown() != SECSuccess) {
0b99e16
-		ThrowException(env, INTERNAL_ERROR);
0b99e16
-	    }
0b99e16
-#endif
0b99e16
         }
0b99e16
         if (privKey.privateValue.data) {
0b99e16
             env->ReleaseByteArrayElements(privateKey,
0b99e16
@@ -378,13 +354,6 @@
0b99e16
         goto cleanup;
0b99e16
     }
0b99e16
 
0b99e16
-#ifdef SYSTEM_NSS
0b99e16
-    if (SECOID_Init() != SECSuccess) {
0b99e16
-	ThrowException(env, INTERNAL_ERROR);
0b99e16
-	goto cleanup;
0b99e16
-    }
0b99e16
-#endif
0b99e16
-
0b99e16
     // Fill a new ECParams using the supplied OID
0b99e16
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
0b99e16
         /* bad curve OID */
0b99e16
@@ -408,11 +377,6 @@
0b99e16
         if (params_item.data) {
0b99e16
             env->ReleaseByteArrayElements(encodedParams,
0b99e16
                 (jbyte *) params_item.data, JNI_ABORT);
0b99e16
-#ifdef SYSTEM_NSS
0b99e16
-	    if (SECOID_Shutdown() != SECSuccess) {
0b99e16
-		ThrowException(env, INTERNAL_ERROR);
0b99e16
-	    }
0b99e16
-#endif
0b99e16
 	}
0b99e16
 
0b99e16
         if (pubKey.publicValue.data)
0b99e16
@@ -474,13 +438,6 @@
0b99e16
         goto cleanup;
0b99e16
     }
0b99e16
 
0b99e16
-#ifdef SYSTEM_NSS
0b99e16
-    if (SECOID_Init() != SECSuccess) {
0b99e16
-	ThrowException(env, INTERNAL_ERROR);
0b99e16
-	goto cleanup;
0b99e16
-    }
0b99e16
-#endif
0b99e16
-
0b99e16
     // Fill a new ECParams using the supplied OID
0b99e16
     if (EC_DecodeParams(&params_item, &ecparams, 0) != SECSuccess) {
0b99e16
         /* bad curve OID */
0b99e16
@@ -525,11 +482,6 @@
0b99e16
         if (params_item.data) {
0b99e16
             env->ReleaseByteArrayElements(encodedParams,
0b99e16
                 (jbyte *) params_item.data, JNI_ABORT);
0b99e16
-#ifdef SYSTEM_NSS
0b99e16
-	    if (SECOID_Shutdown() != SECSuccess) {
0b99e16
-		ThrowException(env, INTERNAL_ERROR);
0b99e16
-	    }
0b99e16
-#endif
0b99e16
 	}
0b99e16
 
0b99e16
         if (ecparams)
0b99e16
@@ -539,4 +491,26 @@
0b99e16
     return jSecret;
0b99e16
 }
0b99e16
 
0b99e16
+JNIEXPORT void
0b99e16
+JNICALL Java_sun_security_ec_SunEC_initialize
0b99e16
+  (JNIEnv *env, jclass UNUSED(clazz))
0b99e16
+{
0b99e16
+#ifdef SYSTEM_NSS
0b99e16
+    if (SECOID_Init() != SECSuccess) {
0b99e16
+	ThrowException(env, INTERNAL_ERROR);
0b99e16
+    }
0b99e16
+#endif
0b99e16
+}
0b99e16
+
0b99e16
+JNIEXPORT void
0b99e16
+JNICALL Java_sun_security_ec_SunEC_cleanup
0b99e16
+  (JNIEnv *env, jclass UNUSED(clazz))
0b99e16
+{
0b99e16
+#ifdef SYSTEM_NSS
0b99e16
+    if (SECOID_Shutdown() != SECSuccess) {
0b99e16
+	ThrowException(env, INTERNAL_ERROR);
0b99e16
+    }
0b99e16
+#endif
0b99e16
+}
0b99e16
+
0b99e16
 } /* extern "C" */