6e6e3ea
# HG changeset patch
6e6e3ea
# User igerasim
6e6e3ea
# Date 1528992969 25200
6e6e3ea
#      Thu Jun 14 09:16:09 2018 -0700
6e6e3ea
# Node ID d9b0b4bd2526818afa73b60da77403245554caa8
6e6e3ea
# Parent  1f4b038b9550afaf88a70cee4cf9c1422ecd86d6
6e6e3ea
8203182, PR3603: Release session if initialization of SunPKCS11 Signature fails
6e6e3ea
Summary: Ensure session is properly released in P11Signature class
6e6e3ea
Reviewed-by: valeriep
6e6e3ea
Contributed-by: Martin Balao <mbalao@redhat.com>
6e6e3ea
6e6e3ea
diff --git openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
6e6e3ea
--- openjdk.orig/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
6e6e3ea
+++ openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
6e6e3ea
@@ -309,47 +309,51 @@
6e6e3ea
             session = token.killSession(session);
6e6e3ea
             return;
6e6e3ea
         }
6e6e3ea
-        // "cancel" operation by finishing it
6e6e3ea
-        // XXX make sure all this always works correctly
6e6e3ea
-        if (mode == M_SIGN) {
6e6e3ea
-            try {
6e6e3ea
-                if (type == T_UPDATE) {
6e6e3ea
-                    token.p11.C_SignFinal(session.id(), 0);
6e6e3ea
-                } else {
6e6e3ea
-                    byte[] digest;
6e6e3ea
-                    if (type == T_DIGEST) {
6e6e3ea
-                        digest = md.digest();
6e6e3ea
-                    } else { // T_RAW
6e6e3ea
-                        digest = buffer;
6e6e3ea
+        try {
6e6e3ea
+            // "cancel" operation by finishing it
6e6e3ea
+            // XXX make sure all this always works correctly
6e6e3ea
+            if (mode == M_SIGN) {
6e6e3ea
+                try {
6e6e3ea
+                    if (type == T_UPDATE) {
6e6e3ea
+                        token.p11.C_SignFinal(session.id(), 0);
6e6e3ea
+                    } else {
6e6e3ea
+                        byte[] digest;
6e6e3ea
+                        if (type == T_DIGEST) {
6e6e3ea
+                            digest = md.digest();
6e6e3ea
+                        } else { // T_RAW
6e6e3ea
+                            digest = buffer;
6e6e3ea
+                        }
6e6e3ea
+                        token.p11.C_Sign(session.id(), digest);
6e6e3ea
                     }
6e6e3ea
-                    token.p11.C_Sign(session.id(), digest);
6e6e3ea
+                } catch (PKCS11Exception e) {
6e6e3ea
+                    throw new ProviderException("cancel failed", e);
6e6e3ea
                 }
6e6e3ea
-            } catch (PKCS11Exception e) {
6e6e3ea
-                throw new ProviderException("cancel failed", e);
6e6e3ea
+            } else { // M_VERIFY
6e6e3ea
+                try {
6e6e3ea
+                    byte[] signature;
6e6e3ea
+                    if (keyAlgorithm.equals("DSA")) {
6e6e3ea
+                        signature = new byte[40];
6e6e3ea
+                    } else {
6e6e3ea
+                        signature = new byte[(p11Key.length() + 7) >> 3];
6e6e3ea
+                    }
6e6e3ea
+                    if (type == T_UPDATE) {
6e6e3ea
+                        token.p11.C_VerifyFinal(session.id(), signature);
6e6e3ea
+                    } else {
6e6e3ea
+                        byte[] digest;
6e6e3ea
+                        if (type == T_DIGEST) {
6e6e3ea
+                            digest = md.digest();
6e6e3ea
+                        } else { // T_RAW
6e6e3ea
+                            digest = buffer;
6e6e3ea
+                        }
6e6e3ea
+                        token.p11.C_Verify(session.id(), digest, signature);
6e6e3ea
+                    }
6e6e3ea
+                } catch (PKCS11Exception e) {
6e6e3ea
+                    // will fail since the signature is incorrect
6e6e3ea
+                    // XXX check error code
6e6e3ea
+                }
6e6e3ea
             }
6e6e3ea
-        } else { // M_VERIFY
6e6e3ea
-            try {
6e6e3ea
-                byte[] signature;
6e6e3ea
-                if (keyAlgorithm.equals("DSA")) {
6e6e3ea
-                    signature = new byte[40];
6e6e3ea
-                } else {
6e6e3ea
-                    signature = new byte[(p11Key.length() + 7) >> 3];
6e6e3ea
-                }
6e6e3ea
-                if (type == T_UPDATE) {
6e6e3ea
-                    token.p11.C_VerifyFinal(session.id(), signature);
6e6e3ea
-                } else {
6e6e3ea
-                    byte[] digest;
6e6e3ea
-                    if (type == T_DIGEST) {
6e6e3ea
-                        digest = md.digest();
6e6e3ea
-                    } else { // T_RAW
6e6e3ea
-                        digest = buffer;
6e6e3ea
-                    }
6e6e3ea
-                    token.p11.C_Verify(session.id(), digest, signature);
6e6e3ea
-                }
6e6e3ea
-            } catch (PKCS11Exception e) {
6e6e3ea
-                // will fail since the signature is incorrect
6e6e3ea
-                // XXX check error code
6e6e3ea
-            }
6e6e3ea
+        } finally {
6e6e3ea
+            session = token.releaseSession(session);
6e6e3ea
         }
6e6e3ea
     }
6e6e3ea
 
6e6e3ea
@@ -368,6 +372,8 @@
6e6e3ea
             }
6e6e3ea
             initialized = true;
6e6e3ea
         } catch (PKCS11Exception e) {
6e6e3ea
+            // release session when initialization failed
6e6e3ea
+            session = token.releaseSession(session);
6e6e3ea
             throw new ProviderException("Initialization failed", e);
6e6e3ea
         }
6e6e3ea
         if (bytesProcessed != 0) {
6e6e3ea
@@ -529,6 +535,8 @@
6e6e3ea
                 }
6e6e3ea
                 bytesProcessed += len;
6e6e3ea
             } catch (PKCS11Exception e) {
6e6e3ea
+                initialized = false;
6e6e3ea
+                session = token.releaseSession(session);
6e6e3ea
                 throw new ProviderException(e);
6e6e3ea
             }
6e6e3ea
             break;
6e6e3ea
@@ -576,6 +584,8 @@
6e6e3ea
                 bytesProcessed += len;
6e6e3ea
                 byteBuffer.position(ofs + len);
6e6e3ea
             } catch (PKCS11Exception e) {
6e6e3ea
+                initialized = false;
6e6e3ea
+                session = token.releaseSession(session);
6e6e3ea
                 throw new ProviderException("Update failed", e);
6e6e3ea
             }
6e6e3ea
             break;