changeset 4908:cdc128128044

6414899: P11Digest should support cloning Summary: Enhanced the PKCS11 Digest implementation to support cloning Reviewed-by: vinnie
author valeriep
date Thu, 05 Jan 2012 18:18:04 -0800
parents 0194fe5ca404
children e6ef778c1df4
files make/sun/security/pkcs11/mapfile-vers src/share/classes/sun/security/pkcs11/P11Digest.java src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java src/share/lib/security/sunpkcs11-solaris.cfg src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h test/sun/security/pkcs11/MessageDigest/TestCloning.java
diffstat 6 files changed, 501 insertions(+), 228 deletions(-) [+]
line wrap: on
line diff
--- a/make/sun/security/pkcs11/mapfile-vers	Wed Jan 04 03:49:35 2012 -0800
+++ b/make/sun/security/pkcs11/mapfile-vers	Thu Jan 05 18:18:04 2012 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -47,8 +47,8 @@
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseSession;
 #		Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseAllSessions;
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionInfo;
-#		Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState;
-#		Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState;
+		Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState;
+		Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState;
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login;
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout;
 		Java_sun_security_pkcs11_wrapper_PKCS11_C_1CreateObject;
--- a/src/share/classes/sun/security/pkcs11/P11Digest.java	Wed Jan 04 03:49:35 2012 -0800
+++ b/src/share/classes/sun/security/pkcs11/P11Digest.java	Thu Jan 05 18:18:04 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,13 +49,12 @@
  * @author  Andreas Sterbenz
  * @since   1.5
  */
-final class P11Digest extends MessageDigestSpi {
+final class P11Digest extends MessageDigestSpi implements Cloneable {
 
-    /* unitialized, fields uninitialized, no session acquired */
+    /* fields initialized, no session acquired */
     private final static int S_BLANK    = 1;
 
-    // data in buffer, all fields valid, session acquired
-    // but digest not initialized
+    /* data in buffer, session acquired, but digest not initialized */
     private final static int S_BUFFERED = 2;
 
     /* session initialized for digesting */
@@ -69,8 +68,8 @@
     // algorithm name
     private final String algorithm;
 
-    // mechanism id
-    private final long mechanism;
+    // mechanism id object
+    private final CK_MECHANISM mechanism;
 
     // length of the digest in bytes
     private final int digestLength;
@@ -81,11 +80,8 @@
     // current state, one of S_* above
     private int state;
 
-    // one byte buffer for the update(byte) method, initialized on demand
-    private byte[] oneByte;
-
     // buffer to reduce number of JNI calls
-    private final byte[] buffer;
+    private byte[] buffer;
 
     // offset into the buffer
     private int bufOfs;
@@ -94,7 +90,7 @@
         super();
         this.token = token;
         this.algorithm = algorithm;
-        this.mechanism = mechanism;
+        this.mechanism = new CK_MECHANISM(mechanism);
         switch ((int)mechanism) {
         case (int)CKM_MD2:
         case (int)CKM_MD5:
@@ -117,7 +113,6 @@
         }
         buffer = new byte[BUFFER_SIZE];
         state = S_BLANK;
-        engineReset();
     }
 
     // see JCA spec
@@ -125,44 +120,31 @@
         return digestLength;
     }
 
