< prev index next >

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java

Print this page

        

@@ -23,11 +23,10 @@
  * questions.
  */
 
 package sun.security.pkcs11;
 
-import java.util.*;
 import java.nio.ByteBuffer;
 
 import java.security.*;
 import java.security.spec.AlgorithmParameterSpec;
 

@@ -52,31 +51,16 @@
  * @author  Andreas Sterbenz
  * @since   1.5
  */
 final class P11Mac extends MacSpi {
 
-    /* unitialized, all fields except session have arbitrary values */
-    private final static int S_UNINIT   = 1;
-
-    /* session initialized, no data processed yet */
-    private final static int S_RESET    = 2;
-
-    /* session initialized, data processed */
-    private final static int S_UPDATE   = 3;
-
-    /* transitional state after doFinal() before we go to S_UNINIT */
-    private final static int S_DOFINAL  = 4;
-
     // token instance
     private final Token token;
 
     // algorithm name
     private final String algorithm;
 
-    // mechanism id
-    private final long mechanism;
-
     // mechanism object
     private final CK_MECHANISM ckMechanism;
 
     // length of the MAC in bytes
     private final int macLength;

@@ -85,22 +69,21 @@
     private P11Key p11Key;
 
     // associated session, if any
     private Session session;
 
-    // state, one of S_* above
-    private int state;
+    // initialization status
+    private boolean initialized;
 
     // one byte buffer for the update(byte) method, initialized on demand
     private byte[] oneByte;
 
     P11Mac(Token token, String algorithm, long mechanism)
             throws PKCS11Exception {
         super();
         this.token = token;
         this.algorithm = algorithm;
-        this.mechanism = mechanism;
         Long params = null;
         switch ((int)mechanism) {
         case (int)CKM_MD5_HMAC:
             macLength = 16;
             break;

@@ -129,101 +112,105 @@
             break;
         default:
             throw new ProviderException("Unknown mechanism: " + mechanism);
         }
         ckMechanism = new CK_MECHANISM(mechanism, params);
-        state = S_UNINIT;
-        initialize();
     }
 
-    private void ensureInitialized() throws PKCS11Exception {
-        token.ensureValid();
-        if (state == S_UNINIT) {
-            initialize();
+    // reset the states to the pre-initialized values
+    private void reset(boolean doCancel) {
+        if (!initialized) {
+            return;
+        }
+        initialized = false;
+        try {
+            if (session == null) {
+                return;
+            }
+            if (doCancel && token.explicitCancel) {
+                cancelOperation();
+            }
+        } finally {
+            p11Key.decNativeKeyRef();
+            session = token.releaseSession(session);
         }
     }
 
     private void cancelOperation() {
         token.ensureValid();
-        if (state == S_UNINIT) {
-            return;
-        }
-        state = S_UNINIT;
-        if ((session == null) || (token.explicitCancel == false)) {
+        if (session.hasObjects() == false) {
+            session = token.killSession(session);
             return;
-        }
+        } else {
         try {
             token.p11.C_SignFinal(session.id(), 0);
         } catch (PKCS11Exception e) {
             throw new ProviderException("Cancel failed", e);
         }
     }
+    }
 
-    private void initialize() throws PKCS11Exception {
-        if (state == S_RESET) {
+    private void ensureInitialized() throws PKCS11Exception {
+        if (initialized) {
             return;
         }
+        if (p11Key == null) {
+            throw new ProviderException(
+                    "Operation cannot be performed without calling engineInit first");
+        }
+        token.ensureValid();
+        p11Key.incNativeKeyRef();
+        try {
         if (session == null) {
             session = token.getOpSession();
         }
-        if (p11Key != null) {
             token.p11.C_SignInit
                 (session.id(), ckMechanism, p11Key.keyID);
-            state = S_RESET;
-        } else {
-            state = S_UNINIT;
+        } catch (Throwable t) {
+            p11Key.decNativeKeyRef();
+            session = token.releaseSession(session);
+            throw t;
         }
+        initialized = true;
     }
 
     // see JCE spec
     protected int engineGetMacLength() {
         return macLength;
     }
 
     // see JCE spec
     protected void engineReset() {
-        // the framework insists on calling reset() after doFinal(),
-        // but we prefer to take care of reinitialization ourselves
-        if (state == S_DOFINAL) {
-            state = S_UNINIT;
-            return;
-        }
-        cancelOperation();
-        try {
-            initialize();
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("reset() failed, ", e);
-        }
+        reset(true);
     }
 
     // see JCE spec
     protected void engineInit(Key key, AlgorithmParameterSpec params)
             throws InvalidKeyException, InvalidAlgorithmParameterException {
         if (params != null) {
             throw new InvalidAlgorithmParameterException
                 ("Parameters not supported");
         }
-        cancelOperation();
+        reset(true);
         p11Key = P11SecretKeyFactory.convertKey(token, key, algorithm);
         try {
-            initialize();
+            ensureInitialized();
         } catch (PKCS11Exception e) {
             throw new InvalidKeyException("init() failed", e);
         }
     }
 
     // see JCE spec
     protected byte[] engineDoFinal() {
         try {
             ensureInitialized();
-            byte[] mac = token.p11.C_SignFinal(session.id(), 0);
-            state = S_DOFINAL;
-            return mac;
+            return token.p11.C_SignFinal(session.id(), 0);
         } catch (PKCS11Exception e) {
+            reset(true);
             throw new ProviderException("doFinal() failed", e);
         } finally {
-            session = token.releaseSession(session);
+            reset(false);
         }
     }
 
     // see JCE spec
     protected void engineUpdate(byte input) {

@@ -237,11 +224,10 @@
     // see JCE spec
     protected void engineUpdate(byte[] b, int ofs, int len) {
         try {
             ensureInitialized();
             token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
-            state = S_UPDATE;
         } catch (PKCS11Exception e) {
             throw new ProviderException("update() failed", e);
         }
     }
 

@@ -259,11 +245,10 @@
             }
             long addr = ((DirectBuffer)byteBuffer).address();
             int ofs = byteBuffer.position();
             token.p11.C_SignUpdate(session.id(), addr + ofs, null, 0, len);
             byteBuffer.position(ofs + len);
-            state = S_UPDATE;
         } catch (PKCS11Exception e) {
             throw new ProviderException("update() failed", e);
         }
     }
 }
< prev index next >