changeset 3332:adff75ebdc00

6924489: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_OPERATION_NOT_INITIALIZED Summary: Reset cipher state to un-initialized wherever necessary. Reviewed-by: weijun
author valeriep
date Wed, 22 Dec 2010 19:19:32 -0800
parents d4c2d2d72cfc
children 3254c3ae63fe
files src/share/classes/sun/security/pkcs11/P11Cipher.java
diffstat 1 files changed, 28 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/pkcs11/P11Cipher.java	Wed Dec 22 18:30:34 2010 -0800
+++ b/src/share/classes/sun/security/pkcs11/P11Cipher.java	Wed Dec 22 19:19:32 2010 -0800
@@ -395,6 +395,8 @@
             }
         } catch (PKCS11Exception e) {
             throw new ProviderException("Cancel failed", e);
+        } finally {
+            reset();
         }
     }
 
@@ -408,12 +410,18 @@
         if (session == null) {
             session = token.getOpSession();
         }
-        if (encrypt) {
-            token.p11.C_EncryptInit(session.id(),
-                    new CK_MECHANISM(mechanism, iv), p11Key.keyID);
-        } else {
-            token.p11.C_DecryptInit(session.id(),
-                    new CK_MECHANISM(mechanism, iv), p11Key.keyID);
+        try {
+            if (encrypt) {
+                token.p11.C_EncryptInit(session.id(),
+                        new CK_MECHANISM(mechanism, iv), p11Key.keyID);
+            } else {
+                token.p11.C_DecryptInit(session.id(),
+                        new CK_MECHANISM(mechanism, iv), p11Key.keyID);
+            }
+        } catch (PKCS11Exception ex) {
+            // release session when initialization failed
+            session = token.releaseSession(session);
+            throw ex;
         }
         bytesBuffered = 0;
         padBufferLen = 0;
@@ -448,6 +456,16 @@
         return result;
     }
 
+    // reset the states to the pre-initialized values
+    private void reset() {
+        initialized = false;
+        bytesBuffered = 0;
+        padBufferLen = 0;
+        if (session != null) {
+            session = token.releaseSession(session);
+        }
+    }
+
     // see JCE spec
     protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
         try {
@@ -566,6 +584,7 @@
                 throw (ShortBufferException)
                         (new ShortBufferException().initCause(e));
             }
+            reset();
             throw new ProviderException("update() failed", e);
         }
     }
@@ -683,6 +702,7 @@
                 throw (ShortBufferException)
                         (new ShortBufferException().initCause(e));
             }
+            reset();
             throw new ProviderException("update() failed", e);
         }
     }
@@ -729,10 +749,7 @@
             handleException(e);
             throw new ProviderException("doFinal() failed", e);
         } finally {
-            initialized = false;
-            bytesBuffered = 0;
-            padBufferLen = 0;
-            session = token.releaseSession(session);
+            reset();
         }
     }
 
@@ -806,9 +823,7 @@
             handleException(e);
             throw new ProviderException("doFinal() failed", e);
         } finally {
-            initialized = false;
-            bytesBuffered = 0;
-            session = token.releaseSession(session);
+            reset();
         }
     }