-    private void cancelOperation() {
-        token.ensureValid();
-        if (session == null) {
-            return;
-        }
-        if ((state != S_INIT) || (token.explicitCancel == false)) {
-            return;
-        }
-        // need to explicitly "cancel" active op by finishing it
-        try {
-            token.p11.C_DigestFinal(session.id(), buffer, 0, buffer.length);
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("cancel() failed", e);
-        } finally {
-            state = S_BUFFERED;
-        }
-    }
-
     private void fetchSession() {
         token.ensureValid();
         if (state == S_BLANK) {
-            engineReset();
+            try {
+                session = token.getOpSession();
+                state = S_BUFFERED;
+            } catch (PKCS11Exception e) {
+                throw new ProviderException("No more session available", e);
+            }
         }
     }
 
     // see JCA spec
     protected void engineReset() {
-        try {
-            cancelOperation();
-            bufOfs = 0;
-            if (session == null) {
-                session = token.getOpSession();
+        token.ensureValid();
+
+        if (session != null) {
+            if (state == S_INIT && token.explicitCancel == true) {
+                session = token.killSession(session);
+            } else {
+                session = token.releaseSession(session);
             }
-            state = S_BUFFERED;
-        } catch (PKCS11Exception e) {
-            state = S_BLANK;
-            throw new ProviderException("reset() failed, ", e);
         }
+        state = S_BLANK;
+        bufOfs = 0;
     }
 
     // see JCA spec
@@ -180,18 +162,22 @@
     protected int engineDigest(byte[] digest, int ofs, int len)
             throws DigestException {
         if (len < digestLength) {
-            throw new DigestException("Length must be at least " + digestLength);
+            throw new DigestException("Length must be at least " +
+                    digestLength);
         }
+
         fetchSession();
         try {
             int n;
             if (state == S_BUFFERED) {
-                n = token.p11.C_DigestSingle(session.id(),
-                        new CK_MECHANISM(mechanism),
-                        buffer, 0, bufOfs, digest, ofs, len);
+                n = token.p11.C_DigestSingle(session.id(), mechanism, buffer, 0,
+                        bufOfs, digest, ofs, len);
+                bufOfs = 0;
             } else {
                 if (bufOfs != 0) {
-                    doUpdate(buffer, 0, bufOfs);
+                    token.p11.C_DigestUpdate(session.id(), 0, buffer, 0,
+                            bufOfs);
+                    bufOfs = 0;
                 }
                 n = token.p11.C_DigestFinal(session.id(), digest, ofs, len);
             }
@@ -202,36 +188,44 @@
         } catch (PKCS11Exception e) {
             throw new ProviderException("digest() failed", e);
         } finally {
-            state = S_BLANK;
-            bufOfs = 0;
-            session = token.releaseSession(session);
+            engineReset();
         }
     }
 
     // see JCA spec
     protected void engineUpdate(byte in) {
-        if (oneByte == null) {
-            oneByte = new byte[1];
-        }
-        oneByte[0] = in;
-        engineUpdate(oneByte, 0, 1);
+        byte[] temp = { in };
+        engineUpdate(temp, 0, 1);
     }
 
     // see JCA spec
     protected void engineUpdate(byte[] in, int ofs, int len) {
-        fetchSession();
         if (len <= 0) {
             return;
         }
-        if ((bufOfs != 0) && (bufOfs + len > buffer.length)) {
-            doUpdate(buffer, 0, bufOfs);
-            bufOfs = 0;
-        }
-        if (bufOfs + len > buffer.length) {
-            doUpdate(in, ofs, len);
-        } else {
-            System.arraycopy(in, ofs, buffer, bufOfs, len);
-            bufOfs += len;
+
+        fetchSession();
+        try {
+            if (state == S_BUFFERED) {
+                token.p11.C_DigestInit(session.id(), mechanism);
+                state = S_INIT;
+            }
+            if ((bufOfs != 0) && (bufOfs + len > buffer.length)) {
+                // process the buffered data
+                token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
+                bufOfs = 0;
+            }
+            if (bufOfs + len > buffer.length) {
+                // process the new data
+                token.p11.C_DigestUpdate(session.id(), 0, in, ofs, len);
+             } else {
+                // buffer the new data
+                System.arraycopy(in, ofs, buffer, bufOfs, len);
+                bufOfs += len;
+            }
+        } catch (PKCS11Exception e) {
+            engineReset();
+            throw new ProviderException("update() failed", e);
         }
     }
 
@@ -239,11 +233,7 @@
     // the master secret is sensitive. We may want to consider making this
     // method public in a future release.
     protected void implUpdate(SecretKey key) throws InvalidKeyException {
-        fetchSession();
-        if (bufOfs != 0) {
-            doUpdate(buffer, 0, bufOfs);
-            bufOfs = 0;
-        }
+
         // SunJSSE calls this method only if the key does not have a RAW
         // encoding, i.e. if it is sensitive. Therefore, no point in calling
         // SecretKeyFactory to try to convert it. Just verify it ourselves.
@@ -252,60 +242,77 @@
         }
         P11Key p11Key = (P11Key)key;
         if (p11Key.token != token) {
-            throw new InvalidKeyException("Not a P11Key of this provider: " + key);
+            throw new InvalidKeyException("Not a P11Key of this provider: " +
+                    key);
         }
+
+        fetchSession();
         try {
             if (state == S_BUFFERED) {
-                token.p11.C_DigestInit(session.id(), new CK_MECHANISM(mechanism));
+                token.p11.C_DigestInit(session.id(), mechanism);
                 state = S_INIT;
             }
+
+            if (bufOfs != 0) {
+                token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
+                bufOfs = 0;
+            }
             token.p11.C_DigestKey(session.id(), p11Key.keyID);
         } catch (PKCS11Exception e) {
+            engineReset();
             throw new ProviderException("update(SecretKey) failed", e);
         }
     }
 
     // see JCA spec
     protected void engineUpdate(ByteBuffer byteBuffer) {
-        fetchSession();
         int len = byteBuffer.remaining();
         if (len <= 0) {
             return;
         }
+
         if (byteBuffer instanceof DirectBuffer == false) {
             super.engineUpdate(byteBuffer);
             return;
         }
+
+        fetchSession();
         long addr = ((DirectBuffer)byteBuffer).address();
         int ofs = byteBuffer.position();
         try {
             if (state == S_BUFFERED) {
-                token.p11.C_DigestInit(session.id(), new CK_MECHANISM(mechanism));
+                token.p11.C_DigestInit(session.id(), mechanism);
                 state = S_INIT;
-                if (bufOfs != 0) {
-                    doUpdate(buffer, 0, bufOfs);
-                    bufOfs = 0;
-                }
+            }
+            if (bufOfs != 0) {
+                token.p11.C_DigestUpdate(session.id(), 0, buffer, 0, bufOfs);
+                bufOfs = 0;
             }
             token.p11.C_DigestUpdate(session.id(), addr + ofs, null, 0, len);
             byteBuffer.position(ofs + len);
         } catch (PKCS11Exception e) {
+            engineReset();
             throw new ProviderException("update() failed", e);
         }
     }
 
-    private void doUpdate(byte[] in, int ofs, int len) {
-        if (len <= 0) {
-            return;
+    public Object clone() throws CloneNotSupportedException {
+        P11Digest copy = (P11Digest) super.clone();
+        copy.buffer = buffer.clone();
+        try {
+            if (session != null) {
+                copy.session = copy.token.getOpSession();
+            }
+            if (state == S_INIT) {
+                byte[] stateValues =
+                    token.p11.C_GetOperationState(session.id());
+                token.p11.C_SetOperationState(copy.session.id(),
+                                              stateValues, 0, 0);
+            }
+        } catch (PKCS11Exception e) {
+            throw (CloneNotSupportedException)
+                (new CloneNotSupportedException(algorithm).initCause(e));
         }
-        try {
-            if (state == S_BUFFERED) {
-                token.p11.C_DigestInit(session.id(), new CK_MECHANISM(mechanism));
-                state = S_INIT;
-            }
-            token.p11.C_DigestUpdate(session.id(), 0, in, ofs, len);
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("update() failed", e);
-        }
+        return copy;
     }
 }
--- a/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java	Wed Jan 04 03:49:35 2012 -0800
+++ b/src/share/classes/sun/security/pkcs11/wrapper/PKCS11.java	Thu Jan 05 18:18:04 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
@@ -133,14 +133,15 @@
      * @preconditions (pkcs11ModulePath <> null)
      * @postconditions
      */
-    PKCS11(String pkcs11ModulePath, String functionListName) throws IOException {
+    PKCS11(String pkcs11ModulePath, String functionListName)
+            throws IOException {
         connect(pkcs11ModulePath, functionListName);
         this.pkcs11ModulePath = pkcs11ModulePath;
     }
 
-    public static synchronized PKCS11 getInstance(String pkcs11ModulePath, String functionList,
-            CK_C_INITIALIZE_ARGS pInitArgs, boolean omitInitialize)
-            throws IOException, PKCS11Exception {
+    public static synchronized PKCS11 getInstance(String pkcs11ModulePath,
+            String functionList, CK_C_INITIALIZE_ARGS pInitArgs,
+            boolean omitInitialize) throws IOException, PKCS11Exception {
         // we may only call C_Initialize once per native .so/.dll
         // so keep a cache using the (non-canonicalized!) path
         PKCS11 pkcs11 = moduleMap.get(pkcs11ModulePath);
@@ -177,7 +178,8 @@
      * @preconditions (pkcs11ModulePath <> null)
      * @postconditions
      */
-    private native void connect(String pkcs11ModulePath, String functionListName) throws IOException;
+    private native void connect(String pkcs11ModulePath, String functionListName)
+            throws IOException;
 
     /**
      * Disconnects the PKCS#11 library from this object. After calling this
@@ -255,7 +257,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native long[] C_GetSlotList(boolean tokenPresent) throws PKCS11Exception;
+    public native long[] C_GetSlotList(boolean tokenPresent)
+            throws PKCS11Exception;
 
 
     /**
@@ -287,7 +290,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native CK_TOKEN_INFO C_GetTokenInfo(long slotID) throws PKCS11Exception;
+    public native CK_TOKEN_INFO C_GetTokenInfo(long slotID)
+            throws PKCS11Exception;
 
 
     /**
@@ -322,7 +326,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native CK_MECHANISM_INFO C_GetMechanismInfo(long slotID, long type) throws PKCS11Exception;
+    public native CK_MECHANISM_INFO C_GetMechanismInfo(long slotID, long type)
+            throws PKCS11Exception;
 
 
     /**
@@ -339,7 +344,8 @@
      * @preconditions
      * @postconditions
      */
-//    public native void C_InitToken(long slotID, char[] pPin, char[] pLabel) throws PKCS11Exception;
+//    public native void C_InitToken(long slotID, char[] pPin, char[] pLabel)
+//            throws PKCS11Exception;
 
 
     /**
@@ -354,7 +360,8 @@
      * @preconditions
      * @postconditions
      */
-//    public native void C_InitPIN(long hSession, char[] pPin) throws PKCS11Exception;
+//    public native void C_InitPIN(long hSession, char[] pPin)
+//            throws PKCS11Exception;
 
 
     /**
@@ -371,7 +378,8 @@
      * @preconditions
      * @postconditions
      */
-//    public native void C_SetPIN(long hSession, char[] pOldPin, char[] pNewPin) throws PKCS11Exception;
+//    public native void C_SetPIN(long hSession, char[] pOldPin, char[] pNewPin)
+//            throws PKCS11Exception;
 
 
 
@@ -398,7 +406,8 @@
      * @preconditions
      * @postconditions
      */
-    public native long C_OpenSession(long slotID, long flags, Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception;
+    public native long C_OpenSession(long slotID, long flags,
+            Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception;
 
 
     /**
@@ -440,7 +449,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native CK_SESSION_INFO C_GetSessionInfo(long hSession) throws PKCS11Exception;
+    public native CK_SESSION_INFO C_GetSessionInfo(long hSession)
+            throws PKCS11Exception;
 
 
     /**
@@ -457,7 +467,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-//    public native byte[] C_GetOperationState(long hSession) throws PKCS11Exception;
+    public native byte[] C_GetOperationState(long hSession)
+            throws PKCS11Exception;
 
 
     /**
@@ -478,7 +489,8 @@
      * @preconditions
      * @postconditions
      */
-//    public native void C_SetOperationState(long hSession, byte[] pOperationState, long hEncryptionKey, long hAuthenticationKey) throws PKCS11Exception;
+    public native void C_SetOperationState(long hSession, byte[] pOperationState,
+            long hEncryptionKey, long hAuthenticationKey) throws PKCS11Exception;
 
 
     /**
@@ -495,7 +507,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_Login(long hSession, long userType, char[] pPin) throws PKCS11Exception;
+    public native void C_Login(long hSession, long userType, char[] pPin)
+            throws PKCS11Exception;
 
 
     /**
@@ -531,7 +544,8 @@
      * @preconditions
      * @postconditions
      */
-    public native long C_CreateObject(long hSession, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+    public native long C_CreateObject(long hSession, CK_ATTRIBUTE[] pTemplate)
+            throws PKCS11Exception;
 
 
     /**
@@ -552,7 +566,8 @@
      * @preconditions
      * @postconditions
      */
-    public native long C_CopyObject(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+    public native long C_CopyObject(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
 
 
     /**
@@ -567,7 +582,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_DestroyObject(long hSession, long hObject) throws PKCS11Exception;
+    public native void C_DestroyObject(long hSession, long hObject)
+            throws PKCS11Exception;
 
 
     /**
@@ -584,7 +600,8 @@
      * @preconditions
      * @postconditions
      */
-//    public native long C_GetObjectSize(long hSession, long hObject) throws PKCS11Exception;
+//    public native long C_GetObjectSize(long hSession, long hObject)
+//            throws PKCS11Exception;
 
 
     /**
@@ -604,7 +621,8 @@
      * @preconditions (pTemplate <> null)
      * @postconditions (result <> null)
      */
-    public native void C_GetAttributeValue(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+    public native void C_GetAttributeValue(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
 
 
     /**
@@ -623,7 +641,8 @@
      * @preconditions (pTemplate <> null)
      * @postconditions
      */
-    public native void C_SetAttributeValue(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+    public native void C_SetAttributeValue(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
 
 
     /**
@@ -640,7 +659,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_FindObjectsInit(long hSession, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+    public native void C_FindObjectsInit(long hSession, CK_ATTRIBUTE[] pTemplate)
+            throws PKCS11Exception;
 
 
     /**
@@ -659,7 +679,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native long[] C_FindObjects(long hSession, long ulMaxObjectCount) throws PKCS11Exception;
+    public native long[] C_FindObjects(long hSession, long ulMaxObjectCount)
+            throws PKCS11Exception;
 
 
     /**
@@ -695,7 +716,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_EncryptInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+    public native void C_EncryptInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
 
 
     /**
@@ -713,7 +735,8 @@
      * @preconditions (pData <> null)
      * @postconditions (result <> null)
      */
-    public native int C_Encrypt(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+    public native int C_Encrypt(long hSession, byte[] in, int inOfs, int inLen,
+            byte[] out, int outOfs, int outLen) throws PKCS11Exception;
 
 
     /**
@@ -732,7 +755,9 @@
      * @preconditions (pPart <> null)
      * @postconditions
      */
-    public native int C_EncryptUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+    public native int C_EncryptUpdate(long hSession, long directIn, byte[] in,
+            int inOfs, int inLen, long directOut, byte[] out, int outOfs,
+            int outLen) throws PKCS11Exception;
 
 
     /**
@@ -749,7 +774,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native int C_EncryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+    public native int C_EncryptFinal(long hSession, long directOut, byte[] out,
+            int outOfs, int outLen) throws PKCS11Exception;
 
 
     /**
@@ -766,7 +792,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_DecryptInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+    public native void C_DecryptInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
 
 
     /**
@@ -785,7 +812,8 @@
      * @preconditions (pEncryptedPart <> null)
      * @postconditions (result <> null)
      */
-    public native int C_Decrypt(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+    public native int C_Decrypt(long hSession, byte[] in, int inOfs, int inLen,
+            byte[] out, int outOfs, int outLen) throws PKCS11Exception;
 
 
     /**
@@ -805,7 +833,9 @@
      * @preconditions (pEncryptedPart <> null)
      * @postconditions
      */
-    public native int C_DecryptUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+    public native int C_DecryptUpdate(long hSession, long directIn, byte[] in,
+            int inOfs, int inLen, long directOut, byte[] out, int outOfs,
+            int outLen) throws PKCS11Exception;
 
 
     /**
@@ -822,7 +852,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native int C_DecryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception;
+    public native int C_DecryptFinal(long hSession, long directOut, byte[] out,
+            int outOfs, int outLen) throws PKCS11Exception;
 
 
 
@@ -842,7 +873,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_DigestInit(long hSession, CK_MECHANISM pMechanism) throws PKCS11Exception;
+    public native void C_DigestInit(long hSession, CK_MECHANISM pMechanism)
+            throws PKCS11Exception;
 
 
     // note that C_DigestSingle does not exist in PKCS#11
@@ -863,7 +895,9 @@
      * @preconditions (data <> null)
      * @postconditions (result <> null)
      */
-    public native int C_DigestSingle(long hSession, CK_MECHANISM pMechanism, byte[] in, int inOfs, int inLen, byte[] digest, int digestOfs, int digestLen) throws PKCS11Exception;
+    public native int C_DigestSingle(long hSession, CK_MECHANISM pMechanism,
+            byte[] in, int inOfs, int inLen, byte[] digest, int digestOfs,
+            int digestLen) throws PKCS11Exception;
 
 
     /**
@@ -879,7 +913,8 @@
      * @preconditions (pPart <> null)
      * @postconditions
      */
-    public native void C_DigestUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception;
+    public native void C_DigestUpdate(long hSession, long directIn, byte[] in,
+            int inOfs, int inLen) throws PKCS11Exception;
 
 
     /**
@@ -896,7 +931,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_DigestKey(long hSession, long hKey) throws PKCS11Exception;
+    public native void C_DigestKey(long hSession, long hKey)
+            throws PKCS11Exception;
 
 
     /**
@@ -912,7 +948,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native int C_DigestFinal(long hSession, byte[] pDigest, int digestOfs, int digestLen) throws PKCS11Exception;
+    public native int C_DigestFinal(long hSession, byte[] pDigest, int digestOfs,
+            int digestLen) throws PKCS11Exception;
 
 
 
@@ -937,7 +974,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_SignInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+    public native void C_SignInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
 
 
     /**
@@ -957,7 +995,8 @@
      * @preconditions (pData <> null)
      * @postconditions (result <> null)
      */
-    public native byte[] C_Sign(long hSession, byte[] pData) throws PKCS11Exception;
+    public native byte[] C_Sign(long hSession, byte[] pData)
+            throws PKCS11Exception;
 
 
     /**
@@ -974,7 +1013,8 @@
      * @preconditions (pPart <> null)
      * @postconditions
      */
-    public native void C_SignUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception;
+    public native void C_SignUpdate(long hSession, long directIn, byte[] in,
+            int inOfs, int inLen) throws PKCS11Exception;
 
 
     /**
@@ -991,7 +1031,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native byte[] C_SignFinal(long hSession, int expectedLen) throws PKCS11Exception;
+    public native byte[] C_SignFinal(long hSession, int expectedLen)
+            throws PKCS11Exception;
 
 
     /**
@@ -1009,7 +1050,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_SignRecoverInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+    public native void C_SignRecoverInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
 
 
     /**
@@ -1028,7 +1070,9 @@
      * @preconditions (pData <> null)
      * @postconditions (result <> null)
      */
-    public native int C_SignRecover(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOufs, int outLen) throws PKCS11Exception;
+    public native int C_SignRecover(long hSession, byte[] in, int inOfs,
+            int inLen, byte[] out, int outOufs, int outLen)
+            throws PKCS11Exception;
 
 
 
@@ -1052,7 +1096,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_VerifyInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+    public native void C_VerifyInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
 
 
     /**
@@ -1071,7 +1116,8 @@
      * @preconditions (pData <> null) and (pSignature <> null)
      * @postconditions
      */
-    public native void C_Verify(long hSession, byte[] pData, byte[] pSignature) throws PKCS11Exception;
+    public native void C_Verify(long hSession, byte[] pData, byte[] pSignature)
+            throws PKCS11Exception;
 
 
     /**
@@ -1088,7 +1134,8 @@
      * @preconditions (pPart <> null)
      * @postconditions
      */
-    public native void C_VerifyUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception;
+    public native void C_VerifyUpdate(long hSession, long directIn, byte[] in,
+            int inOfs, int inLen) throws PKCS11Exception;
 
 
     /**
@@ -1104,7 +1151,8 @@
      * @preconditions (pSignature <> null)
      * @postconditions
      */
-    public native void C_VerifyFinal(long hSession, byte[] pSignature) throws PKCS11Exception;
+    public native void C_VerifyFinal(long hSession, byte[] pSignature)
+            throws PKCS11Exception;
 
 
     /**
@@ -1122,7 +1170,8 @@
      * @preconditions
      * @postconditions
      */
-    public native void C_VerifyRecoverInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+    public native void C_VerifyRecoverInit(long hSession,
+            CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
 
 
     /**
@@ -1140,7 +1189,9 @@
      * @preconditions (pSignature <> null)
      * @postconditions (result <> null)
      */
-    public native int C_VerifyRecover(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOufs, int outLen) throws PKCS11Exception;
+    public native int C_VerifyRecover(long hSession, byte[] in, int inOfs,
+            int inLen, byte[] out, int outOufs, int outLen)
+            throws PKCS11Exception;
 
 
 
@@ -1164,7 +1215,8 @@
      * @preconditions (pPart <> null)
      * @postconditions
      */
-//    public native byte[] C_DigestEncryptUpdate(long hSession, byte[] pPart) throws PKCS11Exception;
+//    public native byte[] C_DigestEncryptUpdate(long hSession, byte[] pPart)
+//            throws PKCS11Exception;
 
 
     /**
@@ -1184,7 +1236,8 @@
      * @preconditions (pEncryptedPart <> null)
      * @postconditions
      */
-//    public native byte[] C_DecryptDigestUpdate(long hSession, byte[] pEncryptedPart) throws PKCS11Exception;
+//    public native byte[] C_DecryptDigestUpdate(long hSession,
+//            byte[] pEncryptedPart) throws PKCS11Exception;
 
 
     /**
@@ -1204,7 +1257,8 @@
      * @preconditions (pPart <> null)
      * @postconditions
      */
-//    public native byte[] C_SignEncryptUpdate(long hSession, byte[] pPart) throws PKCS11Exception;
+//    public native byte[] C_SignEncryptUpdate(long hSession, byte[] pPart)
+//            throws PKCS11Exception;
 
 
     /**
@@ -1224,7 +1278,8 @@
      * @preconditions (pEncryptedPart <> null)
      * @postconditions
      */
-//    public native byte[] C_DecryptVerifyUpdate(long hSession, byte[] pEncryptedPart) throws PKCS11Exception;
+//    public native byte[] C_DecryptVerifyUpdate(long hSession,
+//            byte[] pEncryptedPart) throws PKCS11Exception;
 
 
 
@@ -1250,7 +1305,8 @@
      * @preconditions
      * @postconditions
      */
-    public native long C_GenerateKey(long hSession, CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+    public native long C_GenerateKey(long hSession, CK_MECHANISM pMechanism,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
 
 
     /**
@@ -1280,9 +1336,8 @@
      * @postconditions (result <> null) and (result.length == 2)
      */
     public native long[] C_GenerateKeyPair(long hSession,
-                                   CK_MECHANISM pMechanism,
-                                   CK_ATTRIBUTE[] pPublicKeyTemplate,
-                                   CK_ATTRIBUTE[] pPrivateKeyTemplate) throws PKCS11Exception;
+            CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pPublicKeyTemplate,
+            CK_ATTRIBUTE[] pPrivateKeyTemplate) throws PKCS11Exception;
 
 
 
@@ -1305,7 +1360,8 @@
      * @preconditions
      * @postconditions (result <> null)
      */
-    public native byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism, long hWrappingKey, long hKey) throws PKCS11Exception;
+    public native byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism,
+            long hWrappingKey, long hKey) throws PKCS11Exception;
 
 
     /**
@@ -1331,8 +1387,8 @@
      * @postconditions
      */
     public native long C_UnwrapKey(long hSession, CK_MECHANISM pMechanism,
-                          long hUnwrappingKey, byte[] pWrappedKey,
-                          CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+            long hUnwrappingKey, byte[] pWrappedKey, CK_ATTRIBUTE[] pTemplate)
+            throws PKCS11Exception;
 
 
     /**
@@ -1356,7 +1412,7 @@
      * @postconditions
      */
     public native long C_DeriveKey(long hSession, CK_MECHANISM pMechanism,
-                          long hBaseKey, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+            long hBaseKey, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
 
 
 
@@ -1377,7 +1433,8 @@
      * @preconditions (pSeed <> null)
      * @postconditions
      */
-    public native void C_SeedRandom(long hSession, byte[] pSeed) throws PKCS11Exception;
+    public native void C_SeedRandom(long hSession, byte[] pSeed)
+            throws PKCS11Exception;
 
 
     /**
@@ -1393,7 +1450,8 @@
      * @preconditions (randomData <> null)
      * @postconditions
      */
-    public native void C_GenerateRandom(long hSession, byte[] randomData) throws PKCS11Exception;
+    public native void C_GenerateRandom(long hSession, byte[] randomData)
+            throws PKCS11Exception;
 
 
 
@@ -1413,7 +1471,8 @@
      * @preconditions
      * @postconditions
      */
-//    public native void C_GetFunctionStatus(long hSession) throws PKCS11Exception;
+//    public native void C_GetFunctionStatus(long hSession)
+//            throws PKCS11Exception;
 
 
     /**
@@ -1450,7 +1509,8 @@
      * @preconditions (pRserved == null)
      * @postconditions
      */
-//    public native long C_WaitForSlotEvent(long flags, Object pRserved) throws PKCS11Exception;
+//    public native long C_WaitForSlotEvent(long flags, Object pRserved)
+//            throws PKCS11Exception;
 
     /**
      * Returns the string representation of this object.
@@ -1476,7 +1536,8 @@
 // parent. Used for tokens that only support single threaded access
 static class SynchronizedPKCS11 extends PKCS11 {
 
-    SynchronizedPKCS11(String pkcs11ModulePath, String functionListName) throws IOException {
+    SynchronizedPKCS11(String pkcs11ModulePath, String functionListName)
+            throws IOException {
         super(pkcs11ModulePath, functionListName);
     }
 
@@ -1484,7 +1545,8 @@
         super.C_Initialize(pInitArgs);
     }
 
-    public synchronized void C_Finalize(Object pReserved) throws PKCS11Exception {
+    public synchronized void C_Finalize(Object pReserved)
+            throws PKCS11Exception {
         super.C_Finalize(pReserved);
     }
 
@@ -1492,39 +1554,48 @@
         return super.C_GetInfo();
     }
 
-    public synchronized long[] C_GetSlotList(boolean tokenPresent) throws PKCS11Exception {
+    public synchronized long[] C_GetSlotList(boolean tokenPresent)
+            throws PKCS11Exception {
         return super.C_GetSlotList(tokenPresent);
     }
 
-    public synchronized CK_SLOT_INFO C_GetSlotInfo(long slotID) throws PKCS11Exception {
+    public synchronized CK_SLOT_INFO C_GetSlotInfo(long slotID)
+            throws PKCS11Exception {
         return super.C_GetSlotInfo(slotID);
     }
 
-    public synchronized CK_TOKEN_INFO C_GetTokenInfo(long slotID) throws PKCS11Exception {
+    public synchronized CK_TOKEN_INFO C_GetTokenInfo(long slotID)
+            throws PKCS11Exception {
         return super.C_GetTokenInfo(slotID);
     }
 
-    public synchronized long[] C_GetMechanismList(long slotID) throws PKCS11Exception {
+    public synchronized long[] C_GetMechanismList(long slotID)
+            throws PKCS11Exception {
         return super.C_GetMechanismList(slotID);
     }
 
-    public synchronized CK_MECHANISM_INFO C_GetMechanismInfo(long slotID, long type) throws PKCS11Exception {
+    public synchronized CK_MECHANISM_INFO C_GetMechanismInfo(long slotID,
+            long type) throws PKCS11Exception {
         return super.C_GetMechanismInfo(slotID, type);
     }
 
-    public synchronized long C_OpenSession(long slotID, long flags, Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception {
+    public synchronized long C_OpenSession(long slotID, long flags,
+            Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception {
         return super.C_OpenSession(slotID, flags, pApplication, Notify);
     }
 
-    public synchronized void C_CloseSession(long hSession) throws PKCS11Exception {
+    public synchronized void C_CloseSession(long hSession)
+            throws PKCS11Exception {
         super.C_CloseSession(hSession);
     }
 
-    public synchronized CK_SESSION_INFO C_GetSessionInfo(long hSession) throws PKCS11Exception {
+    public synchronized CK_SESSION_INFO C_GetSessionInfo(long hSession)
+            throws PKCS11Exception {
         return super.C_GetSessionInfo(hSession);
     }
 
-    public synchronized void C_Login(long hSession, long userType, char[] pPin) throws PKCS11Exception {
+    public synchronized void C_Login(long hSession, long userType, char[] pPin)
+            throws PKCS11Exception {
         super.C_Login(hSession, userType, pPin);
     }
 
@@ -1532,157 +1603,207 @@
         super.C_Logout(hSession);
     }
 
-    public synchronized long C_CreateObject(long hSession, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+    public synchronized long C_CreateObject(long hSession,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
         return super.C_CreateObject(hSession, pTemplate);
     }
 
-    public synchronized long C_CopyObject(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+    public synchronized long C_CopyObject(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
         return super.C_CopyObject(hSession, hObject, pTemplate);
     }
 
-    public synchronized void C_DestroyObject(long hSession, long hObject) throws PKCS11Exception {
+    public synchronized void C_DestroyObject(long hSession, long hObject)
+            throws PKCS11Exception {
         super.C_DestroyObject(hSession, hObject);
     }
 
-    public synchronized void C_GetAttributeValue(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+    public synchronized void C_GetAttributeValue(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
         super.C_GetAttributeValue(hSession, hObject, pTemplate);
     }
 
-    public synchronized void C_SetAttributeValue(long hSession, long hObject, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+    public synchronized void C_SetAttributeValue(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
         super.C_SetAttributeValue(hSession, hObject, pTemplate);
     }
 
-    public synchronized void C_FindObjectsInit(long hSession, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+    public synchronized void C_FindObjectsInit(long hSession,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
         super.C_FindObjectsInit(hSession, pTemplate);
     }
 
-    public synchronized long[] C_FindObjects(long hSession, long ulMaxObjectCount) throws PKCS11Exception {
+    public synchronized long[] C_FindObjects(long hSession,
+            long ulMaxObjectCount) throws PKCS11Exception {
         return super.C_FindObjects(hSession, ulMaxObjectCount);
     }
 
-    public synchronized void C_FindObjectsFinal(long hSession) throws PKCS11Exception {
+    public synchronized void C_FindObjectsFinal(long hSession)
+            throws PKCS11Exception {
         super.C_FindObjectsFinal(hSession);
     }
 
-    public synchronized void C_EncryptInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+    public synchronized void C_EncryptInit(long hSession,
+            CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
         super.C_EncryptInit(hSession, pMechanism, hKey);
     }
 
-    public synchronized int C_Encrypt(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
+    public synchronized int C_Encrypt(long hSession, byte[] in, int inOfs,
+            int inLen, byte[] out, int outOfs, int outLen)
+            throws PKCS11Exception {
         return super.C_Encrypt(hSession, in, inOfs, inLen, out, outOfs, outLen);
     }
 
-    public synchronized int C_EncryptUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
-        return super.C_EncryptUpdate(hSession, directIn, in, inOfs, inLen, directOut, out, outOfs, outLen);
+    public synchronized int C_EncryptUpdate(long hSession, long directIn,
+            byte[] in, int inOfs, int inLen, long directOut, byte[] out,
+            int outOfs, int outLen) throws PKCS11Exception {
+        return super.C_EncryptUpdate(hSession, directIn, in, inOfs, inLen,
+                directOut, out, outOfs, outLen);
     }
 
-    public synchronized int C_EncryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
+    public synchronized int C_EncryptFinal(long hSession, long directOut,
+            byte[] out, int outOfs, int outLen) throws PKCS11Exception {
         return super.C_EncryptFinal(hSession, directOut, out, outOfs, outLen);
     }
 
-    public synchronized void C_DecryptInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+    public synchronized void C_DecryptInit(long hSession,
+            CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
         super.C_DecryptInit(hSession, pMechanism, hKey);
     }
 
-    public synchronized int C_Decrypt(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
+    public synchronized int C_Decrypt(long hSession, byte[] in, int inOfs,
+            int inLen, byte[] out, int outOfs, int outLen)
+            throws PKCS11Exception {
         return super.C_Decrypt(hSession, in, inOfs, inLen, out, outOfs, outLen);
     }
 
-    public synchronized int C_DecryptUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
-        return super.C_DecryptUpdate(hSession, directIn, in, inOfs, inLen, directOut, out, outOfs, outLen);
+    public synchronized int C_DecryptUpdate(long hSession, long directIn,
+            byte[] in, int inOfs, int inLen, long directOut, byte[] out,
+            int outOfs, int outLen) throws PKCS11Exception {
+        return super.C_DecryptUpdate(hSession, directIn, in, inOfs, inLen,
+                directOut, out, outOfs, outLen);
     }
 
-    public synchronized int C_DecryptFinal(long hSession, long directOut, byte[] out, int outOfs, int outLen) throws PKCS11Exception {
+    public synchronized int C_DecryptFinal(long hSession, long directOut,
+            byte[] out, int outOfs, int outLen) throws PKCS11Exception {
         return super.C_DecryptFinal(hSession, directOut, out, outOfs, outLen);
     }
 
-    public synchronized void C_DigestInit(long hSession, CK_MECHANISM pMechanism) throws PKCS11Exception {
+    public synchronized void C_DigestInit(long hSession, CK_MECHANISM pMechanism)
+            throws PKCS11Exception {
         super.C_DigestInit(hSession, pMechanism);
     }
 
-    public synchronized int C_DigestSingle(long hSession, CK_MECHANISM pMechanism, byte[] in, int inOfs, int inLen, byte[] digest, int digestOfs, int digestLen) throws PKCS11Exception {
-        return super.C_DigestSingle(hSession, pMechanism, in, inOfs, inLen, digest, digestOfs, digestLen);
+    public synchronized int C_DigestSingle(long hSession,
+            CK_MECHANISM pMechanism, byte[] in, int inOfs, int inLen,
+            byte[] digest, int digestOfs, int digestLen) throws PKCS11Exception {
+        return super.C_DigestSingle(hSession, pMechanism, in, inOfs, inLen,
+                digest, digestOfs, digestLen);
     }
 
-    public synchronized void C_DigestUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception {
+    public synchronized void C_DigestUpdate(long hSession, long directIn,
+            byte[] in, int inOfs, int inLen) throws PKCS11Exception {
         super.C_DigestUpdate(hSession, directIn, in, inOfs, inLen);
     }
 
-    public synchronized void C_DigestKey(long hSession, long hKey) throws PKCS11Exception {
+    public synchronized void C_DigestKey(long hSession, long hKey)
+            throws PKCS11Exception {
         super.C_DigestKey(hSession, hKey);
     }
 
-    public synchronized int C_DigestFinal(long hSession, byte[] pDigest, int digestOfs, int digestLen) throws PKCS11Exception {
+    public synchronized int C_DigestFinal(long hSession, byte[] pDigest,
+            int digestOfs, int digestLen) throws PKCS11Exception {
         return super.C_DigestFinal(hSession, pDigest, digestOfs, digestLen);
     }
 
-    public synchronized void C_SignInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+    public synchronized void C_SignInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception {
         super.C_SignInit(hSession, pMechanism, hKey);
     }
 
-    public synchronized byte[] C_Sign(long hSession, byte[] pData) throws PKCS11Exception {
+    public synchronized byte[] C_Sign(long hSession, byte[] pData)
+            throws PKCS11Exception {
         return super.C_Sign(hSession, pData);
     }
 
-    public synchronized void C_SignUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception {
+    public synchronized void C_SignUpdate(long hSession, long directIn,
+            byte[] in, int inOfs, int inLen) throws PKCS11Exception {
         super.C_SignUpdate(hSession, directIn, in, inOfs, inLen);
     }
 
-    public synchronized byte[] C_SignFinal(long hSession, int expectedLen) throws PKCS11Exception {
+    public synchronized byte[] C_SignFinal(long hSession, int expectedLen)
+            throws PKCS11Exception {
         return super.C_SignFinal(hSession, expectedLen);
     }
 
-    public synchronized void C_SignRecoverInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+    public synchronized void C_SignRecoverInit(long hSession,
+            CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
         super.C_SignRecoverInit(hSession, pMechanism, hKey);
     }
 
-    public synchronized int C_SignRecover(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOufs, int outLen) throws PKCS11Exception {
-        return super.C_SignRecover(hSession, in, inOfs, inLen, out, outOufs, outLen);
+    public synchronized int C_SignRecover(long hSession, byte[] in, int inOfs,
+            int inLen, byte[] out, int outOufs, int outLen)
+            throws PKCS11Exception {
+        return super.C_SignRecover(hSession, in, inOfs, inLen, out, outOufs,
+                outLen);
     }
 
-    public synchronized void C_VerifyInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+    public synchronized void C_VerifyInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception {
         super.C_VerifyInit(hSession, pMechanism, hKey);
     }
 
-    public synchronized void C_Verify(long hSession, byte[] pData, byte[] pSignature) throws PKCS11Exception {
+    public synchronized void C_Verify(long hSession, byte[] pData,
+            byte[] pSignature) throws PKCS11Exception {
         super.C_Verify(hSession, pData, pSignature);
     }
 
-    public synchronized void C_VerifyUpdate(long hSession, long directIn, byte[] in, int inOfs, int inLen) throws PKCS11Exception {
+    public synchronized void C_VerifyUpdate(long hSession, long directIn,
+            byte[] in, int inOfs, int inLen) throws PKCS11Exception {
         super.C_VerifyUpdate(hSession, directIn, in, inOfs, inLen);
     }
 
-    public synchronized void C_VerifyFinal(long hSession, byte[] pSignature) throws PKCS11Exception {
+    public synchronized void C_VerifyFinal(long hSession, byte[] pSignature)
+            throws PKCS11Exception {
         super.C_VerifyFinal(hSession, pSignature);
     }
 
-    public synchronized void C_VerifyRecoverInit(long hSession, CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
+    public synchronized void C_VerifyRecoverInit(long hSession,
+            CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception {
         super.C_VerifyRecoverInit(hSession, pMechanism, hKey);
     }
 
-    public synchronized int C_VerifyRecover(long hSession, byte[] in, int inOfs, int inLen, byte[] out, int outOufs, int outLen) throws PKCS11Exception {
-        return super.C_VerifyRecover(hSession, in, inOfs, inLen, out, outOufs, outLen);
+    public synchronized int C_VerifyRecover(long hSession, byte[] in, int inOfs,
+            int inLen, byte[] out, int outOufs, int outLen)
+            throws PKCS11Exception {
+        return super.C_VerifyRecover(hSession, in, inOfs, inLen, out, outOufs,
+                outLen);
     }
 
-    public synchronized long C_GenerateKey(long hSession, CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+    public synchronized long C_GenerateKey(long hSession,
+            CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pTemplate)
+            throws PKCS11Exception {
         return super.C_GenerateKey(hSession, pMechanism, pTemplate);
     }
 
     public synchronized long[] C_GenerateKeyPair(long hSession,
-                                   CK_MECHANISM pMechanism,
-                                   CK_ATTRIBUTE[] pPublicKeyTemplate,
-                                   CK_ATTRIBUTE[] pPrivateKeyTemplate) throws PKCS11Exception {
-        return super.C_GenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate, pPrivateKeyTemplate);
+            CK_MECHANISM pMechanism, CK_ATTRIBUTE[] pPublicKeyTemplate,
+            CK_ATTRIBUTE[] pPrivateKeyTemplate)
+            throws PKCS11Exception {
+        return super.C_GenerateKeyPair(hSession, pMechanism, pPublicKeyTemplate,
+                pPrivateKeyTemplate);
     }
 
-    public synchronized byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism, long hWrappingKey, long hKey) throws PKCS11Exception {
+    public synchronized byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism,
+            long hWrappingKey, long hKey) throws PKCS11Exception {
         return super.C_WrapKey(hSession, pMechanism, hWrappingKey, hKey);
     }
 
     public synchronized long C_UnwrapKey(long hSession, CK_MECHANISM pMechanism,
-                          long hUnwrappingKey, byte[] pWrappedKey,
-                          CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
-        return super.C_UnwrapKey(hSession, pMechanism, hUnwrappingKey, pWrappedKey, pTemplate);
+            long hUnwrappingKey, byte[] pWrappedKey, CK_ATTRIBUTE[] pTemplate)
+            throws PKCS11Exception {
+        return super.C_UnwrapKey(hSession, pMechanism, hUnwrappingKey,
+                pWrappedKey, pTemplate);
     }
 
     public synchronized long C_DeriveKey(long hSession, CK_MECHANISM pMechanism,
@@ -1690,14 +1811,14 @@
         return super.C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate);
     }
 
-    public synchronized void C_SeedRandom(long hSession, byte[] pSeed) throws PKCS11Exception {
+    public synchronized void C_SeedRandom(long hSession, byte[] pSeed)
+            throws PKCS11Exception {
         super.C_SeedRandom(hSession, pSeed);
     }
 
-    public synchronized void C_GenerateRandom(long hSession, byte[] randomData) throws PKCS11Exception {
+    public synchronized void C_GenerateRandom(long hSession, byte[] randomData)
+            throws PKCS11Exception {
         super.C_GenerateRandom(hSession, randomData);
     }
-
 }
-
 }
--- a/src/share/lib/security/sunpkcs11-solaris.cfg	Wed Jan 04 03:49:35 2012 -0800
+++ b/src/share/lib/security/sunpkcs11-solaris.cfg	Thu Jan 05 18:18:04 2012 -0800
@@ -17,23 +17,27 @@
 attributes = compatibility
 
 disabledMechanisms = {
-# the following mechanisms are disabled due to lack of digest cloning support
-# need to fix 6414899 first
+  CKM_DSA_KEY_PAIR_GEN
+# the following mechanisms are disabled due to CKR_SAVED_STATE_INVALID bug
+# (Solaris bug 7058108)
   CKM_MD2
   CKM_MD5
   CKM_SHA_1
+# the following mechanisms are disabled due to no cloning support
+# (Solaris bug 7050617)
   CKM_SHA256
   CKM_SHA384
   CKM_SHA512
-  CKM_DSA_KEY_PAIR_GEN
-# the following mechanisms are disabled due to performance issues (Solaris bug 6337157)
+# the following mechanisms are disabled due to performance issues
+# (Solaris bug 6337157)
   CKM_DSA_SHA1
   CKM_MD5_RSA_PKCS
   CKM_SHA1_RSA_PKCS
   CKM_SHA256_RSA_PKCS
   CKM_SHA384_RSA_PKCS
   CKM_SHA512_RSA_PKCS
-# the following mechanisms are disabled to ensure backward compatibility (Solaris bug 6545046)
+# the following mechanisms are disabled to ensure backward compatibility
+# (Solaris bug 6545046)
   CKM_DES_CBC_PAD
   CKM_DES3_CBC_PAD
   CKM_AES_CBC_PAD
--- a/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h	Wed Jan 04 03:49:35 2012 -0800
+++ b/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h	Thu Jan 05 18:18:04 2012 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
@@ -96,8 +96,8 @@
 #define P11_ENABLE_C_CLOSESESSION
 #undef  P11_ENABLE_C_CLOSEALLSESSIONS
 #define P11_ENABLE_C_GETSESSIONINFO
-#undef  P11_ENABLE_C_GETOPERATIONSTATE
-#undef  P11_ENABLE_C_SETOPERATIONSTATE
+#define P11_ENABLE_C_GETOPERATIONSTATE
+#define P11_ENABLE_C_SETOPERATIONSTATE
 #define P11_ENABLE_C_LOGIN
 #define P11_ENABLE_C_LOGOUT
 #define P11_ENABLE_C_CREATEOBJECT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/security/pkcs11/MessageDigest/TestCloning.java	Thu Jan 05 18:18:04 2012 -0800
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6414899
+ * @summary Ensure the cloning functionality works.
+ * @author Valerie Peng
+ * @library ..
+ */
+
+import java.util.*;
+
+import java.security.*;
+
+public class TestCloning extends PKCS11Test {
+
+    private static final String[] ALGOS = {
+        "MD2", "MD5", "SHA1", "SHA-256", "SHA-384", "SHA-512"
+    };
+
+    public static void main(String[] args) throws Exception {
+        main(new TestCloning());
+    }
+
+    private static final byte[] data1 = new byte[10];
+    private static final byte[] data2 = new byte[10*1024];
+
+
+    public void main(Provider p) throws Exception {
+        Random r = new Random();
+        byte[] data1 = new byte[10];
+        byte[] data2 = new byte[2*1024];
+        r.nextBytes(data1);
+        r.nextBytes(data2);
+        System.out.println("Testing against provider " + p.getName());
+        for (int i = 0; i < ALGOS.length; i++) {
+            if (p.getService("MessageDigest", ALGOS[i]) == null) {
+                System.out.println(ALGOS[i] + " is not supported, skipping");
+                continue;
+            } else {
+                System.out.println("Testing " + ALGOS[i] + " of " + p.getName());
+                MessageDigest md = MessageDigest.getInstance(ALGOS[i], p);
+                try {
+                    md = testCloning(md, p);
+                    // repeat the test again after generating digest once
+                    for (int j = 0; j < 10; j++) {
+                        md = testCloning(md, p);
+                    }
+                } catch (Exception ex) {
+                    if (ALGOS[i] == "MD2" &&
+                        p.getName().equalsIgnoreCase("SunPKCS11-NSS")) {
+                        // known bug in NSS; ignore for now
+                        System.out.println("Ignore Known bug in MD2 of NSS");
+                        continue;
+                    }
+                    throw ex;
+                }
+            }
+        }
+    }
+
+    private static MessageDigest testCloning(MessageDigest mdObj, Provider p)
+        throws Exception {
+
+        // copy#0: clone at state BLANK w/o any data
+        MessageDigest mdCopy0 = (MessageDigest) mdObj.clone();
+
+        // copy#1: clone again at state BUFFERED w/ very short data
+        mdObj.update(data1);
+        mdCopy0.update(data1);
+        MessageDigest mdCopy1 = (MessageDigest) mdObj.clone();
+
+        // copy#2: clone again after updating it w/ long data to trigger
+        // the state into INIT
+        mdObj.update(data2);
+        mdCopy0.update(data2);
+        mdCopy1.update(data2);
+        MessageDigest mdCopy2 = (MessageDigest) mdObj.clone();
+
+        // copy#3: clone again after updating it w/ very short data
+        mdObj.update(data1);
+        mdCopy0.update(data1);
+        mdCopy1.update(data1);
+        mdCopy2.update(data1);
+        MessageDigest mdCopy3 = (MessageDigest) mdObj.clone();
+
+        // copy#4: clone again after updating it w/ long data
+        mdObj.update(data2);
+        mdCopy0.update(data2);
+        mdCopy1.update(data2);
+        mdCopy2.update(data2);
+        mdCopy3.update(data2);
+        MessageDigest mdCopy4 = (MessageDigest) mdObj.clone();
+
+        // check digest equalities
+        byte[] answer = mdObj.digest();
+        byte[] result0 = mdCopy0.digest();
+        byte[] result1 = mdCopy1.digest();
+        byte[] result2 = mdCopy2.digest();
+        byte[] result3 = mdCopy3.digest();
+        byte[] result4 = mdCopy4.digest();
+
+
+        check(answer, result0, "copy0");
+        check(answer, result1, "copy1");
+        check(answer, result2, "copy2");
+        check(answer, result3, "copy3");
+        check(answer, result4, "copy4");
+
+        return mdCopy3;
+    }
+
+    private static void check(byte[] d1, byte[] d2, String copyName)
+            throws Exception {
+        if (Arrays.equals(d1, d2) == false) {
+            throw new RuntimeException(copyName + " digest mismatch!");
+        }
+    }
+}
+