8172527: Rename jdk.crypto.token to jdk.crypto.cryptoki
authorascarpino
Mon, 23 Jan 2017 11:49:01 -0800
changeset 43248 5e15de85a1a0
parent 43247 8d242299a219
child 43249 b017b10f62ab
8172527: Rename jdk.crypto.token to jdk.crypto.cryptoki Reviewed-by: mchung, wetmore
jdk/make/copy/Copy-jdk.crypto.cryptoki.gmk
jdk/make/copy/Copy-jdk.crypto.token.gmk
jdk/make/lib/Lib-jdk.crypto.cryptoki.gmk
jdk/make/lib/Lib-jdk.crypto.token.gmk
jdk/src/java.base/share/classes/module-info.java
jdk/src/java.base/share/lib/security/default.policy
jdk/src/jdk.crypto.cryptoki/share/classes/module-info.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/KeyCache.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11DHKeyFactory.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11DSAKeyFactory.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECDHKeyAgreement.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyAgreement.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyFactory.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSACipher.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecureRandom.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Secmod.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Session.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/TemplateManager.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ATTRIBUTE.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_CREATEMUTEX.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_C_INITIALIZE_ARGS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_DATE.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_DESTROYMUTEX.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH2_DERIVE_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_INFO.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_LOCKMUTEX.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM_INFO.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_NOTIFY.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_OAEP_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SESSION_INFO.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SLOT_INFO.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_MASTER_KEY_DERIVE_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_TOKEN_INFO.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_UNLOCKMUTEX.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_VERSION.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH2_DERIVE_PARAMS.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/Constants.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/Functions.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java
jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11RuntimeException.java
jdk/src/jdk.crypto.cryptoki/share/legal/pkcs11cryptotoken.md
jdk/src/jdk.crypto.cryptoki/share/legal/pkcs11wrapper.md
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.h
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs-11v2-20a3.h
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h
jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h
jdk/src/jdk.crypto.cryptoki/solaris/conf/security/sunpkcs11-solaris.cfg
jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c
jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c
jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h
jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c
jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c
jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h
jdk/src/jdk.crypto.token/share/classes/module-info.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/Config.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/KeyCache.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Cipher.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11DHKeyFactory.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11DSAKeyFactory.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Digest.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11ECDHKeyAgreement.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11ECKeyFactory.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Key.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyAgreement.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyFactory.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyGenerator.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyStore.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Mac.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11RSACipher.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11SecureRandom.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Signature.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Util.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/Secmod.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/Session.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/SessionManager.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/SunPKCS11.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/TemplateManager.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/Token.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_ATTRIBUTE.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_CREATEMUTEX.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_C_INITIALIZE_ARGS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_DATE.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_DESTROYMUTEX.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_ECDH2_DERIVE_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_INFO.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_LOCKMUTEX.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM_INFO.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_NOTIFY.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_OAEP_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SESSION_INFO.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SLOT_INFO.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_MASTER_KEY_DERIVE_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_TOKEN_INFO.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_UNLOCKMUTEX.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_VERSION.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH2_DERIVE_PARAMS.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/Constants.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/Functions.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/PKCS11.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java
jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/PKCS11RuntimeException.java
jdk/src/jdk.crypto.token/share/legal/pkcs11cryptotoken.md
jdk/src/jdk.crypto.token/share/legal/pkcs11wrapper.md
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs-11v2-20a3.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11f.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11t.h
jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11wrapper.h
jdk/src/jdk.crypto.token/solaris/conf/security/sunpkcs11-solaris.cfg
jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c
jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c
jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.h
jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/j2secmod_md.c
jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/j2secmod_md.h
jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/p11_md.c
jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/p11_md.h
jdk/test/java/lang/SecurityManager/CheckSecurityProvider.java
jdk/test/sun/security/ec/TestEC.java
jdk/test/sun/security/pkcs11/Cipher/ReinitCipher.java
jdk/test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java
jdk/test/sun/security/pkcs11/Cipher/TestRSACipher.java
jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java
jdk/test/sun/security/pkcs11/Cipher/TestRawRSACipher.java
jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java
jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java
jdk/test/sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java
jdk/test/sun/security/pkcs11/KeyAgreement/TestDH.java
jdk/test/sun/security/pkcs11/KeyAgreement/TestInterop.java
jdk/test/sun/security/pkcs11/KeyAgreement/TestShort.java
jdk/test/sun/security/pkcs11/KeyAgreement/UnsupportedDHKeys.java
jdk/test/sun/security/pkcs11/KeyGenerator/DESParity.java
jdk/test/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java
jdk/test/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java
jdk/test/sun/security/pkcs11/Mac/MacKAT.java
jdk/test/sun/security/pkcs11/Mac/MacSameTest.java
jdk/test/sun/security/pkcs11/Mac/ReinitMac.java
jdk/test/sun/security/pkcs11/MessageDigest/ByteBuffers.java
jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java
jdk/test/sun/security/pkcs11/MessageDigest/ReinitDigest.java
jdk/test/sun/security/pkcs11/MessageDigest/TestCloning.java
jdk/test/sun/security/pkcs11/Provider/Absolute.java
jdk/test/sun/security/pkcs11/SampleTest.java
jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java
jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java
jdk/test/sun/security/pkcs11/Secmod/Crypto.java
jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java
jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java
jdk/test/sun/security/pkcs11/Secmod/LoadKeystore.java
jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java
jdk/test/sun/security/pkcs11/SecureRandom/Basic.java
jdk/test/sun/security/pkcs11/SecureRandom/TestDeserialization.java
jdk/test/sun/security/pkcs11/Serialize/SerializeProvider.java
jdk/test/sun/security/pkcs11/Signature/ByteBuffers.java
jdk/test/sun/security/pkcs11/Signature/ReinitSignature.java
jdk/test/sun/security/pkcs11/Signature/TestDSA.java
jdk/test/sun/security/pkcs11/Signature/TestDSAKeyLength.java
jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java
jdk/test/sun/security/pkcs11/ec/ReadCertificates.java
jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java
jdk/test/sun/security/pkcs11/ec/TestCurves.java
jdk/test/sun/security/pkcs11/ec/TestECDH.java
jdk/test/sun/security/pkcs11/ec/TestECDH2.java
jdk/test/sun/security/pkcs11/ec/TestECDSA.java
jdk/test/sun/security/pkcs11/ec/TestECDSA2.java
jdk/test/sun/security/pkcs11/ec/TestECGenSpec.java
jdk/test/sun/security/pkcs11/ec/TestKeyFactory.java
jdk/test/sun/security/pkcs11/rsa/KeyWrap.java
jdk/test/sun/security/pkcs11/rsa/TestCACerts.java
jdk/test/sun/security/pkcs11/rsa/TestKeyFactory.java
jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java
jdk/test/sun/security/pkcs11/rsa/TestSignatures.java
jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java
jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java
jdk/test/sun/security/pkcs11/tls/TestLeadingZeroesP11.java
jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java
jdk/test/sun/security/pkcs11/tls/TestPRF.java
jdk/test/sun/security/pkcs11/tls/TestPremaster.java
jdk/test/tools/launcher/MiscTests.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/copy/Copy-jdk.crypto.cryptoki.gmk	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2014, 2017, 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.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# 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.
+#
+
+include CopyCommon.gmk
+
+################################################################################
+
+ifeq ($(OPENJDK_TARGET_OS), solaris)
+
+  SUNPKCS11_CFG_SRC := \
+      $(JDK_TOPDIR)/src/jdk.crypto.cryptoki/solaris/conf/security/sunpkcs11-solaris.cfg
+  SUNPKCS11_CFG_DST := $(CONF_DST_DIR)/security/sunpkcs11-solaris.cfg
+
+  $(SUNPKCS11_CFG_DST): $(SUNPKCS11_CFG_SRC)
+	$(call install-file)
+
+  SECURITY_PKCS11_CONF_FILES += $(SUNPKCS11_CFG_DST)
+
+  TARGETS := $(SUNPKCS11_CFG_DST)
+
+endif
+
+################################################################################
--- a/jdk/make/copy/Copy-jdk.crypto.token.gmk	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#
-# Copyright (c) 2014, 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.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# 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.
-#
-
-include CopyCommon.gmk
-
-################################################################################
-
-ifeq ($(OPENJDK_TARGET_OS), solaris)
-
-  SUNPKCS11_CFG_SRC := \
-      $(JDK_TOPDIR)/src/jdk.crypto.token/solaris/conf/security/sunpkcs11-solaris.cfg
-  SUNPKCS11_CFG_DST := $(CONF_DST_DIR)/security/sunpkcs11-solaris.cfg
-
-  $(SUNPKCS11_CFG_DST): $(SUNPKCS11_CFG_SRC)
-	$(call install-file)
-
-  SECURITY_PKCS11_CONF_FILES += $(SUNPKCS11_CFG_DST)
-
-  TARGETS := $(SUNPKCS11_CFG_DST)
-
-endif
-
-################################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/lib/Lib-jdk.crypto.cryptoki.gmk	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,56 @@
+#
+# Copyright (c) 2011, 2017, 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.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# 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.
+#
+
+include LibCommon.gmk
+
+################################################################################
+
+LIBJ2PKCS11_SRC := $(JDK_TOPDIR)/src/jdk.crypto.cryptoki/share/native/libj2pkcs11 \
+    $(JDK_TOPDIR)/src/jdk.crypto.cryptoki/$(OPENJDK_TARGET_OS_TYPE)/native/libj2pkcs11
+
+$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
+    LIBRARY := j2pkcs11, \
+    OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+    SRC := $(LIBJ2PKCS11_SRC), \
+    OPTIMIZATION := LOW, \
+    CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
+        $(LIBJAVA_HEADER_FLAGS) \
+        -I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.cryptoki, \
+    MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \
+    LDFLAGS := $(LDFLAGS_JDKLIB) \
+        $(call SET_SHARED_LIBRARY_ORIGIN), \
+    LIBS_unix := $(LIBDL), \
+    LIBS_solaris := -lc, \
+    VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
+    RC_FLAGS := $(RC_FLAGS) \
+        -D "JDK_FNAME=j2pkcs11.dll" \
+        -D "JDK_INTERNAL_NAME=j2pkcs11" \
+        -D "JDK_FTYPE=0x2L", \
+    OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2pkcs11, \
+))
+
+TARGETS += $(BUILD_LIBJ2PKCS11)
+
+################################################################################
--- a/jdk/make/lib/Lib-jdk.crypto.token.gmk	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#
-# Copyright (c) 2011, 2016, 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.  Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# 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.
-#
-
-include LibCommon.gmk
-
-################################################################################
-
-LIBJ2PKCS11_SRC := $(JDK_TOPDIR)/src/jdk.crypto.token/share/native/libj2pkcs11 \
-    $(JDK_TOPDIR)/src/jdk.crypto.token/$(OPENJDK_TARGET_OS_TYPE)/native/libj2pkcs11
-
-$(eval $(call SetupNativeCompilation,BUILD_LIBJ2PKCS11, \
-    LIBRARY := j2pkcs11, \
-    OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
-    SRC := $(LIBJ2PKCS11_SRC), \
-    OPTIMIZATION := LOW, \
-    CFLAGS := $(CFLAGS_JDKLIB) $(addprefix -I, $(LIBJ2PKCS11_SRC)) \
-        $(LIBJAVA_HEADER_FLAGS) \
-        -I$(SUPPORT_OUTPUTDIR)/headers/jdk.crypto.token, \
-    MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libj2pkcs11/mapfile-vers, \
-    LDFLAGS := $(LDFLAGS_JDKLIB) \
-        $(call SET_SHARED_LIBRARY_ORIGIN), \
-    LIBS_unix := $(LIBDL), \
-    LIBS_solaris := -lc, \
-    VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
-    RC_FLAGS := $(RC_FLAGS) \
-        -D "JDK_FNAME=j2pkcs11.dll" \
-        -D "JDK_INTERNAL_NAME=j2pkcs11" \
-        -D "JDK_FTYPE=0x2L", \
-    OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libj2pkcs11, \
-))
-
-TARGETS += $(BUILD_LIBJ2PKCS11)
-
-################################################################################
--- a/jdk/src/java.base/share/classes/module-info.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/src/java.base/share/classes/module-info.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -219,7 +219,7 @@
         java.security.jgss;
     exports sun.nio.ch to
         java.management,
-        jdk.crypto.token,
+        jdk.crypto.cryptoki,
         jdk.sctp,
         jdk.unsupported;
     exports sun.nio.cs to
@@ -244,13 +244,13 @@
         java.desktop,
         java.security.jgss;
     exports sun.security.internal.interfaces to
-        jdk.crypto.token;
+        jdk.crypto.cryptoki;
     exports sun.security.internal.spec to
-        jdk.crypto.token;
+        jdk.crypto.cryptoki;
     exports sun.security.jca to
         java.smartcardio,
         jdk.crypto.ec,
-        jdk.crypto.token,
+        jdk.crypto.cryptoki,
         jdk.naming.dns;
     exports sun.security.pkcs to
         jdk.crypto.ec,
@@ -258,13 +258,13 @@
     exports sun.security.provider to
         java.rmi,
         java.security.jgss,
-        jdk.crypto.token,
+        jdk.crypto.cryptoki,
         jdk.policytool,
         jdk.security.auth;
     exports sun.security.provider.certpath to
         java.naming;
     exports sun.security.rsa to
-        jdk.crypto.token;
+        jdk.crypto.cryptoki;
     exports sun.security.ssl to
         java.security.jgss;
     exports sun.security.timestamp to
@@ -280,14 +280,14 @@
         java.smartcardio,
         java.xml.crypto,
         jdk.crypto.ec,
-        jdk.crypto.token,
+        jdk.crypto.cryptoki,
         jdk.jartool,
         jdk.policytool,
         jdk.security.auth,
         jdk.security.jgss;
     exports sun.security.x509 to
         jdk.crypto.ec,
-        jdk.crypto.token,
+        jdk.crypto.cryptoki,
         jdk.jartool,
         jdk.security.auth;
     exports sun.security.validator to
--- a/jdk/src/java.base/share/lib/security/default.policy	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/src/java.base/share/lib/security/default.policy	Mon Jan 23 11:49:01 2017 -0800
@@ -137,7 +137,7 @@
     permission java.security.SecurityPermission "removeProviderProperty.SunEC";
 };
 
-grant codeBase "jrt:/jdk.crypto.token" {
+grant codeBase "jrt:/jdk.crypto.cryptoki" {
     permission java.lang.RuntimePermission
                    "accessClassInPackage.sun.security.*";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/module-info.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2014, 2017, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+module jdk.crypto.cryptoki {
+    // Depends on SunEC provider for EC related functionality
+    requires jdk.crypto.ec;
+    provides java.security.Provider with sun.security.pkcs11.SunPKCS11;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,1008 @@
+/*
+ * Copyright (c) 2003, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.io.*;
+import static java.io.StreamTokenizer.*;
+import java.math.BigInteger;
+import java.util.*;
+
+import java.security.*;
+
+import sun.security.util.PropertyExpander;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+import static sun.security.pkcs11.wrapper.CK_ATTRIBUTE.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+
+/**
+ * Configuration container and file parsing.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class Config {
+
+    static final int ERR_HALT       = 1;
+    static final int ERR_IGNORE_ALL = 2;
+    static final int ERR_IGNORE_LIB = 3;
+
+    // same as allowSingleThreadedModules but controlled via a system property
+    // and applied to all providers. if set to false, no SunPKCS11 instances
+    // will accept single threaded modules regardless of the setting in their
+    // config files.
+    private static final boolean staticAllowSingleThreadedModules;
+    private static final String osName;
+    private static final String osArch;
+
+    static {
+        List<String> props = AccessController.doPrivileged(
+            new PrivilegedAction<>() {
+                @Override
+                public List<String> run() {
+                    return List.of(
+                        System.getProperty(
+                            "sun.security.pkcs11.allowSingleThreadedModules",
+                            "true"),
+                        System.getProperty("os.name"),
+                        System.getProperty("os.arch"));
+                }
+            }
+        );
+        if ("false".equalsIgnoreCase(props.get(0))) {
+            staticAllowSingleThreadedModules = false;
+        } else {
+            staticAllowSingleThreadedModules = true;
+        }
+        osName = props.get(1);
+        osArch = props.get(2);
+    }
+
+    private final static boolean DEBUG = false;
+
+    private static void debug(Object o) {
+        if (DEBUG) {
+            System.out.println(o);
+        }
+    }
+
+    // file name containing this configuration
+    private String filename;
+
+    // Reader and StringTokenizer used during parsing
+    private Reader reader;
+
+    private StreamTokenizer st;
+
+    private Set<String> parsedKeywords;
+
+    // name suffix of the provider
+    private String name;
+
+    // name of the PKCS#11 library
+    private String library;
+
+    // description to pass to the provider class
+    private String description;
+
+    // slotID of the slot to use
+    private int slotID = -1;
+
+    // slot to use, specified as index in the slotlist
+    private int slotListIndex = -1;
+
+    // set of enabled mechanisms (or null to use default)
+    private Set<Long> enabledMechanisms;
+
+    // set of disabled mechanisms
+    private Set<Long> disabledMechanisms;
+
+    // whether to print debug info during startup
+    private boolean showInfo = false;
+
+    // template manager, initialized from parsed attributes
+    private TemplateManager templateManager;
+
+    // how to handle error during startup, one of ERR_
+    private int handleStartupErrors = ERR_HALT;
+
+    // flag indicating whether the P11KeyStore should
+    // be more tolerant of input parameters
+    private boolean keyStoreCompatibilityMode = true;
+
+    // flag indicating whether we need to explicitly cancel operations
+    // see Token
+    private boolean explicitCancel = true;
+
+    // how often to test for token insertion, if no token is present
+    private int insertionCheckInterval = 2000;
+
+    // flag inidicating whether to omit the call to C_Initialize()
+    // should be used only if we are running within a process that
+    // has already called it (e.g. Plugin inside of Mozilla/NSS)
+    private boolean omitInitialize = false;
+
+    // whether to allow modules that only support single threaded access.
+    // they cannot be used safely from multiple PKCS#11 consumers in the
+    // same process, for example NSS and SunPKCS11
+    private boolean allowSingleThreadedModules = true;
+
+    // name of the C function that returns the PKCS#11 functionlist
+    // This option primarily exists for the deprecated
+    // Secmod.Module.getProvider() method.
+    private String functionList = "C_GetFunctionList";
+
+    // whether to use NSS secmod mode. Implicitly set if nssLibraryDirectory,
+    // nssSecmodDirectory, or nssModule is specified.
+    private boolean nssUseSecmod;
+
+    // location of the NSS library files (libnss3.so, etc.)
+    private String nssLibraryDirectory;
+
+    // location of secmod.db
+    private String nssSecmodDirectory;
+
+    // which NSS module to use
+    private String nssModule;
+
+    private Secmod.DbMode nssDbMode = Secmod.DbMode.READ_WRITE;
+
+    // Whether the P11KeyStore should specify the CKA_NETSCAPE_DB attribute
+    // when creating private keys. Only valid if nssUseSecmod is true.
+    private boolean nssNetscapeDbWorkaround = true;
+
+    // Special init argument string for the NSS softtoken.
+    // This is used when using the NSS softtoken directly without secmod mode.
+    private String nssArgs;
+
+    // whether to use NSS trust attributes for the KeyStore of this provider
+    // this option is for internal use by the SunPKCS11 code only and
+    // works only for NSS providers created via the Secmod API
+    private boolean nssUseSecmodTrust = false;
+
+    // Flag to indicate whether the X9.63 encoding for EC points shall be used
+    // (true) or whether that encoding shall be wrapped in an ASN.1 OctetString
+    // (false).
+    private boolean useEcX963Encoding = false;
+
+    // Flag to indicate whether NSS should favour performance (false) or
+    // memory footprint (true).
+    private boolean nssOptimizeSpace = false;
+
+    Config(String fn) throws IOException {
+        this.filename = fn;
+        if (filename.startsWith("--")) {
+            // inline config
+            String config = filename.substring(2).replace("\\n", "\n");
+            reader = new StringReader(config);
+        } else {
+            reader = new BufferedReader(new InputStreamReader
+                (new FileInputStream(expand(filename))));
+        }
+        parsedKeywords = new HashSet<String>();
+        st = new StreamTokenizer(reader);
+        setupTokenizer();
+        parse();
+    }
+
+    String getFileName() {
+        return filename;
+    }
+
+    String getName() {
+        return name;
+    }
+
+    String getLibrary() {
+        return library;
+    }
+
+    String getDescription() {
+        if (description != null) {
+            return description;
+        }
+        return "SunPKCS11-" + name + " using library " + library;
+    }
+
+    int getSlotID() {
+        return slotID;
+    }
+
+    int getSlotListIndex() {
+        if ((slotID == -1) && (slotListIndex == -1)) {
+            // if neither is set, default to first slot
+            return 0;
+        } else {
+            return slotListIndex;
+        }
+    }
+
+    boolean getShowInfo() {
+        return (SunPKCS11.debug != null) || showInfo;
+    }
+
+    TemplateManager getTemplateManager() {
+        if (templateManager == null) {
+            templateManager = new TemplateManager();
+        }
+        return templateManager;
+    }
+
+    boolean isEnabled(long m) {
+        if (enabledMechanisms != null) {
+            return enabledMechanisms.contains(Long.valueOf(m));
+        }
+        if (disabledMechanisms != null) {
+            return !disabledMechanisms.contains(Long.valueOf(m));
+        }
+        return true;
+    }
+
+    int getHandleStartupErrors() {
+        return handleStartupErrors;
+    }
+
+    boolean getKeyStoreCompatibilityMode() {
+        return keyStoreCompatibilityMode;
+    }
+
+    boolean getExplicitCancel() {
+        return explicitCancel;
+    }
+
+    int getInsertionCheckInterval() {
+        return insertionCheckInterval;
+    }
+
+    boolean getOmitInitialize() {
+        return omitInitialize;
+    }
+
+    boolean getAllowSingleThreadedModules() {
+        return staticAllowSingleThreadedModules && allowSingleThreadedModules;
+    }
+
+    String getFunctionList() {
+        return functionList;
+    }
+
+    boolean getNssUseSecmod() {
+        return nssUseSecmod;
+    }
+
+    String getNssLibraryDirectory() {
+        return nssLibraryDirectory;
+    }
+
+    String getNssSecmodDirectory() {
+        return nssSecmodDirectory;
+    }
+
+    String getNssModule() {
+        return nssModule;
+    }
+
+    Secmod.DbMode getNssDbMode() {
+        return nssDbMode;
+    }
+
+    public boolean getNssNetscapeDbWorkaround() {
+        return nssUseSecmod && nssNetscapeDbWorkaround;
+    }
+
+    String getNssArgs() {
+        return nssArgs;
+    }
+
+    boolean getNssUseSecmodTrust() {
+        return nssUseSecmodTrust;
+    }
+
+    boolean getUseEcX963Encoding() {
+        return useEcX963Encoding;
+    }
+
+    boolean getNssOptimizeSpace() {
+        return nssOptimizeSpace;
+    }
+
+    private static String expand(final String s) throws IOException {
+        try {
+            return PropertyExpander.expand(s);
+        } catch (Exception e) {
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    private void setupTokenizer() {
+        st.resetSyntax();
+        st.wordChars('a', 'z');
+        st.wordChars('A', 'Z');
+        st.wordChars('0', '9');
+        st.wordChars(':', ':');
+        st.wordChars('.', '.');
+        st.wordChars('_', '_');
+        st.wordChars('-', '-');
+        st.wordChars('/', '/');
+        st.wordChars('\\', '\\');
+        st.wordChars('$', '$');
+        st.wordChars('{', '{'); // need {} for property subst
+        st.wordChars('}', '}');
+        st.wordChars('*', '*');
+        st.wordChars('+', '+');
+        st.wordChars('~', '~');
+        // XXX check ASCII table and add all other characters except special
+
+        // special: #="(),
+        st.whitespaceChars(0, ' ');
+        st.commentChar('#');
+        st.eolIsSignificant(true);
+        st.quoteChar('\"');
+    }
+
+    private ConfigurationException excToken(String msg) {
+        return new ConfigurationException(msg + " " + st);
+    }
+
+    private ConfigurationException excLine(String msg) {
+        return new ConfigurationException(msg + ", line " + st.lineno());
+    }
+
+    private void parse() throws IOException {
+        while (true) {
+            int token = nextToken();
+            if (token == TT_EOF) {
+                break;
+            }
+            if (token == TT_EOL) {
+                continue;
+            }
+            if (token != TT_WORD) {
+                throw excToken("Unexpected token:");
+            }
+            String word = st.sval;
+            if (word.equals("name")) {
+                name = parseStringEntry(word);
+            } else if (word.equals("library")) {
+                library = parseLibrary(word);
+            } else if (word.equals("description")) {
+                parseDescription(word);
+            } else if (word.equals("slot")) {
+                parseSlotID(word);
+            } else if (word.equals("slotListIndex")) {
+                parseSlotListIndex(word);
+            } else if (word.equals("enabledMechanisms")) {
+                parseEnabledMechanisms(word);
+            } else if (word.equals("disabledMechanisms")) {
+                parseDisabledMechanisms(word);
+            } else if (word.equals("attributes")) {
+                parseAttributes(word);
+            } else if (word.equals("handleStartupErrors")) {
+                parseHandleStartupErrors(word);
+            } else if (word.endsWith("insertionCheckInterval")) {
+                insertionCheckInterval = parseIntegerEntry(word);
+                if (insertionCheckInterval < 100) {
+                    throw excLine(word + " must be at least 100 ms");
+                }
+            } else if (word.equals("showInfo")) {
+                showInfo = parseBooleanEntry(word);
+            } else if (word.equals("keyStoreCompatibilityMode")) {
+                keyStoreCompatibilityMode = parseBooleanEntry(word);
+            } else if (word.equals("explicitCancel")) {
+                explicitCancel = parseBooleanEntry(word);
+            } else if (word.equals("omitInitialize")) {
+                omitInitialize = parseBooleanEntry(word);
+            } else if (word.equals("allowSingleThreadedModules")) {
+                allowSingleThreadedModules = parseBooleanEntry(word);
+            } else if (word.equals("functionList")) {
+                functionList = parseStringEntry(word);
+            } else if (word.equals("nssUseSecmod")) {
+                nssUseSecmod = parseBooleanEntry(word);
+            } else if (word.equals("nssLibraryDirectory")) {
+                nssLibraryDirectory = parseLibrary(word);
+                nssUseSecmod = true;
+            } else if (word.equals("nssSecmodDirectory")) {
+                nssSecmodDirectory = expand(parseStringEntry(word));
+                nssUseSecmod = true;
+            } else if (word.equals("nssModule")) {
+                nssModule = parseStringEntry(word);
+                nssUseSecmod = true;
+            } else if (word.equals("nssDbMode")) {
+                String mode = parseStringEntry(word);
+                if (mode.equals("readWrite")) {
+                    nssDbMode = Secmod.DbMode.READ_WRITE;
+                } else if (mode.equals("readOnly")) {
+                    nssDbMode = Secmod.DbMode.READ_ONLY;
+                } else if (mode.equals("noDb")) {
+                    nssDbMode = Secmod.DbMode.NO_DB;
+                } else {
+                    throw excToken("nssDbMode must be one of readWrite, readOnly, and noDb:");
+                }
+                nssUseSecmod = true;
+            } else if (word.equals("nssNetscapeDbWorkaround")) {
+                nssNetscapeDbWorkaround = parseBooleanEntry(word);
+                nssUseSecmod = true;
+            } else if (word.equals("nssArgs")) {
+                parseNSSArgs(word);
+            } else if (word.equals("nssUseSecmodTrust")) {
+                nssUseSecmodTrust = parseBooleanEntry(word);
+            } else if (word.equals("useEcX963Encoding")) {
+                useEcX963Encoding = parseBooleanEntry(word);
+            } else if (word.equals("nssOptimizeSpace")) {
+                nssOptimizeSpace = parseBooleanEntry(word);
+            } else {
+                throw new ConfigurationException
+                        ("Unknown keyword '" + word + "', line " + st.lineno());
+            }
+            parsedKeywords.add(word);
+        }
+        reader.close();
+        reader = null;
+        st = null;
+        parsedKeywords = null;
+        if (name == null) {
+            throw new ConfigurationException("name must be specified");
+        }
+        if (nssUseSecmod == false) {
+            if (library == null) {
+                throw new ConfigurationException("library must be specified");
+            }
+        } else {
+            if (library != null) {
+                throw new ConfigurationException
+                    ("library must not be specified in NSS mode");
+            }
+            if ((slotID != -1) || (slotListIndex != -1)) {
+                throw new ConfigurationException
+                    ("slot and slotListIndex must not be specified in NSS mode");
+            }
+            if (nssArgs != null) {
+                throw new ConfigurationException
+                    ("nssArgs must not be specified in NSS mode");
+            }
+            if (nssUseSecmodTrust != false) {
+                throw new ConfigurationException("nssUseSecmodTrust is an "
+                    + "internal option and must not be specified in NSS mode");
+            }
+        }
+    }
+
+    //
+    // Parsing helper methods
+    //
+
+    private int nextToken() throws IOException {
+        int token = st.nextToken();
+        debug(st);
+        return token;
+    }
+
+    private void parseEquals() throws IOException {
+        int token = nextToken();
+        if (token != '=') {
+            throw excToken("Expected '=', read");
+        }
+    }
+
+    private void parseOpenBraces() throws IOException {
+        while (true) {
+            int token = nextToken();
+            if (token == TT_EOL) {
+                continue;
+            }
+            if ((token == TT_WORD) && st.sval.equals("{")) {
+                return;
+            }
+            throw excToken("Expected '{', read");
+        }
+    }
+
+    private boolean isCloseBraces(int token) {
+        return (token == TT_WORD) && st.sval.equals("}");
+    }
+
+    private String parseWord() throws IOException {
+        int token = nextToken();
+        if (token != TT_WORD) {
+            throw excToken("Unexpected value:");
+        }
+        return st.sval;
+    }
+
+    private String parseStringEntry(String keyword) throws IOException {
+        checkDup(keyword);
+        parseEquals();
+
+        int token = nextToken();
+        if (token != TT_WORD && token != '\"') {
+            // not a word token nor a string enclosed by double quotes
+            throw excToken("Unexpected value:");
+        }
+        String value = st.sval;
+
+        debug(keyword + ": " + value);
+        return value;
+    }
+
+    private boolean parseBooleanEntry(String keyword) throws IOException {
+        checkDup(keyword);
+        parseEquals();
+        boolean value = parseBoolean();
+        debug(keyword + ": " + value);
+        return value;
+    }
+
+    private int parseIntegerEntry(String keyword) throws IOException {
+        checkDup(keyword);
+        parseEquals();
+        int value = decodeNumber(parseWord());
+        debug(keyword + ": " + value);
+        return value;
+    }
+
+    private boolean parseBoolean() throws IOException {
+        String val = parseWord();
+        switch (val) {
+            case "true":
+                return true;
+            case "false":
+                return false;
+            default:
+                throw excToken("Expected boolean value, read:");
+        }
+    }
+
+    private String parseLine() throws IOException {
+        // allow quoted string as part of line
+        String s = null;
+        while (true) {
+            int token = nextToken();
+            if ((token == TT_EOL) || (token == TT_EOF)) {
+                break;
+            }
+            if (token != TT_WORD && token != '\"') {
+                throw excToken("Unexpected value");
+            }
+            if (s == null) {
+                s = st.sval;
+            } else {
+                s = s + " " + st.sval;
+            }
+        }
+        if (s == null) {
+            throw excToken("Unexpected empty line");
+        }
+        return s;
+    }
+
+    private int decodeNumber(String str) throws IOException {
+        try {
+            if (str.startsWith("0x") || str.startsWith("0X")) {
+                return Integer.parseInt(str.substring(2), 16);
+            } else {
+                return Integer.parseInt(str);
+            }
+        } catch (NumberFormatException e) {
+            throw excToken("Expected number, read");
+        }
+    }
+
+    private static boolean isNumber(String s) {
+        if (s.length() == 0) {
+            return false;
+        }
+        char ch = s.charAt(0);
+        return ((ch >= '0') && (ch <= '9'));
+    }
+
+    private void parseComma() throws IOException {
+        int token = nextToken();
+        if (token != ',') {
+            throw excToken("Expected ',', read");
+        }
+    }
+
+    private static boolean isByteArray(String val) {
+        return val.startsWith("0h");
+    }
+
+    private byte[] decodeByteArray(String str) throws IOException {
+        if (str.startsWith("0h") == false) {
+            throw excToken("Expected byte array value, read");
+        }
+        str = str.substring(2);
+        // XXX proper hex parsing
+        try {
+            return new BigInteger(str, 16).toByteArray();
+        } catch (NumberFormatException e) {
+            throw excToken("Expected byte array value, read");
+        }
+    }
+
+    private void checkDup(String keyword) throws IOException {
+        if (parsedKeywords.contains(keyword)) {
+            throw excLine(keyword + " must only be specified once");
+        }
+    }
+
+    //
+    // individual entry parsing methods
+    //
+
+    private String parseLibrary(String keyword) throws IOException {
+        checkDup(keyword);
+        parseEquals();
+        String lib = parseLine();
+        lib = expand(lib);
+        int i = lib.indexOf("/$ISA/");
+        if (i != -1) {
+            // replace "/$ISA/" with "/sparcv9/" on 64-bit Solaris SPARC
+            // and with "/amd64/" on Solaris AMD64.
+            // On all other platforms, just turn it into a "/"
+            String prefix = lib.substring(0, i);
+            String suffix = lib.substring(i + 5);
+            if (osName.equals("SunOS") && osArch.equals("sparcv9")) {
+                lib = prefix + "/sparcv9" + suffix;
+            } else if (osName.equals("SunOS") && osArch.equals("amd64")) {
+                lib = prefix + "/amd64" + suffix;
+            } else {
+                lib = prefix + suffix;
+            }
+        }
+        debug(keyword + ": " + lib);
+
+        // Check to see if full path is specified to prevent the DLL
+        // preloading attack
+        if (!(new File(lib)).isAbsolute()) {
+            throw new ConfigurationException(
+                "Absolute path required for library value: " + lib);
+        }
+        return lib;
+    }
+
+    private void parseDescription(String keyword) throws IOException {
+        checkDup(keyword);
+        parseEquals();
+        description = parseLine();
+        debug("description: " + description);
+    }
+
+    private void parseSlotID(String keyword) throws IOException {
+        if (slotID >= 0) {
+            throw excLine("Duplicate slot definition");
+        }
+        if (slotListIndex >= 0) {
+            throw excLine
+                ("Only one of slot and slotListIndex must be specified");
+        }
+        parseEquals();
+        String slotString = parseWord();
+        slotID = decodeNumber(slotString);
+        debug("slot: " + slotID);
+    }
+
+    private void parseSlotListIndex(String keyword) throws IOException {
+        if (slotListIndex >= 0) {
+            throw excLine("Duplicate slotListIndex definition");
+        }
+        if (slotID >= 0) {
+            throw excLine
+                ("Only one of slot and slotListIndex must be specified");
+        }
+        parseEquals();
+        String slotString = parseWord();
+        slotListIndex = decodeNumber(slotString);
+        debug("slotListIndex: " + slotListIndex);
+    }
+
+    private void parseEnabledMechanisms(String keyword) throws IOException {
+        enabledMechanisms = parseMechanisms(keyword);
+    }
+
+    private void parseDisabledMechanisms(String keyword) throws IOException {
+        disabledMechanisms = parseMechanisms(keyword);
+    }
+
+    private Set<Long> parseMechanisms(String keyword) throws IOException {
+        checkDup(keyword);
+        Set<Long> mechs = new HashSet<Long>();
+        parseEquals();
+        parseOpenBraces();
+        while (true) {
+            int token = nextToken();
+            if (isCloseBraces(token)) {
+                break;
+            }
+            if (token == TT_EOL) {
+                continue;
+            }
+            if (token != TT_WORD) {
+                throw excToken("Expected mechanism, read");
+            }
+            long mech = parseMechanism(st.sval);
+            mechs.add(Long.valueOf(mech));
+        }
+        if (DEBUG) {
+            System.out.print("mechanisms: [");
+            for (Long mech : mechs) {
+                System.out.print(Functions.getMechanismName(mech));
+                System.out.print(", ");
+            }
+            System.out.println("]");
+        }
+        return mechs;
+    }
+
+    private long parseMechanism(String mech) throws IOException {
+        if (isNumber(mech)) {
+            return decodeNumber(mech);
+        } else {
+            try {
+                return Functions.getMechanismId(mech);
+            } catch (IllegalArgumentException e) {
+                throw excLine("Unknown mechanism: " + mech);
+            }
+        }
+    }
+
+    private void parseAttributes(String keyword) throws IOException {
+        if (templateManager == null) {
+            templateManager = new TemplateManager();
+        }
+        int token = nextToken();
+        if (token == '=') {
+            String s = parseWord();
+            if (s.equals("compatibility") == false) {
+                throw excLine("Expected 'compatibility', read " + s);
+            }
+            setCompatibilityAttributes();
+            return;
+        }
+        if (token != '(') {
+            throw excToken("Expected '(' or '=', read");
+        }
+        String op = parseOperation();
+        parseComma();
+        long objectClass = parseObjectClass();
+        parseComma();
+        long keyAlg = parseKeyAlgorithm();
+        token = nextToken();
+        if (token != ')') {
+            throw excToken("Expected ')', read");
+        }
+        parseEquals();
+        parseOpenBraces();
+        List<CK_ATTRIBUTE> attributes = new ArrayList<CK_ATTRIBUTE>();
+        while (true) {
+            token = nextToken();
+            if (isCloseBraces(token)) {
+                break;
+            }
+            if (token == TT_EOL) {
+                continue;
+            }
+            if (token != TT_WORD) {
+                throw excToken("Expected mechanism, read");
+            }
+            String attributeName = st.sval;
+            long attributeId = decodeAttributeName(attributeName);
+            parseEquals();
+            String attributeValue = parseWord();
+            attributes.add(decodeAttributeValue(attributeId, attributeValue));
+        }
+        templateManager.addTemplate
+                (op, objectClass, keyAlg, attributes.toArray(CK_A0));
+    }
+
+    private void setCompatibilityAttributes() {
+        // all secret keys
+        templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, PCKK_ANY,
+        new CK_ATTRIBUTE[] {
+            TOKEN_FALSE,
+            SENSITIVE_FALSE,
+            EXTRACTABLE_TRUE,
+            ENCRYPT_TRUE,
+            DECRYPT_TRUE,
+            WRAP_TRUE,
+            UNWRAP_TRUE,
+        });
+
+        // generic secret keys are special
+        // They are used as MAC keys plus for the SSL/TLS (pre)master secrets
+        templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, CKK_GENERIC_SECRET,
+        new CK_ATTRIBUTE[] {
+            SIGN_TRUE,
+            VERIFY_TRUE,
+            ENCRYPT_NULL,
+            DECRYPT_NULL,
+            WRAP_NULL,
+            UNWRAP_NULL,
+            DERIVE_TRUE,
+        });
+
+        // all private and public keys
+        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, PCKK_ANY,
+        new CK_ATTRIBUTE[] {
+            TOKEN_FALSE,
+            SENSITIVE_FALSE,
+            EXTRACTABLE_TRUE,
+        });
+        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, PCKK_ANY,
+        new CK_ATTRIBUTE[] {
+            TOKEN_FALSE,
+        });
+
+        // additional attributes for RSA private keys
+        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_RSA,
+        new CK_ATTRIBUTE[] {
+            DECRYPT_TRUE,
+            SIGN_TRUE,
+            SIGN_RECOVER_TRUE,
+            UNWRAP_TRUE,
+        });
+        // additional attributes for RSA public keys
+        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_RSA,
+        new CK_ATTRIBUTE[] {
+            ENCRYPT_TRUE,
+            VERIFY_TRUE,
+            VERIFY_RECOVER_TRUE,
+            WRAP_TRUE,
+        });
+
+        // additional attributes for DSA private keys
+        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DSA,
+        new CK_ATTRIBUTE[] {
+            SIGN_TRUE,
+        });
+        // additional attributes for DSA public keys
+        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_DSA,
+        new CK_ATTRIBUTE[] {
+            VERIFY_TRUE,
+        });
+
+        // additional attributes for DH private keys
+        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DH,
+        new CK_ATTRIBUTE[] {
+            DERIVE_TRUE,
+        });
+
+        // additional attributes for EC private keys
+        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_EC,
+        new CK_ATTRIBUTE[] {
+            SIGN_TRUE,
+            DERIVE_TRUE,
+        });
+        // additional attributes for EC public keys
+        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_EC,
+        new CK_ATTRIBUTE[] {
+            VERIFY_TRUE,
+        });
+    }
+
+    private final static CK_ATTRIBUTE[] CK_A0 = new CK_ATTRIBUTE[0];
+
+    private String parseOperation() throws IOException {
+        String op = parseWord();
+        switch (op) {
+            case "*":
+                return TemplateManager.O_ANY;
+            case "generate":
+                return TemplateManager.O_GENERATE;
+            case "import":
+                return TemplateManager.O_IMPORT;
+            default:
+                throw excLine("Unknown operation " + op);
+        }
+    }
+
+    private long parseObjectClass() throws IOException {
+        String name = parseWord();
+        try {
+            return Functions.getObjectClassId(name);
+        } catch (IllegalArgumentException e) {
+            throw excLine("Unknown object class " + name);
+        }
+    }
+
+    private long parseKeyAlgorithm() throws IOException {
+        String name = parseWord();
+        if (isNumber(name)) {
+            return decodeNumber(name);
+        } else {
+            try {
+                return Functions.getKeyId(name);
+            } catch (IllegalArgumentException e) {
+                throw excLine("Unknown key algorithm " + name);
+            }
+        }
+    }
+
+    private long decodeAttributeName(String name) throws IOException {
+        if (isNumber(name)) {
+            return decodeNumber(name);
+        } else {
+            try {
+                return Functions.getAttributeId(name);
+            } catch (IllegalArgumentException e) {
+                throw excLine("Unknown attribute name " + name);
+            }
+        }
+    }
+
+    private CK_ATTRIBUTE decodeAttributeValue(long id, String value)
+            throws IOException {
+        if (value.equals("null")) {
+            return new CK_ATTRIBUTE(id);
+        } else if (value.equals("true")) {
+            return new CK_ATTRIBUTE(id, true);
+        } else if (value.equals("false")) {
+            return new CK_ATTRIBUTE(id, false);
+        } else if (isByteArray(value)) {
+            return new CK_ATTRIBUTE(id, decodeByteArray(value));
+        } else if (isNumber(value)) {
+            return new CK_ATTRIBUTE(id, Integer.valueOf(decodeNumber(value)));
+        } else {
+            throw excLine("Unknown attribute value " + value);
+        }
+    }
+
+    private void parseNSSArgs(String keyword) throws IOException {
+        checkDup(keyword);
+        parseEquals();
+        int token = nextToken();
+        if (token != '"') {
+            throw excToken("Expected quoted string");
+        }
+        nssArgs = expand(st.sval);
+        debug("nssArgs: " + nssArgs);
+    }
+
+    private void parseHandleStartupErrors(String keyword) throws IOException {
+        checkDup(keyword);
+        parseEquals();
+        String val = parseWord();
+        if (val.equals("ignoreAll")) {
+            handleStartupErrors = ERR_IGNORE_ALL;
+        } else if (val.equals("ignoreMissingLibrary")) {
+            handleStartupErrors = ERR_IGNORE_LIB;
+        } else if (val.equals("halt")) {
+            handleStartupErrors = ERR_HALT;
+        } else {
+            throw excToken("Invalid value for handleStartupErrors:");
+        }
+        debug("handleStartupErrors: " + handleStartupErrors);
+    }
+
+}
+
+class ConfigurationException extends IOException {
+    private static final long serialVersionUID = 254492758807673194L;
+    ConfigurationException(String msg) {
+        super(msg);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/KeyCache.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003, 2011, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.util.*;
+import java.lang.ref.*;
+
+import java.security.Key;
+
+import sun.security.util.Cache;
+
+/**
+ * Key to P11Key translation cache. The PKCS#11 token can only perform
+ * operations on keys stored on the token (permanently or temporarily). That
+ * means that in order to allow the PKCS#11 provider to use keys from other
+ * providers, we need to transparently convert them to P11Keys. The engines
+ * do that using (Secret)KeyFactories, which in turn use this class as a
+ * cache.
+ *
+ * There are two KeyCache instances per provider, one for secret keys and
+ * one for public and private keys.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class KeyCache {
+
+    private final Cache<IdentityWrapper, P11Key> strongCache;
+
+    private WeakReference<Map<Key,P11Key>> cacheReference;
+
+    KeyCache() {
+        strongCache = Cache.newHardMemoryCache(16);
+    }
+
+    private static final class IdentityWrapper {
+        final Object obj;
+        IdentityWrapper(Object obj) {
+            this.obj = obj;
+        }
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o instanceof IdentityWrapper == false) {
+                return false;
+            }
+            IdentityWrapper other = (IdentityWrapper)o;
+            return this.obj == other.obj;
+        }
+        public int hashCode() {
+            return System.identityHashCode(obj);
+        }
+    }
+
+    synchronized P11Key get(Key key) {
+        P11Key p11Key = strongCache.get(new IdentityWrapper(key));
+        if (p11Key != null) {
+            return p11Key;
+        }
+        Map<Key,P11Key> map =
+                (cacheReference == null) ? null : cacheReference.get();
+        if (map == null) {
+            return null;
+        }
+        return map.get(key);
+    }
+
+    synchronized void put(Key key, P11Key p11Key) {
+        strongCache.put(new IdentityWrapper(key), p11Key);
+        Map<Key,P11Key> map =
+                (cacheReference == null) ? null : cacheReference.get();
+        if (map == null) {
+            map = new IdentityHashMap<>();
+            cacheReference = new WeakReference<>(map);
+        }
+        map.put(key, p11Key);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Cipher.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,929 @@
+/*
+ * Copyright (c) 2003, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package sun.security.pkcs11;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Locale;
+
+import java.security.*;
+import java.security.spec.*;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import sun.nio.ch.DirectBuffer;
+import sun.security.jca.JCAUtil;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * Cipher implementation class. This class currently supports
+ * DES, DESede, AES, ARCFOUR, and Blowfish.
+ *
+ * This class is designed to support ECB, CBC, CTR with NoPadding
+ * and ECB, CBC with PKCS5Padding. It will use its own padding impl
+ * if the native mechanism does not support padding.
+ *
+ * Note that PKCS#11 currently only supports ECB, CBC, and CTR.
+ * There are no provisions for other modes such as CFB, OFB, and PCBC.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11Cipher extends CipherSpi {
+
+    // mode constant for ECB mode
+    private final static int MODE_ECB = 3;
+    // mode constant for CBC mode
+    private final static int MODE_CBC = 4;
+    // mode constant for CTR mode
+    private final static int MODE_CTR = 5;
+
+    // padding constant for NoPadding
+    private final static int PAD_NONE = 5;
+    // padding constant for PKCS5Padding
+    private final static int PAD_PKCS5 = 6;
+
+    private static interface Padding {
+        // ENC: format the specified buffer with padding bytes and return the
+        // actual padding length
+        int setPaddingBytes(byte[] paddingBuffer, int padLen);
+
+        // DEC: return the length of trailing padding bytes given the specified
+        // padded data
+        int unpad(byte[] paddedData, int len)
+                throws BadPaddingException, IllegalBlockSizeException;
+    }
+
+    private static class PKCS5Padding implements Padding {
+
+        private final int blockSize;
+
+        PKCS5Padding(int blockSize)
+                throws NoSuchPaddingException {
+            if (blockSize == 0) {
+                throw new NoSuchPaddingException
+                        ("PKCS#5 padding not supported with stream ciphers");
+            }
+            this.blockSize = blockSize;
+        }
+
+        public int setPaddingBytes(byte[] paddingBuffer, int padLen) {
+            Arrays.fill(paddingBuffer, 0, padLen, (byte) (padLen & 0x007f));
+            return padLen;
+        }
+
+        public int unpad(byte[] paddedData, int len)
+                throws BadPaddingException, IllegalBlockSizeException {
+            if ((len < 1) || (len % blockSize != 0)) {
+                throw new IllegalBlockSizeException
+                    ("Input length must be multiples of " + blockSize);
+            }
+            byte padValue = paddedData[len - 1];
+            if (padValue < 1 || padValue > blockSize) {
+                throw new BadPaddingException("Invalid pad value!");
+            }
+            // sanity check padding bytes
+            int padStartIndex = len - padValue;
+            for (int i = padStartIndex; i < len; i++) {
+                if (paddedData[i] != padValue) {
+                    throw new BadPaddingException("Invalid pad bytes!");
+                }
+            }
+            return padValue;
+        }
+    }
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // name of the key algorithm, e.g. DES instead of algorithm DES/CBC/...
+    private final String keyAlgorithm;
+
+    // mechanism id
+    private final long mechanism;
+
+    // associated session, if any
+    private Session session;
+
+    // key, if init() was called
+    private P11Key p11Key;
+
+    // flag indicating whether an operation is initialized
+    private boolean initialized;
+
+    // falg indicating encrypt or decrypt mode
+    private boolean encrypt;
+
+    // mode, one of MODE_* above (MODE_ECB for stream ciphers)
+    private int blockMode;
+
+    // block size, 0 for stream ciphers
+    private final int blockSize;
+
+    // padding type, on of PAD_* above (PAD_NONE for stream ciphers)
+    private int paddingType;
+
+    // when the padding is requested but unsupported by the native mechanism,
+    // we use the following to do padding and necessary data buffering.
+    // padding object which generate padding and unpad the decrypted data
+    private Padding paddingObj;
+    // buffer for holding back the block which contains padding bytes
+    private byte[] padBuffer;
+    private int padBufferLen;
+
+    // original IV, if in MODE_CBC or MODE_CTR
+    private byte[] iv;
+
+    // number of bytes buffered internally by the native mechanism and padBuffer
+    // if we do the padding
+    private int bytesBuffered;
+
+    // length of key size in bytes; currently only used by AES given its oid
+    // specification mandates a fixed size of the key
+    private int fixedKeySize = -1;
+
+    P11Cipher(Token token, String algorithm, long mechanism)
+            throws PKCS11Exception, NoSuchAlgorithmException {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+
+        String[] algoParts = algorithm.split("/");
+
+        if (algoParts[0].startsWith("AES")) {
+            blockSize = 16;
+            int index = algoParts[0].indexOf('_');
+            if (index != -1) {
+                // should be well-formed since we specify what we support
+                fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1))/8;
+            }
+            keyAlgorithm = "AES";
+        } else {
+            keyAlgorithm = algoParts[0];
+            if (keyAlgorithm.equals("RC4") ||
+                    keyAlgorithm.equals("ARCFOUR")) {
+                blockSize = 0;
+            } else { // DES, DESede, Blowfish
+                blockSize = 8;
+            }
+        }
+        this.blockMode =
+            (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
+        String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding");
+        String paddingStr =
+                (algoParts.length > 2 ? algoParts[2] : defPadding);
+        try {
+            engineSetPadding(paddingStr);
+        } catch (NoSuchPaddingException nspe) {
+            // should not happen
+            throw new ProviderException(nspe);
+        }
+    }
+
+    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+        // Disallow change of mode for now since currently it's explicitly
+        // defined in transformation strings
+        throw new NoSuchAlgorithmException("Unsupported mode " + mode);
+    }
+
+    private int parseMode(String mode) throws NoSuchAlgorithmException {
+        mode = mode.toUpperCase(Locale.ENGLISH);
+        int result;
+        if (mode.equals("ECB")) {
+            result = MODE_ECB;
+        } else if (mode.equals("CBC")) {
+            if (blockSize == 0) {
+                throw new NoSuchAlgorithmException
+                        ("CBC mode not supported with stream ciphers");
+            }
+            result = MODE_CBC;
+        } else if (mode.equals("CTR")) {
+            result = MODE_CTR;
+        } else {
+            throw new NoSuchAlgorithmException("Unsupported mode " + mode);
+        }
+        return result;
+    }
+
+    // see JCE spec
+    protected void engineSetPadding(String padding)
+            throws NoSuchPaddingException {
+        paddingObj = null;
+        padBuffer = null;
+        padding = padding.toUpperCase(Locale.ENGLISH);
+        if (padding.equals("NOPADDING")) {
+            paddingType = PAD_NONE;
+        } else if (padding.equals("PKCS5PADDING")) {
+            if (this.blockMode == MODE_CTR) {
+                throw new NoSuchPaddingException
+                    ("PKCS#5 padding not supported with CTR mode");
+            }
+            paddingType = PAD_PKCS5;
+            if (mechanism != CKM_DES_CBC_PAD && mechanism != CKM_DES3_CBC_PAD &&
+                    mechanism != CKM_AES_CBC_PAD) {
+                // no native padding support; use our own padding impl
+                paddingObj = new PKCS5Padding(blockSize);
+                padBuffer = new byte[blockSize];
+            }
+        } else {
+            throw new NoSuchPaddingException("Unsupported padding " + padding);
+        }
+    }
+
+    // see JCE spec
+    protected int engineGetBlockSize() {
+        return blockSize;
+    }
+
+    // see JCE spec
+    protected int engineGetOutputSize(int inputLen) {
+        return doFinalLength(inputLen);
+    }
+
+    // see JCE spec
+    protected byte[] engineGetIV() {
+        return (iv == null) ? null : iv.clone();
+    }
+
+    // see JCE spec
+    protected AlgorithmParameters engineGetParameters() {
+        if (iv == null) {
+            return null;
+        }
+        IvParameterSpec ivSpec = new IvParameterSpec(iv);
+        try {
+            AlgorithmParameters params =
+                    AlgorithmParameters.getInstance(keyAlgorithm,
+                    P11Util.getSunJceProvider());
+            params.init(ivSpec);
+            return params;
+        } catch (GeneralSecurityException e) {
+            // NoSuchAlgorithmException, NoSuchProviderException
+            // InvalidParameterSpecException
+            throw new ProviderException("Could not encode parameters", e);
+        }
+    }
+
+    // see JCE spec
+    protected void engineInit(int opmode, Key key, SecureRandom random)
+            throws InvalidKeyException {
+        try {
+            implInit(opmode, key, null, random);
+        } catch (InvalidAlgorithmParameterException e) {
+            throw new InvalidKeyException("init() failed", e);
+        }
+    }
+
+    // see JCE spec
+    protected void engineInit(int opmode, Key key,
+            AlgorithmParameterSpec params, SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        byte[] ivValue;
+        if (params != null) {
+            if (params instanceof IvParameterSpec == false) {
+                throw new InvalidAlgorithmParameterException
+                        ("Only IvParameterSpec supported");
+            }
+            IvParameterSpec ivSpec = (IvParameterSpec) params;
+            ivValue = ivSpec.getIV();
+        } else {
+            ivValue = null;
+        }
+        implInit(opmode, key, ivValue, random);
+    }
+
+    // see JCE spec
+    protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+            SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        byte[] ivValue;
+        if (params != null) {
+            try {
+                IvParameterSpec ivSpec =
+                        params.getParameterSpec(IvParameterSpec.class);
+                ivValue = ivSpec.getIV();
+            } catch (InvalidParameterSpecException e) {
+                throw new InvalidAlgorithmParameterException
+                        ("Could not decode IV", e);
+            }
+        } else {
+            ivValue = null;
+        }
+        implInit(opmode, key, ivValue, random);
+    }
+
+    // actual init() implementation
+    private void implInit(int opmode, Key key, byte[] iv,
+            SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        reset(true);
+        if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
+            throw new InvalidKeyException("Key size is invalid");
+        }
+        switch (opmode) {
+            case Cipher.ENCRYPT_MODE:
+                encrypt = true;
+                break;
+            case Cipher.DECRYPT_MODE:
+                encrypt = false;
+                break;
+            default:
+                throw new InvalidAlgorithmParameterException
+                        ("Unsupported mode: " + opmode);
+        }
+        if (blockMode == MODE_ECB) { // ECB or stream cipher
+            if (iv != null) {
+                if (blockSize == 0) {
+                    throw new InvalidAlgorithmParameterException
+                            ("IV not used with stream ciphers");
+                } else {
+                    throw new InvalidAlgorithmParameterException
+                            ("IV not used in ECB mode");
+                }
+            }
+        } else { // MODE_CBC or MODE_CTR
+            if (iv == null) {
+                if (encrypt == false) {
+                    String exMsg =
+                        (blockMode == MODE_CBC ?
+                         "IV must be specified for decryption in CBC mode" :
+                         "IV must be specified for decryption in CTR mode");
+                    throw new InvalidAlgorithmParameterException(exMsg);
+                }
+                // generate random IV
+                if (random == null) {
+                    random = JCAUtil.getSecureRandom();
+                }
+                iv = new byte[blockSize];
+                random.nextBytes(iv);
+            } else {
+                if (iv.length != blockSize) {
+                    throw new InvalidAlgorithmParameterException
+                            ("IV length must match block size");
+                }
+            }
+        }
+        this.iv = iv;
+        p11Key = P11SecretKeyFactory.convertKey(token, key, keyAlgorithm);
+        try {
+            initialize();
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not initialize cipher", e);
+        }
+    }
+
+    private void cancelOperation() {
+        if (initialized == false) {
+            return;
+        }
+
+        if ((session == null) || (token.explicitCancel == false)) {
+            return;
+        }
+        try {
+            if (session.hasObjects() == false) {
+                session = token.killSession(session);
+                return;
+            } else {
+                // cancel operation by finishing it
+                int bufLen = doFinalLength(0);
+                byte[] buffer = new byte[bufLen];
+                if (encrypt) {
+                    token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen);
+                } else {
+                    token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
+                }
+            }
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("Cancel failed", e);
+        }
+    }
+
+    private void ensureInitialized() throws PKCS11Exception {
+        if (initialized == false) {
+            initialize();
+        }
+    }
+
+    private void initialize() throws PKCS11Exception {
+        if (session == null) {
+            session = token.getOpSession();
+        }
+        CK_MECHANISM mechParams = (blockMode == MODE_CTR?
+            new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) :
+            new CK_MECHANISM(mechanism, iv));
+
+        try {
+            if (encrypt) {
+                token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID);
+            } else {
+                token.p11.C_DecryptInit(session.id(), mechParams, p11Key.keyID);
+            }
+        } catch (PKCS11Exception ex) {
+            // release session when initialization failed
+            session = token.releaseSession(session);
+            throw ex;
+        }
+        bytesBuffered = 0;
+        padBufferLen = 0;
+        initialized = true;
+    }
+
+    // if update(inLen) is called, how big does the output buffer have to be?
+    private int updateLength(int inLen) {
+        if (inLen <= 0) {
+            return 0;
+        }
+
+        int result = inLen + bytesBuffered;
+        if (blockSize != 0 && blockMode != MODE_CTR) {
+            // minus the number of bytes in the last incomplete block.
+            result -= (result & (blockSize - 1));
+        }
+        return result;
+    }
+
+    // if doFinal(inLen) is called, how big does the output buffer have to be?
+    private int doFinalLength(int inLen) {
+        if (inLen < 0) {
+            return 0;
+        }
+
+        int result = inLen + bytesBuffered;
+        if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
+            // add the number of bytes to make the last block complete.
+            result += (blockSize - (result & (blockSize - 1)));
+        }
+        return result;
+    }
+
+    // reset the states to the pre-initialized values
+    private void reset(boolean doCancel) {
+        if (doCancel) cancelOperation();
+
+        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 {
+            byte[] out = new byte[updateLength(inLen)];
+            int n = engineUpdate(in, inOfs, inLen, out, 0);
+            return P11Util.convert(out, 0, n);
+        } catch (ShortBufferException e) {
+            // convert since the output length is calculated by updateLength()
+            throw new ProviderException(e);
+        }
+    }
+
+    // see JCE spec
+    protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
+            int outOfs) throws ShortBufferException {
+        int outLen = out.length - outOfs;
+        return implUpdate(in, inOfs, inLen, out, outOfs, outLen);
+    }
+
+    // see JCE spec
+    @Override
+    protected int engineUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
+            throws ShortBufferException {
+        return implUpdate(inBuffer, outBuffer);
+    }
+
+    // see JCE spec
+    protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
+            throws IllegalBlockSizeException, BadPaddingException {
+        try {
+            byte[] out = new byte[doFinalLength(inLen)];
+            int n = engineDoFinal(in, inOfs, inLen, out, 0);
+            return P11Util.convert(out, 0, n);
+        } catch (ShortBufferException e) {
+            // convert since the output length is calculated by doFinalLength()
+            throw new ProviderException(e);
+        }
+    }
+
+    // see JCE spec
+    protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
+            int outOfs) throws ShortBufferException, IllegalBlockSizeException,
+            BadPaddingException {
+        int n = 0;
+        if ((inLen != 0) && (in != null)) {
+            n = engineUpdate(in, inOfs, inLen, out, outOfs);
+            outOfs += n;
+        }
+        n += implDoFinal(out, outOfs, out.length - outOfs);
+        return n;
+    }
+
+    // see JCE spec
+    @Override
+    protected int engineDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
+            throws ShortBufferException, IllegalBlockSizeException,
+            BadPaddingException {
+        int n = engineUpdate(inBuffer, outBuffer);
+        n += implDoFinal(outBuffer);
+        return n;
+    }
+
+    private int implUpdate(byte[] in, int inOfs, int inLen,
+            byte[] out, int outOfs, int outLen) throws ShortBufferException {
+        if (outLen < updateLength(inLen)) {
+            throw new ShortBufferException();
+        }
+        try {
+            ensureInitialized();
+            int k = 0;
+            if (encrypt) {
+                k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen,
+                        0, out, outOfs, outLen);
+            } else {
+                int newPadBufferLen = 0;
+                if (paddingObj != null) {
+                    if (padBufferLen != 0) {
+                        // NSS throws up when called with data not in multiple
+                        // of blocks. Try to work around this by holding the
+                        // extra data in padBuffer.
+                        if (padBufferLen != padBuffer.length) {
+                            int bufCapacity = padBuffer.length - padBufferLen;
+                            if (inLen > bufCapacity) {
+                                bufferInputBytes(in, inOfs, bufCapacity);
+                                inOfs += bufCapacity;
+                                inLen -= bufCapacity;
+                            } else {
+                                bufferInputBytes(in, inOfs, inLen);
+                                return 0;
+                            }
+                        }
+                        k = token.p11.C_DecryptUpdate(session.id(),
+                                0, padBuffer, 0, padBufferLen,
+                                0, out, outOfs, outLen);
+                        padBufferLen = 0;
+                    }
+                    newPadBufferLen = inLen & (blockSize - 1);
+                    if (newPadBufferLen == 0) {
+                        newPadBufferLen = padBuffer.length;
+                    }
+                    inLen -= newPadBufferLen;
+                }
+                if (inLen > 0) {
+                    k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
+                            inLen, 0, out, (outOfs + k), (outLen - k));
+                }
+                // update 'padBuffer' if using our own padding impl.
+                if (paddingObj != null) {
+                    bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
+                }
+            }
+            bytesBuffered += (inLen - k);
+            return k;
+        } catch (PKCS11Exception e) {
+            if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
+                throw (ShortBufferException)
+                        (new ShortBufferException().initCause(e));
+            }
+            reset(false);
+            throw new ProviderException("update() failed", e);
+        }
+    }
+
+    private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
+            throws ShortBufferException {
+        int inLen = inBuffer.remaining();
+        if (inLen <= 0) {
+            return 0;
+        }
+
+        int outLen = outBuffer.remaining();
+        if (outLen < updateLength(inLen)) {
+            throw new ShortBufferException();
+        }
+        int origPos = inBuffer.position();
+        try {
+            ensureInitialized();
+
+            long inAddr = 0;
+            int inOfs = 0;
+            byte[] inArray = null;
+
+            if (inBuffer instanceof DirectBuffer) {
+                inAddr = ((DirectBuffer) inBuffer).address();
+                inOfs = origPos;
+            } else if (inBuffer.hasArray()) {
+                inArray = inBuffer.array();
+                inOfs = (origPos + inBuffer.arrayOffset());
+            }
+
+            long outAddr = 0;
+            int outOfs = 0;
+            byte[] outArray = null;
+            if (outBuffer instanceof DirectBuffer) {
+                outAddr = ((DirectBuffer) outBuffer).address();
+                outOfs = outBuffer.position();
+            } else {
+                if (outBuffer.hasArray()) {
+                    outArray = outBuffer.array();
+                    outOfs = (outBuffer.position() + outBuffer.arrayOffset());
+                } else {
+                    outArray = new byte[outLen];
+                }
+            }
+
+            int k = 0;
+            if (encrypt) {
+                if (inAddr == 0 && inArray == null) {
+                    inArray = new byte[inLen];
+                    inBuffer.get(inArray);
+                } else {
+                    inBuffer.position(origPos + inLen);
+                }
+                k = token.p11.C_EncryptUpdate(session.id(),
+                        inAddr, inArray, inOfs, inLen,
+                        outAddr, outArray, outOfs, outLen);
+            } else {
+                int newPadBufferLen = 0;
+                if (paddingObj != null) {
+                    if (padBufferLen != 0) {
+                        // NSS throws up when called with data not in multiple
+                        // of blocks. Try to work around this by holding the
+                        // extra data in padBuffer.
+                        if (padBufferLen != padBuffer.length) {
+                            int bufCapacity = padBuffer.length - padBufferLen;
+                            if (inLen > bufCapacity) {
+                                bufferInputBytes(inBuffer, bufCapacity);
+                                inOfs += bufCapacity;
+                                inLen -= bufCapacity;
+                            } else {
+                                bufferInputBytes(inBuffer, inLen);
+                                return 0;
+                            }
+                        }
+                        k = token.p11.C_DecryptUpdate(session.id(), 0,
+                                padBuffer, 0, padBufferLen, outAddr, outArray,
+                                outOfs, outLen);
+                        padBufferLen = 0;
+                    }
+                    newPadBufferLen = inLen & (blockSize - 1);
+                    if (newPadBufferLen == 0) {
+                        newPadBufferLen = padBuffer.length;
+                    }
+                    inLen -= newPadBufferLen;
+                }
+                if (inLen > 0) {
+                    if (inAddr == 0 && inArray == null) {
+                        inArray = new byte[inLen];
+                        inBuffer.get(inArray);
+                    } else {
+                        inBuffer.position(inBuffer.position() + inLen);
+                    }
+                    k += token.p11.C_DecryptUpdate(session.id(), inAddr,
+                            inArray, inOfs, inLen, outAddr, outArray,
+                            (outOfs + k), (outLen - k));
+                }
+                // update 'padBuffer' if using our own padding impl.
+                if (paddingObj != null && newPadBufferLen != 0) {
+                    bufferInputBytes(inBuffer, newPadBufferLen);
+                }
+            }
+            bytesBuffered += (inLen - k);
+            if (!(outBuffer instanceof DirectBuffer) &&
+                    !outBuffer.hasArray()) {
+                outBuffer.put(outArray, outOfs, k);
+            } else {
+                outBuffer.position(outBuffer.position() + k);
+            }
+            return k;
+        } catch (PKCS11Exception e) {
+            // Reset input buffer to its original position for
+            inBuffer.position(origPos);
+            if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
+                throw (ShortBufferException)
+                        (new ShortBufferException().initCause(e));
+            }
+            reset(false);
+            throw new ProviderException("update() failed", e);
+        }
+    }
+
+    private int implDoFinal(byte[] out, int outOfs, int outLen)
+            throws ShortBufferException, IllegalBlockSizeException,
+            BadPaddingException {
+        int requiredOutLen = doFinalLength(0);
+        if (outLen < requiredOutLen) {
+            throw new ShortBufferException();
+        }
+        boolean doCancel = true;
+        try {
+            ensureInitialized();
+            int k = 0;
+            if (encrypt) {
+                if (paddingObj != null) {
+                    int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
+                            requiredOutLen - bytesBuffered);
+                    k = token.p11.C_EncryptUpdate(session.id(),
+                            0, padBuffer, 0, actualPadLen,
+                            0, out, outOfs, outLen);
+                }
+                k += token.p11.C_EncryptFinal(session.id(),
+                        0, out, (outOfs + k), (outLen - k));
+                doCancel = false;
+            } else {
+                // Special handling to match SunJCE provider behavior
+                if (bytesBuffered == 0 && padBufferLen == 0) {
+                    return 0;
+                }
+                if (paddingObj != null) {
+                    if (padBufferLen != 0) {
+                        k = token.p11.C_DecryptUpdate(session.id(), 0,
+                                padBuffer, 0, padBufferLen, 0, padBuffer, 0,
+                                padBuffer.length);
+                    }
+                    k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
+                            padBuffer.length - k);
+                    doCancel = false;
+
+                    int actualPadLen = paddingObj.unpad(padBuffer, k);
+                    k -= actualPadLen;
+                    System.arraycopy(padBuffer, 0, out, outOfs, k);
+                } else {
+                    k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
+                            outLen);
+                    doCancel = false;
+                }
+            }
+            return k;
+        } catch (PKCS11Exception e) {
+            doCancel = false;
+            handleException(e);
+            throw new ProviderException("doFinal() failed", e);
+        } finally {
+            reset(doCancel);
+        }
+    }
+
+    private int implDoFinal(ByteBuffer outBuffer)
+            throws ShortBufferException, IllegalBlockSizeException,
+            BadPaddingException {
+        int outLen = outBuffer.remaining();
+        int requiredOutLen = doFinalLength(0);
+        if (outLen < requiredOutLen) {
+            throw new ShortBufferException();
+        }
+
+        boolean doCancel = true;
+        try {
+            ensureInitialized();
+
+            long outAddr = 0;
+            byte[] outArray = null;
+            int outOfs = 0;
+            if (outBuffer instanceof DirectBuffer) {
+                outAddr = ((DirectBuffer) outBuffer).address();
+                outOfs = outBuffer.position();
+            } else {
+                if (outBuffer.hasArray()) {
+                    outArray = outBuffer.array();
+                    outOfs = outBuffer.position() + outBuffer.arrayOffset();
+                } else {
+                    outArray = new byte[outLen];
+                }
+            }
+
+            int k = 0;
+
+            if (encrypt) {
+                if (paddingObj != null) {
+                    int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
+                            requiredOutLen - bytesBuffered);
+                    k = token.p11.C_EncryptUpdate(session.id(),
+                            0, padBuffer, 0, actualPadLen,
+                            outAddr, outArray, outOfs, outLen);
+                }
+                k += token.p11.C_EncryptFinal(session.id(),
+                        outAddr, outArray, (outOfs + k), (outLen - k));
+                doCancel = false;
+            } else {
+                // Special handling to match SunJCE provider behavior
+                if (bytesBuffered == 0 && padBufferLen == 0) {
+                    return 0;
+                }
+
+                if (paddingObj != null) {
+                    if (padBufferLen != 0) {
+                        k = token.p11.C_DecryptUpdate(session.id(),
+                                0, padBuffer, 0, padBufferLen,
+                                0, padBuffer, 0, padBuffer.length);
+                        padBufferLen = 0;
+                    }
+                    k += token.p11.C_DecryptFinal(session.id(),
+                            0, padBuffer, k, padBuffer.length - k);
+                    doCancel = false;
+
+                    int actualPadLen = paddingObj.unpad(padBuffer, k);
+                    k -= actualPadLen;
+                    outArray = padBuffer;
+                    outOfs = 0;
+                } else {
+                    k = token.p11.C_DecryptFinal(session.id(),
+                            outAddr, outArray, outOfs, outLen);
+                    doCancel = false;
+                }
+            }
+            if ((!encrypt && paddingObj != null) ||
+                    (!(outBuffer instanceof DirectBuffer) &&
+                    !outBuffer.hasArray())) {
+                outBuffer.put(outArray, outOfs, k);
+            } else {
+                outBuffer.position(outBuffer.position() + k);
+            }
+            return k;
+        } catch (PKCS11Exception e) {
+            doCancel = false;
+            handleException(e);
+            throw new ProviderException("doFinal() failed", e);
+        } finally {
+            reset(doCancel);
+        }
+    }
+
+    private void handleException(PKCS11Exception e)
+            throws ShortBufferException, IllegalBlockSizeException {
+        long errorCode = e.getErrorCode();
+        if (errorCode == CKR_BUFFER_TOO_SMALL) {
+            throw (ShortBufferException)
+                    (new ShortBufferException().initCause(e));
+        } else if (errorCode == CKR_DATA_LEN_RANGE ||
+                   errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
+            throw (IllegalBlockSizeException)
+                    (new IllegalBlockSizeException(e.toString()).initCause(e));
+        }
+    }
+
+    // see JCE spec
+    protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
+            InvalidKeyException {
+        // XXX key wrapping
+        throw new UnsupportedOperationException("engineWrap()");
+    }
+
+    // see JCE spec
+    protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
+            int wrappedKeyType)
+            throws InvalidKeyException, NoSuchAlgorithmException {
+        // XXX key unwrapping
+        throw new UnsupportedOperationException("engineUnwrap()");
+    }
+
+    // see JCE spec
+    @Override
+    protected int engineGetKeySize(Key key) throws InvalidKeyException {
+        int n = P11SecretKeyFactory.convertKey
+                (token, key, keyAlgorithm).length();
+        return n;
+    }
+
+    private final void bufferInputBytes(byte[] in, int inOfs, int len) {
+        System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
+        padBufferLen += len;
+        bytesBuffered += len;
+    }
+
+    private final void bufferInputBytes(ByteBuffer inBuffer, int len) {
+        inBuffer.get(padBuffer, padBufferLen, len);
+        padBufferLen += len;
+        bytesBuffered += len;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11DHKeyFactory.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2003, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.spec.*;
+
+import javax.crypto.interfaces.*;
+import javax.crypto.spec.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * DH KeyFactory implementation.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11DHKeyFactory extends P11KeyFactory {
+
+    P11DHKeyFactory(Token token, String algorithm) {
+        super(token, algorithm);
+    }
+
+    PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
+        try {
+            if (key instanceof DHPublicKey) {
+                DHPublicKey dhKey = (DHPublicKey)key;
+                DHParameterSpec params = dhKey.getParams();
+                return generatePublic(
+                    dhKey.getY(),
+                    params.getP(),
+                    params.getG()
+                );
+            } else if ("X.509".equals(key.getFormat())) {
+                // let SunJCE provider parse for us, then recurse
+                try {
+                    KeyFactory factory = implGetSoftwareFactory();
+                    key = (PublicKey)factory.translateKey(key);
+                    return implTranslatePublicKey(key);
+                } catch (GeneralSecurityException e) {
+                    throw new InvalidKeyException("Could not translate key", e);
+                }
+            } else {
+                throw new InvalidKeyException("PublicKey must be instance "
+                        + "of DHPublicKey or have X.509 encoding");
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create DH public key", e);
+        }
+    }
+
+    PrivateKey implTranslatePrivateKey(PrivateKey key)
+            throws InvalidKeyException {
+        try {
+            if (key instanceof DHPrivateKey) {
+                DHPrivateKey dhKey = (DHPrivateKey)key;
+                DHParameterSpec params = dhKey.getParams();
+                return generatePrivate(
+                    dhKey.getX(),
+                    params.getP(),
+                    params.getG()
+                );
+            } else if ("PKCS#8".equals(key.getFormat())) {
+                // let SunJCE provider parse for us, then recurse
+                try {
+                    KeyFactory factory = implGetSoftwareFactory();
+                    key = (PrivateKey)factory.translateKey(key);
+                    return implTranslatePrivateKey(key);
+                } catch (GeneralSecurityException e) {
+                    throw new InvalidKeyException("Could not translate key", e);
+                }
+            } else {
+                throw new InvalidKeyException("PrivateKey must be instance "
+                        + "of DHPrivateKey or have PKCS#8 encoding");
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create DH private key", e);
+        }
+    }
+
+    // see JCA spec
+    protected PublicKey engineGeneratePublic(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec instanceof X509EncodedKeySpec) {
+            try {
+                KeyFactory factory = implGetSoftwareFactory();
+                PublicKey key = factory.generatePublic(keySpec);
+                return implTranslatePublicKey(key);
+            } catch (GeneralSecurityException e) {
+                throw new InvalidKeySpecException
+                        ("Could not create DH public key", e);
+            }
+        }
+        if (keySpec instanceof DHPublicKeySpec == false) {
+            throw new InvalidKeySpecException("Only DHPublicKeySpec and "
+                + "X509EncodedKeySpec supported for DH public keys");
+        }
+        try {
+            DHPublicKeySpec ds = (DHPublicKeySpec)keySpec;
+            return generatePublic(
+                ds.getY(),
+                ds.getP(),
+                ds.getG()
+            );
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeySpecException
+                ("Could not create DH public key", e);
+        }
+    }
+
+    // see JCA spec
+    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec instanceof PKCS8EncodedKeySpec) {
+            try {
+                KeyFactory factory = implGetSoftwareFactory();
+                PrivateKey key = factory.generatePrivate(keySpec);
+                return implTranslatePrivateKey(key);
+            } catch (GeneralSecurityException e) {
+                throw new InvalidKeySpecException
+                        ("Could not create DH private key", e);
+            }
+        }
+        if (keySpec instanceof DHPrivateKeySpec == false) {
+            throw new InvalidKeySpecException("Only DHPrivateKeySpec and "
+                + "PKCS8EncodedKeySpec supported for DH private keys");
+        }
+        try {
+            DHPrivateKeySpec ds = (DHPrivateKeySpec)keySpec;
+            return generatePrivate(
+                ds.getX(),
+                ds.getP(),
+                ds.getG()
+            );
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeySpecException
+                ("Could not create DH private key", e);
+        }
+    }
+
+    private PublicKey generatePublic(BigInteger y, BigInteger p, BigInteger g)
+            throws PKCS11Exception {
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DH),
+            new CK_ATTRIBUTE(CKA_VALUE, y),
+            new CK_ATTRIBUTE(CKA_PRIME, p),
+            new CK_ATTRIBUTE(CKA_BASE, g),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PUBLIC_KEY, CKK_DH, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.publicKey
+                (session, keyID, "DH", p.bitLength(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private PrivateKey generatePrivate(BigInteger x, BigInteger p,
+            BigInteger g) throws PKCS11Exception {
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DH),
+            new CK_ATTRIBUTE(CKA_VALUE, x),
+            new CK_ATTRIBUTE(CKA_PRIME, p),
+            new CK_ATTRIBUTE(CKA_BASE, g),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PRIVATE_KEY, CKK_DH, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.privateKey
+                (session, keyID, "DH", p.bitLength(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
+        if (DHPublicKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_PRIME),
+                new CK_ATTRIBUTE(CKA_BASE),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            KeySpec spec = new DHPublicKeySpec(
+                attributes[0].getBigInteger(),
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger()
+            );
+            return keySpec.cast(spec);
+        } else { // X.509 handled in superclass
+            throw new InvalidKeySpecException("Only DHPublicKeySpec and "
+                + "X509EncodedKeySpec supported for DH public keys");
+        }
+    }
+
+    <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
+        if (DHPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_PRIME),
+                new CK_ATTRIBUTE(CKA_BASE),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            KeySpec spec = new DHPrivateKeySpec(
+                attributes[0].getBigInteger(),
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger()
+            );
+            return keySpec.cast(spec);
+        } else { // PKCS#8 handled in superclass
+            throw new InvalidKeySpecException("Only DHPrivateKeySpec "
+                + "and PKCS8EncodedKeySpec supported for DH private keys");
+        }
+    }
+
+    KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
+        return KeyFactory.getInstance("DH", P11Util.getSunJceProvider());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11DSAKeyFactory.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2003, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * DSA KeyFactory implementation.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11DSAKeyFactory extends P11KeyFactory {
+
+    P11DSAKeyFactory(Token token, String algorithm) {
+        super(token, algorithm);
+    }
+
+    PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
+        try {
+            if (key instanceof DSAPublicKey) {
+                DSAPublicKey dsaKey = (DSAPublicKey)key;
+                DSAParams params = dsaKey.getParams();
+                return generatePublic(
+                    dsaKey.getY(),
+                    params.getP(),
+                    params.getQ(),
+                    params.getG()
+                );
+            } else if ("X.509".equals(key.getFormat())) {
+                // let Sun provider parse for us, then recurse
+                byte[] encoded = key.getEncoded();
+                key = new sun.security.provider.DSAPublicKey(encoded);
+                return implTranslatePublicKey(key);
+            } else {
+                throw new InvalidKeyException("PublicKey must be instance "
+                        + "of DSAPublicKey or have X.509 encoding");
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create DSA public key", e);
+        }
+    }
+
+    PrivateKey implTranslatePrivateKey(PrivateKey key)
+            throws InvalidKeyException {
+        try {
+            if (key instanceof DSAPrivateKey) {
+                DSAPrivateKey dsaKey = (DSAPrivateKey)key;
+                DSAParams params = dsaKey.getParams();
+                return generatePrivate(
+                    dsaKey.getX(),
+                    params.getP(),
+                    params.getQ(),
+                    params.getG()
+                );
+            } else if ("PKCS#8".equals(key.getFormat())) {
+                // let Sun provider parse for us, then recurse
+                byte[] encoded = key.getEncoded();
+                key = new sun.security.provider.DSAPrivateKey(encoded);
+                return implTranslatePrivateKey(key);
+            } else {
+                throw new InvalidKeyException("PrivateKey must be instance "
+                        + "of DSAPrivateKey or have PKCS#8 encoding");
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create DSA private key", e);
+        }
+    }
+
+    // see JCA spec
+    protected PublicKey engineGeneratePublic(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec instanceof X509EncodedKeySpec) {
+            try {
+                byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
+                PublicKey key = new sun.security.provider.DSAPublicKey(encoded);
+                return implTranslatePublicKey(key);
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException
+                        ("Could not create DSA public key", e);
+            }
+        }
+        if (keySpec instanceof DSAPublicKeySpec == false) {
+            throw new InvalidKeySpecException("Only DSAPublicKeySpec and "
+                + "X509EncodedKeySpec supported for DSA public keys");
+        }
+        try {
+            DSAPublicKeySpec ds = (DSAPublicKeySpec)keySpec;
+            return generatePublic(
+                ds.getY(),
+                ds.getP(),
+                ds.getQ(),
+                ds.getG()
+            );
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeySpecException
+                ("Could not create DSA public key", e);
+        }
+    }
+
+    // see JCA spec
+    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec instanceof PKCS8EncodedKeySpec) {
+            try {
+                byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
+                PrivateKey key = new sun.security.provider.DSAPrivateKey(encoded);
+                return implTranslatePrivateKey(key);
+            } catch (GeneralSecurityException e) {
+                throw new InvalidKeySpecException
+                        ("Could not create DSA private key", e);
+            }
+        }
+        if (keySpec instanceof DSAPrivateKeySpec == false) {
+            throw new InvalidKeySpecException("Only DSAPrivateKeySpec and "
+                + "PKCS8EncodedKeySpec supported for DSA private keys");
+        }
+        try {
+            DSAPrivateKeySpec ds = (DSAPrivateKeySpec)keySpec;
+            return generatePrivate(
+                ds.getX(),
+                ds.getP(),
+                ds.getQ(),
+                ds.getG()
+            );
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeySpecException
+                ("Could not create DSA private key", e);
+        }
+    }
+
+    private PublicKey generatePublic(BigInteger y, BigInteger p, BigInteger q,
+            BigInteger g) throws PKCS11Exception {
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
+            new CK_ATTRIBUTE(CKA_VALUE, y),
+            new CK_ATTRIBUTE(CKA_PRIME, p),
+            new CK_ATTRIBUTE(CKA_SUBPRIME, q),
+            new CK_ATTRIBUTE(CKA_BASE, g),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PUBLIC_KEY, CKK_DSA, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.publicKey
+                (session, keyID, "DSA", p.bitLength(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private PrivateKey generatePrivate(BigInteger x, BigInteger p,
+            BigInteger q, BigInteger g) throws PKCS11Exception {
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
+            new CK_ATTRIBUTE(CKA_VALUE, x),
+            new CK_ATTRIBUTE(CKA_PRIME, p),
+            new CK_ATTRIBUTE(CKA_SUBPRIME, q),
+            new CK_ATTRIBUTE(CKA_BASE, g),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PRIVATE_KEY, CKK_DSA, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.privateKey
+                (session, keyID, "DSA", p.bitLength(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
+        if (DSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_PRIME),
+                new CK_ATTRIBUTE(CKA_SUBPRIME),
+                new CK_ATTRIBUTE(CKA_BASE),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            KeySpec spec = new DSAPublicKeySpec(
+                attributes[0].getBigInteger(),
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger(),
+                attributes[3].getBigInteger()
+            );
+            return keySpec.cast(spec);
+        } else { // X.509 handled in superclass
+            throw new InvalidKeySpecException("Only DSAPublicKeySpec and "
+                + "X509EncodedKeySpec supported for DSA public keys");
+        }
+    }
+
+    <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
+        if (DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_PRIME),
+                new CK_ATTRIBUTE(CKA_SUBPRIME),
+                new CK_ATTRIBUTE(CKA_BASE),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            KeySpec spec = new DSAPrivateKeySpec(
+                attributes[0].getBigInteger(),
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger(),
+                attributes[3].getBigInteger()
+            );
+            return keySpec.cast(spec);
+        } else { // PKCS#8 handled in superclass
+            throw new InvalidKeySpecException("Only DSAPrivateKeySpec "
+                + "and PKCS8EncodedKeySpec supported for DSA private keys");
+        }
+    }
+
+    KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
+        return KeyFactory.getInstance("DSA", P11Util.getSunProvider());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2003, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.util.*;
+import java.nio.ByteBuffer;
+
+import java.security.*;
+
+import javax.crypto.SecretKey;
+
+import sun.nio.ch.DirectBuffer;
+
+import sun.security.util.MessageDigestSpi2;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * MessageDigest implementation class. This class currently supports
+ * MD2, MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512.
+ *
+ * Note that many digest operations are on fairly small amounts of data
+ * (less than 100 bytes total). For example, the 2nd hashing in HMAC or
+ * the PRF in TLS. In order to speed those up, we use some buffering to
+ * minimize number of the Java->native transitions.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11Digest extends MessageDigestSpi implements Cloneable,
+    MessageDigestSpi2 {
+
+    /* fields initialized, no session acquired */
+    private final static int S_BLANK    = 1;
+
+    /* data in buffer, session acquired, but digest not initialized */
+    private final static int S_BUFFERED = 2;
+
+    /* session initialized for digesting */
+    private final static int S_INIT     = 3;
+
+    private final static int BUFFER_SIZE = 96;
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id object
+    private final CK_MECHANISM mechanism;
+
+    // length of the digest in bytes
+    private final int digestLength;
+
+    // associated session, if any
+    private Session session;
+
+    // current state, one of S_* above
+    private int state;
+
+    // buffer to reduce number of JNI calls
+    private byte[] buffer;
+
+    // offset into the buffer
+    private int bufOfs;
+
+    P11Digest(Token token, String algorithm, long mechanism) {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = new CK_MECHANISM(mechanism);
+        switch ((int)mechanism) {
+        case (int)CKM_MD2:
+        case (int)CKM_MD5:
+            digestLength = 16;
+            break;
+        case (int)CKM_SHA_1:
+            digestLength = 20;
+            break;
+        case (int)CKM_SHA224:
+            digestLength = 28;
+            break;
+        case (int)CKM_SHA256:
+            digestLength = 32;
+            break;
+        case (int)CKM_SHA384:
+            digestLength = 48;
+            break;
+        case (int)CKM_SHA512:
+            digestLength = 64;
+            break;
+        default:
+            throw new ProviderException("Unknown mechanism: " + mechanism);
+        }
+        buffer = new byte[BUFFER_SIZE];
+        state = S_BLANK;
+    }
+
+    // see JCA spec
+    protected int engineGetDigestLength() {
+        return digestLength;
+    }
+
+    private void fetchSession() {
+        token.ensureValid();
+        if (state == S_BLANK) {
+            try {
+                session = token.getOpSession();
+                state = S_BUFFERED;
+            } catch (PKCS11Exception e) {
+                throw new ProviderException("No more session available", e);
+            }
+        }
+    }
+
+    // see JCA spec
+    protected void engineReset() {
+        token.ensureValid();
+
+        if (session != null) {
+            if (state == S_INIT && token.explicitCancel == true) {
+                session = token.killSession(session);
+            } else {
+                session = token.releaseSession(session);
+            }
+        }
+        state = S_BLANK;
+        bufOfs = 0;
+    }
+
+    // see JCA spec
+    protected byte[] engineDigest() {
+        try {
+            byte[] digest = new byte[digestLength];
+            int n = engineDigest(digest, 0, digestLength);
+            return digest;
+        } catch (DigestException e) {
+            throw new ProviderException("internal error", e);
+        }
+    }
+
+    // see JCA spec
+    protected int engineDigest(byte[] digest, int ofs, int len)
+            throws DigestException {
+        if (len < 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(), mechanism, buffer, 0,
+                        bufOfs, digest, ofs, len);
+                bufOfs = 0;
+            } else {
+                if (bufOfs != 0) {
+                    token.p11.C_DigestUpdate(session.id(), 0, buffer, 0,
+                            bufOfs);
+                    bufOfs = 0;
+                }
+                n = token.p11.C_DigestFinal(session.id(), digest, ofs, len);
+            }
+            if (n != digestLength) {
+                throw new ProviderException("internal digest length error");
+            }
+            return n;
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("digest() failed", e);
+        } finally {
+            engineReset();
+        }
+    }
+
+    // see JCA spec
+    protected void engineUpdate(byte in) {
+        byte[] temp = { in };
+        engineUpdate(temp, 0, 1);
+    }
+
+    // see JCA spec
+    protected void engineUpdate(byte[] in, int ofs, int len) {
+        if (len <= 0) {
+            return;
+        }
+
+        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);
+        }
+    }
+
+    // Called by SunJSSE via reflection during the SSL 3.0 handshake if
+    // the master secret is sensitive.
+    // Note: Change to protected after this method is moved from
+    // sun.security.util.MessageSpi2 interface to
+    // java.security.MessageDigestSpi class
+    public void engineUpdate(SecretKey key) throws InvalidKeyException {
+        // 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.
+        if (key instanceof P11Key == false) {
+            throw new InvalidKeyException("Not a P11Key: " + key);
+        }
+        P11Key p11Key = (P11Key)key;
+        if (p11Key.token != token) {
+            throw new InvalidKeyException("Not a P11Key of this provider: " +
+                    key);
+        }
+
+        fetchSession();
+        try {
+            if (state == S_BUFFERED) {
+                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) {
+        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(), mechanism);
+                state = S_INIT;
+            }
+            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);
+        }
+    }
+
+    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));
+        }
+        return copy;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECDHKeyAgreement.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2006, 2007, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.security.*;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * KeyAgreement implementation for ECDH.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.6
+ */
+final class P11ECDHKeyAgreement extends KeyAgreementSpi {
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id
+    private final long mechanism;
+
+    // private key, if initialized
+    private P11Key privateKey;
+
+    // encoded public point, non-null between doPhase() and generateSecret() only
+    private byte[] publicValue;
+
+    // length of the secret to be derived
+    private int secretLen;
+
+    P11ECDHKeyAgreement(Token token, String algorithm, long mechanism) {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+    }
+
+    // see JCE spec
+    protected void engineInit(Key key, SecureRandom random)
+            throws InvalidKeyException {
+        if (key instanceof PrivateKey == false) {
+            throw new InvalidKeyException
+                        ("Key must be instance of PrivateKey");
+        }
+        privateKey = P11KeyFactory.convertKey(token, key, "EC");
+        publicValue = null;
+    }
+
+    // see JCE spec
+    protected void engineInit(Key key, AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidKeyException,
+            InvalidAlgorithmParameterException {
+        if (params != null) {
+            throw new InvalidAlgorithmParameterException
+                        ("Parameters not supported");
+        }
+        engineInit(key, random);
+    }
+
+    // see JCE spec
+    protected Key engineDoPhase(Key key, boolean lastPhase)
+            throws InvalidKeyException, IllegalStateException {
+        if (privateKey == null) {
+            throw new IllegalStateException("Not initialized");
+        }
+        if (publicValue != null) {
+            throw new IllegalStateException("Phase already executed");
+        }
+        if (lastPhase == false) {
+            throw new IllegalStateException
+                ("Only two party agreement supported, lastPhase must be true");
+        }
+        if (key instanceof ECPublicKey == false) {
+            throw new InvalidKeyException
+                ("Key must be a PublicKey with algorithm EC");
+        }
+        ECPublicKey ecKey = (ECPublicKey)key;
+        int keyLenBits = ecKey.getParams().getCurve().getField().getFieldSize();
+        secretLen = (keyLenBits + 7) >> 3;
+        publicValue = P11ECKeyFactory.getEncodedPublicValue(ecKey);
+        return null;
+    }
+
+    // see JCE spec
+    protected byte[] engineGenerateSecret() throws IllegalStateException {
+        if ((privateKey == null) || (publicValue == null)) {
+            throw new IllegalStateException("Not initialized correctly");
+        }
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
+            };
+            CK_ECDH1_DERIVE_PARAMS ckParams =
+                    new CK_ECDH1_DERIVE_PARAMS(CKD_NULL, null, publicValue);
+            attributes = token.getAttributes
+                (O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
+            long keyID = token.p11.C_DeriveKey(session.id(),
+                new CK_MECHANISM(mechanism, ckParams), privateKey.keyID,
+                attributes);
+            attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE)
+            };
+            token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
+            byte[] secret = attributes[0].getByteArray();
+            token.p11.C_DestroyObject(session.id(), keyID);
+            return secret;
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("Could not derive key", e);
+        } finally {
+            publicValue = null;
+            token.releaseSession(session);
+        }
+    }
+
+    // see JCE spec
+    protected int engineGenerateSecret(byte[] sharedSecret, int
+            offset) throws IllegalStateException, ShortBufferException {
+        if (offset + secretLen > sharedSecret.length) {
+            throw new ShortBufferException("Need " + secretLen
+                + " bytes, only " + (sharedSecret.length - offset) + " available");
+        }
+        byte[] secret = engineGenerateSecret();
+        System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
+        return secret.length;
+    }
+
+    // see JCE spec
+    protected SecretKey engineGenerateSecret(String algorithm)
+            throws IllegalStateException, NoSuchAlgorithmException,
+            InvalidKeyException {
+        if (algorithm == null) {
+            throw new NoSuchAlgorithmException("Algorithm must not be null");
+        }
+        if (algorithm.equals("TlsPremasterSecret") == false) {
+            throw new NoSuchAlgorithmException
+                ("Only supported for algorithm TlsPremasterSecret");
+        }
+        return nativeGenerateSecret(algorithm);
+    }
+
+    private SecretKey nativeGenerateSecret(String algorithm)
+            throws IllegalStateException, NoSuchAlgorithmException,
+            InvalidKeyException {
+        if ((privateKey == null) || (publicValue == null)) {
+            throw new IllegalStateException("Not initialized correctly");
+        }
+        long keyType = CKK_GENERIC_SECRET;
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
+            };
+            CK_ECDH1_DERIVE_PARAMS ckParams =
+                    new CK_ECDH1_DERIVE_PARAMS(CKD_NULL, null, publicValue);
+            attributes = token.getAttributes
+                (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
+            long keyID = token.p11.C_DeriveKey(session.id(),
+                new CK_MECHANISM(mechanism, ckParams), privateKey.keyID,
+                attributes);
+            CK_ATTRIBUTE[] lenAttributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE_LEN),
+            };
+            token.p11.C_GetAttributeValue(session.id(), keyID, lenAttributes);
+            int keyLen = (int)lenAttributes[0].getLong();
+            SecretKey key = P11Key.secretKey
+                        (session, keyID, algorithm, keyLen << 3, attributes);
+            return key;
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not derive key", e);
+        } finally {
+            publicValue = null;
+            token.releaseSession(session);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11ECKeyFactory.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2006, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+import sun.security.util.DerValue;
+import sun.security.util.ECUtil;
+
+/**
+ * EC KeyFactory implementation.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.6
+ */
+final class P11ECKeyFactory extends P11KeyFactory {
+    private static Provider sunECprovider;
+
+    private static Provider getSunECProvider() {
+        if (sunECprovider == null) {
+            sunECprovider = Security.getProvider("SunEC");
+            if (sunECprovider == null) {
+                throw new RuntimeException("Cannot load SunEC provider");
+            }
+        }
+
+        return sunECprovider;
+    }
+
+    P11ECKeyFactory(Token token, String algorithm) {
+        super(token, algorithm);
+    }
+
+    static ECParameterSpec getECParameterSpec(String name) {
+        return ECUtil.getECParameterSpec(getSunECProvider(), name);
+    }
+
+    static ECParameterSpec getECParameterSpec(int keySize) {
+        return ECUtil.getECParameterSpec(getSunECProvider(), keySize);
+    }
+
+    // Check that spec is a known supported curve and convert it to our
+    // ECParameterSpec subclass. If not possible, return null.
+    static ECParameterSpec getECParameterSpec(ECParameterSpec spec) {
+        return ECUtil.getECParameterSpec(getSunECProvider(), spec);
+    }
+
+    static ECParameterSpec decodeParameters(byte[] params) throws IOException {
+        return ECUtil.getECParameterSpec(getSunECProvider(), params);
+    }
+
+    static byte[] encodeParameters(ECParameterSpec params) {
+        return ECUtil.encodeECParameterSpec(getSunECProvider(), params);
+    }
+
+    static ECPoint decodePoint(byte[] encoded, EllipticCurve curve) throws IOException {
+        return ECUtil.decodePoint(encoded, curve);
+    }
+
+    // Used by ECDH KeyAgreement
+    static byte[] getEncodedPublicValue(PublicKey key) throws InvalidKeyException {
+        if (key instanceof ECPublicKey) {
+            ECPublicKey ecKey = (ECPublicKey)key;
+            ECPoint w = ecKey.getW();
+            ECParameterSpec params = ecKey.getParams();
+            return ECUtil.encodePoint(w, params.getCurve());
+        } else {
+            // should never occur
+            throw new InvalidKeyException
+                ("Key class not yet supported: " + key.getClass().getName());
+        }
+    }
+
+    PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
+        try {
+            if (key instanceof ECPublicKey) {
+                ECPublicKey ecKey = (ECPublicKey)key;
+                return generatePublic(
+                    ecKey.getW(),
+                    ecKey.getParams()
+                );
+            } else if ("X.509".equals(key.getFormat())) {
+                // let Sun provider parse for us, then recurse
+                byte[] encoded = key.getEncoded();
+
+                try {
+                    key = ECUtil.decodeX509ECPublicKey(encoded);
+                } catch (InvalidKeySpecException ikse) {
+                    throw new InvalidKeyException(ikse);
+                }
+
+                return implTranslatePublicKey(key);
+            } else {
+                throw new InvalidKeyException("PublicKey must be instance "
+                        + "of ECPublicKey or have X.509 encoding");
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create EC public key", e);
+        }
+    }
+
+    PrivateKey implTranslatePrivateKey(PrivateKey key)
+            throws InvalidKeyException {
+        try {
+            if (key instanceof ECPrivateKey) {
+                ECPrivateKey ecKey = (ECPrivateKey)key;
+                return generatePrivate(
+                    ecKey.getS(),
+                    ecKey.getParams()
+                );
+            } else if ("PKCS#8".equals(key.getFormat())) {
+                // let Sun provider parse for us, then recurse
+                byte[] encoded = key.getEncoded();
+
+                try {
+                    key = ECUtil.decodePKCS8ECPrivateKey(encoded);
+                } catch (InvalidKeySpecException ikse) {
+                    throw new InvalidKeyException(ikse);
+                }
+
+                return implTranslatePrivateKey(key);
+            } else {
+                throw new InvalidKeyException("PrivateKey must be instance "
+                        + "of ECPrivateKey or have PKCS#8 encoding");
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create EC private key", e);
+        }
+    }
+
+    // see JCA spec
+    protected PublicKey engineGeneratePublic(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec instanceof X509EncodedKeySpec) {
+            try {
+                byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
+                PublicKey key = ECUtil.decodeX509ECPublicKey(encoded);
+                return implTranslatePublicKey(key);
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException
+                        ("Could not create EC public key", e);
+            }
+        }
+        if (keySpec instanceof ECPublicKeySpec == false) {
+            throw new InvalidKeySpecException("Only ECPublicKeySpec and "
+                + "X509EncodedKeySpec supported for EC public keys");
+        }
+        try {
+            ECPublicKeySpec ec = (ECPublicKeySpec)keySpec;
+            return generatePublic(
+                ec.getW(),
+                ec.getParams()
+            );
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeySpecException
+                ("Could not create EC public key", e);
+        }
+    }
+
+    // see JCA spec
+    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec instanceof PKCS8EncodedKeySpec) {
+            try {
+                byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
+                PrivateKey key = ECUtil.decodePKCS8ECPrivateKey(encoded);
+                return implTranslatePrivateKey(key);
+            } catch (GeneralSecurityException e) {
+                throw new InvalidKeySpecException
+                        ("Could not create EC private key", e);
+            }
+        }
+        if (keySpec instanceof ECPrivateKeySpec == false) {
+            throw new InvalidKeySpecException("Only ECPrivateKeySpec and "
+                + "PKCS8EncodedKeySpec supported for EC private keys");
+        }
+        try {
+            ECPrivateKeySpec ec = (ECPrivateKeySpec)keySpec;
+            return generatePrivate(
+                ec.getS(),
+                ec.getParams()
+            );
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeySpecException
+                ("Could not create EC private key", e);
+        }
+    }
+
+    private PublicKey generatePublic(ECPoint point, ECParameterSpec params)
+            throws PKCS11Exception {
+        byte[] encodedParams =
+            ECUtil.encodeECParameterSpec(getSunECProvider(), params);
+        byte[] encodedPoint =
+            ECUtil.encodePoint(point, params.getCurve());
+
+        // Check whether the X9.63 encoding of an EC point shall be wrapped
+        // in an ASN.1 OCTET STRING
+        if (!token.config.getUseEcX963Encoding()) {
+            try {
+                encodedPoint =
+                    new DerValue(DerValue.tag_OctetString, encodedPoint)
+                        .toByteArray();
+            } catch (IOException e) {
+                throw new
+                    IllegalArgumentException("Could not DER encode point", e);
+            }
+        }
+
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
+            new CK_ATTRIBUTE(CKA_EC_POINT, encodedPoint),
+            new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PUBLIC_KEY, CKK_EC, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.publicKey
+                (session, keyID, "EC", params.getCurve().getField().getFieldSize(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private PrivateKey generatePrivate(BigInteger s, ECParameterSpec params)
+            throws PKCS11Exception {
+        byte[] encodedParams =
+            ECUtil.encodeECParameterSpec(getSunECProvider(), params);
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
+            new CK_ATTRIBUTE(CKA_VALUE, s),
+            new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PRIVATE_KEY, CKK_EC, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.privateKey
+                (session, keyID, "EC", params.getCurve().getField().getFieldSize(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
+        if (ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_EC_POINT),
+                new CK_ATTRIBUTE(CKA_EC_PARAMS),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            try {
+                ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
+                ECPoint point = decodePoint(attributes[0].getByteArray(), params.getCurve());
+                return keySpec.cast(new ECPublicKeySpec(point, params));
+            } catch (IOException e) {
+                throw new InvalidKeySpecException("Could not parse key", e);
+            }
+        } else { // X.509 handled in superclass
+            throw new InvalidKeySpecException("Only ECPublicKeySpec and "
+                + "X509EncodedKeySpec supported for EC public keys");
+        }
+    }
+
+    <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
+        if (ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_EC_PARAMS),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            try {
+                ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
+                return keySpec.cast(
+                    new ECPrivateKeySpec(attributes[0].getBigInteger(), params));
+            } catch (IOException e) {
+                throw new InvalidKeySpecException("Could not parse key", e);
+            }
+        } else { // PKCS#8 handled in superclass
+            throw new InvalidKeySpecException("Only ECPrivateKeySpec "
+                + "and PKCS8EncodedKeySpec supported for EC private keys");
+        }
+    }
+
+    KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
+        return KeyFactory.getInstance("EC", getSunECProvider());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Key.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,1188 @@
+/*
+ * Copyright (c) 2003, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.io.*;
+import java.lang.ref.*;
+import java.math.BigInteger;
+import java.util.*;
+
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import javax.crypto.*;
+import javax.crypto.interfaces.*;
+import javax.crypto.spec.*;
+
+import sun.security.rsa.RSAPublicKeyImpl;
+
+import sun.security.internal.interfaces.TlsMasterSecret;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+import sun.security.util.Debug;
+import sun.security.util.DerValue;
+import sun.security.util.Length;
+import sun.security.util.ECUtil;
+
+/**
+ * Key implementation classes.
+ *
+ * In PKCS#11, the components of private and secret keys may or may not
+ * be accessible. If they are, we use the algorithm specific key classes
+ * (e.g. DSAPrivateKey) for compatibility with existing applications.
+ * If the components are not accessible, we use a generic class that
+ * only implements PrivateKey (or SecretKey). Whether the components of a
+ * key are extractable is automatically determined when the key object is
+ * created.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+abstract class P11Key implements Key, Length {
+
+    private static final long serialVersionUID = -2575874101938349339L;
+
+    private final static String PUBLIC = "public";
+    private final static String PRIVATE = "private";
+    private final static String SECRET = "secret";
+
+    // type of key, one of (PUBLIC, PRIVATE, SECRET)
+    final String type;
+
+    // token instance
+    final Token token;
+
+    // algorithm name, returned by getAlgorithm(), etc.
+    final String algorithm;
+
+    // key id
+    final long keyID;
+
+    // effective key length of the key, e.g. 56 for a DES key
+    final int keyLength;
+
+    // flags indicating whether the key is a token object, sensitive, extractable
+    final boolean tokenObject, sensitive, extractable;
+
+    // phantom reference notification clean up for session keys
+    private final SessionKeyRef sessionKeyRef;
+
+    P11Key(String type, Session session, long keyID, String algorithm,
+            int keyLength, CK_ATTRIBUTE[] attributes) {
+        this.type = type;
+        this.token = session.token;
+        this.keyID = keyID;
+        this.algorithm = algorithm;
+        this.keyLength = keyLength;
+        boolean tokenObject = false;
+        boolean sensitive = false;
+        boolean extractable = true;
+        int n = (attributes == null) ? 0 : attributes.length;
+        for (int i = 0; i < n; i++) {
+            CK_ATTRIBUTE attr = attributes[i];
+            if (attr.type == CKA_TOKEN) {
+                tokenObject = attr.getBoolean();
+            } else if (attr.type == CKA_SENSITIVE) {
+                sensitive = attr.getBoolean();
+            } else if (attr.type == CKA_EXTRACTABLE) {
+                extractable = attr.getBoolean();
+            }
+        }
+        this.tokenObject = tokenObject;
+        this.sensitive = sensitive;
+        this.extractable = extractable;
+        if (tokenObject == false) {
+            sessionKeyRef = new SessionKeyRef(this, keyID, session);
+        } else {
+            sessionKeyRef = null;
+        }
+    }
+
+    // see JCA spec
+    public final String getAlgorithm() {
+        token.ensureValid();
+        return algorithm;
+    }
+
+    // see JCA spec
+    public final byte[] getEncoded() {
+        byte[] b = getEncodedInternal();
+        return (b == null) ? null : b.clone();
+    }
+
+    abstract byte[] getEncodedInternal();
+
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        // equals() should never throw exceptions
+        if (token.isValid() == false) {
+            return false;
+        }
+        if (obj instanceof Key == false) {
+            return false;
+        }
+        String thisFormat = getFormat();
+        if (thisFormat == null) {
+            // no encoding, key only equal to itself
+            // XXX getEncoded() for unextractable keys will change that
+            return false;
+        }
+        Key other = (Key)obj;
+        if (thisFormat.equals(other.getFormat()) == false) {
+            return false;
+        }
+        byte[] thisEnc = this.getEncodedInternal();
+        byte[] otherEnc;
+        if (obj instanceof P11Key) {
+            otherEnc = ((P11Key)other).getEncodedInternal();
+        } else {
+            otherEnc = other.getEncoded();
+        }
+        return MessageDigest.isEqual(thisEnc, otherEnc);
+    }
+
+    public int hashCode() {
+        // hashCode() should never throw exceptions
+        if (token.isValid() == false) {
+            return 0;
+        }
+        byte[] b1 = getEncodedInternal();
+        if (b1 == null) {
+            return 0;
+        }
+        int r = b1.length;
+        for (int i = 0; i < b1.length; i++) {
+            r += (b1[i] & 0xff) * 37;
+        }
+        return r;
+    }
+
+    protected Object writeReplace() throws ObjectStreamException {
+        KeyRep.Type type;
+        String format = getFormat();
+        if (isPrivate() && "PKCS#8".equals(format)) {
+            type = KeyRep.Type.PRIVATE;
+        } else if (isPublic() && "X.509".equals(format)) {
+            type = KeyRep.Type.PUBLIC;
+        } else if (isSecret() && "RAW".equals(format)) {
+            type = KeyRep.Type.SECRET;
+        } else {
+            // XXX short term serialization for unextractable keys
+            throw new NotSerializableException
+                ("Cannot serialize sensitive and unextractable keys");
+        }
+        return new KeyRep(type, getAlgorithm(), format, getEncoded());
+    }
+
+    public String toString() {
+        token.ensureValid();
+        String s1 = token.provider.getName() + " " + algorithm + " " + type
+                + " key, " + keyLength + " bits";
+        s1 += " (id " + keyID + ", "
+                + (tokenObject ? "token" : "session") + " object";
+        if (isPublic()) {
+            s1 += ")";
+        } else {
+            s1 += ", " + (sensitive ? "" : "not ") + "sensitive";
+            s1 += ", " + (extractable ? "" : "un") + "extractable)";
+        }
+        return s1;
+    }
+
+    /**
+     * Return bit length of the key.
+     */
+    @Override
+    public int length() {
+        return keyLength;
+    }
+
+    boolean isPublic() {
+        return type == PUBLIC;
+    }
+
+    boolean isPrivate() {
+        return type == PRIVATE;
+    }
+
+    boolean isSecret() {
+        return type == SECRET;
+    }
+
+    void fetchAttributes(CK_ATTRIBUTE[] attributes) {
+        Session tempSession = null;
+        try {
+            tempSession = token.getOpSession();
+            token.p11.C_GetAttributeValue(tempSession.id(), keyID, attributes);
+        } catch (PKCS11Exception e) {
+            throw new ProviderException(e);
+        } finally {
+            token.releaseSession(tempSession);
+        }
+    }
+
+    private final static CK_ATTRIBUTE[] A0 = new CK_ATTRIBUTE[0];
+
+    private static CK_ATTRIBUTE[] getAttributes(Session session, long keyID,
+            CK_ATTRIBUTE[] knownAttributes, CK_ATTRIBUTE[] desiredAttributes) {
+        if (knownAttributes == null) {
+            knownAttributes = A0;
+        }
+        for (int i = 0; i < desiredAttributes.length; i++) {
+            // For each desired attribute, check to see if we have the value
+            // available already. If everything is here, we save a native call.
+            CK_ATTRIBUTE attr = desiredAttributes[i];
+            for (CK_ATTRIBUTE known : knownAttributes) {
+                if ((attr.type == known.type) && (known.pValue != null)) {
+                    attr.pValue = known.pValue;
+                    break; // break inner for loop
+                }
+            }
+            if (attr.pValue == null) {
+                // nothing found, need to call C_GetAttributeValue()
+                for (int j = 0; j < i; j++) {
+                    // clear values copied from knownAttributes
+                    desiredAttributes[j].pValue = null;
+                }
+                try {
+                    session.token.p11.C_GetAttributeValue
+                            (session.id(), keyID, desiredAttributes);
+                } catch (PKCS11Exception e) {
+                    throw new ProviderException(e);
+                }
+                break; // break loop, goto return
+            }
+        }
+        return desiredAttributes;
+    }
+
+    static SecretKey secretKey(Session session, long keyID, String algorithm,
+            int keyLength, CK_ATTRIBUTE[] attributes) {
+        attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_TOKEN),
+            new CK_ATTRIBUTE(CKA_SENSITIVE),
+            new CK_ATTRIBUTE(CKA_EXTRACTABLE),
+        });
+        return new P11SecretKey(session, keyID, algorithm, keyLength, attributes);
+    }
+
+    static SecretKey masterSecretKey(Session session, long keyID, String algorithm,
+            int keyLength, CK_ATTRIBUTE[] attributes, int major, int minor) {
+        attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_TOKEN),
+            new CK_ATTRIBUTE(CKA_SENSITIVE),
+            new CK_ATTRIBUTE(CKA_EXTRACTABLE),
+        });
+        return new P11TlsMasterSecretKey
+                (session, keyID, algorithm, keyLength, attributes, major, minor);
+    }
+
+    // we assume that all components of public keys are always accessible
+    static PublicKey publicKey(Session session, long keyID, String algorithm,
+            int keyLength, CK_ATTRIBUTE[] attributes) {
+        switch (algorithm) {
+            case "RSA":
+                return new P11RSAPublicKey
+                    (session, keyID, algorithm, keyLength, attributes);
+            case "DSA":
+                return new P11DSAPublicKey
+                    (session, keyID, algorithm, keyLength, attributes);
+            case "DH":
+                return new P11DHPublicKey
+                    (session, keyID, algorithm, keyLength, attributes);
+            case "EC":
+                return new P11ECPublicKey
+                    (session, keyID, algorithm, keyLength, attributes);
+            default:
+                throw new ProviderException
+                    ("Unknown public key algorithm " + algorithm);
+        }
+    }
+
+    static PrivateKey privateKey(Session session, long keyID, String algorithm,
+            int keyLength, CK_ATTRIBUTE[] attributes) {
+        attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_TOKEN),
+            new CK_ATTRIBUTE(CKA_SENSITIVE),
+            new CK_ATTRIBUTE(CKA_EXTRACTABLE),
+        });
+        if (attributes[1].getBoolean() || (attributes[2].getBoolean() == false)) {
+            return new P11PrivateKey
+                (session, keyID, algorithm, keyLength, attributes);
+        } else {
+            switch (algorithm) {
+                case "RSA":
+                    // In order to decide if this is RSA CRT key, we first query
+                    // and see if all extra CRT attributes are available.
+                    CK_ATTRIBUTE[] attrs2 = new CK_ATTRIBUTE[] {
+                        new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
+                        new CK_ATTRIBUTE(CKA_PRIME_1),
+                        new CK_ATTRIBUTE(CKA_PRIME_2),
+                        new CK_ATTRIBUTE(CKA_EXPONENT_1),
+                        new CK_ATTRIBUTE(CKA_EXPONENT_2),
+                        new CK_ATTRIBUTE(CKA_COEFFICIENT),
+                    };
+                    boolean crtKey;
+                    try {
+                        session.token.p11.C_GetAttributeValue
+                            (session.id(), keyID, attrs2);
+                        crtKey = ((attrs2[0].pValue instanceof byte[]) &&
+                                  (attrs2[1].pValue instanceof byte[]) &&
+                                  (attrs2[2].pValue instanceof byte[]) &&
+                                  (attrs2[3].pValue instanceof byte[]) &&
+                                  (attrs2[4].pValue instanceof byte[]) &&
+                                  (attrs2[5].pValue instanceof byte[])) ;
+                    } catch (PKCS11Exception e) {
+                        // ignore, assume not available
+                        crtKey = false;
+                    }
+                    if (crtKey) {
+                        return new P11RSAPrivateKey
+                                (session, keyID, algorithm, keyLength, attributes, attrs2);
+                    } else {
+                        return new P11RSAPrivateNonCRTKey
+                                (session, keyID, algorithm, keyLength, attributes);
+                    }
+                case "DSA":
+                    return new P11DSAPrivateKey
+                            (session, keyID, algorithm, keyLength, attributes);
+                case "DH":
+                    return new P11DHPrivateKey
+                            (session, keyID, algorithm, keyLength, attributes);
+                case "EC":
+                    return new P11ECPrivateKey
+                            (session, keyID, algorithm, keyLength, attributes);
+                default:
+                    throw new ProviderException
+                            ("Unknown private key algorithm " + algorithm);
+            }
+        }
+    }
+
+    // class for sensitive and unextractable private keys
+    private static final class P11PrivateKey extends P11Key
+                                                implements PrivateKey {
+        private static final long serialVersionUID = -2138581185214187615L;
+
+        P11PrivateKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
+        }
+        // XXX temporary encoding for serialization purposes
+        public String getFormat() {
+            token.ensureValid();
+            return null;
+        }
+        byte[] getEncodedInternal() {
+            token.ensureValid();
+            return null;
+        }
+    }
+
+    private static class P11SecretKey extends P11Key implements SecretKey {
+        private static final long serialVersionUID = -7828241727014329084L;
+        private volatile byte[] encoded;
+        P11SecretKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(SECRET, session, keyID, algorithm, keyLength, attributes);
+        }
+        public String getFormat() {
+            token.ensureValid();
+            if (sensitive || (extractable == false)) {
+                return null;
+            } else {
+                return "RAW";
+            }
+        }
+        byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (getFormat() == null) {
+                return null;
+            }
+            byte[] b = encoded;
+            if (b == null) {
+                synchronized (this) {
+                    b = encoded;
+                    if (b == null) {
+                        Session tempSession = null;
+                        try {
+                            tempSession = token.getOpSession();
+                            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                                new CK_ATTRIBUTE(CKA_VALUE),
+                            };
+                            token.p11.C_GetAttributeValue
+                                (tempSession.id(), keyID, attributes);
+                            b = attributes[0].getByteArray();
+                        } catch (PKCS11Exception e) {
+                            throw new ProviderException(e);
+                        } finally {
+                            token.releaseSession(tempSession);
+                        }
+                        encoded = b;
+                    }
+                }
+            }
+            return b;
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private static class P11TlsMasterSecretKey extends P11SecretKey
+            implements TlsMasterSecret {
+        private static final long serialVersionUID = -1318560923770573441L;
+
+        private final int majorVersion, minorVersion;
+        P11TlsMasterSecretKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes, int major, int minor) {
+            super(session, keyID, algorithm, keyLength, attributes);
+            this.majorVersion = major;
+            this.minorVersion = minor;
+        }
+        public int getMajorVersion() {
+            return majorVersion;
+        }
+
+        public int getMinorVersion() {
+            return minorVersion;
+        }
+    }
+
+    // RSA CRT private key
+    private static final class P11RSAPrivateKey extends P11Key
+                implements RSAPrivateCrtKey {
+        private static final long serialVersionUID = 9215872438913515220L;
+
+        private BigInteger n, e, d, p, q, pe, qe, coeff;
+        private byte[] encoded;
+        P11RSAPrivateKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE[] crtAttrs) {
+            super(PRIVATE, session, keyID, algorithm, keyLength, attrs);
+
+            for (CK_ATTRIBUTE a : crtAttrs) {
+                if (a.type == CKA_PUBLIC_EXPONENT) {
+                    e = a.getBigInteger();
+                } else if (a.type == CKA_PRIME_1) {
+                    p = a.getBigInteger();
+                } else if (a.type == CKA_PRIME_2) {
+                    q = a.getBigInteger();
+                } else if (a.type == CKA_EXPONENT_1) {
+                    pe = a.getBigInteger();
+                } else if (a.type == CKA_EXPONENT_2) {
+                    qe = a.getBigInteger();
+                } else if (a.type == CKA_COEFFICIENT) {
+                    coeff = a.getBigInteger();
+                }
+            }
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (n != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_MODULUS),
+                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
+            };
+            fetchAttributes(attributes);
+            n = attributes[0].getBigInteger();
+            d = attributes[1].getBigInteger();
+        }
+
+        public String getFormat() {
+            token.ensureValid();
+            return "PKCS#8";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    // XXX make constructor in SunRsaSign provider public
+                    // and call it directly
+                    KeyFactory factory = KeyFactory.getInstance
+                        ("RSA", P11Util.getSunRsaSignProvider());
+                    Key newKey = factory.translateKey(this);
+                    encoded = newKey.getEncoded();
+                } catch (GeneralSecurityException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public BigInteger getModulus() {
+            fetchValues();
+            return n;
+        }
+        public BigInteger getPublicExponent() {
+            return e;
+        }
+        public BigInteger getPrivateExponent() {
+            fetchValues();
+            return d;
+        }
+        public BigInteger getPrimeP() {
+            return p;
+        }
+        public BigInteger getPrimeQ() {
+            return q;
+        }
+        public BigInteger getPrimeExponentP() {
+            return pe;
+        }
+        public BigInteger getPrimeExponentQ() {
+            return qe;
+        }
+        public BigInteger getCrtCoefficient() {
+            return coeff;
+        }
+    }
+
+    // RSA non-CRT private key
+    private static final class P11RSAPrivateNonCRTKey extends P11Key
+                implements RSAPrivateKey {
+        private static final long serialVersionUID = 1137764983777411481L;
+
+        private BigInteger n, d;
+        private byte[] encoded;
+        P11RSAPrivateNonCRTKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (n != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_MODULUS),
+                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
+            };
+            fetchAttributes(attributes);
+            n = attributes[0].getBigInteger();
+            d = attributes[1].getBigInteger();
+        }
+        public String getFormat() {
+            token.ensureValid();
+            return "PKCS#8";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    // XXX make constructor in SunRsaSign provider public
+                    // and call it directly
+                    KeyFactory factory = KeyFactory.getInstance
+                        ("RSA", P11Util.getSunRsaSignProvider());
+                    Key newKey = factory.translateKey(this);
+                    encoded = newKey.getEncoded();
+                } catch (GeneralSecurityException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public BigInteger getModulus() {
+            fetchValues();
+            return n;
+        }
+        public BigInteger getPrivateExponent() {
+            fetchValues();
+            return d;
+        }
+    }
+
+    private static final class P11RSAPublicKey extends P11Key
+                                                implements RSAPublicKey {
+        private static final long serialVersionUID = -826726289023854455L;
+
+        private BigInteger n, e;
+        private byte[] encoded;
+        P11RSAPublicKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PUBLIC, session, keyID, algorithm, keyLength, attributes);
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (n != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_MODULUS),
+                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
+            };
+            fetchAttributes(attributes);
+            n = attributes[0].getBigInteger();
+            e = attributes[1].getBigInteger();
+        }
+        public String getFormat() {
+            token.ensureValid();
+            return "X.509";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    encoded = new RSAPublicKeyImpl(n, e).getEncoded();
+                } catch (InvalidKeyException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public BigInteger getModulus() {
+            fetchValues();
+            return n;
+        }
+        public BigInteger getPublicExponent() {
+            fetchValues();
+            return e;
+        }
+        public String toString() {
+            fetchValues();
+            return super.toString() +  "\n  modulus: " + n
+                + "\n  public exponent: " + e;
+        }
+    }
+
+    private static final class P11DSAPublicKey extends P11Key
+                                                implements DSAPublicKey {
+        private static final long serialVersionUID = 5989753793316396637L;
+
+        private BigInteger y;
+        private DSAParams params;
+        private byte[] encoded;
+        P11DSAPublicKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PUBLIC, session, keyID, algorithm, keyLength, attributes);
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (y != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_PRIME),
+                new CK_ATTRIBUTE(CKA_SUBPRIME),
+                new CK_ATTRIBUTE(CKA_BASE),
+            };
+            fetchAttributes(attributes);
+            y = attributes[0].getBigInteger();
+            params = new DSAParameterSpec(
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger(),
+                attributes[3].getBigInteger()
+            );
+        }
+        public String getFormat() {
+            token.ensureValid();
+            return "X.509";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    Key key = new sun.security.provider.DSAPublicKey
+                            (y, params.getP(), params.getQ(), params.getG());
+                    encoded = key.getEncoded();
+                } catch (InvalidKeyException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public BigInteger getY() {
+            fetchValues();
+            return y;
+        }
+        public DSAParams getParams() {
+            fetchValues();
+            return params;
+        }
+        public String toString() {
+            fetchValues();
+            return super.toString() +  "\n  y: " + y + "\n  p: " + params.getP()
+                + "\n  q: " + params.getQ() + "\n  g: " + params.getG();
+        }
+    }
+
+    private static final class P11DSAPrivateKey extends P11Key
+                                                implements DSAPrivateKey {
+        private static final long serialVersionUID = 3119629997181999389L;
+
+        private BigInteger x;
+        private DSAParams params;
+        private byte[] encoded;
+        P11DSAPrivateKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (x != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_PRIME),
+                new CK_ATTRIBUTE(CKA_SUBPRIME),
+                new CK_ATTRIBUTE(CKA_BASE),
+            };
+            fetchAttributes(attributes);
+            x = attributes[0].getBigInteger();
+            params = new DSAParameterSpec(
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger(),
+                attributes[3].getBigInteger()
+            );
+        }
+        public String getFormat() {
+            token.ensureValid();
+            return "PKCS#8";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    Key key = new sun.security.provider.DSAPrivateKey
+                            (x, params.getP(), params.getQ(), params.getG());
+                    encoded = key.getEncoded();
+                } catch (InvalidKeyException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public BigInteger getX() {
+            fetchValues();
+            return x;
+        }
+        public DSAParams getParams() {
+            fetchValues();
+            return params;
+        }
+    }
+
+    private static final class P11DHPrivateKey extends P11Key
+                                                implements DHPrivateKey {
+        private static final long serialVersionUID = -1698576167364928838L;
+
+        private BigInteger x;
+        private DHParameterSpec params;
+        private byte[] encoded;
+        P11DHPrivateKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (x != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_PRIME),
+                new CK_ATTRIBUTE(CKA_BASE),
+            };
+            fetchAttributes(attributes);
+            x = attributes[0].getBigInteger();
+            params = new DHParameterSpec(
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger()
+            );
+        }
+        public String getFormat() {
+            token.ensureValid();
+            return "PKCS#8";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    DHPrivateKeySpec spec = new DHPrivateKeySpec
+                        (x, params.getP(), params.getG());
+                    KeyFactory kf = KeyFactory.getInstance
+                        ("DH", P11Util.getSunJceProvider());
+                    Key key = kf.generatePrivate(spec);
+                    encoded = key.getEncoded();
+                } catch (GeneralSecurityException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public BigInteger getX() {
+            fetchValues();
+            return x;
+        }
+        public DHParameterSpec getParams() {
+            fetchValues();
+            return params;
+        }
+        public int hashCode() {
+            if (token.isValid() == false) {
+                return 0;
+            }
+            fetchValues();
+            return Objects.hash(x, params.getP(), params.getG());
+        }
+        public boolean equals(Object obj) {
+            if (this == obj) return true;
+            // equals() should never throw exceptions
+            if (token.isValid() == false) {
+                return false;
+            }
+            if (!(obj instanceof DHPrivateKey)) {
+                return false;
+            }
+            fetchValues();
+            DHPrivateKey other = (DHPrivateKey) obj;
+            DHParameterSpec otherParams = other.getParams();
+            return ((this.x.compareTo(other.getX()) == 0) &&
+                    (this.params.getP().compareTo(otherParams.getP()) == 0) &&
+                    (this.params.getG().compareTo(otherParams.getG()) == 0));
+        }
+    }
+
+    private static final class P11DHPublicKey extends P11Key
+                                                implements DHPublicKey {
+        static final long serialVersionUID = -598383872153843657L;
+
+        private BigInteger y;
+        private DHParameterSpec params;
+        private byte[] encoded;
+        P11DHPublicKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PUBLIC, session, keyID, algorithm, keyLength, attributes);
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (y != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_PRIME),
+                new CK_ATTRIBUTE(CKA_BASE),
+            };
+            fetchAttributes(attributes);
+            y = attributes[0].getBigInteger();
+            params = new DHParameterSpec(
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger()
+            );
+        }
+        public String getFormat() {
+            token.ensureValid();
+            return "X.509";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    DHPublicKeySpec spec = new DHPublicKeySpec
+                        (y, params.getP(), params.getG());
+                    KeyFactory kf = KeyFactory.getInstance
+                        ("DH", P11Util.getSunJceProvider());
+                    Key key = kf.generatePublic(spec);
+                    encoded = key.getEncoded();
+                } catch (GeneralSecurityException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public BigInteger getY() {
+            fetchValues();
+            return y;
+        }
+        public DHParameterSpec getParams() {
+            fetchValues();
+            return params;
+        }
+        public String toString() {
+            fetchValues();
+            return super.toString() +  "\n  y: " + y + "\n  p: " + params.getP()
+                + "\n  g: " + params.getG();
+        }
+        public int hashCode() {
+            if (token.isValid() == false) {
+                return 0;
+            }
+            fetchValues();
+            return Objects.hash(y, params.getP(), params.getG());
+        }
+        public boolean equals(Object obj) {
+            if (this == obj) return true;
+            // equals() should never throw exceptions
+            if (token.isValid() == false) {
+                return false;
+            }
+            if (!(obj instanceof DHPublicKey)) {
+                return false;
+            }
+            fetchValues();
+            DHPublicKey other = (DHPublicKey) obj;
+            DHParameterSpec otherParams = other.getParams();
+            return ((this.y.compareTo(other.getY()) == 0) &&
+                    (this.params.getP().compareTo(otherParams.getP()) == 0) &&
+                    (this.params.getG().compareTo(otherParams.getG()) == 0));
+        }
+    }
+
+    private static final class P11ECPrivateKey extends P11Key
+                                                implements ECPrivateKey {
+        private static final long serialVersionUID = -7786054399510515515L;
+
+        private BigInteger s;
+        private ECParameterSpec params;
+        private byte[] encoded;
+        P11ECPrivateKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (s != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE),
+                new CK_ATTRIBUTE(CKA_EC_PARAMS, params),
+            };
+            fetchAttributes(attributes);
+            s = attributes[0].getBigInteger();
+            try {
+                params = P11ECKeyFactory.decodeParameters
+                            (attributes[1].getByteArray());
+            } catch (Exception e) {
+                throw new RuntimeException("Could not parse key values", e);
+            }
+        }
+        public String getFormat() {
+            token.ensureValid();
+            return "PKCS#8";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    Key key = ECUtil.generateECPrivateKey(s, params);
+                    encoded = key.getEncoded();
+                } catch (InvalidKeySpecException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public BigInteger getS() {
+            fetchValues();
+            return s;
+        }
+        public ECParameterSpec getParams() {
+            fetchValues();
+            return params;
+        }
+    }
+
+    private static final class P11ECPublicKey extends P11Key
+                                                implements ECPublicKey {
+        private static final long serialVersionUID = -6371481375154806089L;
+
+        private ECPoint w;
+        private ECParameterSpec params;
+        private byte[] encoded;
+        P11ECPublicKey(Session session, long keyID, String algorithm,
+                int keyLength, CK_ATTRIBUTE[] attributes) {
+            super(PUBLIC, session, keyID, algorithm, keyLength, attributes);
+        }
+        private synchronized void fetchValues() {
+            token.ensureValid();
+            if (w != null) {
+                return;
+            }
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_EC_POINT),
+                new CK_ATTRIBUTE(CKA_EC_PARAMS),
+            };
+            fetchAttributes(attributes);
+
+            try {
+                params = P11ECKeyFactory.decodeParameters
+                            (attributes[1].getByteArray());
+                byte[] ecKey = attributes[0].getByteArray();
+
+                // Check whether the X9.63 encoding of an EC point is wrapped
+                // in an ASN.1 OCTET STRING
+                if (!token.config.getUseEcX963Encoding()) {
+                    DerValue wECPoint = new DerValue(ecKey);
+
+                    if (wECPoint.getTag() != DerValue.tag_OctetString) {
+                        throw new IOException("Could not DER decode EC point." +
+                            " Unexpected tag: " + wECPoint.getTag());
+                    }
+                    w = P11ECKeyFactory.decodePoint
+                        (wECPoint.getDataBytes(), params.getCurve());
+
+                } else {
+                    w = P11ECKeyFactory.decodePoint(ecKey, params.getCurve());
+                }
+
+            } catch (Exception e) {
+                throw new RuntimeException("Could not parse key values", e);
+            }
+        }
+        public String getFormat() {
+            token.ensureValid();
+            return "X.509";
+        }
+        synchronized byte[] getEncodedInternal() {
+            token.ensureValid();
+            if (encoded == null) {
+                fetchValues();
+                try {
+                    return ECUtil.x509EncodeECPublicKey(w, params);
+                } catch (InvalidKeySpecException e) {
+                    throw new ProviderException(e);
+                }
+            }
+            return encoded;
+        }
+        public ECPoint getW() {
+            fetchValues();
+            return w;
+        }
+        public ECParameterSpec getParams() {
+            fetchValues();
+            return params;
+        }
+        public String toString() {
+            fetchValues();
+            return super.toString()
+                + "\n  public x coord: " + w.getAffineX()
+                + "\n  public y coord: " + w.getAffineY()
+                + "\n  parameters: " + params;
+        }
+    }
+}
+
+/*
+ * NOTE: Must use PhantomReference here and not WeakReference
+ * otherwise the key maybe cleared before other objects which
+ * still use these keys during finalization such as SSLSocket.
+ */
+final class SessionKeyRef extends PhantomReference<P11Key>
+    implements Comparable<SessionKeyRef> {
+    private static ReferenceQueue<P11Key> refQueue =
+        new ReferenceQueue<P11Key>();
+    private static Set<SessionKeyRef> refList =
+        Collections.synchronizedSortedSet(new TreeSet<SessionKeyRef>());
+
+    static ReferenceQueue<P11Key> referenceQueue() {
+        return refQueue;
+    }
+
+    private static void drainRefQueueBounded() {
+        Session sess = null;
+        Token tkn = null;
+        while (true) {
+            SessionKeyRef next = (SessionKeyRef) refQueue.poll();
+            if (next == null) {
+                break;
+            }
+
+            // If the token is still valid, try to remove the object
+            if (next.session.token.isValid()) {
+                // If this key's token is the same as the previous key, the
+                // same session can be used for C_DestroyObject.
+                try {
+                    if (next.session.token != tkn || sess == null) {
+                        // Release session if not using previous token
+                        if (tkn != null && sess != null) {
+                            tkn.releaseSession(sess);
+                            sess = null;
+                        }
+
+                        tkn = next.session.token;
+                        sess = tkn.getOpSession();
+                    }
+                    next.disposeNative(sess);
+                } catch (PKCS11Exception e) {
+                    // ignore
+                }
+            }
+            // Regardless of native results, dispose of java references
+            next.dispose();
+        }
+
+        if (tkn != null && sess != null) {
+            tkn.releaseSession(sess);
+        }
+    }
+
+    // handle to the native key
+    private long keyID;
+    private Session session;
+
+    SessionKeyRef(P11Key key , long keyID, Session session) {
+        super(key, refQueue);
+        this.keyID = keyID;
+        this.session = session;
+        this.session.addObject();
+        refList.add(this);
+        drainRefQueueBounded();
+    }
+
+    private void disposeNative(Session s) throws PKCS11Exception {
+        session.token.p11.C_DestroyObject(s.id(), keyID);
+    }
+
+    private void dispose() {
+        refList.remove(this);
+        this.clear();
+        session.removeObject();
+    }
+
+    public int compareTo(SessionKeyRef other) {
+        if (this.keyID == other.keyID) {
+            return 0;
+        } else {
+            return (this.keyID < other.keyID) ? -1 : 1;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyAgreement.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2003, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.spec.*;
+
+import javax.crypto.*;
+import javax.crypto.interfaces.*;
+import javax.crypto.spec.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+import sun.security.util.KeyUtil;
+
+/**
+ * KeyAgreement implementation class. This class currently supports
+ * DH.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11KeyAgreement extends KeyAgreementSpi {
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id
+    private final long mechanism;
+
+    // private key, if initialized
+    private P11Key privateKey;
+
+    // other sides public value ("y"), if doPhase() already called
+    private BigInteger publicValue;
+
+    // length of the secret to be derived
+    private int secretLen;
+
+    // KeyAgreement from SunJCE as fallback for > 2 party agreement
+    private KeyAgreement multiPartyAgreement;
+
+    P11KeyAgreement(Token token, String algorithm, long mechanism) {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+    }
+
+    // see JCE spec
+    protected void engineInit(Key key, SecureRandom random)
+            throws InvalidKeyException {
+        if (key instanceof PrivateKey == false) {
+            throw new InvalidKeyException
+                        ("Key must be instance of PrivateKey");
+        }
+        privateKey = P11KeyFactory.convertKey(token, key, algorithm);
+        publicValue = null;
+        multiPartyAgreement = null;
+    }
+
+    // see JCE spec
+    protected void engineInit(Key key, AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidKeyException,
+            InvalidAlgorithmParameterException {
+        if (params != null) {
+            throw new InvalidAlgorithmParameterException
+                        ("Parameters not supported");
+        }
+        engineInit(key, random);
+    }
+
+    // see JCE spec
+    protected Key engineDoPhase(Key key, boolean lastPhase)
+            throws InvalidKeyException, IllegalStateException {
+        if (privateKey == null) {
+            throw new IllegalStateException("Not initialized");
+        }
+        if (publicValue != null) {
+            throw new IllegalStateException("Phase already executed");
+        }
+        // PKCS#11 only allows key agreement between 2 parties
+        // JCE allows >= 2 parties. To support that case (for compatibility
+        // and to pass JCK), fall back to SunJCE in this case.
+        // NOTE that we initialize using the P11Key, which will fail if it
+        // is sensitive/unextractable. However, this is not an issue in the
+        // compatibility configuration, which is all we are targeting here.
+        if ((multiPartyAgreement != null) || (lastPhase == false)) {
+            if (multiPartyAgreement == null) {
+                try {
+                    multiPartyAgreement = KeyAgreement.getInstance
+                        ("DH", P11Util.getSunJceProvider());
+                    multiPartyAgreement.init(privateKey);
+                } catch (NoSuchAlgorithmException e) {
+                    throw new InvalidKeyException
+                        ("Could not initialize multi party agreement", e);
+                }
+            }
+            return multiPartyAgreement.doPhase(key, lastPhase);
+        }
+        if ((key instanceof PublicKey == false)
+                || (key.getAlgorithm().equals(algorithm) == false)) {
+            throw new InvalidKeyException
+                ("Key must be a PublicKey with algorithm DH");
+        }
+        BigInteger p, g, y;
+        if (key instanceof DHPublicKey) {
+            DHPublicKey dhKey = (DHPublicKey)key;
+
+            // validate the Diffie-Hellman public key
+            KeyUtil.validate(dhKey);
+
+            y = dhKey.getY();
+            DHParameterSpec params = dhKey.getParams();
+            p = params.getP();
+            g = params.getG();
+        } else {
+            // normally, DH PublicKeys will always implement DHPublicKey
+            // just in case not, attempt conversion
+            P11DHKeyFactory kf = new P11DHKeyFactory(token, "DH");
+            try {
+                DHPublicKeySpec spec = kf.engineGetKeySpec(
+                        key, DHPublicKeySpec.class);
+
+                // validate the Diffie-Hellman public key
+                KeyUtil.validate(spec);
+
+                y = spec.getY();
+                p = spec.getP();
+                g = spec.getG();
+            } catch (InvalidKeySpecException e) {
+                throw new InvalidKeyException("Could not obtain key values", e);
+            }
+        }
+        // if parameters of private key are accessible, verify that
+        // they match parameters of public key
+        // XXX p and g should always be readable, even if the key is sensitive
+        if (privateKey instanceof DHPrivateKey) {
+            DHPrivateKey dhKey = (DHPrivateKey)privateKey;
+            DHParameterSpec params = dhKey.getParams();
+            if ((p.equals(params.getP()) == false)
+                                || (g.equals(params.getG()) == false)) {
+                throw new InvalidKeyException
+                ("PublicKey DH parameters must match PrivateKey DH parameters");
+            }
+        }
+        publicValue = y;
+        // length of the secret is length of key
+        secretLen = (p.bitLength() + 7) >> 3;
+        return null;
+    }
+
+    // see JCE spec
+    protected byte[] engineGenerateSecret() throws IllegalStateException {
+        if (multiPartyAgreement != null) {
+            byte[] val = multiPartyAgreement.generateSecret();
+            multiPartyAgreement = null;
+            return val;
+        }
+        if ((privateKey == null) || (publicValue == null)) {
+            throw new IllegalStateException("Not initialized correctly");
+        }
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
+            };
+            attributes = token.getAttributes
+                (O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
+            long keyID = token.p11.C_DeriveKey(session.id(),
+                new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
+                attributes);
+            attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE)
+            };
+            token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
+            byte[] secret = attributes[0].getByteArray();
+            token.p11.C_DestroyObject(session.id(), keyID);
+            // Some vendors, e.g. NSS, trim off the leading 0x00 byte(s) from
+            // the generated secret. Thus, we need to check the secret length
+            // and trim/pad it so the returned value has the same length as
+            // the modulus size
+            if (secret.length == secretLen) {
+                return secret;
+            } else {
+                if (secret.length > secretLen) {
+                    // Shouldn't happen; but check just in case
+                    throw new ProviderException("generated secret is out-of-range");
+                }
+                byte[] newSecret = new byte[secretLen];
+                System.arraycopy(secret, 0, newSecret, secretLen - secret.length,
+                    secret.length);
+                return newSecret;
+            }
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("Could not derive key", e);
+        } finally {
+            publicValue = null;
+            token.releaseSession(session);
+        }
+    }
+
+    // see JCE spec
+    protected int engineGenerateSecret(byte[] sharedSecret, int
+            offset) throws IllegalStateException, ShortBufferException {
+        if (multiPartyAgreement != null) {
+            int n = multiPartyAgreement.generateSecret(sharedSecret, offset);
+            multiPartyAgreement = null;
+            return n;
+        }
+        if (offset + secretLen > sharedSecret.length) {
+            throw new ShortBufferException("Need " + secretLen
+                + " bytes, only " + (sharedSecret.length - offset) + " available");
+        }
+        byte[] secret = engineGenerateSecret();
+        System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
+        return secret.length;
+    }
+
+    // see JCE spec
+    protected SecretKey engineGenerateSecret(String algorithm)
+            throws IllegalStateException, NoSuchAlgorithmException,
+            InvalidKeyException {
+        if (multiPartyAgreement != null) {
+            SecretKey key = multiPartyAgreement.generateSecret(algorithm);
+            multiPartyAgreement = null;
+            return key;
+        }
+        if (algorithm == null) {
+            throw new NoSuchAlgorithmException("Algorithm must not be null");
+        }
+        if (algorithm.equals("TlsPremasterSecret")) {
+            // For now, only perform native derivation for TlsPremasterSecret
+            // as that is required for FIPS compliance.
+            // For other algorithms, there are unresolved issues regarding
+            // how this should work in JCE plus a Solaris truncation bug.
+            // (bug not yet filed).
+            return nativeGenerateSecret(algorithm);
+        }
+        byte[] secret = engineGenerateSecret();
+        // Maintain compatibility for SunJCE:
+        // verify secret length is sensible for algorithm / truncate
+        // return generated key itself if possible
+        int keyLen;
+        if (algorithm.equalsIgnoreCase("DES")) {
+            keyLen = 8;
+        } else if (algorithm.equalsIgnoreCase("DESede")) {
+            keyLen = 24;
+        } else if (algorithm.equalsIgnoreCase("Blowfish")) {
+            keyLen = Math.min(56, secret.length);
+        } else if (algorithm.equalsIgnoreCase("TlsPremasterSecret")) {
+            keyLen = secret.length;
+        } else {
+            throw new NoSuchAlgorithmException
+                ("Unknown algorithm " + algorithm);
+        }
+        if (secret.length < keyLen) {
+            throw new InvalidKeyException("Secret too short");
+        }
+        if (algorithm.equalsIgnoreCase("DES") ||
+            algorithm.equalsIgnoreCase("DESede")) {
+                for (int i = 0; i < keyLen; i+=8) {
+                    P11SecretKeyFactory.fixDESParity(secret, i);
+                }
+        }
+        return new SecretKeySpec(secret, 0, keyLen, algorithm);
+    }
+
+    private SecretKey nativeGenerateSecret(String algorithm)
+            throws IllegalStateException, NoSuchAlgorithmException,
+            InvalidKeyException {
+        if ((privateKey == null) || (publicValue == null)) {
+            throw new IllegalStateException("Not initialized correctly");
+        }
+        long keyType = CKK_GENERIC_SECRET;
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
+            };
+            attributes = token.getAttributes
+                (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
+            long keyID = token.p11.C_DeriveKey(session.id(),
+                new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
+                attributes);
+            CK_ATTRIBUTE[] lenAttributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE_LEN),
+            };
+            token.p11.C_GetAttributeValue(session.id(), keyID, lenAttributes);
+            int keyLen = (int)lenAttributes[0].getLong();
+            SecretKey key = P11Key.secretKey
+                        (session, keyID, algorithm, keyLen << 3, attributes);
+            if ("RAW".equals(key.getFormat())) {
+                // Workaround for Solaris bug 6318543.
+                // Strip leading zeroes ourselves if possible (key not sensitive).
+                // This should be removed once the Solaris fix is available
+                // as here we always retrieve the CKA_VALUE even for tokens
+                // that do not have that bug.
+                byte[] keyBytes = key.getEncoded();
+                byte[] newBytes = KeyUtil.trimZeroes(keyBytes);
+                if (keyBytes != newBytes) {
+                    key = new SecretKeySpec(newBytes, algorithm);
+                }
+            }
+            return key;
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not derive key", e);
+        } finally {
+            publicValue = null;
+            token.releaseSession(session);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyFactory.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2003, 2011, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.security.*;
+import java.security.spec.*;
+
+import sun.security.pkcs11.wrapper.PKCS11Exception;
+
+/**
+ * KeyFactory base class. Provides common infrastructure for the RSA, DSA,
+ * and DH implementations.
+ *
+ * The subclasses support conversion between keys and keyspecs
+ * using X.509, PKCS#8, and their individual algorithm specific formats,
+ * assuming keys are extractable.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+abstract class P11KeyFactory extends KeyFactorySpi {
+
+    // token instance
+    final Token token;
+
+    // algorithm name, currently one of RSA, DSA, DH
+    final String algorithm;
+
+    P11KeyFactory(Token token, String algorithm) {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+    }
+
+    /**
+     * Convert an arbitrary key of algorithm into a P11Key of token.
+     * Used by P11Signature.init() and RSACipher.init().
+     */
+    static P11Key convertKey(Token token, Key key, String algorithm)
+            throws InvalidKeyException {
+        return (P11Key)token.getKeyFactory(algorithm).engineTranslateKey(key);
+    }
+
+    // see JCA spec
+    protected final <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if ((key == null) || (keySpec == null)) {
+            throw new InvalidKeySpecException
+                ("key and keySpec must not be null");
+        }
+        // delegate to our Java based providers for PKCS#8 and X.509
+        if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)
+                || X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
+            try {
+                return implGetSoftwareFactory().getKeySpec(key, keySpec);
+            } catch (GeneralSecurityException e) {
+                throw new InvalidKeySpecException("Could not encode key", e);
+            }
+        }
+        // first translate into a key of this token, if it is not already
+        P11Key p11Key;
+        try {
+            p11Key = (P11Key)engineTranslateKey(key);
+        } catch (InvalidKeyException e) {
+            throw new InvalidKeySpecException("Could not convert key", e);
+        }
+        Session[] session = new Session[1];
+        try {
+            if (p11Key.isPublic()) {
+                return implGetPublicKeySpec(p11Key, keySpec, session);
+            } else {
+                return implGetPrivateKeySpec(p11Key, keySpec, session);
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeySpecException("Could not generate KeySpec", e);
+        } finally {
+            session[0] = token.releaseSession(session[0]);
+        }
+    }
+
+    // see JCA spec
+    protected final Key engineTranslateKey(Key key) throws InvalidKeyException {
+        token.ensureValid();
+        if (key == null) {
+            throw new InvalidKeyException("Key must not be null");
+        }
+        if (key.getAlgorithm().equals(this.algorithm) == false) {
+            throw new InvalidKeyException
+                ("Key algorithm must be " + algorithm);
+        }
+        if (key instanceof P11Key) {
+            P11Key p11Key = (P11Key)key;
+            if (p11Key.token == token) {
+                // already a key of this token, no need to translate
+                return key;
+            }
+        }
+        P11Key p11Key = token.privateCache.get(key);
+        if (p11Key != null) {
+            return p11Key;
+        }
+        if (key instanceof PublicKey) {
+            PublicKey publicKey = implTranslatePublicKey((PublicKey)key);
+            token.privateCache.put(key, (P11Key)publicKey);
+            return publicKey;
+        } else if (key instanceof PrivateKey) {
+            PrivateKey privateKey = implTranslatePrivateKey((PrivateKey)key);
+            token.privateCache.put(key, (P11Key)privateKey);
+            return privateKey;
+        } else {
+            throw new InvalidKeyException
+                ("Key must be instance of PublicKey or PrivateKey");
+        }
+    }
+
+    abstract <T extends KeySpec> T  implGetPublicKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException;
+
+    abstract <T extends KeySpec> T  implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException;
+
+    abstract PublicKey implTranslatePublicKey(PublicKey key)
+            throws InvalidKeyException;
+
+    abstract PrivateKey implTranslatePrivateKey(PrivateKey key)
+            throws InvalidKeyException;
+
+    abstract KeyFactory implGetSoftwareFactory() throws GeneralSecurityException;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyGenerator.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2003, 2008, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * KeyGenerator implementation class. This class currently supports
+ * DES, DESede, AES, ARCFOUR, and Blowfish.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11KeyGenerator extends KeyGeneratorSpi {
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id
+    private long mechanism;
+
+    // raw key size in bits, e.g. 64 for DES. Always valid.
+    private int keySize;
+
+    // bits of entropy in the key, e.g. 56 for DES. Always valid.
+    private int significantKeySize;
+
+    // keyType (CKK_*), needed for TemplateManager call only.
+    private long keyType;
+
+    // for determining if both 112 and 168 bits of DESede key lengths
+    // are supported.
+    private boolean supportBothKeySizes;
+
+    /**
+     * Utility method for checking if the specified key size is valid
+     * and within the supported range. Return the significant key size
+     * upon successful validation.
+     * @param keyGenMech the PKCS#11 key generation mechanism.
+     * @param keySize the to-be-checked key size for this mechanism.
+     * @param token token which provides this mechanism.
+     * @return the significant key size (in bits) corresponding to the
+     * specified key size.
+     * @throws InvalidParameterException if the specified key size is invalid.
+     * @throws ProviderException if this mechanism isn't supported by SunPKCS11
+     * or underlying native impl.
+     */
+    static int checkKeySize(long keyGenMech, int keySize, Token token)
+        throws InvalidAlgorithmParameterException, ProviderException {
+        int sigKeySize;
+        switch ((int)keyGenMech) {
+            case (int)CKM_DES_KEY_GEN:
+                if ((keySize != 64) && (keySize != 56)) {
+                    throw new InvalidAlgorithmParameterException
+                            ("DES key length must be 56 bits");
+                }
+                sigKeySize = 56;
+                break;
+            case (int)CKM_DES2_KEY_GEN:
+            case (int)CKM_DES3_KEY_GEN:
+                if ((keySize == 112) || (keySize == 128)) {
+                    sigKeySize = 112;
+                } else if ((keySize == 168) || (keySize == 192)) {
+                    sigKeySize = 168;
+                } else {
+                    throw new InvalidAlgorithmParameterException
+                            ("DESede key length must be 112, or 168 bits");
+                }
+                break;
+            default:
+                // Handle all variable-key-length algorithms here
+                CK_MECHANISM_INFO info = null;
+                try {
+                    info = token.getMechanismInfo(keyGenMech);
+                } catch (PKCS11Exception p11e) {
+                    // Should never happen
+                    throw new ProviderException
+                            ("Cannot retrieve mechanism info", p11e);
+                }
+                if (info == null) {
+                    // XXX Unable to retrieve the supported key length from
+                    // the underlying native impl. Skip the checking for now.
+                    return keySize;
+                }
+                // PKCS#11 defines these to be in number of bytes except for
+                // RC4 which is in bits. However, some PKCS#11 impls still use
+                // bytes for all mechs, e.g. NSS. We try to detect this
+                // inconsistency if the minKeySize seems unreasonably small.
+                int minKeySize = (int)info.ulMinKeySize;
+                int maxKeySize = (int)info.ulMaxKeySize;
+                if (keyGenMech != CKM_RC4_KEY_GEN || minKeySize < 8) {
+                    minKeySize = (int)info.ulMinKeySize << 3;
+                    maxKeySize = (int)info.ulMaxKeySize << 3;
+                }
+                // Explicitly disallow keys shorter than 40-bits for security
+                if (minKeySize < 40) minKeySize = 40;
+                if (keySize < minKeySize || keySize > maxKeySize) {
+                    throw new InvalidAlgorithmParameterException
+                            ("Key length must be between " + minKeySize +
+                            " and " + maxKeySize + " bits");
+                }
+                if (keyGenMech == CKM_AES_KEY_GEN) {
+                    if ((keySize != 128) && (keySize != 192) &&
+                        (keySize != 256)) {
+                        throw new InvalidAlgorithmParameterException
+                                ("AES key length must be " + minKeySize +
+                                (maxKeySize >= 192? ", 192":"") +
+                                (maxKeySize >= 256? ", or 256":"") + " bits");
+                    }
+                }
+                sigKeySize = keySize;
+        }
+        return sigKeySize;
+    }
+
+    P11KeyGenerator(Token token, String algorithm, long mechanism)
+            throws PKCS11Exception {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+
+        if (this.mechanism == CKM_DES3_KEY_GEN) {
+            /* Given the current lookup order specified in SunPKCS11.java,
+               if CKM_DES2_KEY_GEN is used to construct this object, it
+               means that CKM_DES3_KEY_GEN is disabled or unsupported.
+            */
+            supportBothKeySizes =
+                (token.provider.config.isEnabled(CKM_DES2_KEY_GEN) &&
+                 (token.getMechanismInfo(CKM_DES2_KEY_GEN) != null));
+        }
+        setDefaultKeySize();
+    }
+
+    // set default keysize and also initialize keyType
+    private void setDefaultKeySize() {
+        switch ((int)mechanism) {
+        case (int)CKM_DES_KEY_GEN:
+            keySize = 64;
+            keyType = CKK_DES;
+            break;
+        case (int)CKM_DES2_KEY_GEN:
+            keySize = 128;
+            keyType = CKK_DES2;
+            break;
+        case (int)CKM_DES3_KEY_GEN:
+            keySize = 192;
+            keyType = CKK_DES3;
+            break;
+        case (int)CKM_AES_KEY_GEN:
+            keySize = 128;
+            keyType = CKK_AES;
+            break;
+        case (int)CKM_RC4_KEY_GEN:
+            keySize = 128;
+            keyType = CKK_RC4;
+            break;
+        case (int)CKM_BLOWFISH_KEY_GEN:
+            keySize = 128;
+            keyType = CKK_BLOWFISH;
+            break;
+        default:
+            throw new ProviderException("Unknown mechanism " + mechanism);
+        }
+        try {
+            significantKeySize = checkKeySize(mechanism, keySize, token);
+        } catch (InvalidAlgorithmParameterException iape) {
+            throw new ProviderException("Unsupported default key size", iape);
+        }
+    }
+
+    // see JCE spec
+    protected void engineInit(SecureRandom random) {
+        token.ensureValid();
+        setDefaultKeySize();
+    }
+
+    // see JCE spec
+    protected void engineInit(AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidAlgorithmParameterException {
+        throw new InvalidAlgorithmParameterException
+                ("AlgorithmParameterSpec not supported");
+    }
+
+    // see JCE spec
+    protected void engineInit(int keySize, SecureRandom random) {
+        token.ensureValid();
+        int newSignificantKeySize;
+        try {
+            newSignificantKeySize = checkKeySize(mechanism, keySize, token);
+        } catch (InvalidAlgorithmParameterException iape) {
+            throw (InvalidParameterException)
+                    (new InvalidParameterException().initCause(iape));
+        }
+        if ((mechanism == CKM_DES2_KEY_GEN) ||
+            (mechanism == CKM_DES3_KEY_GEN))  {
+            long newMechanism = (newSignificantKeySize == 112 ?
+                CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN);
+            if (mechanism != newMechanism) {
+                if (supportBothKeySizes) {
+                    mechanism = newMechanism;
+                    // Adjust keyType to reflect the mechanism change
+                    keyType = (mechanism == CKM_DES2_KEY_GEN ?
+                        CKK_DES2 : CKK_DES3);
+                } else {
+                    throw new InvalidParameterException
+                            ("Only " + significantKeySize +
+                             "-bit DESede is supported");
+                }
+            }
+        }
+        this.keySize = keySize;
+        this.significantKeySize = newSignificantKeySize;
+    }
+
+    // see JCE spec
+    protected SecretKey engineGenerateKey() {
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            CK_ATTRIBUTE[] attributes;
+            switch ((int)keyType) {
+            case (int)CKK_DES:
+            case (int)CKK_DES2:
+            case (int)CKK_DES3:
+                // fixed length, do not specify CKA_VALUE_LEN
+                attributes = new CK_ATTRIBUTE[] {
+                    new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
+                };
+                break;
+            default:
+                attributes = new CK_ATTRIBUTE[] {
+                    new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
+                    new CK_ATTRIBUTE(CKA_VALUE_LEN, keySize >> 3),
+                };
+                break;
+            }
+            attributes = token.getAttributes
+                (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
+            long keyID = token.p11.C_GenerateKey
+                (session.id(), new CK_MECHANISM(mechanism), attributes);
+            return P11Key.secretKey
+                (session, keyID, algorithm, significantKeySize, attributes);
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("Could not generate key", e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2003, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.spec.*;
+
+import javax.crypto.spec.DHParameterSpec;
+
+import sun.security.provider.ParameterCache;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+import sun.security.rsa.RSAKeyFactory;
+
+/**
+ * KeyPairGenerator implementation class. This class currently supports
+ * RSA, DSA, DH, and EC.
+ *
+ * Note that for DSA and DH we rely on the Sun and SunJCE providers to
+ * obtain the parameters from.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id
+    private final long mechanism;
+
+    // selected or default key size, always valid
+    private int keySize;
+
+    // parameters specified via init, if any
+    private AlgorithmParameterSpec params;
+
+    // for RSA, selected or default value of public exponent, always valid
+    private BigInteger rsaPublicExponent = RSAKeyGenParameterSpec.F4;
+
+    // the supported keysize range of the native PKCS11 library
+    // if the value cannot be retrieved or unspecified, -1 is used.
+    private final int minKeySize;
+    private final int maxKeySize;
+
+    // SecureRandom instance, if specified in init
+    private SecureRandom random;
+
+    P11KeyPairGenerator(Token token, String algorithm, long mechanism)
+            throws PKCS11Exception {
+        super();
+        int minKeyLen = -1;
+        int maxKeyLen = -1;
+        try {
+            CK_MECHANISM_INFO mechInfo = token.getMechanismInfo(mechanism);
+            if (mechInfo != null) {
+                minKeyLen = (int) mechInfo.ulMinKeySize;
+                maxKeyLen = (int) mechInfo.ulMaxKeySize;
+            }
+        } catch (PKCS11Exception p11e) {
+            // Should never happen
+            throw new ProviderException
+                        ("Unexpected error while getting mechanism info", p11e);
+        }
+        // set default key sizes and apply our own algorithm-specific limits
+        // override lower limit to disallow unsecure keys being generated
+        // override upper limit to deter DOS attack
+        if (algorithm.equals("EC")) {
+            keySize = 256;
+            if ((minKeyLen == -1) || (minKeyLen < 112)) {
+                minKeyLen = 112;
+            }
+            if ((maxKeyLen == -1) || (maxKeyLen > 2048)) {
+                maxKeyLen = 2048;
+            }
+        } else {
+            if (algorithm.equals("DSA")) {
+                // keep default keysize at 1024 since larger keysizes may be
+                // incompatible with SHA1withDSA and SHA-2 Signature algs
+                // may not be supported by native pkcs11 implementations
+                keySize = 1024;
+            } else {
+                // RSA and DH
+                keySize = 2048;
+            }
+            if ((minKeyLen == -1) || (minKeyLen < 512)) {
+                minKeyLen = 512;
+            }
+            if (algorithm.equals("RSA")) {
+                if ((maxKeyLen == -1) || (maxKeyLen > 64 * 1024)) {
+                    maxKeyLen = 64 * 1024;
+                }
+            }
+        }
+
+        // auto-adjust default keysize in case it's out-of-range
+        if ((minKeyLen != -1) && (keySize < minKeyLen)) {
+            keySize = minKeyLen;
+        }
+        if ((maxKeyLen != -1) && (keySize > maxKeyLen)) {
+            keySize = maxKeyLen;
+        }
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+        this.minKeySize = minKeyLen;
+        this.maxKeySize = maxKeyLen;
+        initialize(keySize, null);
+    }
+
+    // see JCA spec
+    @Override
+    public void initialize(int keySize, SecureRandom random) {
+        token.ensureValid();
+        try {
+            checkKeySize(keySize, null);
+        } catch (InvalidAlgorithmParameterException e) {
+            throw new InvalidParameterException(e.getMessage());
+        }
+        this.params = null;
+        if (algorithm.equals("EC")) {
+            params = P11ECKeyFactory.getECParameterSpec(keySize);
+            if (params == null) {
+                throw new InvalidParameterException(
+                    "No EC parameters available for key size "
+                    + keySize + " bits");
+            }
+        }
+        this.keySize = keySize;
+        this.random = random;
+    }
+
+    // see JCA spec
+    @Override
+    public void initialize(AlgorithmParameterSpec params, SecureRandom random)
+            throws InvalidAlgorithmParameterException {
+        token.ensureValid();
+        int tmpKeySize;
+        if (algorithm.equals("DH")) {
+            if (params instanceof DHParameterSpec == false) {
+                throw new InvalidAlgorithmParameterException
+                        ("DHParameterSpec required for Diffie-Hellman");
+            }
+            DHParameterSpec dhParams = (DHParameterSpec) params;
+            tmpKeySize = dhParams.getP().bitLength();
+            checkKeySize(tmpKeySize, dhParams);
+            // XXX sanity check params
+        } else if (algorithm.equals("RSA")) {
+            if (params instanceof RSAKeyGenParameterSpec == false) {
+                throw new InvalidAlgorithmParameterException
+                        ("RSAKeyGenParameterSpec required for RSA");
+            }
+            RSAKeyGenParameterSpec rsaParams =
+                (RSAKeyGenParameterSpec) params;
+            tmpKeySize = rsaParams.getKeysize();
+            checkKeySize(tmpKeySize, rsaParams);
+            // override the supplied params to null
+            params = null;
+            this.rsaPublicExponent = rsaParams.getPublicExponent();
+            // XXX sanity check params
+        } else if (algorithm.equals("DSA")) {
+            if (params instanceof DSAParameterSpec == false) {
+                throw new InvalidAlgorithmParameterException
+                        ("DSAParameterSpec required for DSA");
+            }
+            DSAParameterSpec dsaParams = (DSAParameterSpec) params;
+            tmpKeySize = dsaParams.getP().bitLength();
+            checkKeySize(tmpKeySize, dsaParams);
+            // XXX sanity check params
+        } else if (algorithm.equals("EC")) {
+            ECParameterSpec ecParams;
+            if (params instanceof ECParameterSpec) {
+                ecParams = P11ECKeyFactory.getECParameterSpec(
+                    (ECParameterSpec)params);
+                if (ecParams == null) {
+                    throw new InvalidAlgorithmParameterException
+                        ("Unsupported curve: " + params);
+                }
+            } else if (params instanceof ECGenParameterSpec) {
+                String name = ((ECGenParameterSpec) params).getName();
+                ecParams = P11ECKeyFactory.getECParameterSpec(name);
+                if (ecParams == null) {
+                    throw new InvalidAlgorithmParameterException
+                        ("Unknown curve name: " + name);
+                }
+                // override the supplied params with the derived one
+                params = ecParams;
+            } else {
+                throw new InvalidAlgorithmParameterException
+                    ("ECParameterSpec or ECGenParameterSpec required for EC");
+            }
+            tmpKeySize = ecParams.getCurve().getField().getFieldSize();
+            checkKeySize(tmpKeySize, ecParams);
+        } else {
+            throw new ProviderException("Unknown algorithm: " + algorithm);
+        }
+        this.keySize = tmpKeySize;
+        this.params = params;
+        this.random = random;
+    }
+
+    private void checkKeySize(int keySize, AlgorithmParameterSpec params)
+        throws InvalidAlgorithmParameterException {
+        // check native range first
+        if ((minKeySize != -1) && (keySize < minKeySize)) {
+            throw new InvalidAlgorithmParameterException(algorithm +
+                " key must be at least " + minKeySize + " bits. " +
+                "The specific key size " + keySize + " is not supported");
+        }
+        if ((maxKeySize != -1) && (keySize > maxKeySize)) {
+            throw new InvalidAlgorithmParameterException(algorithm +
+                " key must be at most " + maxKeySize + " bits. " +
+                "The specific key size " + keySize + " is not supported");
+        }
+
+        // check our own algorithm-specific limits also
+        if (algorithm.equals("EC")) {
+            if (keySize < 112) {
+                throw new InvalidAlgorithmParameterException(
+                    "EC key size must be at least 112 bit. " +
+                    "The specific key size " + keySize + " is not supported");
+            }
+            if (keySize > 2048) {
+                // sanity check, nobody really wants keys this large
+                throw new InvalidAlgorithmParameterException(
+                    "EC key size must be at most 2048 bit. " +
+                    "The specific key size " + keySize + " is not supported");
+            }
+        } else {
+            // RSA, DH, DSA
+            if (keySize < 512) {
+                throw new InvalidAlgorithmParameterException(algorithm +
+                    " key size must be at least 512 bit. " +
+                    "The specific key size " + keySize + " is not supported");
+            }
+            if (algorithm.equals("RSA")) {
+                BigInteger tmpExponent = rsaPublicExponent;
+                if (params != null) {
+                    tmpExponent =
+                        ((RSAKeyGenParameterSpec)params).getPublicExponent();
+                }
+                try {
+                    // Reuse the checking in SunRsaSign provider.
+                    // If maxKeySize is -1, then replace it with
+                    // Integer.MAX_VALUE to indicate no limit.
+                    RSAKeyFactory.checkKeyLengths(keySize, tmpExponent,
+                        minKeySize,
+                        (maxKeySize==-1? Integer.MAX_VALUE:maxKeySize));
+                } catch (InvalidKeyException e) {
+                    throw new InvalidAlgorithmParameterException(e);
+                }
+            } else if (algorithm.equals("DH")) {
+                if (params != null) {   // initialized with specified parameters
+                    // sanity check, nobody really wants keys this large
+                    if (keySize > 64 * 1024) {
+                        throw new InvalidAlgorithmParameterException(
+                            "DH key size must be at most 65536 bit. " +
+                            "The specific key size " +
+                            keySize + " is not supported");
+                    }
+                } else {        // default parameters will be used.
+                    // Range is based on the values in
+                    // sun.security.provider.ParameterCache class.
+                    if ((keySize > 8192) || (keySize < 512) ||
+                            ((keySize & 0x3f) != 0)) {
+                        throw new InvalidAlgorithmParameterException(
+                            "DH key size must be multiple of 64, and can " +
+                            "only range from 512 to 8192 (inclusive). " +
+                            "The specific key size " +
+                            keySize + " is not supported");
+                    }
+
+                    DHParameterSpec cache =
+                            ParameterCache.getCachedDHParameterSpec(keySize);
+                    // Except 2048 and 3072, not yet support generation of
+                    // parameters bigger than 1024 bits.
+                    if ((cache == null) && (keySize > 1024)) {
+                        throw new InvalidAlgorithmParameterException(
+                                "Unsupported " + keySize +
+                                "-bit DH parameter generation");
+                    }
+                }
+            } else {
+                // this restriction is in the spec for DSA
+                if ((keySize != 3072) && (keySize != 2048) &&
+                        ((keySize > 1024) || ((keySize & 0x3f) != 0))) {
+                    throw new InvalidAlgorithmParameterException(
+                        "DSA key must be multiples of 64 if less than " +
+                        "1024 bits, or 2048, 3072 bits. " +
+                        "The specific key size " +
+                        keySize + " is not supported");
+                }
+            }
+        }
+    }
+
+    // see JCA spec
+    @Override
+    public KeyPair generateKeyPair() {
+        token.ensureValid();
+        CK_ATTRIBUTE[] publicKeyTemplate;
+        CK_ATTRIBUTE[] privateKeyTemplate;
+        long keyType;
+        if (algorithm.equals("RSA")) {
+            keyType = CKK_RSA;
+            publicKeyTemplate = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_MODULUS_BITS, keySize),
+                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, rsaPublicExponent),
+            };
+            privateKeyTemplate = new CK_ATTRIBUTE[] {
+                // empty
+            };
+        } else if (algorithm.equals("DSA")) {
+            keyType = CKK_DSA;
+            DSAParameterSpec dsaParams;
+            if (params == null) {
+                try {
+                    dsaParams = ParameterCache.getDSAParameterSpec
+                                                    (keySize, random);
+                } catch (GeneralSecurityException e) {
+                    throw new ProviderException
+                            ("Could not generate DSA parameters", e);
+                }
+            } else {
+                dsaParams = (DSAParameterSpec)params;
+            }
+            publicKeyTemplate = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_PRIME, dsaParams.getP()),
+                new CK_ATTRIBUTE(CKA_SUBPRIME, dsaParams.getQ()),
+                new CK_ATTRIBUTE(CKA_BASE, dsaParams.getG()),
+            };
+            privateKeyTemplate = new CK_ATTRIBUTE[] {
+                // empty
+            };
+        } else if (algorithm.equals("DH")) {
+            keyType = CKK_DH;
+            DHParameterSpec dhParams;
+            int privateBits;
+            if (params == null) {
+                try {
+                    dhParams = ParameterCache.getDHParameterSpec
+                                                    (keySize, random);
+                } catch (GeneralSecurityException e) {
+                    throw new ProviderException
+                            ("Could not generate DH parameters", e);
+                }
+                privateBits = 0;
+            } else {
+                dhParams = (DHParameterSpec)params;
+                privateBits = dhParams.getL();
+            }
+            if (privateBits <= 0) {
+                // XXX find better defaults
+                privateBits = (keySize >= 1024) ? 768 : 512;
+            }
+            publicKeyTemplate = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_PRIME, dhParams.getP()),
+                new CK_ATTRIBUTE(CKA_BASE, dhParams.getG())
+            };
+            privateKeyTemplate = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_VALUE_BITS, privateBits),
+            };
+        } else if (algorithm.equals("EC")) {
+            keyType = CKK_EC;
+            byte[] encodedParams =
+                    P11ECKeyFactory.encodeParameters((ECParameterSpec)params);
+            publicKeyTemplate = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
+            };
+            privateKeyTemplate = new CK_ATTRIBUTE[] {
+                // empty
+            };
+        } else {
+            throw new ProviderException("Unknown algorithm: " + algorithm);
+        }
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            publicKeyTemplate = token.getAttributes
+                (O_GENERATE, CKO_PUBLIC_KEY, keyType, publicKeyTemplate);
+            privateKeyTemplate = token.getAttributes
+                (O_GENERATE, CKO_PRIVATE_KEY, keyType, privateKeyTemplate);
+            long[] keyIDs = token.p11.C_GenerateKeyPair
+                (session.id(), new CK_MECHANISM(mechanism),
+                publicKeyTemplate, privateKeyTemplate);
+            PublicKey publicKey = P11Key.publicKey
+                (session, keyIDs[0], algorithm, keySize, publicKeyTemplate);
+            PrivateKey privateKey = P11Key.privateKey
+                (session, keyIDs[1], algorithm, keySize, privateKeyTemplate);
+            return new KeyPair(publicKey, privateKey);
+        } catch (PKCS11Exception e) {
+            throw new ProviderException(e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11KeyStore.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,2683 @@
+/*
+ * Copyright (c) 2003, 2015, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.math.BigInteger;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Set;
+
+import java.security.*;
+import java.security.KeyStore.*;
+
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CertificateException;
+
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import javax.crypto.SecretKey;
+import javax.crypto.interfaces.*;
+
+import javax.security.auth.x500.X500Principal;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import sun.security.util.Debug;
+import sun.security.util.DerValue;
+import sun.security.util.ECUtil;
+
+import sun.security.pkcs11.Secmod.*;
+import static sun.security.pkcs11.P11Util.*;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+import sun.security.rsa.RSAKeyFactory;
+
+final class P11KeyStore extends KeyStoreSpi {
+
+    private static final CK_ATTRIBUTE ATTR_CLASS_CERT =
+                        new CK_ATTRIBUTE(CKA_CLASS, CKO_CERTIFICATE);
+    private static final CK_ATTRIBUTE ATTR_CLASS_PKEY =
+                        new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY);
+    private static final CK_ATTRIBUTE ATTR_CLASS_SKEY =
+                        new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
+
+    private static final CK_ATTRIBUTE ATTR_X509_CERT_TYPE =
+                        new CK_ATTRIBUTE(CKA_CERTIFICATE_TYPE, CKC_X_509);
+
+    private static final CK_ATTRIBUTE ATTR_TOKEN_TRUE =
+                        new CK_ATTRIBUTE(CKA_TOKEN, true);
+
+    // XXX for testing purposes only
+    //  - NSS doesn't support persistent secret keys
+    //    (key type gets mangled if secret key is a token key)
+    //  - if debug is turned on, then this is set to false
+    private static CK_ATTRIBUTE ATTR_SKEY_TOKEN_TRUE = ATTR_TOKEN_TRUE;
+
+    private static final CK_ATTRIBUTE ATTR_TRUSTED_TRUE =
+                        new CK_ATTRIBUTE(CKA_TRUSTED, true);
+    private static final CK_ATTRIBUTE ATTR_PRIVATE_TRUE =
+                        new CK_ATTRIBUTE(CKA_PRIVATE, true);
+
+    private static final long NO_HANDLE = -1;
+    private static final long FINDOBJECTS_MAX = 100;
+    private static final String ALIAS_SEP = "/";
+
+    private static final boolean NSS_TEST = false;
+    private static final Debug debug =
+                        Debug.getInstance("pkcs11keystore");
+    private static boolean CKA_TRUSTED_SUPPORTED = true;
+
+    private final Token token;
+
+    // If multiple certs are found to share the same CKA_LABEL
+    // at load time (NSS-style keystore), then the keystore is read
+    // and the unique keystore aliases are mapped to the entries.
+    // However, write capabilities are disabled.
+    private boolean writeDisabled = false;
+
+    // Map of unique keystore aliases to entries in the token
+    private HashMap<String, AliasInfo> aliasMap;
+
+    // whether to use NSS Secmod info for trust attributes
+    private final boolean useSecmodTrust;
+
+    // if useSecmodTrust == true, which type of trust we are interested in
+    private Secmod.TrustType nssTrustType;
+
+    /**
+     * The underlying token may contain multiple certs belonging to the
+     * same "personality" (for example, a signing cert and encryption cert),
+     * all sharing the same CKA_LABEL.  These must be resolved
+     * into unique keystore aliases.
+     *
+     * In addition, private keys and certs may not have a CKA_LABEL.
+     * It is assumed that a private key and corresponding certificate
+     * share the same CKA_ID, and that the CKA_ID is unique across the token.
+     * The CKA_ID may not be human-readable.
+     * These pairs must be resolved into unique keystore aliases.
+     *
+     * Furthermore, secret keys are assumed to have a CKA_LABEL
+     * unique across the entire token.
+     *
+     * When the KeyStore is loaded, instances of this class are
+     * created to represent the private keys/secret keys/certs
+     * that reside on the token.
+     */
+    private static class AliasInfo {
+
+        // CKA_CLASS - entry type
+        private CK_ATTRIBUTE type = null;
+
+        // CKA_LABEL of cert and secret key
+        private String label = null;
+
+        // CKA_ID of the private key/cert pair
+        private byte[] id = null;
+
+        // CKA_TRUSTED - true if cert is trusted
+        private boolean trusted = false;
+
+        // either end-entity cert or trusted cert depending on 'type'
+        private X509Certificate cert = null;
+
+        // chain
+        private X509Certificate[] chain = null;
+
+        // true if CKA_ID for private key and cert match up
+        private boolean matched = false;
+
+        // SecretKeyEntry
+        public AliasInfo(String label) {
+            this.type = ATTR_CLASS_SKEY;
+            this.label = label;
+        }
+
+        // PrivateKeyEntry
+        public AliasInfo(String label,
+                        byte[] id,
+                        boolean trusted,
+                        X509Certificate cert) {
+            this.type = ATTR_CLASS_PKEY;
+            this.label = label;
+            this.id = id;
+            this.trusted = trusted;
+            this.cert = cert;
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            if (type == ATTR_CLASS_PKEY) {
+                sb.append("\ttype=[private key]\n");
+            } else if (type == ATTR_CLASS_SKEY) {
+                sb.append("\ttype=[secret key]\n");
+            } else if (type == ATTR_CLASS_CERT) {
+                sb.append("\ttype=[trusted cert]\n");
+            }
+            sb.append("\tlabel=[" + label + "]\n");
+            if (id == null) {
+                sb.append("\tid=[null]\n");
+            } else {
+                sb.append("\tid=" + P11KeyStore.getID(id) + "\n");
+            }
+            sb.append("\ttrusted=[" + trusted + "]\n");
+            sb.append("\tmatched=[" + matched + "]\n");
+            if (cert == null) {
+                sb.append("\tcert=[null]\n");
+            } else {
+                sb.append("\tcert=[\tsubject: " +
+                        cert.getSubjectX500Principal() +
+                        "\n\t\tissuer: " +
+                        cert.getIssuerX500Principal() +
+                        "\n\t\tserialNum: " +
+                        cert.getSerialNumber().toString() +
+                        "]");
+            }
+            return sb.toString();
+        }
+    }
+
+    /**
+     * callback handler for passing password to Provider.login method
+     */
+    private static class PasswordCallbackHandler implements CallbackHandler {
+
+        private char[] password;
+
+        private PasswordCallbackHandler(char[] password) {
+            if (password != null) {
+                this.password = password.clone();
+            }
+        }
+
+        public void handle(Callback[] callbacks)
+                throws IOException, UnsupportedCallbackException {
+            if (!(callbacks[0] instanceof PasswordCallback)) {
+                throw new UnsupportedCallbackException(callbacks[0]);
+            }
+            PasswordCallback pc = (PasswordCallback)callbacks[0];
+            pc.setPassword(password);  // this clones the password if not null
+        }
+
+        protected void finalize() throws Throwable {
+            if (password != null) {
+                Arrays.fill(password, ' ');
+            }
+            super.finalize();
+        }
+    }
+
+    /**
+     * getTokenObject return value.
+     *
+     * if object is not found, type is set to null.
+     * otherwise, type is set to the requested type.
+     */
+    private static class THandle {
+        private final long handle;              // token object handle
+        private final CK_ATTRIBUTE type;        // CKA_CLASS
+
+        private THandle(long handle, CK_ATTRIBUTE type) {
+            this.handle = handle;
+            this.type = type;
+        }
+    }
+
+    P11KeyStore(Token token) {
+        this.token = token;
+        this.useSecmodTrust = token.provider.nssUseSecmodTrust;
+    }
+
+    /**
+     * Returns the key associated with the given alias.
+     * The key must have been associated with
+     * the alias by a call to <code>setKeyEntry</code>,
+     * or by a call to <code>setEntry</code> with a
+     * <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>.
+     *
+     * @param alias the alias name
+     * @param password the password, which must be <code>null</code>
+     *
+     * @return the requested key, or null if the given alias does not exist
+     * or does not identify a key-related entry.
+     *
+     * @exception NoSuchAlgorithmException if the algorithm for recovering the
+     * key cannot be found
+     * @exception UnrecoverableKeyException if the key cannot be recovered
+     */
+    public synchronized Key engineGetKey(String alias, char[] password)
+                throws NoSuchAlgorithmException, UnrecoverableKeyException {
+
+        token.ensureValid();
+        if (password != null && !token.config.getKeyStoreCompatibilityMode()) {
+            throw new NoSuchAlgorithmException("password must be null");
+        }
+
+        AliasInfo aliasInfo = aliasMap.get(alias);
+        if (aliasInfo == null || aliasInfo.type == ATTR_CLASS_CERT) {
+            return null;
+        }
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            if (aliasInfo.type == ATTR_CLASS_PKEY) {
+                THandle h = getTokenObject(session,
+                                        aliasInfo.type,
+                                        aliasInfo.id,
+                                        null);
+                if (h.type == ATTR_CLASS_PKEY) {
+                    return loadPkey(session, h.handle);
+                }
+            } else {
+                THandle h = getTokenObject(session,
+                                        ATTR_CLASS_SKEY,
+                                        null,
+                                        alias);
+                if (h.type == ATTR_CLASS_SKEY) {
+                    return loadSkey(session, h.handle);
+                }
+            }
+
+            // did not find anything
+            return null;
+        } catch (PKCS11Exception | KeyStoreException e) {
+            throw new ProviderException(e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    /**
+     * Returns the certificate chain associated with the given alias.
+     * The certificate chain must have been associated with the alias
+     * by a call to <code>setKeyEntry</code>,
+     * or by a call to <code>setEntry</code> with a
+     * <code>PrivateKeyEntry</code>.
+     *
+     * @param alias the alias name
+     *
+     * @return the certificate chain (ordered with the user's certificate first
+     * and the root certificate authority last), or null if the given alias
+     * does not exist or does not contain a certificate chain
+     */
+    public synchronized Certificate[] engineGetCertificateChain(String alias) {
+
+        token.ensureValid();
+
+        AliasInfo aliasInfo = aliasMap.get(alias);
+        if (aliasInfo == null || aliasInfo.type != ATTR_CLASS_PKEY) {
+            return null;
+        }
+        return aliasInfo.chain;
+    }
+
+    /**
+     * Returns the certificate associated with the given alias.
+     *
+     * <p> If the given alias name identifies an entry
+     * created by a call to <code>setCertificateEntry</code>,
+     * or created by a call to <code>setEntry</code> with a
+     * <code>TrustedCertificateEntry</code>,
+     * then the trusted certificate contained in that entry is returned.
+     *
+     * <p> If the given alias name identifies an entry
+     * created by a call to <code>setKeyEntry</code>,
+     * or created by a call to <code>setEntry</code> with a
+     * <code>PrivateKeyEntry</code>,
+     * then the first element of the certificate chain in that entry
+     * (if a chain exists) is returned.
+     *
+     * @param alias the alias name
+     *
+     * @return the certificate, or null if the given alias does not exist or
+     * does not contain a certificate.
+     */
+    public synchronized Certificate engineGetCertificate(String alias) {
+        token.ensureValid();
+
+        AliasInfo aliasInfo = aliasMap.get(alias);
+        if (aliasInfo == null) {
+            return null;
+        }
+        return aliasInfo.cert;
+    }
+
+    /**
+     * Returns the creation date of the entry identified by the given alias.
+     *
+     * @param alias the alias name
+     *
+     * @return the creation date of this entry, or null if the given alias does
+     * not exist
+     */
+    public Date engineGetCreationDate(String alias) {
+        token.ensureValid();
+        throw new ProviderException(new UnsupportedOperationException());
+    }
+
+    /**
+     * Assigns the given key to the given alias, protecting it with the given
+     * password.
+     *
+     * <p>If the given key is of type <code>java.security.PrivateKey</code>,
+     * it must be accompanied by a certificate chain certifying the
+     * corresponding public key.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key (and possibly
+     * certificate chain).
+     *
+     * @param alias the alias name
+     * @param key the key to be associated with the alias
+     * @param password the password to protect the key
+     * @param chain the certificate chain for the corresponding public
+     * key (only required if the given key is of type
+     * <code>java.security.PrivateKey</code>).
+     *
+     * @exception KeyStoreException if the given key cannot be protected, or
+     * this operation fails for some other reason
+     */
+    public synchronized void engineSetKeyEntry(String alias, Key key,
+                                   char[] password,
+                                   Certificate[] chain)
+                throws KeyStoreException {
+
+        token.ensureValid();
+        checkWrite();
+
+        if (!(key instanceof PrivateKey) && !(key instanceof SecretKey)) {
+            throw new KeyStoreException("key must be PrivateKey or SecretKey");
+        } else if (key instanceof PrivateKey && chain == null) {
+            throw new KeyStoreException
+                ("PrivateKey must be accompanied by non-null chain");
+        } else if (key instanceof SecretKey && chain != null) {
+            throw new KeyStoreException
+                ("SecretKey must be accompanied by null chain");
+        } else if (password != null &&
+                    !token.config.getKeyStoreCompatibilityMode()) {
+            throw new KeyStoreException("Password must be null");
+        }
+
+        KeyStore.Entry entry = null;
+        try {
+            if (key instanceof PrivateKey) {
+                entry = new KeyStore.PrivateKeyEntry((PrivateKey)key, chain);
+            } else if (key instanceof SecretKey) {
+                entry = new KeyStore.SecretKeyEntry((SecretKey)key);
+            }
+        } catch (NullPointerException | IllegalArgumentException e) {
+            throw new KeyStoreException(e);
+        }
+        engineSetEntry(alias, entry, new KeyStore.PasswordProtection(password));
+    }
+
+    /**
+     * Assigns the given key (that has already been protected) to the given
+     * alias.
+     *
+     * <p>If the protected key is of type
+     * <code>java.security.PrivateKey</code>,
+     * it must be accompanied by a certificate chain certifying the
+     * corresponding public key.
+     *
+     * <p>If the given alias already exists, the keystore information
+     * associated with it is overridden by the given key (and possibly
+     * certificate chain).
+     *
+     * @param alias the alias name
+     * @param key the key (in protected format) to be associated with the alias
+     * @param chain the certificate chain for the corresponding public
+     * key (only useful if the protected key is of type
+     * <code>java.security.PrivateKey</code>).
+     *
+     * @exception KeyStoreException if this operation fails.
+     */
+    public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
+                throws KeyStoreException {
+        token.ensureValid();
+        throw new ProviderException(new UnsupportedOperationException());
+    }
+
+    /**
+     * Assigns the given certificate to the given alias.
+     *
+     * <p> If the given alias identifies an existing entry
+     * created by a call to <code>setCertificateEntry</code>,
+     * or created by a call to <code>setEntry</code> with a
+     * <code>TrustedCertificateEntry</code>,
+     * the trusted certificate in the existing entry
+     * is overridden by the given certificate.
+     *
+     * @param alias the alias name
+     * @param cert the certificate
+     *
+     * @exception KeyStoreException if the given alias already exists and does
+     * not identify an entry containing a trusted certificate,
+     * or this operation fails for some other reason.
+     */
+    public synchronized void engineSetCertificateEntry
+        (String alias, Certificate cert) throws KeyStoreException {
+
+        token.ensureValid();
+        checkWrite();
+
+        if (cert == null) {
+            throw new KeyStoreException("invalid null certificate");
+        }
+
+        KeyStore.Entry entry = null;
+        entry = new KeyStore.TrustedCertificateEntry(cert);
+        engineSetEntry(alias, entry, null);
+    }
+
+    /**
+     * Deletes the entry identified by the given alias from this keystore.
+     *
+     * @param alias the alias name
+     *
+     * @exception KeyStoreException if the entry cannot be removed.
+     */
+    public synchronized void engineDeleteEntry(String alias)
+                throws KeyStoreException {
+        token.ensureValid();
+
+        if (token.isWriteProtected()) {
+            throw new KeyStoreException("token write-protected");
+        }
+        checkWrite();
+        deleteEntry(alias);
+    }
+
+    /**
+     * XXX - not sure whether to keep this
+     */
+    private boolean deleteEntry(String alias) throws KeyStoreException {
+        AliasInfo aliasInfo = aliasMap.get(alias);
+        if (aliasInfo != null) {
+
+            aliasMap.remove(alias);
+
+            try {
+                if (aliasInfo.type == ATTR_CLASS_CERT) {
+                    // trusted certificate entry
+                    return destroyCert(aliasInfo.id);
+                } else if (aliasInfo.type == ATTR_CLASS_PKEY) {
+                    // private key entry
+                    return destroyPkey(aliasInfo.id) &&
+                                destroyChain(aliasInfo.id);
+                } else if (aliasInfo.type == ATTR_CLASS_SKEY) {
+                    // secret key entry
+                    return destroySkey(alias);
+                } else {
+                    throw new KeyStoreException("unexpected entry type");
+                }
+            } catch (PKCS11Exception | CertificateException e) {
+                throw new KeyStoreException(e);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Lists all the alias names of this keystore.
+     *
+     * @return enumeration of the alias names
+     */
+    public synchronized Enumeration<String> engineAliases() {
+        token.ensureValid();
+
+        // don't want returned enumeration to iterate off actual keySet -
+        // otherwise applications that iterate and modify the keystore
+        // may run into concurrent modification problems
+        return Collections.enumeration(new HashSet<String>(aliasMap.keySet()));
+    }
+
+    /**
+     * Checks if the given alias exists in this keystore.
+     *
+     * @param alias the alias name
+     *
+     * @return true if the alias exists, false otherwise
+     */
+    public synchronized boolean engineContainsAlias(String alias) {
+        token.ensureValid();
+        return aliasMap.containsKey(alias);
+    }
+
+    /**
+     * Retrieves the number of entries in this keystore.
+     *
+     * @return the number of entries in this keystore
+     */
+    public synchronized int engineSize() {
+        token.ensureValid();
+        return aliasMap.size();
+    }
+
+    /**
+     * Returns true if the entry identified by the given alias
+     * was created by a call to <code>setKeyEntry</code>,
+     * or created by a call to <code>setEntry</code> with a
+     * <code>PrivateKeyEntry</code> or a <code>SecretKeyEntry</code>.
+     *
+     * @param alias the alias for the keystore entry to be checked
+     *
+     * @return true if the entry identified by the given alias is a
+     * key-related, false otherwise.
+     */
+    public synchronized boolean engineIsKeyEntry(String alias) {
+        token.ensureValid();
+
+        AliasInfo aliasInfo = aliasMap.get(alias);
+        if (aliasInfo == null || aliasInfo.type == ATTR_CLASS_CERT) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the entry identified by the given alias
+     * was created by a call to <code>setCertificateEntry</code>,
+     * or created by a call to <code>setEntry</code> with a
+     * <code>TrustedCertificateEntry</code>.
+     *
+     * @param alias the alias for the keystore entry to be checked
+     *
+     * @return true if the entry identified by the given alias contains a
+     * trusted certificate, false otherwise.
+     */
+    public synchronized boolean engineIsCertificateEntry(String alias) {
+        token.ensureValid();
+
+        AliasInfo aliasInfo = aliasMap.get(alias);
+        if (aliasInfo == null || aliasInfo.type != ATTR_CLASS_CERT) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns the (alias) name of the first keystore entry whose certificate
+     * matches the given certificate.
+     *
+     * <p>This method attempts to match the given certificate with each
+     * keystore entry. If the entry being considered was
+     * created by a call to <code>setCertificateEntry</code>,
+     * or created by a call to <code>setEntry</code> with a
+     * <code>TrustedCertificateEntry</code>,
+     * then the given certificate is compared to that entry's certificate.
+     *
+     * <p> If the entry being considered was
+     * created by a call to <code>setKeyEntry</code>,
+     * or created by a call to <code>setEntry</code> with a
+     * <code>PrivateKeyEntry</code>,
+     * then the given certificate is compared to the first
+     * element of that entry's certificate chain.
+     *
+     * @param cert the certificate to match with.
+     *
+     * @return the alias name of the first entry with matching certificate,
+     * or null if no such entry exists in this keystore.
+     */
+    public synchronized String engineGetCertificateAlias(Certificate cert) {
+        token.ensureValid();
+        Enumeration<String> e = engineAliases();
+        while (e.hasMoreElements()) {
+            String alias = e.nextElement();
+            Certificate tokenCert = engineGetCertificate(alias);
+            if (tokenCert != null && tokenCert.equals(cert)) {
+                return alias;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * engineStore currently is a No-op.
+     * Entries are stored to the token during engineSetEntry
+     *
+     * @param stream this must be <code>null</code>
+     * @param password this must be <code>null</code>
+     */
+    public synchronized void engineStore(OutputStream stream, char[] password)
+        throws IOException, NoSuchAlgorithmException, CertificateException {
+        token.ensureValid();
+        if (stream != null && !token.config.getKeyStoreCompatibilityMode()) {
+            throw new IOException("output stream must be null");
+        }
+
+        if (password != null && !token.config.getKeyStoreCompatibilityMode()) {
+            throw new IOException("password must be null");
+        }
+    }
+
+    /**
+     * engineStore currently is a No-op.
+     * Entries are stored to the token during engineSetEntry
+     *
+     * @param param this must be <code>null</code>
+     *
+     * @exception IllegalArgumentException if the given
+     *          <code>KeyStore.LoadStoreParameter</code>
+     *          input is not <code>null</code>
+     */
+    public synchronized void engineStore(KeyStore.LoadStoreParameter param)
+        throws IOException, NoSuchAlgorithmException, CertificateException {
+        token.ensureValid();
+        if (param != null) {
+            throw new IllegalArgumentException
+                ("LoadStoreParameter must be null");
+        }
+    }
+
+    /**
+     * Loads the keystore.
+     *
+     * @param stream the input stream, which must be <code>null</code>
+     * @param password the password used to unlock the keystore,
+     *          or <code>null</code> if the token supports a
+     *          CKF_PROTECTED_AUTHENTICATION_PATH
+     *
+     * @exception IOException if the given <code>stream</code> is not
+     *          <code>null</code>, if the token supports a
+     *          CKF_PROTECTED_AUTHENTICATION_PATH and a non-null
+     *          password is given, of if the token login operation failed
+     */
+    public synchronized void engineLoad(InputStream stream, char[] password)
+        throws IOException, NoSuchAlgorithmException, CertificateException {
+
+        token.ensureValid();
+
+        if (NSS_TEST) {
+            ATTR_SKEY_TOKEN_TRUE = new CK_ATTRIBUTE(CKA_TOKEN, false);
+        }
+
+        if (stream != null && !token.config.getKeyStoreCompatibilityMode()) {
+            throw new IOException("input stream must be null");
+        }
+
+        if (useSecmodTrust) {
+            nssTrustType = Secmod.TrustType.ALL;
+        }
+
+        try {
+            if (password == null) {
+                login(null);
+            } else {
+                login(new PasswordCallbackHandler(password));
+            }
+        } catch(LoginException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof PKCS11Exception) {
+                PKCS11Exception pe = (PKCS11Exception) cause;
+                if (pe.getErrorCode() == CKR_PIN_INCORRECT) {
+                    // if password is wrong, the cause of the IOException
+                    // should be an UnrecoverableKeyException
+                    throw new IOException("load failed",
+                            new UnrecoverableKeyException().initCause(e));
+                }
+            }
+            throw new IOException("load failed", e);
+        }
+
+        try {
+            if (mapLabels() == true) {
+                // CKA_LABELs are shared by multiple certs
+                writeDisabled = true;
+            }
+            if (debug != null) {
+                dumpTokenMap();
+            }
+        } catch (KeyStoreException | PKCS11Exception e) {
+            throw new IOException("load failed", e);
+        }
+    }
+
+    /**
+     * Loads the keystore using the given
+     * <code>KeyStore.LoadStoreParameter</code>.
+     *
+     * <p> The <code>LoadStoreParameter.getProtectionParameter()</code>
+     * method is expected to return a <code>KeyStore.PasswordProtection</code>
+     * object.  The password is retrieved from that object and used
+     * to unlock the PKCS#11 token.
+     *
+     * <p> If the token supports a CKF_PROTECTED_AUTHENTICATION_PATH
+     * then the provided password must be <code>null</code>.
+     *
+     * @param param the <code>KeyStore.LoadStoreParameter</code>
+     *
+     * @exception IllegalArgumentException if the given
+     *          <code>KeyStore.LoadStoreParameter</code> is <code>null</code>,
+     *          or if that parameter returns a <code>null</code>
+     *          <code>ProtectionParameter</code> object.
+     *          input is not recognized
+     * @exception IOException if the token supports a
+     *          CKF_PROTECTED_AUTHENTICATION_PATH and the provided password
+     *          is non-null, or if the token login operation fails
+     */
+    public synchronized void engineLoad(KeyStore.LoadStoreParameter param)
+                throws IOException, NoSuchAlgorithmException,
+                CertificateException {
+
+        token.ensureValid();
+
+        if (NSS_TEST) {
+            ATTR_SKEY_TOKEN_TRUE = new CK_ATTRIBUTE(CKA_TOKEN, false);
+        }
+
+        // if caller wants to pass a NULL password,
+        // force it to pass a non-NULL PasswordProtection that returns
+        // a NULL password
+
+        if (param == null) {
+            throw new IllegalArgumentException
+                        ("invalid null LoadStoreParameter");
+        }
+        if (useSecmodTrust) {
+            if (param instanceof Secmod.KeyStoreLoadParameter) {
+                nssTrustType = ((Secmod.KeyStoreLoadParameter)param).getTrustType();
+            } else {
+                nssTrustType = Secmod.TrustType.ALL;
+            }
+        }
+
+        CallbackHandler handler;
+        KeyStore.ProtectionParameter pp = param.getProtectionParameter();
+        if (pp instanceof PasswordProtection) {
+            char[] password = ((PasswordProtection)pp).getPassword();
+            if (password == null) {
+                handler = null;
+            } else {
+                handler = new PasswordCallbackHandler(password);
+            }
+        } else if (pp instanceof CallbackHandlerProtection) {
+            handler = ((CallbackHandlerProtection)pp).getCallbackHandler();
+        } else {
+            throw new IllegalArgumentException
+                        ("ProtectionParameter must be either " +
+                        "PasswordProtection or CallbackHandlerProtection");
+        }
+
+        try {
+            login(handler);
+            if (mapLabels() == true) {
+                // CKA_LABELs are shared by multiple certs
+                writeDisabled = true;
+            }
+            if (debug != null) {
+                dumpTokenMap();
+            }
+        } catch (LoginException | KeyStoreException | PKCS11Exception e) {
+            throw new IOException("load failed", e);
+        }
+    }
+
+    private void login(CallbackHandler handler) throws LoginException {
+        if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
+            token.provider.login(null, handler);
+        } else {
+            // token supports protected authentication path
+            // (external pin-pad, for example)
+            if (handler != null &&
+                !token.config.getKeyStoreCompatibilityMode()) {
+                throw new LoginException("can not specify password if token " +
+                                "supports protected authentication path");
+            }
+
+            // must rely on application-set or default handler
+            // if one is necessary
+            token.provider.login(null, null);
+        }
+    }
+
+    /**
+     * Get a <code>KeyStore.Entry</code> for the specified alias
+     *
+     * @param alias get the <code>KeyStore.Entry</code> for this alias
+     * @param protParam this must be <code>null</code>
+     *
+     * @return the <code>KeyStore.Entry</code> for the specified alias,
+     *          or <code>null</code> if there is no such entry
+     *
+     * @exception KeyStoreException if the operation failed
+     * @exception NoSuchAlgorithmException if the algorithm for recovering the
+     *          entry cannot be found
+     * @exception UnrecoverableEntryException if the specified
+     *          <code>protParam</code> were insufficient or invalid
+     *
+     * @since 1.5
+     */
+    public synchronized KeyStore.Entry engineGetEntry(String alias,
+                        KeyStore.ProtectionParameter protParam)
+                throws KeyStoreException, NoSuchAlgorithmException,
+                UnrecoverableEntryException {
+
+        token.ensureValid();
+
+        if (protParam != null &&
+            protParam instanceof KeyStore.PasswordProtection &&
+            ((KeyStore.PasswordProtection)protParam).getPassword() != null &&
+            !token.config.getKeyStoreCompatibilityMode()) {
+            throw new KeyStoreException("ProtectionParameter must be null");
+        }
+
+        AliasInfo aliasInfo = aliasMap.get(alias);
+        if (aliasInfo == null) {
+            if (debug != null) {
+                debug.println("engineGetEntry did not find alias [" +
+                        alias +
+                        "] in map");
+            }
+            return null;
+        }
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            if (aliasInfo.type == ATTR_CLASS_CERT) {
+                // trusted certificate entry
+                if (debug != null) {
+                    debug.println("engineGetEntry found trusted cert entry");
+                }
+                return new KeyStore.TrustedCertificateEntry(aliasInfo.cert);
+            } else if (aliasInfo.type == ATTR_CLASS_SKEY) {
+                // secret key entry
+                if (debug != null) {
+                    debug.println("engineGetEntry found secret key entry");
+                }
+
+                THandle h = getTokenObject
+                        (session, ATTR_CLASS_SKEY, null, aliasInfo.label);
+                if (h.type != ATTR_CLASS_SKEY) {
+                    throw new KeyStoreException
+                        ("expected but could not find secret key");
+                } else {
+                    SecretKey skey = loadSkey(session, h.handle);
+                    return new KeyStore.SecretKeyEntry(skey);
+                }
+            } else {
+                // private key entry
+                if (debug != null) {
+                    debug.println("engineGetEntry found private key entry");
+                }
+
+                THandle h = getTokenObject
+                        (session, ATTR_CLASS_PKEY, aliasInfo.id, null);
+                if (h.type != ATTR_CLASS_PKEY) {
+                    throw new KeyStoreException
+                        ("expected but could not find private key");
+                } else {
+                    PrivateKey pkey = loadPkey(session, h.handle);
+                    Certificate[] chain = aliasInfo.chain;
+                    if ((pkey != null) && (chain != null)) {
+                        return new KeyStore.PrivateKeyEntry(pkey, chain);
+                    } else {
+                        if (debug != null) {
+                            debug.println
+                                ("engineGetEntry got null cert chain or private key");
+                        }
+                    }
+                }
+            }
+            return null;
+        } catch (PKCS11Exception pe) {
+            throw new KeyStoreException(pe);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    /**
+     * Save a <code>KeyStore.Entry</code> under the specified alias.
+     *
+     * <p> If an entry already exists for the specified alias,
+     * it is overridden.
+     *
+     * <p> This KeyStore implementation only supports the standard
+     * entry types, and only supports X509Certificates in
+     * TrustedCertificateEntries.  Also, this implementation does not support
+     * protecting entries using a different password
+     * from the one used for token login.
+     *
+     * <p> Entries are immediately stored on the token.
+     *
+     * @param alias save the <code>KeyStore.Entry</code> under this alias
+     * @param entry the <code>Entry</code> to save
+     * @param protParam this must be <code>null</code>
+     *
+     * @exception KeyStoreException if this operation fails
+     *
+     * @since 1.5
+     */
+    public synchronized void engineSetEntry(String alias, KeyStore.Entry entry,
+                        KeyStore.ProtectionParameter protParam)
+                throws KeyStoreException {
+
+        token.ensureValid();
+        checkWrite();
+
+        if (protParam != null &&
+            protParam instanceof KeyStore.PasswordProtection &&
+            ((KeyStore.PasswordProtection)protParam).getPassword() != null &&
+            !token.config.getKeyStoreCompatibilityMode()) {
+            throw new KeyStoreException(new UnsupportedOperationException
+                                ("ProtectionParameter must be null"));
+        }
+
+        if (token.isWriteProtected()) {
+            throw new KeyStoreException("token write-protected");
+        }
+
+        if (entry instanceof KeyStore.TrustedCertificateEntry) {
+
+            if (useSecmodTrust == false) {
+                // PKCS #11 does not allow app to modify trusted certs -
+                throw new KeyStoreException(new UnsupportedOperationException
+                                    ("trusted certificates may only be set by " +
+                                    "token initialization application"));
+            }
+            Module module = token.provider.nssModule;
+            if ((module.type != ModuleType.KEYSTORE) && (module.type != ModuleType.FIPS)) {
+                // XXX allow TRUSTANCHOR module
+                throw new KeyStoreException("Trusted certificates can only be "
+                    + "added to the NSS KeyStore module");
+            }
+            Certificate cert = ((TrustedCertificateEntry)entry).getTrustedCertificate();
+            if (cert instanceof X509Certificate == false) {
+                throw new KeyStoreException("Certificate must be an X509Certificate");
+            }
+            X509Certificate xcert = (X509Certificate)cert;
+            AliasInfo info = aliasMap.get(alias);
+            if (info != null) {
+                // XXX try to update
+                deleteEntry(alias);
+            }
+            try {
+                storeCert(alias, xcert);
+                module.setTrust(token, xcert);
+                mapLabels();
+            } catch (PKCS11Exception | CertificateException e) {
+                throw new KeyStoreException(e);
+            }
+
+        } else {
+
+            if (entry instanceof KeyStore.PrivateKeyEntry) {
+
+                PrivateKey key =
+                        ((KeyStore.PrivateKeyEntry)entry).getPrivateKey();
+                if (!(key instanceof P11Key) &&
+                    !(key instanceof RSAPrivateKey) &&
+                    !(key instanceof DSAPrivateKey) &&
+                    !(key instanceof DHPrivateKey) &&
+                    !(key instanceof ECPrivateKey)) {
+                    throw new KeyStoreException("unsupported key type: " +
+                                                key.getClass().getName());
+                }
+
+                // only support X509Certificate chains
+                Certificate[] chain =
+                    ((KeyStore.PrivateKeyEntry)entry).getCertificateChain();
+                if (!(chain instanceof X509Certificate[])) {
+                    throw new KeyStoreException
+                        (new UnsupportedOperationException
+                                ("unsupported certificate array type: " +
+                                chain.getClass().getName()));
+                }
+
+                try {
+                    boolean updatedAlias = false;
+                    Set<String> aliases = aliasMap.keySet();
+                    for (String oldAlias : aliases) {
+
+                        // see if there's an existing entry with the same info
+
+                        AliasInfo aliasInfo = aliasMap.get(oldAlias);
+                        if (aliasInfo.type == ATTR_CLASS_PKEY &&
+                            aliasInfo.cert.getPublicKey().equals
+                                        (chain[0].getPublicKey())) {
+
+                            // found existing entry -
+                            // caller is renaming entry or updating cert chain
+                            //
+                            // set new CKA_LABEL/CKA_ID
+                            // and update certs if necessary
+
+                            updatePkey(alias,
+                                        aliasInfo.id,
+                                        (X509Certificate[])chain,
+                                        !aliasInfo.cert.equals(chain[0]));
+                            updatedAlias = true;
+                            break;
+                        }
+                    }
+
+                    if (!updatedAlias) {
+                        // caller adding new entry
+                        engineDeleteEntry(alias);
+                        storePkey(alias, (KeyStore.PrivateKeyEntry)entry);
+                    }
+
+                } catch (PKCS11Exception | CertificateException pe) {
+                    throw new KeyStoreException(pe);
+                }
+
+            } else if (entry instanceof KeyStore.SecretKeyEntry) {
+
+                KeyStore.SecretKeyEntry ske = (KeyStore.SecretKeyEntry)entry;
+                SecretKey skey = ske.getSecretKey();
+
+                try {
+                    // first check if the key already exists
+                    AliasInfo aliasInfo = aliasMap.get(alias);
+
+                    if (aliasInfo != null) {
+                        engineDeleteEntry(alias);
+                    }
+                    storeSkey(alias, ske);
+
+                } catch (PKCS11Exception pe) {
+                    throw new KeyStoreException(pe);
+                }
+
+            } else {
+                throw new KeyStoreException(new UnsupportedOperationException
+                    ("unsupported entry type: " + entry.getClass().getName()));
+            }
+
+            try {
+
+                // XXX  NSS does not write out the CKA_ID we pass to them
+                //
+                // therefore we must re-map labels
+                // (can not simply update aliasMap)
+
+                mapLabels();
+                if (debug != null) {
+                    dumpTokenMap();
+                }
+            } catch (PKCS11Exception | CertificateException pe) {
+                throw new KeyStoreException(pe);
+            }
+        }
+
+        if (debug != null) {
+            debug.println
+                ("engineSetEntry added new entry for [" +
+                alias +
+                "] to token");
+        }
+    }
+
+    /**
+     * Determines if the keystore <code>Entry</code> for the specified
+     * <code>alias</code> is an instance or subclass of the specified
+     * <code>entryClass</code>.
+     *
+     * @param alias the alias name
+     * @param entryClass the entry class
+     *
+     * @return true if the keystore <code>Entry</code> for the specified
+     *          <code>alias</code> is an instance or subclass of the
+     *          specified <code>entryClass</code>, false otherwise
+     */
+    public synchronized boolean engineEntryInstanceOf
+                (String alias, Class<? extends KeyStore.Entry> entryClass) {
+        token.ensureValid();
+        return super.engineEntryInstanceOf(alias, entryClass);
+    }
+
+    private X509Certificate loadCert(Session session, long oHandle)
+                throws PKCS11Exception, CertificateException {
+
+        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[]
+                        { new CK_ATTRIBUTE(CKA_VALUE) };
+        token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
+
+        byte[] bytes = attrs[0].getByteArray();
+        if (bytes == null) {
+            throw new CertificateException
+                        ("unexpectedly retrieved null byte array");
+        }
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        return (X509Certificate)cf.generateCertificate
+                        (new ByteArrayInputStream(bytes));
+    }
+
+    private X509Certificate[] loadChain(Session session,
+                                        X509Certificate endCert)
+                throws PKCS11Exception, CertificateException {
+
+        ArrayList<X509Certificate> lChain = null;
+
+        if (endCert.getSubjectX500Principal().equals
+            (endCert.getIssuerX500Principal())) {
+            // self signed
+            return new X509Certificate[] { endCert };
+        } else {
+            lChain = new ArrayList<X509Certificate>();
+            lChain.add(endCert);
+        }
+
+        // try loading remaining certs in chain by following
+        // issuer->subject links
+
+        X509Certificate next = endCert;
+        while (true) {
+            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                        ATTR_TOKEN_TRUE,
+                        ATTR_CLASS_CERT,
+                        new CK_ATTRIBUTE(CKA_SUBJECT,
+                                next.getIssuerX500Principal().getEncoded()) };
+            long[] ch = findObjects(session, attrs);
+
+            if (ch == null || ch.length == 0) {
+                // done
+                break;
+            } else {
+                // if more than one found, use first
+                if (debug != null && ch.length > 1) {
+                    debug.println("engineGetEntry found " +
+                                ch.length +
+                                " certificate entries for subject [" +
+                                next.getIssuerX500Principal().toString() +
+                                "] in token - using first entry");
+                }
+
+                next = loadCert(session, ch[0]);
+                lChain.add(next);
+                if (next.getSubjectX500Principal().equals
+                    (next.getIssuerX500Principal())) {
+                    // self signed
+                    break;
+                }
+            }
+        }
+
+        return lChain.toArray(new X509Certificate[lChain.size()]);
+    }
+
+    private SecretKey loadSkey(Session session, long oHandle)
+                throws PKCS11Exception {
+
+        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                        new CK_ATTRIBUTE(CKA_KEY_TYPE) };
+        token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
+        long kType = attrs[0].getLong();
+
+        String keyType = null;
+        int keyLength = -1;
+
+        // XXX NSS mangles the stored key type for secret key token objects
+
+        if (kType == CKK_DES || kType == CKK_DES3) {
+            if (kType == CKK_DES) {
+                keyType = "DES";
+                keyLength = 64;
+            } else if (kType == CKK_DES3) {
+                keyType = "DESede";
+                keyLength = 192;
+            }
+        } else {
+            if (kType == CKK_AES) {
+                keyType = "AES";
+            } else if (kType == CKK_BLOWFISH) {
+                keyType = "Blowfish";
+            } else if (kType == CKK_RC4) {
+                keyType = "ARCFOUR";
+            } else {
+                if (debug != null) {
+                    debug.println("unknown key type [" +
+                                kType +
+                                "] - using 'Generic Secret'");
+                }
+                keyType = "Generic Secret";
+            }
+
+            // XXX NSS problem CKR_ATTRIBUTE_TYPE_INVALID?
+            if (NSS_TEST) {
+                keyLength = 128;
+            } else {
+                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_VALUE_LEN) };
+                token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
+                keyLength = (int)attrs[0].getLong();
+            }
+        }
+
+        return P11Key.secretKey(session, oHandle, keyType, keyLength, null);
+    }
+
+    private PrivateKey loadPkey(Session session, long oHandle)
+        throws PKCS11Exception, KeyStoreException {
+
+        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                        new CK_ATTRIBUTE(CKA_KEY_TYPE) };
+        token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
+        long kType = attrs[0].getLong();
+        String keyType = null;
+        int keyLength = 0;
+
+        if (kType == CKK_RSA) {
+
+            keyType = "RSA";
+
+            attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_MODULUS) };
+            token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
+            BigInteger modulus = attrs[0].getBigInteger();
+            keyLength = modulus.bitLength();
+
+            // This check will combine our "don't care" values here
+            // with the system-wide min/max values.
+            try {
+                RSAKeyFactory.checkKeyLengths(keyLength, null,
+                    -1, Integer.MAX_VALUE);
+            } catch (InvalidKeyException e) {
+                throw new KeyStoreException(e.getMessage());
+            }
+
+            return P11Key.privateKey(session,
+                                oHandle,
+                                keyType,
+                                keyLength,
+                                null);
+
+        } else if (kType == CKK_DSA) {
+
+            keyType = "DSA";
+
+            attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
+            token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
+            BigInteger prime = attrs[0].getBigInteger();
+            keyLength = prime.bitLength();
+
+            return P11Key.privateKey(session,
+                                oHandle,
+                                keyType,
+                                keyLength,
+                                null);
+
+        } else if (kType == CKK_DH) {
+
+            keyType = "DH";
+
+            attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
+            token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
+            BigInteger prime = attrs[0].getBigInteger();
+            keyLength = prime.bitLength();
+
+            return P11Key.privateKey(session,
+                                oHandle,
+                                keyType,
+                                keyLength,
+                                null);
+
+        } else if (kType == CKK_EC) {
+
+            attrs = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_EC_PARAMS),
+            };
+            token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
+            byte[] encodedParams = attrs[0].getByteArray();
+            try {
+                ECParameterSpec params =
+                    ECUtil.getECParameterSpec(null, encodedParams);
+                keyLength = params.getCurve().getField().getFieldSize();
+            } catch (IOException e) {
+                // we do not want to accept key with unsupported parameters
+                throw new KeyStoreException("Unsupported parameters", e);
+            }
+
+            return P11Key.privateKey(session, oHandle, "EC", keyLength, null);
+
+        } else {
+            if (debug != null) {
+                debug.println("unknown key type [" + kType + "]");
+            }
+            throw new KeyStoreException("unknown key type");
+        }
+    }
+
+
+    /**
+     * XXX  On ibutton, when you C_SetAttribute(CKA_ID) for a private key
+     *      it not only changes the CKA_ID of the private key,
+     *      it changes the CKA_ID of the corresponding cert too.
+     *      And vice versa.
+     *
+     * XXX  On ibutton, CKR_DEVICE_ERROR if you C_SetAttribute(CKA_ID)
+     *      for a private key, and then try to delete the corresponding cert.
+     *      So this code reverses the order.
+     *      After the cert is first destroyed (if necessary),
+     *      then the CKA_ID of the private key can be changed successfully.
+     *
+     * @param replaceCert if true, then caller is updating alias info for
+     *                  existing cert (only update CKA_ID/CKA_LABEL).
+     *                  if false, then caller is updating cert chain
+     *                  (delete old end cert and add new chain).
+     */
+    private void updatePkey(String alias,
+                        byte[] cka_id,
+                        X509Certificate[] chain,
+                        boolean replaceCert) throws
+                KeyStoreException, CertificateException, PKCS11Exception {
+
+        // XXX
+        //
+        // always set replaceCert to true
+        //
+        // NSS does not allow resetting of CKA_LABEL on an existing cert
+        // (C_SetAttribute call succeeds, but is ignored)
+
+        replaceCert = true;
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            // first get private key object handle and hang onto it
+
+            THandle h = getTokenObject(session, ATTR_CLASS_PKEY, cka_id, null);
+            long pKeyHandle;
+            if (h.type == ATTR_CLASS_PKEY) {
+                pKeyHandle = h.handle;
+            } else {
+                throw new KeyStoreException
+                        ("expected but could not find private key " +
+                        "with CKA_ID " +
+                        getID(cka_id));
+            }
+
+            // next find existing end entity cert
+
+            h = getTokenObject(session, ATTR_CLASS_CERT, cka_id, null);
+            if (h.type != ATTR_CLASS_CERT) {
+                throw new KeyStoreException
+                        ("expected but could not find certificate " +
+                        "with CKA_ID " +
+                        getID(cka_id));
+            } else {
+                if (replaceCert) {
+                    // replacing existing cert and chain
+                    destroyChain(cka_id);
+                } else {
+                    // renaming alias for existing cert
+                    CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                        new CK_ATTRIBUTE(CKA_LABEL, alias),
+                        new CK_ATTRIBUTE(CKA_ID, alias) };
+                    token.p11.C_SetAttributeValue
+                        (session.id(), h.handle, attrs);
+                }
+            }
+
+            // add new chain
+
+            if (replaceCert) {
+                // add all certs in chain
+                storeChain(alias, chain);
+            } else {
+                // already updated alias info for existing end cert -
+                // just update CA certs
+                storeCaCerts(chain, 1);
+            }
+
+            // finally update CKA_ID for private key
+            //
+            // ibutton may have already done this (that is ok)
+
+            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                                new CK_ATTRIBUTE(CKA_ID, alias) };
+            token.p11.C_SetAttributeValue(session.id(), pKeyHandle, attrs);
+
+            if (debug != null) {
+                debug.println("updatePkey set new alias [" +
+                                alias +
+                                "] for private key entry");
+            }
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private void updateP11Pkey(String alias, CK_ATTRIBUTE attribute, P11Key key)
+                throws PKCS11Exception {
+
+        // if token key, update alias.
+        // if session key, convert to token key.
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            if (key.tokenObject == true) {
+
+                // token key - set new CKA_ID
+
+                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                                new CK_ATTRIBUTE(CKA_ID, alias) };
+                token.p11.C_SetAttributeValue
+                                (session.id(), key.keyID, attrs);
+                if (debug != null) {
+                    debug.println("updateP11Pkey set new alias [" +
+                                alias +
+                                "] for key entry");
+                }
+            } else {
+
+                // session key - convert to token key and set CKA_ID
+
+                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                    ATTR_TOKEN_TRUE,
+                    new CK_ATTRIBUTE(CKA_ID, alias),
+                };
+                if (attribute != null) {
+                    attrs = addAttribute(attrs, attribute);
+                }
+                token.p11.C_CopyObject(session.id(), key.keyID, attrs);
+                if (debug != null) {
+                    debug.println("updateP11Pkey copied private session key " +
+                                "for [" +
+                                alias +
+                                "] to token entry");
+                }
+            }
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private void storeCert(String alias, X509Certificate cert)
+                throws PKCS11Exception, CertificateException {
+
+        ArrayList<CK_ATTRIBUTE> attrList = new ArrayList<CK_ATTRIBUTE>();
+        attrList.add(ATTR_TOKEN_TRUE);
+        attrList.add(ATTR_CLASS_CERT);
+        attrList.add(ATTR_X509_CERT_TYPE);
+        attrList.add(new CK_ATTRIBUTE(CKA_SUBJECT,
+                                cert.getSubjectX500Principal().getEncoded()));
+        attrList.add(new CK_ATTRIBUTE(CKA_ISSUER,
+                                cert.getIssuerX500Principal().getEncoded()));
+        attrList.add(new CK_ATTRIBUTE(CKA_SERIAL_NUMBER,
+                                cert.getSerialNumber().toByteArray()));
+        attrList.add(new CK_ATTRIBUTE(CKA_VALUE, cert.getEncoded()));
+
+        if (alias != null) {
+            attrList.add(new CK_ATTRIBUTE(CKA_LABEL, alias));
+            attrList.add(new CK_ATTRIBUTE(CKA_ID, alias));
+        } else {
+            // ibutton requires something to be set
+            // - alias must be unique
+            attrList.add(new CK_ATTRIBUTE(CKA_ID,
+                        getID(cert.getSubjectX500Principal().getName
+                                        (X500Principal.CANONICAL), cert)));
+        }
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            token.p11.C_CreateObject(session.id(),
+                        attrList.toArray(new CK_ATTRIBUTE[attrList.size()]));
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private void storeChain(String alias, X509Certificate[] chain)
+                throws PKCS11Exception, CertificateException {
+
+        // add new chain
+        //
+        // end cert has CKA_LABEL and CKA_ID set to alias.
+        // other certs in chain have neither set.
+
+        storeCert(alias, chain[0]);
+        storeCaCerts(chain, 1);
+    }
+
+    private void storeCaCerts(X509Certificate[] chain, int start)
+                throws PKCS11Exception, CertificateException {
+
+        // do not add duplicate CA cert if already in token
+        //
+        // XXX   ibutton stores duplicate CA certs, NSS does not
+
+        Session session = null;
+        HashSet<X509Certificate> cacerts = new HashSet<X509Certificate>();
+        try {
+            session = token.getOpSession();
+            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                        ATTR_TOKEN_TRUE,
+                        ATTR_CLASS_CERT };
+            long[] handles = findObjects(session, attrs);
+
+            // load certs currently on the token
+            for (long handle : handles) {
+                cacerts.add(loadCert(session, handle));
+            }
+        } finally {
+            token.releaseSession(session);
+        }
+
+        for (int i = start; i < chain.length; i++) {
+            if (!cacerts.contains(chain[i])) {
+                storeCert(null, chain[i]);
+            } else if (debug != null) {
+                debug.println("ignoring duplicate CA cert for [" +
+                        chain[i].getSubjectX500Principal() +
+                        "]");
+            }
+        }
+    }
+
+    private void storeSkey(String alias, KeyStore.SecretKeyEntry ske)
+                throws PKCS11Exception, KeyStoreException {
+
+        SecretKey skey = ske.getSecretKey();
+        // No need to specify CKA_CLASS, CKA_KEY_TYPE, CKA_VALUE since
+        // they are handled in P11SecretKeyFactory.createKey() method.
+        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+            ATTR_SKEY_TOKEN_TRUE,
+            ATTR_PRIVATE_TRUE,
+            new CK_ATTRIBUTE(CKA_LABEL, alias),
+        };
+        try {
+            P11SecretKeyFactory.convertKey(token, skey, null, attrs);
+        } catch (InvalidKeyException ike) {
+            // re-throw KeyStoreException to match javadoc
+            throw new KeyStoreException("Cannot convert to PKCS11 keys", ike);
+        }
+
+        // update global alias map
+        aliasMap.put(alias, new AliasInfo(alias));
+
+        if (debug != null) {
+            debug.println("storeSkey created token secret key for [" +
+                          alias + "]");
+        }
+    }
+
+    private static CK_ATTRIBUTE[] addAttribute(CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE attr) {
+        int n = attrs.length;
+        CK_ATTRIBUTE[] newAttrs = new CK_ATTRIBUTE[n + 1];
+        System.arraycopy(attrs, 0, newAttrs, 0, n);
+        newAttrs[n] = attr;
+        return newAttrs;
+    }
+
+    private void storePkey(String alias, KeyStore.PrivateKeyEntry pke)
+        throws PKCS11Exception, CertificateException, KeyStoreException  {
+
+        PrivateKey key = pke.getPrivateKey();
+        CK_ATTRIBUTE[] attrs = null;
+
+        // If the key is a token object on this token, update it instead
+        // of creating a duplicate key object.
+        // Otherwise, treat a P11Key like any other key, if it is extractable.
+        if (key instanceof P11Key) {
+            P11Key p11Key = (P11Key)key;
+            if (p11Key.tokenObject && (p11Key.token == this.token)) {
+                updateP11Pkey(alias, null, p11Key);
+                storeChain(alias, (X509Certificate[])pke.getCertificateChain());
+                return;
+            }
+        }
+
+        boolean useNDB = token.config.getNssNetscapeDbWorkaround();
+        PublicKey publicKey = pke.getCertificate().getPublicKey();
+
+        if (key instanceof RSAPrivateKey) {
+
+            X509Certificate cert = (X509Certificate)pke.getCertificate();
+            attrs = getRsaPrivKeyAttrs
+                (alias, (RSAPrivateKey)key, cert.getSubjectX500Principal());
+
+        } else if (key instanceof DSAPrivateKey) {
+
+            DSAPrivateKey dsaKey = (DSAPrivateKey)key;
+
+            CK_ATTRIBUTE[] idAttrs = getIdAttributes(key, publicKey, false, useNDB);
+            if (idAttrs[0] == null) {
+                idAttrs[0] = new CK_ATTRIBUTE(CKA_ID, alias);
+            }
+
+            attrs = new CK_ATTRIBUTE[] {
+                ATTR_TOKEN_TRUE,
+                ATTR_CLASS_PKEY,
+                ATTR_PRIVATE_TRUE,
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
+                idAttrs[0],
+                new CK_ATTRIBUTE(CKA_PRIME, dsaKey.getParams().getP()),
+                new CK_ATTRIBUTE(CKA_SUBPRIME, dsaKey.getParams().getQ()),
+                new CK_ATTRIBUTE(CKA_BASE, dsaKey.getParams().getG()),
+                new CK_ATTRIBUTE(CKA_VALUE, dsaKey.getX()),
+            };
+            if (idAttrs[1] != null) {
+                attrs = addAttribute(attrs, idAttrs[1]);
+            }
+
+            attrs = token.getAttributes
+                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_DSA, attrs);
+
+            if (debug != null) {
+                debug.println("storePkey created DSA template");
+            }
+
+        } else if (key instanceof DHPrivateKey) {
+
+            DHPrivateKey dhKey = (DHPrivateKey)key;
+
+            CK_ATTRIBUTE[] idAttrs = getIdAttributes(key, publicKey, false, useNDB);
+            if (idAttrs[0] == null) {
+                idAttrs[0] = new CK_ATTRIBUTE(CKA_ID, alias);
+            }
+
+            attrs = new CK_ATTRIBUTE[] {
+                ATTR_TOKEN_TRUE,
+                ATTR_CLASS_PKEY,
+                ATTR_PRIVATE_TRUE,
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DH),
+                idAttrs[0],
+                new CK_ATTRIBUTE(CKA_PRIME, dhKey.getParams().getP()),
+                new CK_ATTRIBUTE(CKA_BASE, dhKey.getParams().getG()),
+                new CK_ATTRIBUTE(CKA_VALUE, dhKey.getX()),
+            };
+            if (idAttrs[1] != null) {
+                attrs = addAttribute(attrs, idAttrs[1]);
+            }
+
+            attrs = token.getAttributes
+                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_DH, attrs);
+
+        } else if (key instanceof ECPrivateKey) {
+
+            ECPrivateKey ecKey = (ECPrivateKey)key;
+
+            CK_ATTRIBUTE[] idAttrs = getIdAttributes(key, publicKey, false, useNDB);
+            if (idAttrs[0] == null) {
+                idAttrs[0] = new CK_ATTRIBUTE(CKA_ID, alias);
+            }
+
+            byte[] encodedParams =
+                ECUtil.encodeECParameterSpec(null, ecKey.getParams());
+            attrs = new CK_ATTRIBUTE[] {
+                ATTR_TOKEN_TRUE,
+                ATTR_CLASS_PKEY,
+                ATTR_PRIVATE_TRUE,
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
+                idAttrs[0],
+                new CK_ATTRIBUTE(CKA_VALUE, ecKey.getS()),
+                new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
+            };
+            if (idAttrs[1] != null) {
+                attrs = addAttribute(attrs, idAttrs[1]);
+            }
+
+            attrs = token.getAttributes
+                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_EC, attrs);
+
+            if (debug != null) {
+                debug.println("storePkey created EC template");
+            }
+
+        } else if (key instanceof P11Key) {
+            // sensitive/non-extractable P11Key
+            P11Key p11Key = (P11Key)key;
+            if (p11Key.token != this.token) {
+                throw new KeyStoreException
+                    ("Cannot move sensitive keys across tokens");
+            }
+            CK_ATTRIBUTE netscapeDB = null;
+            if (useNDB) {
+                // Note that this currently fails due to an NSS bug.
+                // They do not allow the CKA_NETSCAPE_DB attribute to be
+                // specified during C_CopyObject() and fail with
+                // CKR_ATTRIBUTE_READ_ONLY.
+                // But if we did not specify it, they would fail with
+                // CKA_TEMPLATE_INCOMPLETE, so leave this code in here.
+                CK_ATTRIBUTE[] idAttrs = getIdAttributes(key, publicKey, false, true);
+                netscapeDB = idAttrs[1];
+            }
+            // Update the key object.
+            updateP11Pkey(alias, netscapeDB, p11Key);
+            storeChain(alias, (X509Certificate[])pke.getCertificateChain());
+            return;
+
+        } else {
+            throw new KeyStoreException("unsupported key type: " + key);
+        }
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            // create private key entry
+            token.p11.C_CreateObject(session.id(), attrs);
+            if (debug != null) {
+                debug.println("storePkey created token key for [" +
+                                alias +
+                                "]");
+            }
+        } finally {
+            token.releaseSession(session);
+        }
+
+        storeChain(alias, (X509Certificate[])pke.getCertificateChain());
+    }
+
+    private CK_ATTRIBUTE[] getRsaPrivKeyAttrs(String alias,
+                                RSAPrivateKey key,
+                                X500Principal subject) throws PKCS11Exception {
+
+        // subject is currently ignored - could be used to set CKA_SUBJECT
+
+        CK_ATTRIBUTE[] attrs = null;
+        if (key instanceof RSAPrivateCrtKey) {
+
+            if (debug != null) {
+                debug.println("creating RSAPrivateCrtKey attrs");
+            }
+
+            RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
+
+            attrs = new CK_ATTRIBUTE[] {
+                ATTR_TOKEN_TRUE,
+                ATTR_CLASS_PKEY,
+                ATTR_PRIVATE_TRUE,
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
+                new CK_ATTRIBUTE(CKA_ID, alias),
+                new CK_ATTRIBUTE(CKA_MODULUS,
+                                rsaKey.getModulus()),
+                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT,
+                                rsaKey.getPrivateExponent()),
+                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT,
+                                rsaKey.getPublicExponent()),
+                new CK_ATTRIBUTE(CKA_PRIME_1,
+                                rsaKey.getPrimeP()),
+                new CK_ATTRIBUTE(CKA_PRIME_2,
+                                rsaKey.getPrimeQ()),
+                new CK_ATTRIBUTE(CKA_EXPONENT_1,
+                                rsaKey.getPrimeExponentP()),
+                new CK_ATTRIBUTE(CKA_EXPONENT_2,
+                                rsaKey.getPrimeExponentQ()),
+                new CK_ATTRIBUTE(CKA_COEFFICIENT,
+                                rsaKey.getCrtCoefficient()) };
+            attrs = token.getAttributes
+                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attrs);
+
+        } else {
+
+            if (debug != null) {
+                debug.println("creating RSAPrivateKey attrs");
+            }
+
+            RSAPrivateKey rsaKey = key;
+
+            attrs = new CK_ATTRIBUTE[] {
+                ATTR_TOKEN_TRUE,
+                ATTR_CLASS_PKEY,
+                ATTR_PRIVATE_TRUE,
+                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
+                new CK_ATTRIBUTE(CKA_ID, alias),
+                new CK_ATTRIBUTE(CKA_MODULUS,
+                                rsaKey.getModulus()),
+                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT,
+                                rsaKey.getPrivateExponent()) };
+            attrs = token.getAttributes
+                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attrs);
+        }
+
+        return attrs;
+    }
+
+    /**
+     * Compute the CKA_ID and/or CKA_NETSCAPE_DB attributes that should be
+     * used for this private key. It uses the same algorithm to calculate the
+     * values as NSS. The public and private keys MUST match for the result to
+     * be correct.
+     *
+     * It returns a 2 element array with CKA_ID at index 0 and CKA_NETSCAPE_DB
+     * at index 1. The boolean flags determine what is to be calculated.
+     * If false or if we could not calculate the value, that element is null.
+     *
+     * NOTE that we currently do not use the CKA_ID value calculated by this
+     * method.
+     */
+    private CK_ATTRIBUTE[] getIdAttributes(PrivateKey privateKey,
+            PublicKey publicKey, boolean id, boolean netscapeDb) {
+        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[2];
+        if ((id || netscapeDb) == false) {
+            return attrs;
+        }
+        String alg = privateKey.getAlgorithm();
+        if (id && alg.equals("RSA") && (publicKey instanceof RSAPublicKey)) {
+            // CKA_NETSCAPE_DB not needed for RSA public keys
+            BigInteger n = ((RSAPublicKey)publicKey).getModulus();
+            attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(n)));
+        } else if (alg.equals("DSA") && (publicKey instanceof DSAPublicKey)) {
+            BigInteger y = ((DSAPublicKey)publicKey).getY();
+            if (id) {
+                attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(y)));
+            }
+            if (netscapeDb) {
+                attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, y);
+            }
+        } else if (alg.equals("DH") && (publicKey instanceof DHPublicKey)) {
+            BigInteger y = ((DHPublicKey)publicKey).getY();
+            if (id) {
+                attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(y)));
+            }
+            if (netscapeDb) {
+                attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, y);
+            }
+        } else if (alg.equals("EC") && (publicKey instanceof ECPublicKey)) {
+            ECPublicKey ecPub = (ECPublicKey)publicKey;
+            ECPoint point = ecPub.getW();
+            ECParameterSpec params = ecPub.getParams();
+            byte[] encodedPoint = ECUtil.encodePoint(point, params.getCurve());
+            if (id) {
+                attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(encodedPoint));
+            }
+            if (netscapeDb) {
+                attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, encodedPoint);
+            }
+        } else {
+            throw new RuntimeException("Unknown key algorithm " + alg);
+        }
+        return attrs;
+    }
+
+    /**
+     * return true if cert destroyed
+     */
+    private boolean destroyCert(byte[] cka_id)
+                throws PKCS11Exception, KeyStoreException {
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            THandle h = getTokenObject(session, ATTR_CLASS_CERT, cka_id, null);
+            if (h.type != ATTR_CLASS_CERT) {
+                return false;
+            }
+
+            token.p11.C_DestroyObject(session.id(), h.handle);
+            if (debug != null) {
+                debug.println("destroyCert destroyed cert with CKA_ID [" +
+                                                getID(cka_id) +
+                                                "]");
+            }
+            return true;
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    /**
+     * return true if chain destroyed
+     */
+    private boolean destroyChain(byte[] cka_id)
+        throws PKCS11Exception, CertificateException, KeyStoreException {
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            THandle h = getTokenObject(session, ATTR_CLASS_CERT, cka_id, null);
+            if (h.type != ATTR_CLASS_CERT) {
+                if (debug != null) {
+                    debug.println("destroyChain could not find " +
+                        "end entity cert with CKA_ID [0x" +
+                        Functions.toHexString(cka_id) +
+                        "]");
+                }
+                return false;
+            }
+
+            X509Certificate endCert = loadCert(session, h.handle);
+            token.p11.C_DestroyObject(session.id(), h.handle);
+            if (debug != null) {
+                debug.println("destroyChain destroyed end entity cert " +
+                        "with CKA_ID [" +
+                        getID(cka_id) +
+                        "]");
+            }
+
+            // build chain following issuer->subject links
+
+            X509Certificate next = endCert;
+            while (true) {
+
+                if (next.getSubjectX500Principal().equals
+                    (next.getIssuerX500Principal())) {
+                    // self signed - done
+                    break;
+                }
+
+                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                        ATTR_TOKEN_TRUE,
+                        ATTR_CLASS_CERT,
+                        new CK_ATTRIBUTE(CKA_SUBJECT,
+                                  next.getIssuerX500Principal().getEncoded()) };
+                long[] ch = findObjects(session, attrs);
+
+                if (ch == null || ch.length == 0) {
+                    // done
+                    break;
+                } else {
+                    // if more than one found, use first
+                    if (debug != null && ch.length > 1) {
+                        debug.println("destroyChain found " +
+                                ch.length +
+                                " certificate entries for subject [" +
+                                next.getIssuerX500Principal() +
+                                "] in token - using first entry");
+                    }
+
+                    next = loadCert(session, ch[0]);
+
+                    // only delete if not part of any other chain
+
+                    attrs = new CK_ATTRIBUTE[] {
+                        ATTR_TOKEN_TRUE,
+                        ATTR_CLASS_CERT,
+                        new CK_ATTRIBUTE(CKA_ISSUER,
+                                next.getSubjectX500Principal().getEncoded()) };
+                    long[] issuers = findObjects(session, attrs);
+
+                    boolean destroyIt = false;
+                    if (issuers == null || issuers.length == 0) {
+                        // no other certs with this issuer -
+                        // destroy it
+                        destroyIt = true;
+                    } else if (issuers.length == 1) {
+                        X509Certificate iCert = loadCert(session, issuers[0]);
+                        if (next.equals(iCert)) {
+                            // only cert with issuer is itself (self-signed) -
+                            // destroy it
+                            destroyIt = true;
+                        }
+                    }
+
+                    if (destroyIt) {
+                        token.p11.C_DestroyObject(session.id(), ch[0]);
+                        if (debug != null) {
+                            debug.println
+                                ("destroyChain destroyed cert in chain " +
+                                "with subject [" +
+                                next.getSubjectX500Principal() + "]");
+                        }
+                    } else {
+                        if (debug != null) {
+                            debug.println("destroyChain did not destroy " +
+                                "shared cert in chain with subject [" +
+                                next.getSubjectX500Principal() + "]");
+                        }
+                    }
+                }
+            }
+
+            return true;
+
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    /**
+     * return true if secret key destroyed
+     */
+    private boolean destroySkey(String alias)
+                throws PKCS11Exception, KeyStoreException {
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            THandle h = getTokenObject(session, ATTR_CLASS_SKEY, null, alias);
+            if (h.type != ATTR_CLASS_SKEY) {
+                if (debug != null) {
+                    debug.println("destroySkey did not find secret key " +
+                        "with CKA_LABEL [" +
+                        alias +
+                        "]");
+                }
+                return false;
+            }
+            token.p11.C_DestroyObject(session.id(), h.handle);
+            return true;
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    /**
+     * return true if private key destroyed
+     */
+    private boolean destroyPkey(byte[] cka_id)
+                throws PKCS11Exception, KeyStoreException {
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            THandle h = getTokenObject(session, ATTR_CLASS_PKEY, cka_id, null);
+            if (h.type != ATTR_CLASS_PKEY) {
+                if (debug != null) {
+                    debug.println
+                        ("destroyPkey did not find private key with CKA_ID [" +
+                        getID(cka_id) +
+                        "]");
+                }
+                return false;
+            }
+            token.p11.C_DestroyObject(session.id(), h.handle);
+            return true;
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    /**
+     * build [alias + issuer + serialNumber] string from a cert
+     */
+    private String getID(String alias, X509Certificate cert) {
+        X500Principal issuer = cert.getIssuerX500Principal();
+        BigInteger serialNum = cert.getSerialNumber();
+
+        return alias +
+                ALIAS_SEP +
+                issuer.getName(X500Principal.CANONICAL) +
+                ALIAS_SEP +
+                serialNum.toString();
+    }
+
+    /**
+     * build CKA_ID string from bytes
+     */
+    private static String getID(byte[] bytes) {
+        boolean printable = true;
+        for (int i = 0; i < bytes.length; i++) {
+            if (!DerValue.isPrintableStringChar((char)bytes[i])) {
+                printable = false;
+                break;
+            }
+        }
+
+        if (!printable) {
+            return "0x" + Functions.toHexString(bytes);
+        } else {
+            try {
+                return new String(bytes, "UTF-8");
+            } catch (UnsupportedEncodingException uee) {
+                return "0x" + Functions.toHexString(bytes);
+            }
+        }
+    }
+
+    /**
+     * find an object on the token
+     *
+     * @param type either ATTR_CLASS_CERT, ATTR_CLASS_PKEY, or ATTR_CLASS_SKEY
+     * @param cka_id the CKA_ID if type is ATTR_CLASS_CERT or ATTR_CLASS_PKEY
+     * @param cka_label the CKA_LABEL if type is ATTR_CLASS_SKEY
+     */
+    private THandle getTokenObject(Session session,
+                                CK_ATTRIBUTE type,
+                                byte[] cka_id,
+                                String cka_label)
+                throws PKCS11Exception, KeyStoreException {
+
+        CK_ATTRIBUTE[] attrs;
+        if (type == ATTR_CLASS_SKEY) {
+            attrs = new CK_ATTRIBUTE[] {
+                        ATTR_SKEY_TOKEN_TRUE,
+                        new CK_ATTRIBUTE(CKA_LABEL, cka_label),
+                        type };
+        } else {
+            attrs = new CK_ATTRIBUTE[] {
+                        ATTR_TOKEN_TRUE,
+                        new CK_ATTRIBUTE(CKA_ID, cka_id),
+                        type };
+        }
+        long[] h = findObjects(session, attrs);
+        if (h.length == 0) {
+            if (debug != null) {
+                if (type == ATTR_CLASS_SKEY) {
+                    debug.println("getTokenObject did not find secret key " +
+                                "with CKA_LABEL [" +
+                                cka_label +
+                                "]");
+                } else if (type == ATTR_CLASS_CERT) {
+                    debug.println
+                        ("getTokenObject did not find cert with CKA_ID [" +
+                        getID(cka_id) +
+                        "]");
+                } else {
+                    debug.println("getTokenObject did not find private key " +
+                        "with CKA_ID [" +
+                        getID(cka_id) +
+                        "]");
+                }
+            }
+        } else if (h.length == 1) {
+
+            // found object handle - return it
+            return new THandle(h[0], type);
+
+        } else {
+
+            // found multiple object handles -
+            // see if token ignored CKA_LABEL during search (e.g. NSS)
+
+            if (type == ATTR_CLASS_SKEY) {
+
+                ArrayList<THandle> list = new ArrayList<THandle>(h.length);
+                for (int i = 0; i < h.length; i++) {
+
+                    CK_ATTRIBUTE[] label = new CK_ATTRIBUTE[]
+                                        { new CK_ATTRIBUTE(CKA_LABEL) };
+                    token.p11.C_GetAttributeValue(session.id(), h[i], label);
+                    if (label[0].pValue != null &&
+                        cka_label.equals(new String(label[0].getCharArray()))) {
+                        list.add(new THandle(h[i], ATTR_CLASS_SKEY));
+                    }
+                }
+                if (list.size() == 1) {
+                    // yes, there was only one CKA_LABEL that matched
+                    return list.get(0);
+                } else {
+                    throw new KeyStoreException("invalid KeyStore state: " +
+                        "found " +
+                        list.size() +
+                        " secret keys sharing CKA_LABEL [" +
+                        cka_label +
+                        "]");
+                }
+            } else if (type == ATTR_CLASS_CERT) {
+                throw new KeyStoreException("invalid KeyStore state: " +
+                        "found " +
+                        h.length +
+                        " certificates sharing CKA_ID " +
+                        getID(cka_id));
+            } else {
+                throw new KeyStoreException("invalid KeyStore state: " +
+                        "found " +
+                        h.length +
+                        " private keys sharing CKA_ID " +
+                        getID(cka_id));
+            }
+        }
+        return new THandle(NO_HANDLE, null);
+    }
+
+    /**
+     * Create a mapping of all key pairs, trusted certs, and secret keys
+     * on the token into logical KeyStore entries unambiguously
+     * accessible via an alias.
+     *
+     * If the token is removed, the map may contain stale values.
+     * KeyStore.load should be called to re-create the map.
+     *
+     * Assume all private keys and matching certs share a unique CKA_ID.
+     *
+     * Assume all secret keys have a unique CKA_LABEL.
+     *
+     * @return true if multiple certs found sharing the same CKA_LABEL
+     *          (if so, write capabilities are disabled)
+     */
+    private boolean mapLabels() throws
+                PKCS11Exception, CertificateException, KeyStoreException {
+
+        CK_ATTRIBUTE[] trustedAttr = new CK_ATTRIBUTE[] {
+                                new CK_ATTRIBUTE(CKA_TRUSTED) };
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            // get all private key CKA_IDs
+
+            ArrayList<byte[]> pkeyIDs = new ArrayList<byte[]>();
+            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                ATTR_TOKEN_TRUE,
+                ATTR_CLASS_PKEY,
+            };
+            long[] handles = findObjects(session, attrs);
+
+            for (long handle : handles) {
+                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_ID) };
+                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
+
+                if (attrs[0].pValue != null) {
+                    pkeyIDs.add(attrs[0].getByteArray());
+                }
+            }
+
+            // Get all certificates
+            //
+            // If cert does not have a CKA_LABEL nor CKA_ID, it is ignored.
+            //
+            // Get the CKA_LABEL for each cert
+            // (if the cert does not have a CKA_LABEL, use the CKA_ID).
+            //
+            // Map each cert to the its CKA_LABEL
+            // (multiple certs may be mapped to a single CKA_LABEL)
+
+            HashMap<String, HashSet<AliasInfo>> certMap =
+                                new HashMap<String, HashSet<AliasInfo>>();
+
+            attrs = new CK_ATTRIBUTE[] {
+                ATTR_TOKEN_TRUE,
+                ATTR_CLASS_CERT,
+            };
+            handles = findObjects(session, attrs);
+
+            for (long handle : handles) {
+                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_LABEL) };
+
+                String cka_label = null;
+                byte[] cka_id = null;
+                try {
+                    token.p11.C_GetAttributeValue(session.id(), handle, attrs);
+                    if (attrs[0].pValue != null) {
+                        // there is a CKA_LABEL
+                        cka_label = new String(attrs[0].getCharArray());
+                    }
+                } catch (PKCS11Exception pe) {
+                    if (pe.getErrorCode() != CKR_ATTRIBUTE_TYPE_INVALID) {
+                        throw pe;
+                    }
+
+                    // GetAttributeValue for CKA_LABEL not supported
+                    //
+                    // XXX SCA1000
+                }
+
+                // get CKA_ID
+
+                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_ID) };
+                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
+                if (attrs[0].pValue == null) {
+                    if (cka_label == null) {
+                        // no cka_label nor cka_id - ignore
+                        continue;
+                    }
+                } else {
+                    if (cka_label == null) {
+                        // use CKA_ID as CKA_LABEL
+                        cka_label = getID(attrs[0].getByteArray());
+                    }
+                    cka_id = attrs[0].getByteArray();
+                }
+
+                X509Certificate cert = loadCert(session, handle);
+
+                // get CKA_TRUSTED
+
+                boolean cka_trusted = false;
+
+                if (useSecmodTrust) {
+                    cka_trusted = Secmod.getInstance().isTrusted(cert, nssTrustType);
+                } else {
+                    if (CKA_TRUSTED_SUPPORTED) {
+                        try {
+                            token.p11.C_GetAttributeValue
+                                    (session.id(), handle, trustedAttr);
+                            cka_trusted = trustedAttr[0].getBoolean();
+                        } catch (PKCS11Exception pe) {
+                            if (pe.getErrorCode() == CKR_ATTRIBUTE_TYPE_INVALID) {
+                                // XXX  NSS, ibutton, sca1000
+                                CKA_TRUSTED_SUPPORTED = false;
+                                if (debug != null) {
+                                    debug.println
+                                            ("CKA_TRUSTED attribute not supported");
+                                }
+                            }
+                        }
+                    }
+                }
+
+                HashSet<AliasInfo> infoSet = certMap.get(cka_label);
+                if (infoSet == null) {
+                    infoSet = new HashSet<AliasInfo>(2);
+                    certMap.put(cka_label, infoSet);
+                }
+
+                // initially create private key entry AliasInfo entries -
+                // these entries will get resolved into their true
+                // entry types later
+
+                infoSet.add(new AliasInfo
+                                (cka_label,
+                                cka_id,
+                                cka_trusted,
+                                cert));
+            }
+
+            // create list secret key CKA_LABELS -
+            // if there are duplicates (either between secret keys,
+            // or between a secret key and another object),
+            // throw an exception
+            HashMap<String, AliasInfo> sKeyMap =
+                    new HashMap<String, AliasInfo>();
+
+            attrs = new CK_ATTRIBUTE[] {
+                ATTR_SKEY_TOKEN_TRUE,
+                ATTR_CLASS_SKEY,
+            };
+            handles = findObjects(session, attrs);
+
+            for (long handle : handles) {
+                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_LABEL) };
+                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
+                if (attrs[0].pValue != null) {
+
+                    // there is a CKA_LABEL
+                    String cka_label = new String(attrs[0].getCharArray());
+                    if (sKeyMap.get(cka_label) == null) {
+                        sKeyMap.put(cka_label, new AliasInfo(cka_label));
+                    } else {
+                        throw new KeyStoreException("invalid KeyStore state: " +
+                                "found multiple secret keys sharing same " +
+                                "CKA_LABEL [" +
+                                cka_label +
+                                "]");
+                    }
+                }
+            }
+
+            // update global aliasMap with alias mappings
+            ArrayList<AliasInfo> matchedCerts =
+                                mapPrivateKeys(pkeyIDs, certMap);
+            boolean sharedLabel = mapCerts(matchedCerts, certMap);
+            mapSecretKeys(sKeyMap);
+
+            return sharedLabel;
+
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    /**
+     * for each private key CKA_ID, find corresponding cert with same CKA_ID.
+     * if found cert, see if cert CKA_LABEL is unique.
+     *     if CKA_LABEL unique, map private key/cert alias to that CKA_LABEL.
+     *     if CKA_LABEL not unique, map private key/cert alias to:
+     *                   CKA_LABEL + ALIAS_SEP + ISSUER + ALIAS_SEP + SERIAL
+     * if cert not found, ignore private key
+     * (don't support private key entries without a cert chain yet)
+     *
+     * @return a list of AliasInfo entries that represents all matches
+     */
+    private ArrayList<AliasInfo> mapPrivateKeys(ArrayList<byte[]> pkeyIDs,
+                        HashMap<String, HashSet<AliasInfo>> certMap)
+                throws PKCS11Exception, CertificateException {
+
+        // reset global alias map
+        aliasMap = new HashMap<String, AliasInfo>();
+
+        // list of matched certs that we will return
+        ArrayList<AliasInfo> matchedCerts = new ArrayList<AliasInfo>();
+
+        for (byte[] pkeyID : pkeyIDs) {
+
+            // try to find a matching CKA_ID in a certificate
+
+            boolean foundMatch = false;
+            Set<String> certLabels = certMap.keySet();
+            for (String certLabel : certLabels) {
+
+                // get cert CKA_IDs (if present) for each cert
+
+                HashSet<AliasInfo> infoSet = certMap.get(certLabel);
+                for (AliasInfo aliasInfo : infoSet) {
+                    if (Arrays.equals(pkeyID, aliasInfo.id)) {
+
+                        // found private key with matching cert
+
+                        if (infoSet.size() == 1) {
+                            // unique CKA_LABEL - use certLabel as alias
+                            aliasInfo.matched = true;
+                            aliasMap.put(certLabel, aliasInfo);
+                        } else {
+                            // create new alias
+                            aliasInfo.matched = true;
+                            aliasMap.put(getID(certLabel, aliasInfo.cert),
+                                        aliasInfo);
+                        }
+                        matchedCerts.add(aliasInfo);
+                        foundMatch = true;
+                        break;
+                    }
+                }
+                if (foundMatch) {
+                    break;
+                }
+            }
+
+            if (!foundMatch) {
+                if (debug != null) {
+                    debug.println
+                        ("did not find match for private key with CKA_ID [" +
+                        getID(pkeyID) +
+                        "] (ignoring entry)");
+                }
+            }
+        }
+
+        return matchedCerts;
+    }
+
+    /**
+     * for each cert not matched with a private key but is CKA_TRUSTED:
+     *     if CKA_LABEL unique, map cert to CKA_LABEL.
+     *     if CKA_LABEL not unique, map cert to [label+issuer+serialNum]
+     *
+     * if CKA_TRUSTED not supported, treat all certs not part of a chain
+     * as trusted
+     *
+     * @return true if multiple certs found sharing the same CKA_LABEL
+     */
+    private boolean mapCerts(ArrayList<AliasInfo> matchedCerts,
+                        HashMap<String, HashSet<AliasInfo>> certMap)
+                throws PKCS11Exception, CertificateException {
+
+        // load all cert chains
+        for (AliasInfo aliasInfo : matchedCerts) {
+            Session session = null;
+            try {
+                session = token.getOpSession();
+                aliasInfo.chain = loadChain(session, aliasInfo.cert);
+            } finally {
+                token.releaseSession(session);
+            }
+        }
+
+        // find all certs in certMap not part of a cert chain
+        // - these are trusted
+
+        boolean sharedLabel = false;
+
+        Set<String> certLabels = certMap.keySet();
+        for (String certLabel : certLabels) {
+            HashSet<AliasInfo> infoSet = certMap.get(certLabel);
+            for (AliasInfo aliasInfo : infoSet) {
+
+                if (aliasInfo.matched == true) {
+                    // already found a private key match for this cert -
+                    // just continue
+                    aliasInfo.trusted = false;
+                    continue;
+                }
+
+                // cert in this aliasInfo is not matched yet
+                //
+                // if CKA_TRUSTED_SUPPORTED == true,
+                // then check if cert is trusted
+
+                if (CKA_TRUSTED_SUPPORTED) {
+                    if (aliasInfo.trusted) {
+                        // trusted certificate
+                        if (mapTrustedCert
+                                (certLabel, aliasInfo, infoSet) == true) {
+                            sharedLabel = true;
+                        }
+                    }
+                    continue;
+                }
+
+                // CKA_TRUSTED_SUPPORTED == false
+                //
+                // XXX treat all certs not part of a chain as trusted
+                // XXX
+                // XXX Unsupported
+                //
+                // boolean partOfChain = false;
+                // for (AliasInfo matchedInfo : matchedCerts) {
+                //     for (int i = 0; i < matchedInfo.chain.length; i++) {
+                //      if (matchedInfo.chain[i].equals(aliasInfo.cert)) {
+                //          partOfChain = true;
+                //          break;
+                //      }
+                //     }
+                //     if (partOfChain) {
+                //      break;
+                //     }
+                // }
+                //
+                // if (!partOfChain) {
+                //     if (mapTrustedCert(certLabel,aliasInfo,infoSet) == true){
+                //      sharedLabel = true;
+                //     }
+                // } else {
+                //    if (debug != null) {
+                //      debug.println("ignoring unmatched/untrusted cert " +
+                //          "that is part of cert chain - cert subject is [" +
+                //          aliasInfo.cert.getSubjectX500Principal().getName
+                //                              (X500Principal.CANONICAL) +
+                //          "]");
+                //     }
+                // }
+            }
+        }
+
+        return sharedLabel;
+    }
+
+    private boolean mapTrustedCert(String certLabel,
+                                AliasInfo aliasInfo,
+                                HashSet<AliasInfo> infoSet) {
+
+        boolean sharedLabel = false;
+
+        aliasInfo.type = ATTR_CLASS_CERT;
+        aliasInfo.trusted = true;
+        if (infoSet.size() == 1) {
+            // unique CKA_LABEL - use certLabel as alias
+            aliasMap.put(certLabel, aliasInfo);
+        } else {
+            // create new alias
+            sharedLabel = true;
+            aliasMap.put(getID(certLabel, aliasInfo.cert), aliasInfo);
+        }
+
+        return sharedLabel;
+    }
+
+    /**
+     * If the secret key shares a CKA_LABEL with another entry,
+     * throw an exception
+     */
+    private void mapSecretKeys(HashMap<String, AliasInfo> sKeyMap)
+                throws KeyStoreException {
+        for (String label : sKeyMap.keySet()) {
+            if (aliasMap.containsKey(label)) {
+                throw new KeyStoreException("invalid KeyStore state: " +
+                        "found secret key sharing CKA_LABEL [" +
+                        label +
+                        "] with another token object");
+            }
+        }
+        aliasMap.putAll(sKeyMap);
+    }
+
+    private void dumpTokenMap() {
+        Set<String> aliases = aliasMap.keySet();
+        System.out.println("Token Alias Map:");
+        if (aliases.isEmpty()) {
+            System.out.println("  [empty]");
+        } else {
+            for (String s : aliases) {
+                System.out.println("  " + s + aliasMap.get(s));
+            }
+        }
+    }
+
+    private void checkWrite() throws KeyStoreException {
+        if (writeDisabled) {
+            throw new KeyStoreException
+                ("This PKCS11KeyStore does not support write capabilities");
+        }
+    }
+
+    private final static long[] LONG0 = new long[0];
+
+    private static long[] findObjects(Session session, CK_ATTRIBUTE[] attrs)
+            throws PKCS11Exception {
+        Token token = session.token;
+        long[] handles = LONG0;
+        token.p11.C_FindObjectsInit(session.id(), attrs);
+        while (true) {
+            long[] h = token.p11.C_FindObjects(session.id(), FINDOBJECTS_MAX);
+            if (h.length == 0) {
+                break;
+            }
+            handles = P11Util.concat(handles, h);
+        }
+        token.p11.C_FindObjectsFinal(session.id());
+        return handles;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,269 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.util.*;
+import java.nio.ByteBuffer;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.MacSpi;
+
+import sun.nio.ch.DirectBuffer;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * MAC implementation class. This class currently supports HMAC using
+ * MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 and the SSL3 MAC
+ * using MD5 and SHA-1.
+ *
+ * Note that unlike other classes (e.g. Signature), this does not
+ * composite various operations if the token only supports part of the
+ * required functionality. The MAC implementations in SunJCE already
+ * do exactly that by implementing an MAC on top of MessageDigests. We
+ * could not do any better than they.
+ *
+ * @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;
+
+    // key instance used, if operation active
+    private P11Key p11Key;
+
+    // associated session, if any
+    private Session session;
+
+    // state, one of S_* above
+    private int state;
+
+    // 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;
+        case (int)CKM_SHA_1_HMAC:
+            macLength = 20;
+            break;
+        case (int)CKM_SHA224_HMAC:
+            macLength = 28;
+            break;
+        case (int)CKM_SHA256_HMAC:
+            macLength = 32;
+            break;
+        case (int)CKM_SHA384_HMAC:
+            macLength = 48;
+            break;
+        case (int)CKM_SHA512_HMAC:
+            macLength = 64;
+            break;
+        case (int)CKM_SSL3_MD5_MAC:
+            macLength = 16;
+            params = Long.valueOf(16);
+            break;
+        case (int)CKM_SSL3_SHA1_MAC:
+            macLength = 20;
+            params = Long.valueOf(20);
+            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();
+        }
+    }
+
+    private void cancelOperation() {
+        token.ensureValid();
+        if (state == S_UNINIT) {
+            return;
+        }
+        state = S_UNINIT;
+        if ((session == null) || (token.explicitCancel == false)) {
+            return;
+        }
+        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) {
+            return;
+        }
+        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;
+        }
+    }
+
+    // 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);
+        }
+    }
+
+    // see JCE spec
+    protected void engineInit(Key key, AlgorithmParameterSpec params)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        if (params != null) {
+            throw new InvalidAlgorithmParameterException
+                ("Parameters not supported");
+        }
+        cancelOperation();
+        p11Key = P11SecretKeyFactory.convertKey(token, key, algorithm);
+        try {
+            initialize();
+        } 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;
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("doFinal() failed", e);
+        } finally {
+            session = token.releaseSession(session);
+        }
+    }
+
+    // see JCE spec
+    protected void engineUpdate(byte input) {
+        if (oneByte == null) {
+           oneByte = new byte[1];
+        }
+        oneByte[0] = input;
+        engineUpdate(oneByte, 0, 1);
+    }
+
+    // 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);
+        }
+    }
+
+    // see JCE spec
+    protected void engineUpdate(ByteBuffer byteBuffer) {
+        try {
+            ensureInitialized();
+            int len = byteBuffer.remaining();
+            if (len <= 0) {
+                return;
+            }
+            if (byteBuffer instanceof DirectBuffer == false) {
+                super.engineUpdate(byteBuffer);
+                return;
+            }
+            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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSACipher.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,677 @@
+/*
+ * Copyright (c) 2003, 2015, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.*;
+
+import java.util.Locale;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
+import sun.security.util.KeyUtil;
+
+/**
+ * RSA Cipher implementation class. We currently only support
+ * PKCS#1 v1.5 padding on top of CKM_RSA_PKCS.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11RSACipher extends CipherSpi {
+
+    // minimum length of PKCS#1 v1.5 padding
+    private final static int PKCS1_MIN_PADDING_LENGTH = 11;
+
+    // constant byte[] of length 0
+    private final static byte[] B0 = new byte[0];
+
+    // mode constant for public key encryption
+    private final static int MODE_ENCRYPT = 1;
+    // mode constant for private key decryption
+    private final static int MODE_DECRYPT = 2;
+    // mode constant for private key encryption (signing)
+    private final static int MODE_SIGN    = 3;
+    // mode constant for public key decryption (verifying)
+    private final static int MODE_VERIFY  = 4;
+
+    // padding type constant for NoPadding
+    private final static int PAD_NONE = 1;
+    // padding type constant for PKCS1Padding
+    private final static int PAD_PKCS1 = 2;
+
+    // token instance
+    private final Token token;
+
+    // algorithm name (always "RSA")
+    private final String algorithm;
+
+    // mechanism id
+    private final long mechanism;
+
+    // associated session, if any
+    private Session session;
+
+    // mode, one of MODE_* above
+    private int mode;
+
+    // padding, one of PAD_* above
+    private int padType;
+
+    private byte[] buffer;
+    private int bufOfs;
+
+    // key, if init() was called
+    private P11Key p11Key;
+
+    // flag indicating whether an operation is initialized
+    private boolean initialized;
+
+    // maximum input data size allowed
+    // for decryption, this is the length of the key
+    // for encryption, length of the key minus minimum padding length
+    private int maxInputSize;
+
+    // maximum output size. this is the length of the key
+    private int outputSize;
+
+    // cipher parameter for TLS RSA premaster secret
+    private AlgorithmParameterSpec spec = null;
+
+    // the source of randomness
+    private SecureRandom random;
+
+    P11RSACipher(Token token, String algorithm, long mechanism)
+            throws PKCS11Exception {
+        super();
+        this.token = token;
+        this.algorithm = "RSA";
+        this.mechanism = mechanism;
+    }
+
+    // modes do not make sense for RSA, but allow ECB
+    // see JCE spec
+    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
+        if (mode.equalsIgnoreCase("ECB") == false) {
+            throw new NoSuchAlgorithmException("Unsupported mode " + mode);
+        }
+    }
+
+    protected void engineSetPadding(String padding)
+            throws NoSuchPaddingException {
+        String lowerPadding = padding.toLowerCase(Locale.ENGLISH);
+        if (lowerPadding.equals("pkcs1padding")) {
+            padType = PAD_PKCS1;
+        } else if (lowerPadding.equals("nopadding")) {
+            padType = PAD_NONE;
+        } else {
+            throw new NoSuchPaddingException("Unsupported padding " + padding);
+        }
+    }
+
+    // return 0 as block size, we are not a block cipher
+    // see JCE spec
+    protected int engineGetBlockSize() {
+        return 0;
+    }
+
+    // return the output size
+    // see JCE spec
+    protected int engineGetOutputSize(int inputLen) {
+        return outputSize;
+    }
+
+    // no IV, return null
+    // see JCE spec
+    protected byte[] engineGetIV() {
+        return null;
+    }
+
+    // no parameters, return null
+    // see JCE spec
+    protected AlgorithmParameters engineGetParameters() {
+        return null;
+    }
+
+    // see JCE spec
+    protected void engineInit(int opmode, Key key, SecureRandom random)
+            throws InvalidKeyException {
+        implInit(opmode, key);
+    }
+
+    // see JCE spec
+    @SuppressWarnings("deprecation")
+    protected void engineInit(int opmode, Key key,
+            AlgorithmParameterSpec params, SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        if (params != null) {
+            if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
+                throw new InvalidAlgorithmParameterException(
+                        "Parameters not supported");
+            }
+            spec = params;
+            this.random = random;   // for TLS RSA premaster secret
+        }
+        implInit(opmode, key);
+    }
+
+    // see JCE spec
+    protected void engineInit(int opmode, Key key, AlgorithmParameters params,
+            SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        if (params != null) {
+            throw new InvalidAlgorithmParameterException(
+                        "Parameters not supported");
+        }
+        implInit(opmode, key);
+    }
+
+    private void implInit(int opmode, Key key) throws InvalidKeyException {
+        cancelOperation();
+        p11Key = P11KeyFactory.convertKey(token, key, algorithm);
+        boolean encrypt;
+        if (opmode == Cipher.ENCRYPT_MODE) {
+            encrypt = true;
+        } else if (opmode == Cipher.DECRYPT_MODE) {
+            encrypt = false;
+        } else if (opmode == Cipher.WRAP_MODE) {
+            if (p11Key.isPublic() == false) {
+                throw new InvalidKeyException
+                                ("Wrap has to be used with public keys");
+            }
+            // No further setup needed for C_Wrap(). We'll initialize later if
+            // we can't use C_Wrap().
+            return;
+        } else if (opmode == Cipher.UNWRAP_MODE) {
+            if (p11Key.isPrivate() == false) {
+                throw new InvalidKeyException
+                                ("Unwrap has to be used with private keys");
+            }
+            // No further setup needed for C_Unwrap(). We'll initialize later
+            // if we can't use C_Unwrap().
+            return;
+        } else {
+            throw new InvalidKeyException("Unsupported mode: " + opmode);
+        }
+        if (p11Key.isPublic()) {
+            mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
+        } else if (p11Key.isPrivate()) {
+            mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
+        } else {
+            throw new InvalidKeyException("Unknown key type: " + p11Key);
+        }
+        int n = (p11Key.length() + 7) >> 3;
+        outputSize = n;
+        buffer = new byte[n];
+        maxInputSize = ((padType == PAD_PKCS1 && encrypt) ?
+                            (n - PKCS1_MIN_PADDING_LENGTH) : n);
+        try {
+            initialize();
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("init() failed", e);
+        }
+    }
+
+    private void cancelOperation() {
+        token.ensureValid();
+        if (initialized == false) {
+            return;
+        }
+        initialized = false;
+        if ((session == null) || (token.explicitCancel == false)) {
+            return;
+        }
+        if (session.hasObjects() == false) {
+            session = token.killSession(session);
+            return;
+        }
+        try {
+            PKCS11 p11 = token.p11;
+            int inLen = maxInputSize;
+            int outLen = buffer.length;
+            switch (mode) {
+            case MODE_ENCRYPT:
+                p11.C_Encrypt
+                        (session.id(), buffer, 0, inLen, buffer, 0, outLen);
+                break;
+            case MODE_DECRYPT:
+                p11.C_Decrypt
+                        (session.id(), buffer, 0, inLen, buffer, 0, outLen);
+                break;
+            case MODE_SIGN:
+                byte[] tmpBuffer = new byte[maxInputSize];
+                p11.C_Sign
+                        (session.id(), tmpBuffer);
+                break;
+            case MODE_VERIFY:
+                p11.C_VerifyRecover
+                        (session.id(), buffer, 0, inLen, buffer, 0, outLen);
+                break;
+            default:
+                throw new ProviderException("internal error");
+            }
+        } catch (PKCS11Exception e) {
+            // XXX ensure this always works, ignore error
+        }
+    }
+
+    private void ensureInitialized() throws PKCS11Exception {
+        token.ensureValid();
+        if (initialized == false) {
+            initialize();
+        }
+    }
+
+    private void initialize() throws PKCS11Exception {
+        if (session == null) {
+            session = token.getOpSession();
+        }
+        PKCS11 p11 = token.p11;
+        CK_MECHANISM ckMechanism = new CK_MECHANISM(mechanism);
+        switch (mode) {
+        case MODE_ENCRYPT:
+            p11.C_EncryptInit(session.id(), ckMechanism, p11Key.keyID);
+            break;
+        case MODE_DECRYPT:
+            p11.C_DecryptInit(session.id(), ckMechanism, p11Key.keyID);
+            break;
+        case MODE_SIGN:
+            p11.C_SignInit(session.id(), ckMechanism, p11Key.keyID);
+            break;
+        case MODE_VERIFY:
+            p11.C_VerifyRecoverInit(session.id(), ckMechanism, p11Key.keyID);
+            break;
+        default:
+            throw new AssertionError("internal error");
+        }
+        bufOfs = 0;
+        initialized = true;
+    }
+
+    private void implUpdate(byte[] in, int inOfs, int inLen) {
+        try {
+            ensureInitialized();
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("update() failed", e);
+        }
+        if ((inLen == 0) || (in == null)) {
+            return;
+        }
+        if (bufOfs + inLen > maxInputSize) {
+            bufOfs = maxInputSize + 1;
+            return;
+        }
+        System.arraycopy(in, inOfs, buffer, bufOfs, inLen);
+        bufOfs += inLen;
+    }
+
+    private int implDoFinal(byte[] out, int outOfs, int outLen)
+            throws BadPaddingException, IllegalBlockSizeException {
+        if (bufOfs > maxInputSize) {
+            throw new IllegalBlockSizeException("Data must not be longer "
+                + "than " + maxInputSize + " bytes");
+        }
+        try {
+            ensureInitialized();
+            PKCS11 p11 = token.p11;
+            int n;
+            switch (mode) {
+            case MODE_ENCRYPT:
+                n = p11.C_Encrypt
+                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
+                break;
+            case MODE_DECRYPT:
+                n = p11.C_Decrypt
+                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
+                break;
+            case MODE_SIGN:
+                byte[] tmpBuffer = new byte[bufOfs];
+                System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
+                tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
+                if (tmpBuffer.length > outLen) {
+                    throw new BadPaddingException(
+                        "Output buffer (" + outLen + ") is too small to " +
+                        "hold the produced data (" + tmpBuffer.length + ")");
+                }
+                System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
+                n = tmpBuffer.length;
+                break;
+            case MODE_VERIFY:
+                n = p11.C_VerifyRecover
+                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
+                break;
+            default:
+                throw new ProviderException("internal error");
+            }
+            return n;
+        } catch (PKCS11Exception e) {
+            throw (BadPaddingException)new BadPaddingException
+                ("doFinal() failed").initCause(e);
+        } finally {
+            initialized = false;
+            session = token.releaseSession(session);
+        }
+    }
+
+    // see JCE spec
+    protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
+        implUpdate(in, inOfs, inLen);
+        return B0;
+    }
+
+    // see JCE spec
+    protected int engineUpdate(byte[] in, int inOfs, int inLen,
+            byte[] out, int outOfs) throws ShortBufferException {
+        implUpdate(in, inOfs, inLen);
+        return 0;
+    }
+
+    // see JCE spec
+    protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
+            throws IllegalBlockSizeException, BadPaddingException {
+        implUpdate(in, inOfs, inLen);
+        int n = implDoFinal(buffer, 0, buffer.length);
+        byte[] out = new byte[n];
+        System.arraycopy(buffer, 0, out, 0, n);
+        return out;
+    }
+
+    // see JCE spec
+    protected int engineDoFinal(byte[] in, int inOfs, int inLen,
+            byte[] out, int outOfs) throws ShortBufferException,
+            IllegalBlockSizeException, BadPaddingException {
+        implUpdate(in, inOfs, inLen);
+        return implDoFinal(out, outOfs, out.length - outOfs);
+    }
+
+    private byte[] doFinal() throws BadPaddingException,
+            IllegalBlockSizeException {
+        byte[] t = new byte[2048];
+        int n = implDoFinal(t, 0, t.length);
+        byte[] out = new byte[n];
+        System.arraycopy(t, 0, out, 0, n);
+        return out;
+    }
+
+    // see JCE spec
+    protected byte[] engineWrap(Key key) throws InvalidKeyException,
+            IllegalBlockSizeException {
+        String keyAlg = key.getAlgorithm();
+        P11Key sKey = null;
+        try {
+            // The conversion may fail, e.g. trying to wrap an AES key on
+            // a token that does not support AES, or when the key size is
+            // not within the range supported by the token.
+            sKey = P11SecretKeyFactory.convertKey(token, key, keyAlg);
+        } catch (InvalidKeyException ike) {
+            byte[] toBeWrappedKey = key.getEncoded();
+            if (toBeWrappedKey == null) {
+                throw new InvalidKeyException
+                        ("wrap() failed, no encoding available", ike);
+            }
+            // Directly encrypt the key encoding when key conversion failed
+            implInit(Cipher.ENCRYPT_MODE, p11Key);
+            implUpdate(toBeWrappedKey, 0, toBeWrappedKey.length);
+            try {
+                return doFinal();
+            } catch (BadPaddingException bpe) {
+                // should not occur
+                throw new InvalidKeyException("wrap() failed", bpe);
+            } finally {
+                // Restore original mode
+                implInit(Cipher.WRAP_MODE, p11Key);
+            }
+        }
+        Session s = null;
+        try {
+            s = token.getOpSession();
+            return token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism),
+                p11Key.keyID, sKey.keyID);
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("wrap() failed", e);
+        } finally {
+            token.releaseSession(s);
+        }
+    }
+
+    // see JCE spec
+    @SuppressWarnings("deprecation")
+    protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
+            int type) throws InvalidKeyException, NoSuchAlgorithmException {
+
+        boolean isTlsRsaPremasterSecret =
+                algorithm.equals("TlsRsaPremasterSecret");
+        Exception failover = null;
+
+        // Should C_Unwrap be preferred for non-TLS RSA premaster secret?
+        if (token.supportsRawSecretKeyImport()) {
+            // XXX implement unwrap using C_Unwrap() for all keys
+            implInit(Cipher.DECRYPT_MODE, p11Key);
+            try {
+                if (wrappedKey.length > maxInputSize) {
+                    throw new InvalidKeyException("Key is too long for unwrapping");
+                }
+
+                byte[] encoded = null;
+                implUpdate(wrappedKey, 0, wrappedKey.length);
+                try {
+                    encoded = doFinal();
+                } catch (BadPaddingException e) {
+                    if (isTlsRsaPremasterSecret) {
+                        failover = e;
+                    } else {
+                        throw new InvalidKeyException("Unwrapping failed", e);
+                    }
+                } catch (IllegalBlockSizeException e) {
+                    // should not occur, handled with length check above
+                    throw new InvalidKeyException("Unwrapping failed", e);
+                }
+
+                if (isTlsRsaPremasterSecret) {
+                    if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
+                        throw new IllegalStateException(
+                                "No TlsRsaPremasterSecretParameterSpec specified");
+                    }
+
+                    // polish the TLS premaster secret
+                    TlsRsaPremasterSecretParameterSpec psps =
+                            (TlsRsaPremasterSecretParameterSpec)spec;
+                    encoded = KeyUtil.checkTlsPreMasterSecretKey(
+                            psps.getClientVersion(), psps.getServerVersion(),
+                            random, encoded, (failover != null));
+                }
+
+                return ConstructKeys.constructKey(encoded, algorithm, type);
+            } finally {
+                // Restore original mode
+                implInit(Cipher.UNWRAP_MODE, p11Key);
+            }
+        } else {
+            Session s = null;
+            SecretKey secretKey = null;
+            try {
+                try {
+                    s = token.getObjSession();
+                    long keyType = CKK_GENERIC_SECRET;
+                    CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                            new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
+                            new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
+                        };
+                    attributes = token.getAttributes(
+                            O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
+                    long keyID = token.p11.C_UnwrapKey(s.id(),
+                            new CK_MECHANISM(mechanism), p11Key.keyID,
+                            wrappedKey, attributes);
+                    secretKey = P11Key.secretKey(s, keyID,
+                            algorithm, 48 << 3, attributes);
+                } catch (PKCS11Exception e) {
+                    if (isTlsRsaPremasterSecret) {
+                        failover = e;
+                    } else {
+                        throw new InvalidKeyException("unwrap() failed", e);
+                    }
+                }
+
+                if (isTlsRsaPremasterSecret) {
+                    TlsRsaPremasterSecretParameterSpec psps =
+                            (TlsRsaPremasterSecretParameterSpec)spec;
+
+                    // Please use the tricky failover as the parameter so that
+                    // smart compiler won't dispose the unused variable.
+                    secretKey = polishPreMasterSecretKey(token, s,
+                            failover, secretKey,
+                            psps.getClientVersion(), psps.getServerVersion());
+                }
+
+                return secretKey;
+            } finally {
+                token.releaseSession(s);
+            }
+        }
+    }
+
+    // see JCE spec
+    protected int engineGetKeySize(Key key) throws InvalidKeyException {
+        int n = P11KeyFactory.convertKey(token, key, algorithm).length();
+        return n;
+    }
+
+    private static SecretKey polishPreMasterSecretKey(
+            Token token, Session session,
+            Exception failover, SecretKey unwrappedKey,
+            int clientVersion, int serverVersion) {
+
+        SecretKey newKey;
+        CK_VERSION version = new CK_VERSION(
+                (clientVersion >>> 8) & 0xFF, clientVersion & 0xFF);
+        try {
+            CK_ATTRIBUTE[] attributes = token.getAttributes(
+                    O_GENERATE, CKO_SECRET_KEY,
+                    CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
+            long keyID = token.p11.C_GenerateKey(session.id(),
+                    new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version),
+                    attributes);
+            newKey = P11Key.secretKey(session,
+                    keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
+        } catch (PKCS11Exception e) {
+            throw new ProviderException(
+                    "Could not generate premaster secret", e);
+        }
+
+        return (failover == null) ? unwrappedKey : newKey;
+    }
+
+}
+
+final class ConstructKeys {
+    /**
+     * Construct a public key from its encoding.
+     *
+     * @param encodedKey the encoding of a public key.
+     *
+     * @param encodedKeyAlgorithm the algorithm the encodedKey is for.
+     *
+     * @return a public key constructed from the encodedKey.
+     */
+    private static final PublicKey constructPublicKey(byte[] encodedKey,
+            String encodedKeyAlgorithm)
+            throws InvalidKeyException, NoSuchAlgorithmException {
+        try {
+            KeyFactory keyFactory =
+                KeyFactory.getInstance(encodedKeyAlgorithm);
+            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
+            return keyFactory.generatePublic(keySpec);
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new NoSuchAlgorithmException("No installed providers " +
+                                               "can create keys for the " +
+                                               encodedKeyAlgorithm +
+                                               "algorithm", nsae);
+        } catch (InvalidKeySpecException ike) {
+            throw new InvalidKeyException("Cannot construct public key", ike);
+        }
+    }
+
+    /**
+     * Construct a private key from its encoding.
+     *
+     * @param encodedKey the encoding of a private key.
+     *
+     * @param encodedKeyAlgorithm the algorithm the wrapped key is for.
+     *
+     * @return a private key constructed from the encodedKey.
+     */
+    private static final PrivateKey constructPrivateKey(byte[] encodedKey,
+            String encodedKeyAlgorithm) throws InvalidKeyException,
+            NoSuchAlgorithmException {
+        try {
+            KeyFactory keyFactory =
+                KeyFactory.getInstance(encodedKeyAlgorithm);
+            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
+            return keyFactory.generatePrivate(keySpec);
+        } catch (NoSuchAlgorithmException nsae) {
+            throw new NoSuchAlgorithmException("No installed providers " +
+                                               "can create keys for the " +
+                                               encodedKeyAlgorithm +
+                                               "algorithm", nsae);
+        } catch (InvalidKeySpecException ike) {
+            throw new InvalidKeyException("Cannot construct private key", ike);
+        }
+    }
+
+    /**
+     * Construct a secret key from its encoding.
+     *
+     * @param encodedKey the encoding of a secret key.
+     *
+     * @param encodedKeyAlgorithm the algorithm the secret key is for.
+     *
+     * @return a secret key constructed from the encodedKey.
+     */
+    private static final SecretKey constructSecretKey(byte[] encodedKey,
+            String encodedKeyAlgorithm) {
+        return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
+    }
+
+    static final Key constructKey(byte[] encoding, String keyAlgorithm,
+            int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
+        switch (keyType) {
+        case Cipher.SECRET_KEY:
+            return constructSecretKey(encoding, keyAlgorithm);
+        case Cipher.PRIVATE_KEY:
+            return constructPrivateKey(encoding, keyAlgorithm);
+        case Cipher.PUBLIC_KEY:
+            return constructPublicKey(encoding, keyAlgorithm);
+        default:
+            throw new InvalidKeyException("Unknown keytype " + keyType);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2003, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.math.BigInteger;
+
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+import sun.security.rsa.RSAKeyFactory;
+
+/**
+ * RSA KeyFactory implementation.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11RSAKeyFactory extends P11KeyFactory {
+
+    P11RSAKeyFactory(Token token, String algorithm) {
+        super(token, algorithm);
+    }
+
+    PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
+        try {
+            if (key instanceof RSAPublicKey) {
+                RSAPublicKey rsaKey = (RSAPublicKey)key;
+                return generatePublic(
+                    rsaKey.getModulus(),
+                    rsaKey.getPublicExponent()
+                );
+            } else if ("X.509".equals(key.getFormat())) {
+                // let SunRsaSign provider parse for us, then recurse
+                byte[] encoded = key.getEncoded();
+                key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
+                return implTranslatePublicKey(key);
+            } else {
+                throw new InvalidKeyException("PublicKey must be instance "
+                        + "of RSAPublicKey or have X.509 encoding");
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create RSA public key", e);
+        }
+    }
+
+    PrivateKey implTranslatePrivateKey(PrivateKey key)
+            throws InvalidKeyException {
+        try {
+            if (key instanceof RSAPrivateCrtKey) {
+                RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
+                return generatePrivate(
+                    rsaKey.getModulus(),
+                    rsaKey.getPublicExponent(),
+                    rsaKey.getPrivateExponent(),
+                    rsaKey.getPrimeP(),
+                    rsaKey.getPrimeQ(),
+                    rsaKey.getPrimeExponentP(),
+                    rsaKey.getPrimeExponentQ(),
+                    rsaKey.getCrtCoefficient()
+                );
+            } else if (key instanceof RSAPrivateKey) {
+                RSAPrivateKey rsaKey = (RSAPrivateKey)key;
+                return generatePrivate(
+                    rsaKey.getModulus(),
+                    rsaKey.getPrivateExponent()
+                );
+            } else if ("PKCS#8".equals(key.getFormat())) {
+                // let SunRsaSign provider parse for us, then recurse
+                byte[] encoded = key.getEncoded();
+                key = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
+                return implTranslatePrivateKey(key);
+            } else {
+                throw new InvalidKeyException("Private key must be instance "
+                        + "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
+            }
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create RSA private key", e);
+        }
+    }
+
+    // see JCA spec
+    protected PublicKey engineGeneratePublic(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec instanceof X509EncodedKeySpec) {
+            try {
+                byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
+                PublicKey key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
+                return implTranslatePublicKey(key);
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException
+                        ("Could not create RSA public key", e);
+            }
+        }
+        if (keySpec instanceof RSAPublicKeySpec == false) {
+            throw new InvalidKeySpecException("Only RSAPublicKeySpec and "
+                + "X509EncodedKeySpec supported for RSA public keys");
+        }
+        try {
+            RSAPublicKeySpec rs = (RSAPublicKeySpec)keySpec;
+            return generatePublic(
+                rs.getModulus(),
+                rs.getPublicExponent()
+            );
+        } catch (PKCS11Exception | InvalidKeyException e) {
+            throw new InvalidKeySpecException
+                ("Could not create RSA public key", e);
+        }
+    }
+
+    // see JCA spec
+    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec instanceof PKCS8EncodedKeySpec) {
+            try {
+                byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
+                PrivateKey key =
+                        sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
+                return implTranslatePrivateKey(key);
+            } catch (GeneralSecurityException e) {
+                throw new InvalidKeySpecException
+                        ("Could not create RSA private key", e);
+            }
+        }
+        try {
+            if (keySpec instanceof RSAPrivateCrtKeySpec) {
+                RSAPrivateCrtKeySpec rs = (RSAPrivateCrtKeySpec)keySpec;
+                return generatePrivate(
+                    rs.getModulus(),
+                    rs.getPublicExponent(),
+                    rs.getPrivateExponent(),
+                    rs.getPrimeP(),
+                    rs.getPrimeQ(),
+                    rs.getPrimeExponentP(),
+                    rs.getPrimeExponentQ(),
+                    rs.getCrtCoefficient()
+                );
+            } else if (keySpec instanceof RSAPrivateKeySpec) {
+                RSAPrivateKeySpec rs = (RSAPrivateKeySpec)keySpec;
+                return generatePrivate(
+                    rs.getModulus(),
+                    rs.getPrivateExponent()
+                );
+            } else {
+                throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
+                    + "and PKCS8EncodedKeySpec supported for RSA private keys");
+            }
+        } catch (PKCS11Exception | InvalidKeyException e) {
+            throw new InvalidKeySpecException
+                ("Could not create RSA private key", e);
+        }
+    }
+
+    private PublicKey generatePublic(BigInteger n, BigInteger e)
+            throws PKCS11Exception, InvalidKeyException {
+        RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
+            new CK_ATTRIBUTE(CKA_MODULUS, n),
+            new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PUBLIC_KEY, CKK_RSA, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.publicKey
+                (session, keyID, "RSA", n.bitLength(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private PrivateKey generatePrivate(BigInteger n, BigInteger d)
+            throws PKCS11Exception, InvalidKeyException {
+        RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024);
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
+            new CK_ATTRIBUTE(CKA_MODULUS, n),
+            new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.privateKey
+                (session,  keyID, "RSA", n.bitLength(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private PrivateKey generatePrivate(BigInteger n, BigInteger e,
+            BigInteger d, BigInteger p, BigInteger q, BigInteger pe,
+            BigInteger qe, BigInteger coeff) throws PKCS11Exception,
+            InvalidKeyException {
+        RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
+        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
+            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
+            new CK_ATTRIBUTE(CKA_MODULUS, n),
+            new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),
+            new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),
+            new CK_ATTRIBUTE(CKA_PRIME_1, p),
+            new CK_ATTRIBUTE(CKA_PRIME_2, q),
+            new CK_ATTRIBUTE(CKA_EXPONENT_1, pe),
+            new CK_ATTRIBUTE(CKA_EXPONENT_2, qe),
+            new CK_ATTRIBUTE(CKA_COEFFICIENT, coeff),
+        };
+        attributes = token.getAttributes
+                (O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            return P11Key.privateKey
+                (session, keyID, "RSA", n.bitLength(), attributes);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
+        if (RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_MODULUS),
+                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            KeySpec spec = new RSAPublicKeySpec(
+                attributes[0].getBigInteger(),
+                attributes[1].getBigInteger()
+            );
+            return keySpec.cast(spec);
+        } else { // X.509 handled in superclass
+            throw new InvalidKeySpecException("Only RSAPublicKeySpec and "
+                + "X509EncodedKeySpec supported for RSA public keys");
+        }
+    }
+
+    <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
+            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
+        if (RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_MODULUS),
+                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
+                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
+                new CK_ATTRIBUTE(CKA_PRIME_1),
+                new CK_ATTRIBUTE(CKA_PRIME_2),
+                new CK_ATTRIBUTE(CKA_EXPONENT_1),
+                new CK_ATTRIBUTE(CKA_EXPONENT_2),
+                new CK_ATTRIBUTE(CKA_COEFFICIENT),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            KeySpec spec = new RSAPrivateCrtKeySpec(
+                attributes[0].getBigInteger(),
+                attributes[1].getBigInteger(),
+                attributes[2].getBigInteger(),
+                attributes[3].getBigInteger(),
+                attributes[4].getBigInteger(),
+                attributes[5].getBigInteger(),
+                attributes[6].getBigInteger(),
+                attributes[7].getBigInteger()
+            );
+            return keySpec.cast(spec);
+        } else if (RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
+            session[0] = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_MODULUS),
+                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
+            };
+            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
+            KeySpec spec = new RSAPrivateKeySpec(
+                attributes[0].getBigInteger(),
+                attributes[1].getBigInteger()
+            );
+            return keySpec.cast(spec);
+        } else { // PKCS#8 handled in superclass
+            throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
+                + "and PKCS8EncodedKeySpec supported for RSA private keys");
+        }
+    }
+
+    KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
+        return KeyFactory.getInstance("RSA", P11Util.getSunRsaSignProvider());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2003, 2011, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.util.*;
+
+import java.security.*;
+import java.security.spec.*;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * SecretKeyFactory implementation class. This class currently supports
+ * DES, DESede, AES, ARCFOUR, and Blowfish.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11SecretKeyFactory extends SecretKeyFactorySpi {
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    P11SecretKeyFactory(Token token, String algorithm) {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+    }
+
+    private static final Map<String,Long> keyTypes;
+
+    static {
+        keyTypes = new HashMap<String,Long>();
+        addKeyType("RC4",      CKK_RC4);
+        addKeyType("ARCFOUR",  CKK_RC4);
+        addKeyType("DES",      CKK_DES);
+        addKeyType("DESede",   CKK_DES3);
+        addKeyType("AES",      CKK_AES);
+        addKeyType("Blowfish", CKK_BLOWFISH);
+
+        // we don't implement RC2 or IDEA, but we want to be able to generate
+        // keys for those SSL/TLS ciphersuites.
+        addKeyType("RC2",      CKK_RC2);
+        addKeyType("IDEA",     CKK_IDEA);
+
+        addKeyType("TlsPremasterSecret",    PCKK_TLSPREMASTER);
+        addKeyType("TlsRsaPremasterSecret", PCKK_TLSRSAPREMASTER);
+        addKeyType("TlsMasterSecret",       PCKK_TLSMASTER);
+        addKeyType("Generic",               CKK_GENERIC_SECRET);
+    }
+
+    private static void addKeyType(String name, long id) {
+        Long l = Long.valueOf(id);
+        keyTypes.put(name, l);
+        keyTypes.put(name.toUpperCase(Locale.ENGLISH), l);
+    }
+
+    static long getKeyType(String algorithm) {
+        Long l = keyTypes.get(algorithm);
+        if (l == null) {
+            algorithm = algorithm.toUpperCase(Locale.ENGLISH);
+            l = keyTypes.get(algorithm);
+            if (l == null) {
+                if (algorithm.startsWith("HMAC")) {
+                    return PCKK_HMAC;
+                } else if (algorithm.startsWith("SSLMAC")) {
+                    return PCKK_SSLMAC;
+                }
+            }
+        }
+        return (l != null) ? l.longValue() : -1;
+    }
+
+    /**
+     * Convert an arbitrary key of algorithm into a P11Key of provider.
+     * Used in engineTranslateKey(), P11Cipher.init(), and P11Mac.init().
+     */
+    static P11Key convertKey(Token token, Key key, String algo)
+            throws InvalidKeyException {
+        return convertKey(token, key, algo, null);
+    }
+
+    /**
+     * Convert an arbitrary key of algorithm w/ custom attributes into a
+     * P11Key of provider.
+     * Used in P11KeyStore.storeSkey.
+     */
+    static P11Key convertKey(Token token, Key key, String algo,
+            CK_ATTRIBUTE[] extraAttrs)
+            throws InvalidKeyException {
+        token.ensureValid();
+        if (key == null) {
+            throw new InvalidKeyException("Key must not be null");
+        }
+        if (key instanceof SecretKey == false) {
+            throw new InvalidKeyException("Key must be a SecretKey");
+        }
+        long algoType;
+        if (algo == null) {
+            algo = key.getAlgorithm();
+            algoType = getKeyType(algo);
+        } else {
+            algoType = getKeyType(algo);
+            long keyAlgorithmType = getKeyType(key.getAlgorithm());
+            if (algoType != keyAlgorithmType) {
+                if ((algoType == PCKK_HMAC) || (algoType == PCKK_SSLMAC)) {
+                    // ignore key algorithm for MACs
+                } else {
+                    throw new InvalidKeyException
+                            ("Key algorithm must be " + algo);
+                }
+            }
+        }
+        if (key instanceof P11Key) {
+            P11Key p11Key = (P11Key)key;
+            if (p11Key.token == token) {
+                if (extraAttrs != null) {
+                    Session session = null;
+                    try {
+                        session = token.getObjSession();
+                        long newKeyID = token.p11.C_CopyObject(session.id(),
+                                p11Key.keyID, extraAttrs);
+                        p11Key = (P11Key) (P11Key.secretKey(session,
+                                newKeyID, p11Key.algorithm, p11Key.keyLength,
+                                extraAttrs));
+                    } catch (PKCS11Exception p11e) {
+                        throw new InvalidKeyException
+                                ("Cannot duplicate the PKCS11 key", p11e);
+                    } finally {
+                        token.releaseSession(session);
+                    }
+                }
+                return p11Key;
+            }
+        }
+        P11Key p11Key = token.secretCache.get(key);
+        if (p11Key != null) {
+            return p11Key;
+        }
+        if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
+            throw new InvalidKeyException("Encoded format must be RAW");
+        }
+        byte[] encoded = key.getEncoded();
+        p11Key = createKey(token, encoded, algo, algoType, extraAttrs);
+        token.secretCache.put(key, p11Key);
+        return p11Key;
+    }
+
+    static void fixDESParity(byte[] key, int offset) {
+        for (int i = 0; i < 8; i++) {
+            int b = key[offset] & 0xfe;
+            b |= (Integer.bitCount(b) & 1) ^ 1;
+            key[offset++] = (byte)b;
+        }
+    }
+
+    private static P11Key createKey(Token token, byte[] encoded,
+            String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs)
+            throws InvalidKeyException {
+        int n = encoded.length << 3;
+        int keyLength = n;
+        try {
+            switch ((int)keyType) {
+                case (int)CKK_DES:
+                    keyLength =
+                        P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token);
+                    fixDESParity(encoded, 0);
+                    break;
+                case (int)CKK_DES3:
+                    keyLength =
+                        P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token);
+                    fixDESParity(encoded, 0);
+                    fixDESParity(encoded, 8);
+                    if (keyLength == 112) {
+                        keyType = CKK_DES2;
+                    } else {
+                        keyType = CKK_DES3;
+                        fixDESParity(encoded, 16);
+                    }
+                    break;
+                case (int)CKK_AES:
+                    keyLength =
+                        P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token);
+                    break;
+                case (int)CKK_RC4:
+                    keyLength =
+                        P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token);
+                    break;
+                case (int)CKK_BLOWFISH:
+                    keyLength =
+                        P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n,
+                        token);
+                    break;
+                case (int)CKK_GENERIC_SECRET:
+                case (int)PCKK_TLSPREMASTER:
+                case (int)PCKK_TLSRSAPREMASTER:
+                case (int)PCKK_TLSMASTER:
+                    keyType = CKK_GENERIC_SECRET;
+                    break;
+                case (int)PCKK_SSLMAC:
+                case (int)PCKK_HMAC:
+                    if (n == 0) {
+                        throw new InvalidKeyException
+                                ("MAC keys must not be empty");
+                    }
+                    keyType = CKK_GENERIC_SECRET;
+                    break;
+                default:
+                    throw new InvalidKeyException("Unknown algorithm " +
+                            algorithm);
+            }
+        } catch (InvalidAlgorithmParameterException iape) {
+            throw new InvalidKeyException("Invalid key for " + algorithm,
+                    iape);
+        } catch (ProviderException pe) {
+            throw new InvalidKeyException("Could not create key", pe);
+        }
+        Session session = null;
+        try {
+            CK_ATTRIBUTE[] attributes;
+            if (extraAttrs != null) {
+                attributes = new CK_ATTRIBUTE[3 + extraAttrs.length];
+                System.arraycopy(extraAttrs, 0, attributes, 3,
+                        extraAttrs.length);
+            } else {
+                attributes = new CK_ATTRIBUTE[3];
+            }
+            attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
+            attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType);
+            attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
+            attributes = token.getAttributes
+                (O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
+            session = token.getObjSession();
+            long keyID = token.p11.C_CreateObject(session.id(), attributes);
+            P11Key p11Key = (P11Key)P11Key.secretKey
+                (session, keyID, algorithm, keyLength, attributes);
+            return p11Key;
+        } catch (PKCS11Exception e) {
+            throw new InvalidKeyException("Could not create key", e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    // see JCE spec
+    protected SecretKey engineGenerateSecret(KeySpec keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if (keySpec == null) {
+            throw new InvalidKeySpecException("KeySpec must not be null");
+        }
+        if (keySpec instanceof SecretKeySpec) {
+            try {
+                Key key = convertKey(token, (SecretKey)keySpec, algorithm);
+                return (SecretKey)key;
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException(e);
+            }
+        } else if (algorithm.equalsIgnoreCase("DES")) {
+            if (keySpec instanceof DESKeySpec) {
+                byte[] keyBytes = ((DESKeySpec)keySpec).getKey();
+                keySpec = new SecretKeySpec(keyBytes, "DES");
+                return engineGenerateSecret(keySpec);
+            }
+        } else if (algorithm.equalsIgnoreCase("DESede")) {
+            if (keySpec instanceof DESedeKeySpec) {
+                byte[] keyBytes = ((DESedeKeySpec)keySpec).getKey();
+                keySpec = new SecretKeySpec(keyBytes, "DESede");
+                return engineGenerateSecret(keySpec);
+            }
+        }
+        throw new InvalidKeySpecException
+                ("Unsupported spec: " + keySpec.getClass().getName());
+    }
+
+    private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException {
+        try {
+            key = engineTranslateKey(key);
+            if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
+                throw new InvalidKeySpecException
+                    ("Could not obtain key bytes");
+            }
+            byte[] k = key.getEncoded();
+            return k;
+        } catch (InvalidKeyException e) {
+            throw new InvalidKeySpecException(e);
+        }
+    }
+
+    // see JCE spec
+    protected KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpec)
+            throws InvalidKeySpecException {
+        token.ensureValid();
+        if ((key == null) || (keySpec == null)) {
+            throw new InvalidKeySpecException
+                ("key and keySpec must not be null");
+        }
+        if (SecretKeySpec.class.isAssignableFrom(keySpec)) {
+            return new SecretKeySpec(getKeyBytes(key), algorithm);
+        } else if (algorithm.equalsIgnoreCase("DES")) {
+            try {
+                if (DESKeySpec.class.isAssignableFrom(keySpec)) {
+                    return new DESKeySpec(getKeyBytes(key));
+                }
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException(e);
+            }
+        } else if (algorithm.equalsIgnoreCase("DESede")) {
+            try {
+                if (DESedeKeySpec.class.isAssignableFrom(keySpec)) {
+                    return new DESedeKeySpec(getKeyBytes(key));
+                }
+            } catch (InvalidKeyException e) {
+                throw new InvalidKeySpecException(e);
+            }
+        }
+        throw new InvalidKeySpecException
+                ("Unsupported spec: " + keySpec.getName());
+    }
+
+    // see JCE spec
+    protected SecretKey engineTranslateKey(SecretKey key)
+            throws InvalidKeyException {
+        return (SecretKey)convertKey(token, key, algorithm);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11SecureRandom.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2003, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.io.*;
+import java.security.*;
+import sun.security.pkcs11.wrapper.*;
+
+/**
+ * SecureRandom implementation class. Some tokens support only
+ * C_GenerateRandom() and not C_SeedRandom(). In order not to lose an
+ * application specified seed, we create a SHA1PRNG that we mix with in that
+ * case.
+ *
+ * Note that since SecureRandom is thread safe, we only need one
+ * instance per PKCS#11 token instance. It is created on demand and cached
+ * in the SunPKCS11 class.
+ *
+ * Also note that we obtain the PKCS#11 session on demand, no need to tie one
+ * up.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11SecureRandom extends SecureRandomSpi {
+
+    private static final long serialVersionUID = -8939510236124553291L;
+
+    // token instance
+    private final Token token;
+
+    // PRNG for mixing, non-null if active (i.e. setSeed() has been called)
+    private volatile SecureRandom mixRandom;
+
+    // buffer, if mixing is used
+    private byte[] mixBuffer;
+
+    // bytes remaining in mixBuffer, if mixing is used
+    private int buffered;
+
+    /*
+     * we buffer data internally for efficiency but limit the lifetime
+     * to avoid using stale bits.
+     */
+    // lifetime in ms, currently 100 ms (0.1 s)
+    private static final long MAX_IBUFFER_TIME = 100;
+
+    // size of the internal buffer
+    private static final int IBUFFER_SIZE = 32;
+
+    // internal buffer for the random bits
+    private transient byte[] iBuffer = new byte[IBUFFER_SIZE];
+
+    // number of bytes remain in iBuffer
+    private transient int ibuffered = 0;
+
+    // time that data was read into iBuffer
+    private transient long lastRead = 0L;
+
+    P11SecureRandom(Token token) {
+        this.token = token;
+    }
+
+    // see JCA spec
+    @Override
+    protected synchronized void engineSetSeed(byte[] seed) {
+        if (seed == null) {
+            throw new NullPointerException("seed must not be null");
+        }
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            token.p11.C_SeedRandom(session.id(), seed);
+        } catch (PKCS11Exception e) {
+            // cannot set seed
+            // let a SHA1PRNG use that seed instead
+            SecureRandom random = mixRandom;
+            if (random != null) {
+                random.setSeed(seed);
+            } else {
+                try {
+                    mixBuffer = new byte[20];
+                    random = SecureRandom.getInstance("SHA1PRNG");
+                    // initialize object before assigning to class field
+                    random.setSeed(seed);
+                    mixRandom = random;
+                } catch (NoSuchAlgorithmException ee) {
+                    throw new ProviderException(ee);
+                }
+            }
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    // see JCA spec
+    @Override
+    protected void engineNextBytes(byte[] bytes) {
+        if ((bytes == null) || (bytes.length == 0)) {
+            return;
+        }
+        if (bytes.length <= IBUFFER_SIZE)  {
+            int ofs = 0;
+            synchronized (iBuffer) {
+                while (ofs < bytes.length) {
+                    long time = System.currentTimeMillis();
+                    // refill the internal buffer if empty or stale
+                    if ((ibuffered == 0) ||
+                            !(time - lastRead < MAX_IBUFFER_TIME)) {
+                        lastRead = time;
+                        implNextBytes(iBuffer);
+                        ibuffered = IBUFFER_SIZE;
+                    }
+                    // copy the buffered bytes into 'bytes'
+                    while ((ofs < bytes.length) && (ibuffered > 0)) {
+                        bytes[ofs++] = iBuffer[IBUFFER_SIZE - ibuffered--];
+                    }
+                }
+            }
+        } else {
+            // avoid using the buffer - just fill bytes directly
+            implNextBytes(bytes);
+        }
+
+    }
+
+    // see JCA spec
+    @Override
+    protected byte[] engineGenerateSeed(int numBytes) {
+        byte[] b = new byte[numBytes];
+        engineNextBytes(b);
+        return b;
+    }
+
+    private void mix(byte[] b) {
+        SecureRandom random = mixRandom;
+        if (random == null) {
+            // avoid mixing if setSeed() has never been called
+            return;
+        }
+        synchronized (this) {
+            int ofs = 0;
+            int len = b.length;
+            while (len-- > 0) {
+                if (buffered == 0) {
+                    random.nextBytes(mixBuffer);
+                    buffered = mixBuffer.length;
+                }
+                b[ofs++] ^= mixBuffer[mixBuffer.length - buffered];
+                buffered--;
+            }
+        }
+    }
+
+    // fill up the specified buffer with random bytes, and mix them
+    private void implNextBytes(byte[] bytes) {
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            token.p11.C_GenerateRandom(session.id(), bytes);
+            mix(bytes);
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("nextBytes() failed", e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    private void readObject(ObjectInputStream in)
+            throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+        // assign default values to non-null transient fields
+        iBuffer = new byte[IBUFFER_SIZE];
+        ibuffered = 0;
+        lastRead = 0L;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 2003, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
+import java.security.*;
+import java.security.interfaces.*;
+import sun.nio.ch.DirectBuffer;
+
+import sun.security.util.*;
+import sun.security.x509.AlgorithmId;
+
+import sun.security.rsa.RSASignature;
+import sun.security.rsa.RSAPadding;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+import sun.security.util.KeyUtil;
+
+/**
+ * Signature implementation class. This class currently supports the
+ * following algorithms:
+ *
+ * . DSA
+ *   . NONEwithDSA (RawDSA)
+ *   . SHA1withDSA
+ *   . NONEwithDSAinP1363Format (RawDSAinP1363Format)
+ *   . SHA1withDSAinP1363Format
+ * . RSA:
+ *   . MD2withRSA
+ *   . MD5withRSA
+ *   . SHA1withRSA
+ *   . SHA224withRSA
+ *   . SHA256withRSA
+ *   . SHA384withRSA
+ *   . SHA512withRSA
+ * . ECDSA
+ *   . NONEwithECDSA
+ *   . SHA1withECDSA
+ *   . SHA224withECDSA
+ *   . SHA256withECDSA
+ *   . SHA384withECDSA
+ *   . SHA512withECDSA
+ *   . NONEwithECDSAinP1363Format
+ *   . SHA1withECDSAinP1363Format
+ *   . SHA224withECDSAinP1363Format
+ *   . SHA256withECDSAinP1363Format
+ *   . SHA384withECDSAinP1363Format
+ *   . SHA512withECDSAinP1363Format
+ *
+ * Note that the underlying PKCS#11 token may support complete signature
+ * algorithm (e.g. CKM_DSA_SHA1, CKM_MD5_RSA_PKCS), or it may just
+ * implement the signature algorithm without hashing (e.g. CKM_DSA, CKM_PKCS),
+ * or it may only implement the raw public key operation (CKM_RSA_X_509).
+ * This class uses what is available and adds whatever extra processing
+ * is needed.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class P11Signature extends SignatureSpi {
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // name of the key algorithm, currently either RSA or DSA
+    private final String keyAlgorithm;
+
+    // mechanism id
+    private final long mechanism;
+
+    // digest algorithm OID, if we encode RSA signature ourselves
+    private final ObjectIdentifier digestOID;
+
+    // type, one of T_* below
+    private final int type;
+
+    // key instance used, if init*() was called
+    private P11Key p11Key;
+
+    // message digest, if we do the digesting ourselves
+    private final MessageDigest md;
+
+    // associated session, if any
+    private Session session;
+
+    // mode, one of M_* below
+    private int mode;
+
+    // flag indicating whether an operation is initialized
+    private boolean initialized;
+
+    // buffer, for update(byte) or DSA
+    private final byte[] buffer;
+
+    // total number of bytes processed in current operation
+    private int bytesProcessed;
+
+    // The format, to be used for DSA and ECDSA signatures.
+    // If true, the IEEE P1363 format will be used, the concatenation of
+    // r and s. If false (default), the signature will be formatted as a
+    // DER-encoded ASN.1 sequence of r and s.
+    private boolean p1363Format = false;
+
+    // constant for signing mode
+    private final static int M_SIGN   = 1;
+    // constant for verification mode
+    private final static int M_VERIFY = 2;
+
+    // constant for type digesting, we do the hashing ourselves
+    private final static int T_DIGEST = 1;
+    // constant for type update, token does everything
+    private final static int T_UPDATE = 2;
+    // constant for type raw, used with RawDSA and NONEwithECDSA only
+    private final static int T_RAW    = 3;
+
+    // XXX PKCS#11 v2.20 says "should not be longer than 1024 bits",
+    // but this is a little arbitrary
+    private final static int RAW_ECDSA_MAX = 128;
+
+    P11Signature(Token token, String algorithm, long mechanism)
+            throws NoSuchAlgorithmException, PKCS11Exception {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+        byte[] buffer = null;
+        ObjectIdentifier digestOID = null;
+        MessageDigest md = null;
+        switch ((int)mechanism) {
+        case (int)CKM_MD2_RSA_PKCS:
+        case (int)CKM_MD5_RSA_PKCS:
+        case (int)CKM_SHA1_RSA_PKCS:
+        case (int)CKM_SHA224_RSA_PKCS:
+        case (int)CKM_SHA256_RSA_PKCS:
+        case (int)CKM_SHA384_RSA_PKCS:
+        case (int)CKM_SHA512_RSA_PKCS:
+            keyAlgorithm = "RSA";
+            type = T_UPDATE;
+            buffer = new byte[1];
+            break;
+        case (int)CKM_DSA_SHA1:
+            keyAlgorithm = "DSA";
+            type = T_UPDATE;
+            buffer = new byte[1];
+            break;
+        case (int)CKM_ECDSA_SHA1:
+            keyAlgorithm = "EC";
+            type = T_UPDATE;
+            buffer = new byte[1];
+            break;
+        case (int)CKM_DSA:
+            keyAlgorithm = "DSA";
+            if (algorithm.equals("DSA") ||
+                algorithm.equals("DSAinP1363Format")) {
+                type = T_DIGEST;
+                md = MessageDigest.getInstance("SHA-1");
+            } else if (algorithm.equals("RawDSA") ||
+                       algorithm.equals("RawDSAinP1363Format")) {
+                type = T_RAW;
+                buffer = new byte[20];
+            } else {
+                throw new ProviderException(algorithm);
+            }
+            break;
+        case (int)CKM_ECDSA:
+            keyAlgorithm = "EC";
+            if (algorithm.equals("NONEwithECDSA") ||
+                algorithm.equals("NONEwithECDSAinP1363Format")) {
+                type = T_RAW;
+                buffer = new byte[RAW_ECDSA_MAX];
+            } else {
+                String digestAlg;
+                if (algorithm.equals("SHA1withECDSA") ||
+                    algorithm.equals("SHA1withECDSAinP1363Format")) {
+                    digestAlg = "SHA-1";
+                } else if (algorithm.equals("SHA224withECDSA") ||
+                           algorithm.equals("SHA224withECDSAinP1363Format")) {
+                    digestAlg = "SHA-224";
+                } else if (algorithm.equals("SHA256withECDSA") ||
+                           algorithm.equals("SHA256withECDSAinP1363Format")) {
+                    digestAlg = "SHA-256";
+                } else if (algorithm.equals("SHA384withECDSA") ||
+                           algorithm.equals("SHA384withECDSAinP1363Format")) {
+                    digestAlg = "SHA-384";
+                } else if (algorithm.equals("SHA512withECDSA") ||
+                           algorithm.equals("SHA512withECDSAinP1363Format")) {
+                    digestAlg = "SHA-512";
+                } else {
+                    throw new ProviderException(algorithm);
+                }
+                type = T_DIGEST;
+                md = MessageDigest.getInstance(digestAlg);
+            }
+            break;
+        case (int)CKM_RSA_PKCS:
+        case (int)CKM_RSA_X_509:
+            keyAlgorithm = "RSA";
+            type = T_DIGEST;
+            if (algorithm.equals("MD5withRSA")) {
+                md = MessageDigest.getInstance("MD5");
+                digestOID = AlgorithmId.MD5_oid;
+            } else if (algorithm.equals("SHA1withRSA")) {
+                md = MessageDigest.getInstance("SHA-1");
+                digestOID = AlgorithmId.SHA_oid;
+            } else if (algorithm.equals("MD2withRSA")) {
+                md = MessageDigest.getInstance("MD2");
+                digestOID = AlgorithmId.MD2_oid;
+            } else if (algorithm.equals("SHA224withRSA")) {
+                md = MessageDigest.getInstance("SHA-224");
+                digestOID = AlgorithmId.SHA224_oid;
+            } else if (algorithm.equals("SHA256withRSA")) {
+                md = MessageDigest.getInstance("SHA-256");
+                digestOID = AlgorithmId.SHA256_oid;
+            } else if (algorithm.equals("SHA384withRSA")) {
+                md = MessageDigest.getInstance("SHA-384");
+                digestOID = AlgorithmId.SHA384_oid;
+            } else if (algorithm.equals("SHA512withRSA")) {
+                md = MessageDigest.getInstance("SHA-512");
+                digestOID = AlgorithmId.SHA512_oid;
+            } else {
+                throw new ProviderException("Unknown signature: " + algorithm);
+            }
+            break;
+        default:
+            throw new ProviderException("Unknown mechanism: " + mechanism);
+        }
+        this.buffer = buffer;
+        this.digestOID = digestOID;
+        this.md = md;
+        if (algorithm.endsWith("inP1363Format")) {
+            this.p1363Format = true;
+        }
+    }
+
+    private void ensureInitialized() {
+        token.ensureValid();
+        if (initialized == false) {
+            initialize();
+        }
+    }
+
+    private void cancelOperation() {
+        token.ensureValid();
+        if (initialized == false) {
+            return;
+        }
+        initialized = false;
+        if ((session == null) || (token.explicitCancel == false)) {
+            return;
+        }
+        if (session.hasObjects() == false) {
+            session = token.killSession(session);
+            return;
+        }
+        // "cancel" operation by finishing it
+        // XXX make sure all this always works correctly
+        if (mode == M_SIGN) {
+            try {
+                if (type == T_UPDATE) {
+                    token.p11.C_SignFinal(session.id(), 0);
+                } else {
+                    byte[] digest;
+                    if (type == T_DIGEST) {
+                        digest = md.digest();
+                    } else { // T_RAW
+                        digest = buffer;
+                    }
+                    token.p11.C_Sign(session.id(), digest);
+                }
+            } catch (PKCS11Exception e) {
+                throw new ProviderException("cancel failed", e);
+            }
+        } else { // M_VERIFY
+            try {
+                byte[] signature;
+                if (keyAlgorithm.equals("DSA")) {
+                    signature = new byte[40];
+                } else {
+                    signature = new byte[(p11Key.length() + 7) >> 3];
+                }
+                if (type == T_UPDATE) {
+                    token.p11.C_VerifyFinal(session.id(), signature);
+                } else {
+                    byte[] digest;
+                    if (type == T_DIGEST) {
+                        digest = md.digest();
+                    } else { // T_RAW
+                        digest = buffer;
+                    }
+                    token.p11.C_Verify(session.id(), digest, signature);
+                }
+            } catch (PKCS11Exception e) {
+                // will fail since the signature is incorrect
+                // XXX check error code
+            }
+        }
+    }
+
+    // assumes current state is initialized == false
+    private void initialize() {
+        try {
+            if (session == null) {
+                session = token.getOpSession();
+            }
+            if (mode == M_SIGN) {
+                token.p11.C_SignInit(session.id(),
+                        new CK_MECHANISM(mechanism), p11Key.keyID);
+            } else {
+                token.p11.C_VerifyInit(session.id(),
+                        new CK_MECHANISM(mechanism), p11Key.keyID);
+            }
+            initialized = true;
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("Initialization failed", e);
+        }
+        if (bytesProcessed != 0) {
+            bytesProcessed = 0;
+            if (md != null) {
+                md.reset();
+            }
+        }
+    }
+
+    private void checkKeySize(String keyAlgo, Key key)
+        throws InvalidKeyException {
+        CK_MECHANISM_INFO mechInfo = null;
+        try {
+            mechInfo = token.getMechanismInfo(mechanism);
+        } catch (PKCS11Exception e) {
+            // should not happen, ignore for now.
+        }
+        if (mechInfo == null) {
+            // skip the check if no native info available
+            return;
+        }
+        int minKeySize = (int) mechInfo.ulMinKeySize;
+        int maxKeySize = (int) mechInfo.ulMaxKeySize;
+        // need to override the MAX keysize for SHA1withDSA
+        if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
+               maxKeySize = 1024;
+        }
+        int keySize = 0;
+        if (key instanceof P11Key) {
+            keySize = ((P11Key) key).length();
+        } else {
+            if (keyAlgo.equals("RSA")) {
+                keySize = ((RSAKey) key).getModulus().bitLength();
+            } else if (keyAlgo.equals("DSA")) {
+                keySize = ((DSAKey) key).getParams().getP().bitLength();
+            } else if (keyAlgo.equals("EC")) {
+                keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();
+            } else {
+                throw new ProviderException("Error: unsupported algo " + keyAlgo);
+            }
+        }
+        if ((minKeySize != -1) && (keySize < minKeySize)) {
+            throw new InvalidKeyException(keyAlgo +
+                " key must be at least " + minKeySize + " bits");
+        }
+        if ((maxKeySize != -1) && (keySize > maxKeySize)) {
+            throw new InvalidKeyException(keyAlgo +
+                " key must be at most " + maxKeySize + " bits");
+        }
+        if (keyAlgo.equals("RSA")) {
+            checkRSAKeyLength(keySize);
+        }
+    }
+
+    private void checkRSAKeyLength(int len) throws InvalidKeyException {
+        RSAPadding padding;
+        try {
+            padding = RSAPadding.getInstance
+                (RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);
+        } catch (InvalidAlgorithmParameterException iape) {
+            throw new InvalidKeyException(iape.getMessage());
+        }
+        int maxDataSize = padding.getMaxDataSize();
+        int encodedLength;
+        if (algorithm.equals("MD5withRSA") ||
+            algorithm.equals("MD2withRSA")) {
+            encodedLength = 34;
+        } else if (algorithm.equals("SHA1withRSA")) {
+            encodedLength = 35;
+        } else if (algorithm.equals("SHA224withRSA")) {
+            encodedLength = 47;
+        } else if (algorithm.equals("SHA256withRSA")) {
+            encodedLength = 51;
+        } else if (algorithm.equals("SHA384withRSA")) {
+            encodedLength = 67;
+        } else if (algorithm.equals("SHA512withRSA")) {
+            encodedLength = 83;
+        } else {
+            throw new ProviderException("Unknown signature algo: " + algorithm);
+        }
+        if (encodedLength > maxDataSize) {
+            throw new InvalidKeyException
+                ("Key is too short for this signature algorithm");
+        }
+    }
+
+    // see JCA spec
+    protected void engineInitVerify(PublicKey publicKey)
+            throws InvalidKeyException {
+        if (publicKey == null) {
+            throw new InvalidKeyException("Key must not be null");
+        }
+        // Need to check key length whenever a new key is set
+        if (publicKey != p11Key) {
+            checkKeySize(keyAlgorithm, publicKey);
+        }
+        cancelOperation();
+        mode = M_VERIFY;
+        p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
+        initialize();
+    }
+
+    // see JCA spec
+    protected void engineInitSign(PrivateKey privateKey)
+            throws InvalidKeyException {
+        if (privateKey == null) {
+            throw new InvalidKeyException("Key must not be null");
+        }
+        // Need to check RSA key length whenever a new key is set
+        if (privateKey != p11Key) {
+            checkKeySize(keyAlgorithm, privateKey);
+        }
+        cancelOperation();
+        mode = M_SIGN;
+        p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
+        initialize();
+    }
+
+    // see JCA spec
+    protected void engineUpdate(byte b) throws SignatureException {
+        ensureInitialized();
+        switch (type) {
+        case T_UPDATE:
+            buffer[0] = b;
+            engineUpdate(buffer, 0, 1);
+            break;
+        case T_DIGEST:
+            md.update(b);
+            bytesProcessed++;
+            break;
+        case T_RAW:
+            if (bytesProcessed >= buffer.length) {
+                bytesProcessed = buffer.length + 1;
+                return;
+            }
+            buffer[bytesProcessed++] = b;
+            break;
+        default:
+            throw new ProviderException("Internal error");
+        }
+    }
+
+    // see JCA spec
+    protected void engineUpdate(byte[] b, int ofs, int len)
+            throws SignatureException {
+        ensureInitialized();
+        if (len == 0) {
+            return;
+        }
+        switch (type) {
+        case T_UPDATE:
+            try {
+                if (mode == M_SIGN) {
+                    token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
+                } else {
+                    token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
+                }
+                bytesProcessed += len;
+            } catch (PKCS11Exception e) {
+                throw new ProviderException(e);
+            }
+            break;
+        case T_DIGEST:
+            md.update(b, ofs, len);
+            bytesProcessed += len;
+            break;
+        case T_RAW:
+            if (bytesProcessed + len > buffer.length) {
+                bytesProcessed = buffer.length + 1;
+                return;
+            }
+            System.arraycopy(b, ofs, buffer, bytesProcessed, len);
+            bytesProcessed += len;
+            break;
+        default:
+            throw new ProviderException("Internal error");
+        }
+    }
+
+    // see JCA spec
+    protected void engineUpdate(ByteBuffer byteBuffer) {
+        ensureInitialized();
+        int len = byteBuffer.remaining();
+        if (len <= 0) {
+            return;
+        }
+        switch (type) {
+        case T_UPDATE:
+            if (byteBuffer instanceof DirectBuffer == false) {
+                // cannot do better than default impl
+                super.engineUpdate(byteBuffer);
+                return;
+            }
+            long addr = ((DirectBuffer)byteBuffer).address();
+            int ofs = byteBuffer.position();
+            try {
+                if (mode == M_SIGN) {
+                    token.p11.C_SignUpdate
+                        (session.id(), addr + ofs, null, 0, len);
+                } else {
+                    token.p11.C_VerifyUpdate
+                        (session.id(), addr + ofs, null, 0, len);
+                }
+                bytesProcessed += len;
+                byteBuffer.position(ofs + len);
+            } catch (PKCS11Exception e) {
+                throw new ProviderException("Update failed", e);
+            }
+            break;
+        case T_DIGEST:
+            md.update(byteBuffer);
+            bytesProcessed += len;
+            break;
+        case T_RAW:
+            if (bytesProcessed + len > buffer.length) {
+                bytesProcessed = buffer.length + 1;
+                return;
+            }
+            byteBuffer.get(buffer, bytesProcessed, len);
+            bytesProcessed += len;
+            break;
+        default:
+            throw new ProviderException("Internal error");
+        }
+    }
+
+    // see JCA spec
+    protected byte[] engineSign() throws SignatureException {
+        ensureInitialized();
+        try {
+            byte[] signature;
+            if (type == T_UPDATE) {
+                int len = keyAlgorithm.equals("DSA") ? 40 : 0;
+                signature = token.p11.C_SignFinal(session.id(), len);
+            } else {
+                byte[] digest;
+                if (type == T_DIGEST) {
+                    digest = md.digest();
+                } else { // T_RAW
+                    if (mechanism == CKM_DSA) {
+                        if (bytesProcessed != buffer.length) {
+                            throw new SignatureException
+                            ("Data for RawDSA must be exactly 20 bytes long");
+                        }
+                        digest = buffer;
+                    } else { // CKM_ECDSA
+                        if (bytesProcessed > buffer.length) {
+                            throw new SignatureException("Data for NONEwithECDSA"
+                            + " must be at most " + RAW_ECDSA_MAX + " bytes long");
+                        }
+                        digest = new byte[bytesProcessed];
+                        System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
+                    }
+                }
+                if (keyAlgorithm.equals("RSA") == false) {
+                    // DSA and ECDSA
+                    signature = token.p11.C_Sign(session.id(), digest);
+                } else { // RSA
+                    byte[] data = encodeSignature(digest);
+                    if (mechanism == CKM_RSA_X_509) {
+                        data = pkcs1Pad(data);
+                    }
+                    signature = token.p11.C_Sign(session.id(), data);
+                }
+            }
+            if (keyAlgorithm.equals("RSA")) {
+                return signature;
+            } else {
+                if (p1363Format) {
+                    return signature;
+                } else {
+                    return dsaToASN1(signature);
+                }
+            }
+        } catch (PKCS11Exception pe) {
+            throw new ProviderException(pe);
+        } catch (SignatureException | ProviderException e) {
+            cancelOperation();
+            throw e;
+        } finally {
+            initialized = false;
+            session = token.releaseSession(session);
+        }
+    }
+
+    // see JCA spec
+    protected boolean engineVerify(byte[] signature) throws SignatureException {
+        ensureInitialized();
+        try {
+            if (!p1363Format) {
+                if (keyAlgorithm.equals("DSA")) {
+                    signature = asn1ToDSA(signature);
+                } else if (keyAlgorithm.equals("EC")) {
+                    signature = asn1ToECDSA(signature);
+                }
+            }
+            if (type == T_UPDATE) {
+                token.p11.C_VerifyFinal(session.id(), signature);
+            } else {
+                byte[] digest;
+                if (type == T_DIGEST) {
+                    digest = md.digest();
+                } else { // T_RAW
+                    if (mechanism == CKM_DSA) {
+                        if (bytesProcessed != buffer.length) {
+                            throw new SignatureException
+                            ("Data for RawDSA must be exactly 20 bytes long");
+                        }
+                        digest = buffer;
+                    } else {
+                        if (bytesProcessed > buffer.length) {
+                            throw new SignatureException("Data for NONEwithECDSA"
+                            + " must be at most " + RAW_ECDSA_MAX + " bytes long");
+                        }
+                        digest = new byte[bytesProcessed];
+                        System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
+                    }
+                }
+                if (keyAlgorithm.equals("RSA") == false) {
+                    // DSA and ECDSA
+                    token.p11.C_Verify(session.id(), digest, signature);
+                } else { // RSA
+                    byte[] data = encodeSignature(digest);
+                    if (mechanism == CKM_RSA_X_509) {
+                        data = pkcs1Pad(data);
+                    }
+                    token.p11.C_Verify(session.id(), data, signature);
+                }
+            }
+            return true;
+        } catch (PKCS11Exception pe) {
+            long errorCode = pe.getErrorCode();
+            if (errorCode == CKR_SIGNATURE_INVALID) {
+                return false;
+            }
+            if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
+                // return false rather than throwing an exception
+                return false;
+            }
+            // ECF bug?
+            if (errorCode == CKR_DATA_LEN_RANGE) {
+                return false;
+            }
+            throw new ProviderException(pe);
+        }  catch (SignatureException | ProviderException e) {
+            cancelOperation();
+            throw e;
+        } finally {
+            initialized = false;
+            session = token.releaseSession(session);
+        }
+    }
+
+    private byte[] pkcs1Pad(byte[] data) {
+        try {
+            int len = (p11Key.length() + 7) >> 3;
+            RSAPadding padding = RSAPadding.getInstance
+                                        (RSAPadding.PAD_BLOCKTYPE_1, len);
+            byte[] padded = padding.pad(data);
+            return padded;
+        } catch (GeneralSecurityException e) {
+            throw new ProviderException(e);
+        }
+    }
+
+    private byte[] encodeSignature(byte[] digest) throws SignatureException {
+        try {
+            return RSASignature.encodeSignature(digestOID, digest);
+        } catch (IOException e) {
+            throw new SignatureException("Invalid encoding", e);
+        }
+    }
+
+//    private static byte[] decodeSignature(byte[] signature) throws IOException {
+//      return RSASignature.decodeSignature(digestOID, signature);
+//    }
+
+    // For DSA and ECDSA signatures, PKCS#11 represents them as a simple
+    // byte array that contains the concatenation of r and s.
+    // For DSA, r and s are always exactly 20 bytes long.
+    // For ECDSA, r and s are of variable length, but we know that each
+    // occupies half of the array.
+    private static byte[] dsaToASN1(byte[] signature) {
+        int n = signature.length >> 1;
+        BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));
+        BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));
+        try {
+            DerOutputStream outseq = new DerOutputStream(100);
+            outseq.putInteger(r);
+            outseq.putInteger(s);
+            DerValue result = new DerValue(DerValue.tag_Sequence,
+                                           outseq.toByteArray());
+            return result.toByteArray();
+        } catch (java.io.IOException e) {
+            throw new RuntimeException("Internal error", e);
+        }
+    }
+
+    private static byte[] asn1ToDSA(byte[] sig) throws SignatureException {
+        try {
+            // Enforce strict DER checking for signatures
+            DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
+            DerValue[] values = in.getSequence(2);
+
+            // check number of components in the read sequence
+            // and trailing data
+            if ((values.length != 2) || (in.available() != 0)) {
+                throw new IOException("Invalid encoding for signature");
+            }
+
+            BigInteger r = values[0].getPositiveBigInteger();
+            BigInteger s = values[1].getPositiveBigInteger();
+
+            byte[] br = toByteArray(r, 20);
+            byte[] bs = toByteArray(s, 20);
+            if ((br == null) || (bs == null)) {
+                throw new SignatureException("Out of range value for R or S");
+            }
+            return P11Util.concat(br, bs);
+        } catch (SignatureException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SignatureException("Invalid encoding for signature", e);
+        }
+    }
+
+    private byte[] asn1ToECDSA(byte[] sig) throws SignatureException {
+        try {
+            // Enforce strict DER checking for signatures
+            DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
+            DerValue[] values = in.getSequence(2);
+
+            // check number of components in the read sequence
+            // and trailing data
+            if ((values.length != 2) || (in.available() != 0)) {
+                throw new IOException("Invalid encoding for signature");
+            }
+
+            BigInteger r = values[0].getPositiveBigInteger();
+            BigInteger s = values[1].getPositiveBigInteger();
+
+            // trim leading zeroes
+            byte[] br = KeyUtil.trimZeroes(r.toByteArray());
+            byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
+            int k = Math.max(br.length, bs.length);
+            // r and s each occupy half the array
+            byte[] res = new byte[k << 1];
+            System.arraycopy(br, 0, res, k - br.length, br.length);
+            System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);
+            return res;
+        } catch (Exception e) {
+            throw new SignatureException("Invalid encoding for signature", e);
+        }
+    }
+
+    private static byte[] toByteArray(BigInteger bi, int len) {
+        byte[] b = bi.toByteArray();
+        int n = b.length;
+        if (n == len) {
+            return b;
+        }
+        if ((n == len + 1) && (b[0] == 0)) {
+            byte[] t = new byte[len];
+            System.arraycopy(b, 1, t, 0, len);
+            return t;
+        }
+        if (n > len) {
+            return null;
+        }
+        // must be smaller
+        byte[] t = new byte[len];
+        System.arraycopy(b, 0, t, (len - n), n);
+        return t;
+    }
+
+    // see JCA spec
+    @SuppressWarnings("deprecation")
+    protected void engineSetParameter(String param, Object value)
+            throws InvalidParameterException {
+        throw new UnsupportedOperationException("setParameter() not supported");
+    }
+
+    // see JCA spec
+    @SuppressWarnings("deprecation")
+    protected Object engineGetParameter(String param)
+            throws InvalidParameterException {
+        throw new UnsupportedOperationException("getParameter() not supported");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2005, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.util.*;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import sun.security.internal.spec.*;
+import sun.security.internal.interfaces.TlsMasterSecret;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * KeyGenerator to calculate the SSL/TLS key material (cipher keys and ivs,
+ * mac keys) from the master secret.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.6
+ */
+public final class P11TlsKeyMaterialGenerator extends KeyGeneratorSpi {
+
+    private final static String MSG = "TlsKeyMaterialGenerator must be "
+        + "initialized using a TlsKeyMaterialParameterSpec";
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id
+    private long mechanism;
+
+    // parameter spec
+    @SuppressWarnings("deprecation")
+    private TlsKeyMaterialParameterSpec spec;
+
+    // master secret as a P11Key
+    private P11Key p11Key;
+
+    // whether SSLv3 is supported
+    private final boolean supportSSLv3;
+
+    P11TlsKeyMaterialGenerator(Token token, String algorithm, long mechanism)
+            throws PKCS11Exception {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+
+        // Given the current lookup order specified in SunPKCS11.java,
+        // if CKM_SSL3_KEY_AND_MAC_DERIVE is not used to construct this object,
+        // it means that this mech is disabled or unsupported.
+        this.supportSSLv3 = (mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE);
+    }
+
+    protected void engineInit(SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    @SuppressWarnings("deprecation")
+    protected void engineInit(AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidAlgorithmParameterException {
+        if (params instanceof TlsKeyMaterialParameterSpec == false) {
+            throw new InvalidAlgorithmParameterException(MSG);
+        }
+
+        TlsKeyMaterialParameterSpec spec = (TlsKeyMaterialParameterSpec)params;
+        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
+
+        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
+            (version > 0x0302)) {
+             throw new InvalidAlgorithmParameterException
+                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
+                     " TLS 1.0, and TLS 1.1 are supported (0x" +
+                     Integer.toHexString(version) + ")");
+        }
+        try {
+            p11Key = P11SecretKeyFactory.convertKey
+                            (token, spec.getMasterSecret(), "TlsMasterSecret");
+        } catch (InvalidKeyException e) {
+            throw new InvalidAlgorithmParameterException("init() failed", e);
+        }
+        this.spec = spec;
+        this.mechanism = (version == 0x0300)?
+            CKM_SSL3_KEY_AND_MAC_DERIVE : CKM_TLS_KEY_AND_MAC_DERIVE;
+    }
+
+    protected void engineInit(int keysize, SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    @SuppressWarnings("deprecation")
+    protected SecretKey engineGenerateKey() {
+        if (spec == null) {
+            throw new IllegalStateException
+                ("TlsKeyMaterialGenerator must be initialized");
+        }
+        int macBits = spec.getMacKeyLength() << 3;
+        int ivBits = spec.getIvLength() << 3;
+
+        int expandedKeyBits = spec.getExpandedCipherKeyLength() << 3;
+        int keyBits = spec.getCipherKeyLength() << 3;
+        boolean isExportable;
+        if (expandedKeyBits != 0) {
+            isExportable = true;
+        } else {
+            isExportable = false;
+            expandedKeyBits = keyBits;
+        }
+
+        CK_SSL3_RANDOM_DATA random = new CK_SSL3_RANDOM_DATA
+                            (spec.getClientRandom(), spec.getServerRandom());
+        CK_SSL3_KEY_MAT_PARAMS params = new CK_SSL3_KEY_MAT_PARAMS
+                            (macBits, keyBits, ivBits, isExportable, random);
+
+        String cipherAlgorithm = spec.getCipherAlgorithm();
+        long keyType = P11SecretKeyFactory.getKeyType(cipherAlgorithm);
+        if (keyType < 0) {
+            if (keyBits != 0) {
+                throw new ProviderException
+                            ("Unknown algorithm: " + spec.getCipherAlgorithm());
+            } else {
+                // NULL encryption ciphersuites
+                keyType = CKK_GENERIC_SECRET;
+            }
+        }
+
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            CK_ATTRIBUTE[] attributes;
+            if (keyBits != 0) {
+                attributes = new CK_ATTRIBUTE[] {
+                    new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
+                    new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
+                    new CK_ATTRIBUTE(CKA_VALUE_LEN, expandedKeyBits >> 3),
+                };
+            } else {
+                // ciphersuites with NULL ciphers
+                attributes = new CK_ATTRIBUTE[0];
+            }
+            attributes = token.getAttributes
+                (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
+            // the returned keyID is a dummy, ignore
+            long keyID = token.p11.C_DeriveKey(session.id(),
+                new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes);
+
+            CK_SSL3_KEY_MAT_OUT out = params.pReturnedKeyMaterial;
+            // Note that the MAC keys do not inherit all attributes from the
+            // template, but they do inherit the sensitive/extractable/token
+            // flags, which is all P11Key cares about.
+            SecretKey clientMacKey, serverMacKey;
+
+            // The MAC size may be zero for GCM mode.
+            //
+            // PKCS11 does not support GCM mode as the author made the comment,
+            // so the macBits is unlikely to be zero. It's only a place holder.
+            if (macBits != 0) {
+                clientMacKey = P11Key.secretKey
+                    (session, out.hClientMacSecret, "MAC", macBits, attributes);
+                serverMacKey = P11Key.secretKey
+                    (session, out.hServerMacSecret, "MAC", macBits, attributes);
+            } else {
+                clientMacKey = null;
+                serverMacKey = null;
+            }
+
+            SecretKey clientCipherKey, serverCipherKey;
+            if (keyBits != 0) {
+                clientCipherKey = P11Key.secretKey(session, out.hClientKey,
+                        cipherAlgorithm, expandedKeyBits, attributes);
+                serverCipherKey = P11Key.secretKey(session, out.hServerKey,
+                        cipherAlgorithm, expandedKeyBits, attributes);
+            } else {
+                clientCipherKey = null;
+                serverCipherKey = null;
+            }
+            IvParameterSpec clientIv = (out.pIVClient == null)
+                                    ? null : new IvParameterSpec(out.pIVClient);
+            IvParameterSpec serverIv = (out.pIVServer == null)
+                                    ? null : new IvParameterSpec(out.pIVServer);
+
+            return new TlsKeyMaterialSpec(clientMacKey, serverMacKey,
+                    clientCipherKey, clientIv, serverCipherKey, serverIv);
+
+        } catch (Exception e) {
+            throw new ProviderException("Could not generate key", e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2005, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import sun.security.internal.spec.TlsMasterSecretParameterSpec;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * KeyGenerator for the SSL/TLS master secret.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.6
+ */
+public final class P11TlsMasterSecretGenerator extends KeyGeneratorSpi {
+
+    private final static String MSG = "TlsMasterSecretGenerator must be "
+        + "initialized using a TlsMasterSecretParameterSpec";
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id
+    private long mechanism;
+
+    @SuppressWarnings("deprecation")
+    private TlsMasterSecretParameterSpec spec;
+    private P11Key p11Key;
+
+    CK_VERSION ckVersion;
+
+    // whether SSLv3 is supported
+    private final boolean supportSSLv3;
+
+    P11TlsMasterSecretGenerator(Token token, String algorithm, long mechanism)
+            throws PKCS11Exception {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+
+        // Given the current lookup order specified in SunPKCS11.java, if
+        // CKM_SSL3_MASTER_KEY_DERIVE is not used to construct this object,
+        // it means that this mech is disabled or unsupported.
+        supportSSLv3 = (mechanism == CKM_SSL3_MASTER_KEY_DERIVE);
+    }
+
+    protected void engineInit(SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    @SuppressWarnings("deprecation")
+    protected void engineInit(AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidAlgorithmParameterException {
+        if (params instanceof TlsMasterSecretParameterSpec == false) {
+            throw new InvalidAlgorithmParameterException(MSG);
+        }
+
+        TlsMasterSecretParameterSpec spec = (TlsMasterSecretParameterSpec)params;
+        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
+        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
+            (version > 0x0302)) {
+             throw new InvalidAlgorithmParameterException
+                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
+                     " TLS 1.0, and TLS 1.1 are supported (0x" +
+                     Integer.toHexString(version) + ")");
+        }
+
+        SecretKey key = spec.getPremasterSecret();
+        // algorithm should be either TlsRsaPremasterSecret or TlsPremasterSecret,
+        // but we omit the check
+        try {
+            p11Key = P11SecretKeyFactory.convertKey(token, key, null);
+        } catch (InvalidKeyException e) {
+            throw new InvalidAlgorithmParameterException("init() failed", e);
+        }
+        this.spec = spec;
+        if (p11Key.getAlgorithm().equals("TlsRsaPremasterSecret")) {
+            mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE
+                                             : CKM_TLS_MASTER_KEY_DERIVE;
+            ckVersion = new CK_VERSION(0, 0);
+        } else {
+            // Note: we use DH for all non-RSA premaster secrets. That includes
+            // Kerberos. That should not be a problem because master secret
+            // calculation is always a straightforward application of the
+            // TLS PRF (or the SSL equivalent).
+            // The only thing special about RSA master secret calculation is
+            // that it extracts the version numbers from the premaster secret.
+            mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE_DH
+                                             : CKM_TLS_MASTER_KEY_DERIVE_DH;
+            ckVersion = null;
+        }
+    }
+
+    protected void engineInit(int keysize, SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    protected SecretKey engineGenerateKey() {
+        if (spec == null) {
+            throw new IllegalStateException
+                ("TlsMasterSecretGenerator must be initialized");
+        }
+        byte[] clientRandom = spec.getClientRandom();
+        byte[] serverRandom = spec.getServerRandom();
+        CK_SSL3_RANDOM_DATA random =
+                new CK_SSL3_RANDOM_DATA(clientRandom, serverRandom);
+        CK_SSL3_MASTER_KEY_DERIVE_PARAMS params =
+                new CK_SSL3_MASTER_KEY_DERIVE_PARAMS(random, ckVersion);
+
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = token.getAttributes(O_GENERATE,
+                CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
+            long keyID = token.p11.C_DeriveKey(session.id(),
+                new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes);
+            int major, minor;
+            if (params.pVersion == null) {
+                major = -1;
+                minor = -1;
+            } else {
+                major = params.pVersion.major;
+                minor = params.pVersion.minor;
+            }
+            SecretKey key = P11Key.masterSecretKey(session, keyID,
+                "TlsMasterSecret", 48 << 3, attributes, major, minor);
+            return key;
+        } catch (Exception e) {
+            throw new ProviderException("Could not generate key", e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2005, 2014, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import sun.security.internal.spec.TlsPrfParameterSpec;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * KeyGenerator for the TLS PRF. Note that although the PRF is used in a number
+ * of places during the handshake, this class is usually only used to calculate
+ * the Finished messages. The reason is that for those other uses more specific
+ * PKCS#11 mechanisms have been defined (CKM_SSL3_MASTER_KEY_DERIVE, etc.).
+ *
+ * <p>This class supports the CKM_TLS_PRF mechanism from PKCS#11 v2.20 and
+ * the older NSS private mechanism.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.6
+ */
+final class P11TlsPrfGenerator extends KeyGeneratorSpi {
+
+    private final static String MSG =
+            "TlsPrfGenerator must be initialized using a TlsPrfParameterSpec";
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id
+    private final long mechanism;
+
+    @SuppressWarnings("deprecation")
+    private TlsPrfParameterSpec spec;
+
+    private P11Key p11Key;
+
+    P11TlsPrfGenerator(Token token, String algorithm, long mechanism)
+            throws PKCS11Exception {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+    }
+
+    protected void engineInit(SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    @SuppressWarnings("deprecation")
+    protected void engineInit(AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidAlgorithmParameterException {
+        if (params instanceof TlsPrfParameterSpec == false) {
+            throw new InvalidAlgorithmParameterException(MSG);
+        }
+        this.spec = (TlsPrfParameterSpec)params;
+        SecretKey key = spec.getSecret();
+        if (key == null) {
+            key = NULL_KEY;
+        }
+        try {
+            p11Key = P11SecretKeyFactory.convertKey(token, key, null);
+        } catch (InvalidKeyException e) {
+            throw new InvalidAlgorithmParameterException("init() failed", e);
+        }
+    }
+
+    // SecretKeySpec does not allow zero length keys, so we define our
+    // own class.
+    //
+    // As an anonymous class cannot make any guarantees about serialization
+    // compatibility, it is nonsensical for an anonymous class to define a
+    // serialVersionUID. Suppress warnings relative to missing serialVersionUID
+    // field in the anonymous subclass of serializable SecretKey.
+    @SuppressWarnings("serial")
+    private static final SecretKey NULL_KEY = new SecretKey() {
+        public byte[] getEncoded() {
+            return new byte[0];
+        }
+        public String getFormat() {
+            return "RAW";
+        }
+        public String getAlgorithm() {
+            return "Generic";
+        }
+    };
+
+    protected void engineInit(int keysize, SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    protected SecretKey engineGenerateKey() {
+        if (spec == null) {
+            throw new IllegalStateException("TlsPrfGenerator must be initialized");
+        }
+        byte[] label = P11Util.getBytesUTF8(spec.getLabel());
+        byte[] seed = spec.getSeed();
+
+        if (mechanism == CKM_NSS_TLS_PRF_GENERAL) {
+            Session session = null;
+            try {
+                session = token.getOpSession();
+                token.p11.C_SignInit
+                    (session.id(), new CK_MECHANISM(mechanism), p11Key.keyID);
+                token.p11.C_SignUpdate(session.id(), 0, label, 0, label.length);
+                token.p11.C_SignUpdate(session.id(), 0, seed, 0, seed.length);
+                byte[] out = token.p11.C_SignFinal
+                                    (session.id(), spec.getOutputLength());
+                return new SecretKeySpec(out, "TlsPrf");
+            } catch (PKCS11Exception e) {
+                throw new ProviderException("Could not calculate PRF", e);
+            } finally {
+                token.releaseSession(session);
+            }
+        }
+
+        // mechanism == CKM_TLS_PRF
+
+        byte[] out = new byte[spec.getOutputLength()];
+        CK_TLS_PRF_PARAMS params = new CK_TLS_PRF_PARAMS(seed, label, out);
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            long keyID = token.p11.C_DeriveKey(session.id(),
+                new CK_MECHANISM(mechanism, params), p11Key.keyID, null);
+            // ignore keyID, returned PRF bytes are in 'out'
+            return new SecretKeySpec(out, "TlsPrf");
+        } catch (PKCS11Exception e) {
+            throw new ProviderException("Could not calculate PRF", e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2005, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.security.*;
+import java.security.spec.AlgorithmParameterSpec;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
+
+import static sun.security.pkcs11.TemplateManager.*;
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * KeyGenerator for the SSL/TLS RSA premaster secret.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.6
+ */
+final class P11TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
+
+    private final static String MSG = "TlsRsaPremasterSecretGenerator must be "
+        + "initialized using a TlsRsaPremasterSecretParameterSpec";
+
+    // token instance
+    private final Token token;
+
+    // algorithm name
+    private final String algorithm;
+
+    // mechanism id
+    private long mechanism;
+
+    @SuppressWarnings("deprecation")
+    private TlsRsaPremasterSecretParameterSpec spec;
+
+    // whether SSLv3 is supported
+    private final boolean supportSSLv3;
+
+    P11TlsRsaPremasterSecretGenerator(Token token, String algorithm, long mechanism)
+            throws PKCS11Exception {
+        super();
+        this.token = token;
+        this.algorithm = algorithm;
+        this.mechanism = mechanism;
+
+        // Given the current lookup order specified in SunPKCS11.java,
+        // if CKM_SSL3_PRE_MASTER_KEY_GEN is not used to construct this object,
+        // it means that this mech is disabled or unsupported.
+        this.supportSSLv3 = (mechanism == CKM_SSL3_PRE_MASTER_KEY_GEN);
+    }
+
+    protected void engineInit(SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    @SuppressWarnings("deprecation")
+    protected void engineInit(AlgorithmParameterSpec params,
+            SecureRandom random) throws InvalidAlgorithmParameterException {
+        if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
+            throw new InvalidAlgorithmParameterException(MSG);
+        }
+
+        TlsRsaPremasterSecretParameterSpec spec =
+            (TlsRsaPremasterSecretParameterSpec) params;
+
+        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
+
+        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
+            (version > 0x0302)) {
+             throw new InvalidAlgorithmParameterException
+                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
+                     " TLS 1.0, and TLS 1.1 are supported (0x" +
+                     Integer.toHexString(version) + ")");
+        }
+        this.spec = spec;
+    }
+
+    protected void engineInit(int keysize, SecureRandom random) {
+        throw new InvalidParameterException(MSG);
+    }
+
+    // Only can be used in client side to generate TLS RSA premaster secret.
+    protected SecretKey engineGenerateKey() {
+        if (spec == null) {
+            throw new IllegalStateException
+                        ("TlsRsaPremasterSecretGenerator must be initialized");
+        }
+
+        CK_VERSION version = new CK_VERSION(
+                        spec.getMajorVersion(), spec.getMinorVersion());
+        Session session = null;
+        try {
+            session = token.getObjSession();
+            CK_ATTRIBUTE[] attributes = token.getAttributes(
+                    O_GENERATE, CKO_SECRET_KEY,
+                    CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
+            long keyID = token.p11.C_GenerateKey(session.id(),
+                    new CK_MECHANISM(mechanism, version), attributes);
+            SecretKey key = P11Key.secretKey(session,
+                    keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
+            return key;
+        } catch (PKCS11Exception e) {
+            throw new ProviderException(
+                    "Could not generate premaster secret", e);
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Util.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2003, 2014, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.math.BigInteger;
+import java.security.*;
+
+/**
+ * Collection of static utility methods.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+public final class P11Util {
+
+    private static Object LOCK = new Object();
+
+    private static volatile Provider sun, sunRsaSign, sunJce;
+
+    private P11Util() {
+        // empty
+    }
+
+    static Provider getSunProvider() {
+        Provider p = sun;
+        if (p == null) {
+            synchronized (LOCK) {
+                p = getProvider
+                    (sun, "SUN", "sun.security.provider.Sun");
+                sun = p;
+            }
+        }
+        return p;
+    }
+
+    static Provider getSunRsaSignProvider() {
+        Provider p = sunRsaSign;
+        if (p == null) {
+            synchronized (LOCK) {
+                p = getProvider
+                    (sunRsaSign, "SunRsaSign", "sun.security.rsa.SunRsaSign");
+                sunRsaSign = p;
+            }
+        }
+        return p;
+    }
+
+    static Provider getSunJceProvider() {
+        Provider p = sunJce;
+        if (p == null) {
+            synchronized (LOCK) {
+                p = getProvider
+                    (sunJce, "SunJCE", "com.sun.crypto.provider.SunJCE");
+                sunJce = p;
+            }
+        }
+        return p;
+    }
+
+    private static Provider getProvider(Provider p, String providerName,
+            String className) {
+        if (p != null) {
+            return p;
+        }
+        p = Security.getProvider(providerName);
+        if (p == null) {
+            try {
+                @SuppressWarnings("deprecation")
+                Object o = Class.forName(className).newInstance();
+                p = (Provider)o;
+            } catch (Exception e) {
+                throw new ProviderException
+                        ("Could not find provider " + providerName, e);
+            }
+        }
+        return p;
+    }
+
+    static byte[] convert(byte[] input, int offset, int len) {
+        if ((offset == 0) && (len == input.length)) {
+            return input;
+        } else {
+            byte[] t = new byte[len];
+            System.arraycopy(input, offset, t, 0, len);
+            return t;
+        }
+    }
+
+    static byte[] subarray(byte[] b, int ofs, int len) {
+        byte[] out = new byte[len];
+        System.arraycopy(b, ofs, out, 0, len);
+        return out;
+    }
+
+    static byte[] concat(byte[] b1, byte[] b2) {
+        byte[] b = new byte[b1.length + b2.length];
+        System.arraycopy(b1, 0, b, 0, b1.length);
+        System.arraycopy(b2, 0, b, b1.length, b2.length);
+        return b;
+    }
+
+    static long[] concat(long[] b1, long[] b2) {
+        if (b1.length == 0) {
+            return b2;
+        }
+        long[] b = new long[b1.length + b2.length];
+        System.arraycopy(b1, 0, b, 0, b1.length);
+        System.arraycopy(b2, 0, b, b1.length, b2.length);
+        return b;
+    }
+
+    public static byte[] getMagnitude(BigInteger bi) {
+        byte[] b = bi.toByteArray();
+        if ((b.length > 1) && (b[0] == 0)) {
+            int n = b.length - 1;
+            byte[] newarray = new byte[n];
+            System.arraycopy(b, 1, newarray, 0, n);
+            b = newarray;
+        }
+        return b;
+    }
+
+    static byte[] getBytesUTF8(String s) {
+        try {
+            return s.getBytes("UTF8");
+        } catch (java.io.UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    static byte[] sha1(byte[] data) {
+        try {
+            MessageDigest md = MessageDigest.getInstance("SHA-1");
+            md.update(data);
+            return md.digest();
+        } catch (GeneralSecurityException e) {
+            throw new ProviderException(e);
+        }
+    }
+
+    private final static char[] hexDigits = "0123456789abcdef".toCharArray();
+
+    static String toString(byte[] b) {
+        if (b == null) {
+            return "(null)";
+        }
+        StringBuilder sb = new StringBuilder(b.length * 3);
+        for (int i = 0; i < b.length; i++) {
+            int k = b[i] & 0xff;
+            if (i != 0) {
+                sb.append(':');
+            }
+            sb.append(hexDigits[k >>> 4]);
+            sb.append(hexDigits[k & 0xf]);
+        }
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Secmod.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,787 @@
+/*
+ * Copyright (c) 2005, 2015, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.io.*;
+import java.util.*;
+
+import java.security.*;
+import java.security.KeyStore.*;
+import java.security.cert.X509Certificate;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+
+/**
+ * The Secmod class defines the interface to the native NSS
+ * library and the configuration information it stores in its
+ * secmod.db file.
+ *
+ * <p>Example code:
+ * <pre>
+ *   Secmod secmod = Secmod.getInstance();
+ *   if (secmod.isInitialized() == false) {
+ *       secmod.initialize("/home/myself/.mozilla");
+ *   }
+ *
+ *   Provider p = secmod.getModule(ModuleType.KEYSTORE).getProvider();
+ *   KeyStore ks = KeyStore.getInstance("PKCS11", p);
+ *   ks.load(null, password);
+ * </pre>
+ *
+ * @since   1.6
+ * @author  Andreas Sterbenz
+ */
+public final class Secmod {
+
+    private final static boolean DEBUG = false;
+
+    private final static Secmod INSTANCE;
+
+    static {
+        sun.security.pkcs11.wrapper.PKCS11.loadNative();
+        INSTANCE = new Secmod();
+    }
+
+    private final static String NSS_LIB_NAME = "nss3";
+
+    private final static String SOFTTOKEN_LIB_NAME = "softokn3";
+
+    private final static String TRUST_LIB_NAME = "nssckbi";
+
+    // handle to be passed to the native code, 0 means not initialized
+    private long nssHandle;
+
+    // whether this is a supported version of NSS
+    private boolean supported;
+
+    // list of the modules
+    private List<Module> modules;
+
+    private String configDir;
+
+    private String nssLibDir;
+
+    private Secmod() {
+        // empty
+    }
+
+    /**
+     * Return the singleton Secmod instance.
+     */
+    public static Secmod getInstance() {
+        return INSTANCE;
+    }
+
+    private boolean isLoaded() {
+        if (nssHandle == 0) {
+            nssHandle = nssGetLibraryHandle(System.mapLibraryName(NSS_LIB_NAME));
+            if (nssHandle != 0) {
+                fetchVersions();
+            }
+        }
+        return (nssHandle != 0);
+    }
+
+    private void fetchVersions() {
+        supported = nssVersionCheck(nssHandle, "3.7");
+    }
+
+    /**
+     * Test whether this Secmod has been initialized. Returns true
+     * if NSS has been initialized using either the initialize() method
+     * or by directly calling the native NSS APIs. The latter may be
+     * the case if the current process contains components that use
+     * NSS directly.
+     *
+     * @throws IOException if an incompatible version of NSS
+     *   has been loaded
+     */
+    public synchronized boolean isInitialized() throws IOException {
+        // NSS does not allow us to check if it is initialized already
+        // assume that if it is loaded it is also initialized
+        if (isLoaded() == false) {
+            return false;
+        }
+        if (supported == false) {
+            throw new IOException
+                ("An incompatible version of NSS is already loaded, "
+                + "3.7 or later required");
+        }
+        return true;
+    }
+
+    String getConfigDir() {
+        return configDir;
+    }
+
+    String getLibDir() {
+        return nssLibDir;
+    }
+
+    /**
+     * Initialize this Secmod.
+     *
+     * @param configDir the directory containing the NSS configuration
+     *   files such as secmod.db
+     * @param nssLibDir the directory containing the NSS libraries
+     *   (libnss3.so or nss3.dll) or null if the library is on
+     *   the system default shared library path
+     *
+     * @throws IOException if NSS has already been initialized,
+     *   the specified directories are invalid, or initialization
+     *   fails for any other reason
+     */
+    public void initialize(String configDir, String nssLibDir)
+            throws IOException {
+        initialize(DbMode.READ_WRITE, configDir, nssLibDir, false);
+    }
+
+    public void initialize(DbMode dbMode, String configDir, String nssLibDir)
+            throws IOException {
+        initialize(dbMode, configDir, nssLibDir, false);
+    }
+
+    public synchronized void initialize(DbMode dbMode, String configDir,
+        String nssLibDir, boolean nssOptimizeSpace) throws IOException {
+
+        if (isInitialized()) {
+            throw new IOException("NSS is already initialized");
+        }
+
+        if (dbMode == null) {
+            throw new NullPointerException();
+        }
+        if ((dbMode != DbMode.NO_DB) && (configDir == null)) {
+            throw new NullPointerException();
+        }
+        String platformLibName = System.mapLibraryName("nss3");
+        String platformPath;
+        if (nssLibDir == null) {
+            platformPath = platformLibName;
+        } else {
+            File base = new File(nssLibDir);
+            if (base.isDirectory() == false) {
+                throw new IOException("nssLibDir must be a directory:" + nssLibDir);
+            }
+            File platformFile = new File(base, platformLibName);
+            if (platformFile.isFile() == false) {
+                throw new FileNotFoundException(platformFile.getPath());
+            }
+            platformPath = platformFile.getPath();
+        }
+
+        if (configDir != null) {
+            File configBase = new File(configDir);
+            if (configBase.isDirectory() == false ) {
+                throw new IOException("configDir must be a directory: " + configDir);
+            }
+            File secmodFile = new File(configBase, "secmod.db");
+            if (secmodFile.isFile() == false) {
+                throw new FileNotFoundException(secmodFile.getPath());
+            }
+        }
+
+        if (DEBUG) System.out.println("lib: " + platformPath);
+        nssHandle = nssLoadLibrary(platformPath);
+        if (DEBUG) System.out.println("handle: " + nssHandle);
+        fetchVersions();
+        if (supported == false) {
+            throw new IOException
+                ("The specified version of NSS is incompatible, "
+                + "3.7 or later required");
+        }
+
+        if (DEBUG) System.out.println("dir: " + configDir);
+        boolean initok = nssInitialize(dbMode.functionName, nssHandle,
+            configDir, nssOptimizeSpace);
+        if (DEBUG) System.out.println("init: " + initok);
+        if (initok == false) {
+            throw new IOException("NSS initialization failed");
+        }
+
+        this.configDir = configDir;
+        this.nssLibDir = nssLibDir;
+    }
+
+    /**
+     * Return an immutable list of all available modules.
+     *
+     * @throws IllegalStateException if this Secmod is misconfigured
+     *   or not initialized
+     */
+    public synchronized List<Module> getModules() {
+        try {
+            if (isInitialized() == false) {
+                throw new IllegalStateException("NSS not initialized");
+            }
+        } catch (IOException e) {
+            // IOException if misconfigured
+            throw new IllegalStateException(e);
+        }
+        if (modules == null) {
+            @SuppressWarnings("unchecked")
+            List<Module> modules = (List<Module>)nssGetModuleList(nssHandle,
+                nssLibDir);
+            this.modules = Collections.unmodifiableList(modules);
+        }
+        return modules;
+    }
+
+    private static byte[] getDigest(X509Certificate cert, String algorithm) {
+        try {
+            MessageDigest md = MessageDigest.getInstance(algorithm);
+            return md.digest(cert.getEncoded());
+        } catch (GeneralSecurityException e) {
+            throw new ProviderException(e);
+        }
+    }
+
+    boolean isTrusted(X509Certificate cert, TrustType trustType) {
+        Bytes bytes = new Bytes(getDigest(cert, "SHA-1"));
+        TrustAttributes attr = getModuleTrust(ModuleType.KEYSTORE, bytes);
+        if (attr == null) {
+            attr = getModuleTrust(ModuleType.FIPS, bytes);
+            if (attr == null) {
+                attr = getModuleTrust(ModuleType.TRUSTANCHOR, bytes);
+            }
+        }
+        return (attr == null) ? false : attr.isTrusted(trustType);
+    }
+
+    private TrustAttributes getModuleTrust(ModuleType type, Bytes bytes) {
+        Module module = getModule(type);
+        TrustAttributes t = (module == null) ? null : module.getTrust(bytes);
+        return t;
+    }
+
+    /**
+     * Constants describing the different types of NSS modules.
+     * For this API, NSS modules are classified as either one
+     * of the internal modules delivered as part of NSS or
+     * as an external module provided by a 3rd party.
+     */
+    public static enum ModuleType {
+        /**
+         * The NSS Softtoken crypto module. This is the first
+         * slot of the softtoken object.
+         * This module provides
+         * implementations for cryptographic algorithms but no KeyStore.
+         */
+        CRYPTO,
+        /**
+         * The NSS Softtoken KeyStore module. This is the second
+         * slot of the softtoken object.
+         * This module provides
+         * implementations for cryptographic algorithms (after login)
+         * and the KeyStore.
+         */
+        KEYSTORE,
+        /**
+         * The NSS Softtoken module in FIPS mode. Note that in FIPS mode the
+         * softtoken presents only one slot, not separate CRYPTO and KEYSTORE
+         * slots as in non-FIPS mode.
+         */
+        FIPS,
+        /**
+         * The NSS builtin trust anchor module. This is the
+         * NSSCKBI object. It provides no crypto functions.
+         */
+        TRUSTANCHOR,
+        /**
+         * An external module.
+         */
+        EXTERNAL,
+    }
+
+    /**
+     * Returns the first module of the specified type. If no such
+     * module exists, this method returns null.
+     *
+     * @throws IllegalStateException if this Secmod is misconfigured
+     *   or not initialized
+     */
+    public Module getModule(ModuleType type) {
+        for (Module module : getModules()) {
+            if (module.getType() == type) {
+                return module;
+            }
+        }
+        return null;
+    }
+
+    static final String TEMPLATE_EXTERNAL =
+        "library = %s\n"
+        + "name = \"%s\"\n"
+        + "slotListIndex = %d\n";
+
+    static final String TEMPLATE_TRUSTANCHOR =
+        "library = %s\n"
+        + "name = \"NSS Trust Anchors\"\n"
+        + "slotListIndex = 0\n"
+        + "enabledMechanisms = { KeyStore }\n"
+        + "nssUseSecmodTrust = true\n";
+
+    static final String TEMPLATE_CRYPTO =
+        "library = %s\n"
+        + "name = \"NSS SoftToken Crypto\"\n"
+        + "slotListIndex = 0\n"
+        + "disabledMechanisms = { KeyStore }\n";
+
+    static final String TEMPLATE_KEYSTORE =
+        "library = %s\n"
+        + "name = \"NSS SoftToken KeyStore\"\n"
+        + "slotListIndex = 1\n"
+        + "nssUseSecmodTrust = true\n";
+
+    static final String TEMPLATE_FIPS =
+        "library = %s\n"
+        + "name = \"NSS FIPS SoftToken\"\n"
+        + "slotListIndex = 0\n"
+        + "nssUseSecmodTrust = true\n";
+
+    /**
+     * A representation of one PKCS#11 slot in a PKCS#11 module.
+     */
+    public static final class Module {
+        // path of the native library
+        final String libraryName;
+        // descriptive name used by NSS
+        final String commonName;
+        final int slot;
+        final ModuleType type;
+
+        private String config;
+        private SunPKCS11 provider;
+
+        // trust attributes. Used for the KEYSTORE and TRUSTANCHOR modules only
+        private Map<Bytes,TrustAttributes> trust;
+
+        Module(String libraryDir, String libraryName, String commonName,
+                boolean fips, int slot) {
+            ModuleType type;
+
+            if ((libraryName == null) || (libraryName.length() == 0)) {
+                // must be softtoken
+                libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME);
+                if (fips == false) {
+                    type = (slot == 0) ? ModuleType.CRYPTO : ModuleType.KEYSTORE;
+                } else {
+                    type = ModuleType.FIPS;
+                    if (slot != 0) {
+                        throw new RuntimeException
+                            ("Slot index should be 0 for FIPS slot");
+                    }
+                }
+            } else {
+                if (libraryName.endsWith(System.mapLibraryName(TRUST_LIB_NAME))
+                        || commonName.equals("Builtin Roots Module")) {
+                    type = ModuleType.TRUSTANCHOR;
+                } else {
+                    type = ModuleType.EXTERNAL;
+                }
+                if (fips) {
+                    throw new RuntimeException("FIPS flag set for non-internal "
+                        + "module: " + libraryName + ", " + commonName);
+                }
+            }
+            // On Ubuntu the libsoftokn3 library is located in a subdirectory
+            // of the system libraries directory. (Since Ubuntu 11.04.)
+            File libraryFile = new File(libraryDir, libraryName);
+            if (!libraryFile.isFile()) {
+               File failover = new File(libraryDir, "nss/" + libraryName);
+               if (failover.isFile()) {
+                   libraryFile = failover;
+               }
+            }
+            this.libraryName = libraryFile.getPath();
+            this.commonName = commonName;
+            this.slot = slot;
+            this.type = type;
+            initConfiguration();
+        }
+
+        private void initConfiguration() {
+            switch (type) {
+            case EXTERNAL:
+                config = String.format(TEMPLATE_EXTERNAL, libraryName,
+                                            commonName + " " + slot, slot);
+                break;
+            case CRYPTO:
+                config = String.format(TEMPLATE_CRYPTO, libraryName);
+                break;
+            case KEYSTORE:
+                config = String.format(TEMPLATE_KEYSTORE, libraryName);
+                break;
+            case FIPS:
+                config = String.format(TEMPLATE_FIPS, libraryName);
+                break;
+            case TRUSTANCHOR:
+                config = String.format(TEMPLATE_TRUSTANCHOR, libraryName);
+                break;
+            default:
+                throw new RuntimeException("Unknown module type: " + type);
+            }
+        }
+
+        /**
+         * Get the configuration for this module. This is a string
+         * in the SunPKCS11 configuration format. It can be
+         * customized with additional options and then made
+         * current using the setConfiguration() method.
+         */
+        @Deprecated
+        public synchronized String getConfiguration() {
+            return config;
+        }
+
+        /**
+         * Set the configuration for this module.
+         *
+         * @throws IllegalStateException if the associated provider
+         *   instance has already been created.
+         */
+        @Deprecated
+        public synchronized void setConfiguration(String config) {
+            if (provider != null) {
+                throw new IllegalStateException("Provider instance already created");
+            }
+            this.config = config;
+        }
+
+        /**
+         * Return the pathname of the native library that implements
+         * this module. For example, /usr/lib/libpkcs11.so.
+         */
+        public String getLibraryName() {
+            return libraryName;
+        }
+
+        /**
+         * Returns the type of this module.
+         */
+        public ModuleType getType() {
+            return type;
+        }
+
+        /**
+         * Returns the provider instance that is associated with this
+         * module. The first call to this method creates the provider
+         * instance.
+         */
+        @Deprecated
+        public synchronized Provider getProvider() {
+            if (provider == null) {
+                provider = newProvider();
+            }
+            return provider;
+        }
+
+        synchronized boolean hasInitializedProvider() {
+            return provider != null;
+        }
+
+        void setProvider(SunPKCS11 p) {
+            if (provider != null) {
+                throw new ProviderException("Secmod provider already initialized");
+            }
+            provider = p;
+        }
+
+        private SunPKCS11 newProvider() {
+            try {
+                return new SunPKCS11(new Config("--" + config));
+            } catch (Exception e) {
+                // XXX
+                throw new ProviderException(e);
+            }
+        }
+
+        synchronized void setTrust(Token token, X509Certificate cert) {
+            Bytes bytes = new Bytes(getDigest(cert, "SHA-1"));
+            TrustAttributes attr = getTrust(bytes);
+            if (attr == null) {
+                attr = new TrustAttributes(token, cert, bytes, CKT_NETSCAPE_TRUSTED_DELEGATOR);
+                trust.put(bytes, attr);
+            } else {
+                // does it already have the correct trust settings?
+                if (attr.isTrusted(TrustType.ALL) == false) {
+                    // XXX not yet implemented
+                    throw new ProviderException("Cannot change existing trust attributes");
+                }
+            }
+        }
+
+        TrustAttributes getTrust(Bytes hash) {
+            if (trust == null) {
+                // If provider is not set, create a temporary provider to
+                // retrieve the trust information. This can happen if we need
+                // to get the trust information for the trustanchor module
+                // because we need to look for user customized settings in the
+                // keystore module (which may not have a provider created yet).
+                // Creating a temporary provider and then dropping it on the
+                // floor immediately is flawed, but it's the best we can do
+                // for now.
+                synchronized (this) {
+                    SunPKCS11 p = provider;
+                    if (p == null) {
+                        p = newProvider();
+                    }
+                    try {
+                        trust = Secmod.getTrust(p);
+                    } catch (PKCS11Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }
+            return trust.get(hash);
+        }
+
+        public String toString() {
+            return
+            commonName + " (" + type + ", " + libraryName + ", slot " + slot + ")";
+        }
+
+    }
+
+    /**
+     * Constants representing NSS trust categories.
+     */
+    public static enum TrustType {
+        /** Trusted for all purposes */
+        ALL,
+        /** Trusted for SSL client authentication */
+        CLIENT_AUTH,
+        /** Trusted for SSL server authentication */
+        SERVER_AUTH,
+        /** Trusted for code signing */
+        CODE_SIGNING,
+        /** Trusted for email protection */
+        EMAIL_PROTECTION,
+    }
+
+    public static enum DbMode {
+        READ_WRITE("NSS_InitReadWrite"),
+        READ_ONLY ("NSS_Init"),
+        NO_DB     ("NSS_NoDB_Init");
+
+        final String functionName;
+        DbMode(String functionName) {
+            this.functionName = functionName;
+        }
+    }
+
+    /**
+     * A LoadStoreParameter for use with the NSS Softtoken or
+     * NSS TrustAnchor KeyStores.
+     * <p>
+     * It allows the set of trusted certificates that are returned by
+     * the KeyStore to be specified.
+     */
+    public static final class KeyStoreLoadParameter implements LoadStoreParameter {
+        final TrustType trustType;
+        final ProtectionParameter protection;
+        public KeyStoreLoadParameter(TrustType trustType, char[] password) {
+            this(trustType, new PasswordProtection(password));
+
+        }
+        public KeyStoreLoadParameter(TrustType trustType, ProtectionParameter prot) {
+            if (trustType == null) {
+                throw new NullPointerException("trustType must not be null");
+            }
+            this.trustType = trustType;
+            this.protection = prot;
+        }
+        public ProtectionParameter getProtectionParameter() {
+            return protection;
+        }
+        public TrustType getTrustType() {
+            return trustType;
+        }
+    }
+
+    static class TrustAttributes {
+        final long handle;
+        final long clientAuth, serverAuth, codeSigning, emailProtection;
+        final byte[] shaHash;
+        TrustAttributes(Token token, X509Certificate cert, Bytes bytes, long trustValue) {
+            Session session = null;
+            try {
+                session = token.getOpSession();
+                // XXX use KeyStore TrustType settings to determine which
+                // attributes to set
+                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                    new CK_ATTRIBUTE(CKA_TOKEN, true),
+                    new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST),
+                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH, trustValue),
+                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING, trustValue),
+                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, trustValue),
+                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH, trustValue),
+                    new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH, bytes.b),
+                    new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_MD5_HASH, getDigest(cert, "MD5")),
+                    new CK_ATTRIBUTE(CKA_ISSUER, cert.getIssuerX500Principal().getEncoded()),
+                    new CK_ATTRIBUTE(CKA_SERIAL_NUMBER, cert.getSerialNumber().toByteArray()),
+                    // XXX per PKCS#11 spec, the serial number should be in ASN.1
+                };
+                handle = token.p11.C_CreateObject(session.id(), attrs);
+                shaHash = bytes.b;
+                clientAuth = trustValue;
+                serverAuth = trustValue;
+                codeSigning = trustValue;
+                emailProtection = trustValue;
+            } catch (PKCS11Exception e) {
+                throw new ProviderException("Could not create trust object", e);
+            } finally {
+                token.releaseSession(session);
+            }
+        }
+        TrustAttributes(Token token, Session session, long handle)
+                        throws PKCS11Exception {
+            this.handle = handle;
+            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH),
+                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING),
+                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION),
+                new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH),
+            };
+
+            token.p11.C_GetAttributeValue(session.id(), handle, attrs);
+            serverAuth = attrs[0].getLong();
+            codeSigning = attrs[1].getLong();
+            emailProtection = attrs[2].getLong();
+            shaHash = attrs[3].getByteArray();
+
+            attrs = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH),
+            };
+            long c;
+            try {
+                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
+                c = attrs[0].getLong();
+            } catch (PKCS11Exception e) {
+                // trust anchor module does not support this attribute
+                c = serverAuth;
+            }
+            clientAuth = c;
+        }
+        Bytes getHash() {
+            return new Bytes(shaHash);
+        }
+        boolean isTrusted(TrustType type) {
+            switch (type) {
+            case CLIENT_AUTH:
+                return isTrusted(clientAuth);
+            case SERVER_AUTH:
+                return isTrusted(serverAuth);
+            case CODE_SIGNING:
+                return isTrusted(codeSigning);
+            case EMAIL_PROTECTION:
+                return isTrusted(emailProtection);
+            case ALL:
+                return isTrusted(TrustType.CLIENT_AUTH)
+                    && isTrusted(TrustType.SERVER_AUTH)
+                    && isTrusted(TrustType.CODE_SIGNING)
+                    && isTrusted(TrustType.EMAIL_PROTECTION);
+            default:
+                return false;
+            }
+        }
+
+        private boolean isTrusted(long l) {
+            // XXX CKT_TRUSTED?
+            return (l == CKT_NETSCAPE_TRUSTED_DELEGATOR);
+        }
+
+    }
+
+    private static class Bytes {
+        final byte[] b;
+        Bytes(byte[] b) {
+            this.b = b;
+        }
+        public int hashCode() {
+            return Arrays.hashCode(b);
+        }
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o instanceof Bytes == false) {
+                return false;
+            }
+            Bytes other = (Bytes)o;
+            return Arrays.equals(this.b, other.b);
+        }
+    }
+
+    private static Map<Bytes,TrustAttributes> getTrust(SunPKCS11 provider)
+            throws PKCS11Exception {
+        Map<Bytes,TrustAttributes> trustMap = new HashMap<Bytes,TrustAttributes>();
+        Token token = provider.getToken();
+        Session session = null;
+        boolean exceptionOccurred = true;
+        try {
+            session = token.getOpSession();
+            int MAX_NUM = 8192;
+            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
+                new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST),
+            };
+            token.p11.C_FindObjectsInit(session.id(), attrs);
+            long[] handles = token.p11.C_FindObjects(session.id(), MAX_NUM);
+            token.p11.C_FindObjectsFinal(session.id());
+            if (DEBUG) System.out.println("handles: " + handles.length);
+
+            for (long handle : handles) {
+                try {
+                    TrustAttributes trust = new TrustAttributes(token, session, handle);
+                    trustMap.put(trust.getHash(), trust);
+                } catch (PKCS11Exception e) {
+                    // skip put on pkcs11 error
+                }
+            }
+            exceptionOccurred = false;
+        } finally {
+            if (exceptionOccurred) {
+                token.killSession(session);
+            } else {
+                token.releaseSession(session);
+            }
+        }
+        return trustMap;
+    }
+
+    private static native long nssGetLibraryHandle(String libraryName);
+
+    private static native long nssLoadLibrary(String name) throws IOException;
+
+    private static native boolean nssVersionCheck(long handle, String minVersion);
+
+    private static native boolean nssInitialize(String functionName, long handle, String configDir, boolean nssOptimizeSpace);
+
+    private static native Object nssGetModuleList(long handle, String libDir);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Session.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2003, 2011, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.lang.ref.*;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import java.security.*;
+
+import sun.security.pkcs11.wrapper.*;
+
+/**
+ * A session object. Sessions are obtained via the SessionManager,
+ * see there for details. Most code will only ever need one method in
+ * this class, the id() method to obtain the session id.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class Session implements Comparable<Session> {
+
+    // time after which to close idle sessions, in milliseconds (3 minutes)
+    private final static long MAX_IDLE_TIME = 3 * 60 * 1000;
+
+    // token instance
+    final Token token;
+
+    // session id
+    private final long id;
+
+    // number of objects created within this session
+    private final AtomicInteger createdObjects;
+
+    // time this session was last used
+    // not synchronized/volatile for performance, so may be unreliable
+    // this could lead to idle sessions being closed early, but that is harmless
+    private long lastAccess;
+
+    private final SessionRef sessionRef;
+
+    Session(Token token, long id) {
+        this.token = token;
+        this.id = id;
+        createdObjects = new AtomicInteger();
+        id();
+        sessionRef = new SessionRef(this, id, token);
+    }
+
+    public int compareTo(Session other) {
+        if (this.lastAccess == other.lastAccess) {
+            return 0;
+        } else {
+            return (this.lastAccess < other.lastAccess) ? -1 : 1;
+        }
+    }
+
+    boolean isLive(long currentTime) {
+        return currentTime - lastAccess < MAX_IDLE_TIME;
+    }
+
+    long idInternal() {
+        return id;
+    }
+
+    long id() {
+        if (token.isPresent(this.id) == false) {
+            throw new ProviderException("Token has been removed");
+        }
+        lastAccess = System.currentTimeMillis();
+        return id;
+    }
+
+    void addObject() {
+        int n = createdObjects.incrementAndGet();
+        // XXX update statistics in session manager if n == 1
+    }
+
+    void removeObject() {
+        int n = createdObjects.decrementAndGet();
+        if (n == 0) {
+            token.sessionManager.demoteObjSession(this);
+        } else if (n < 0) {
+            throw new ProviderException("Internal error: objects created " + n);
+        }
+    }
+
+    boolean hasObjects() {
+        return createdObjects.get() != 0;
+    }
+
+    void close() {
+        if (hasObjects()) {
+            throw new ProviderException(
+                "Internal error: close session with active objects");
+        }
+        sessionRef.dispose();
+    }
+}
+
+/*
+ * NOTE: Use PhantomReference here and not WeakReference
+ * otherwise the sessions maybe closed before other objects
+ * which are still being finalized.
+ */
+final class SessionRef extends PhantomReference<Session>
+        implements Comparable<SessionRef> {
+
+    private static ReferenceQueue<Session> refQueue =
+        new ReferenceQueue<Session>();
+
+    private static Set<SessionRef> refList =
+        Collections.synchronizedSortedSet(new TreeSet<SessionRef>());
+
+    static ReferenceQueue<Session> referenceQueue() {
+        return refQueue;
+    }
+
+    static int totalCount() {
+        return refList.size();
+    }
+
+    private static void drainRefQueueBounded() {
+        while (true) {
+            SessionRef next = (SessionRef) refQueue.poll();
+            if (next == null) break;
+            next.dispose();
+        }
+    }
+
+    // handle to the native session
+    private long id;
+    private Token token;
+
+    SessionRef(Session session, long id, Token token) {
+        super(session, refQueue);
+        this.id = id;
+        this.token = token;
+        refList.add(this);
+        // TBD: run at some interval and not every time?
+        drainRefQueueBounded();
+    }
+
+    void dispose() {
+        refList.remove(this);
+        try {
+            if (token.isPresent(id)) {
+                token.p11.C_CloseSession(id);
+            }
+        } catch (PKCS11Exception e1) {
+            // ignore
+        } catch (ProviderException e2) {
+            // ignore
+        } finally {
+            this.clear();
+        }
+    }
+
+    public int compareTo(SessionRef other) {
+        if (this.id == other.id) {
+            return 0;
+        } else {
+            return (this.id < other.id) ? -1 : 1;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SessionManager.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2003, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.util.*;
+
+import java.security.ProviderException;
+
+import sun.security.util.Debug;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Session manager. There is one session manager object per PKCS#11
+ * provider. It allows code to checkout a session, release it
+ * back to the pool, or force it to be closed.
+ *
+ * The session manager pools sessions to minimize the number of
+ * C_OpenSession() and C_CloseSession() that have to be made. It
+ * maintains two pools: one for "object" sessions and one for
+ * "operation" sessions.
+ *
+ * The reason for this separation is how PKCS#11 deals with session objects.
+ * It defines that when a session is closed, all objects created within
+ * that session are destroyed. In other words, we may never close a session
+ * while a Key created it in is still in use. We would like to keep the
+ * number of such sessions low. Note that we occasionally want to explicitly
+ * close a session, see P11Signature.
+ *
+ * NOTE that sessions obtained from this class SHOULD be returned using
+ * either releaseSession() or closeSession() using a finally block when
+ * not needed anymore. Otherwise, they will be left for cleanup via the
+ * PhantomReference mechanism when GC kicks in, but it's best not to rely
+ * on that since GC may not run timely enough since the native PKCS11 library
+ * is also consuming memory.
+ *
+ * Note that sessions are automatically closed when they are not used for a
+ * period of time, see Session.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class SessionManager {
+
+    private final static int DEFAULT_MAX_SESSIONS = 32;
+
+    private final static Debug debug = Debug.getInstance("pkcs11");
+
+    // token instance
+    private final Token token;
+
+    // maximum number of sessions to open with this token
+    private final int maxSessions;
+
+    // total number of active sessions
+    private AtomicInteger activeSessions = new AtomicInteger();
+
+    // pool of available object sessions
+    private final Pool objSessions;
+
+    // pool of available operation sessions
+    private final Pool opSessions;
+
+    // maximum number of active sessions during this invocation, for debugging
+    private int maxActiveSessions;
+    private Object maxActiveSessionsLock;
+
+    // flags to use in the C_OpenSession() call
+    private final long openSessionFlags;
+
+    SessionManager(Token token) {
+        long n;
+        if (token.isWriteProtected()) {
+            openSessionFlags = CKF_SERIAL_SESSION;
+            n = token.tokenInfo.ulMaxSessionCount;
+        } else {
+            openSessionFlags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
+            n = token.tokenInfo.ulMaxRwSessionCount;
+        }
+        if (n == CK_EFFECTIVELY_INFINITE) {
+            n = Integer.MAX_VALUE;
+        } else if ((n == CK_UNAVAILABLE_INFORMATION) || (n < 0)) {
+            // choose an arbitrary concrete value
+            n = DEFAULT_MAX_SESSIONS;
+        }
+        maxSessions = (int)Math.min(n, Integer.MAX_VALUE);
+        this.token = token;
+        this.objSessions = new Pool(this, true);
+        this.opSessions = new Pool(this, false);
+        if (debug != null) {
+            maxActiveSessionsLock = new Object();
+        }
+    }
+
+    // returns whether only a fairly low number of sessions are
+    // supported by this token.
+    boolean lowMaxSessions() {
+        return (maxSessions <= DEFAULT_MAX_SESSIONS);
+    }
+
+    Session getObjSession() throws PKCS11Exception {
+        Session session = objSessions.poll();
+        if (session != null) {
+            return ensureValid(session);
+        }
+        session = opSessions.poll();
+        if (session != null) {
+            return ensureValid(session);
+        }
+        session = openSession();
+        return ensureValid(session);
+    }
+
+    Session getOpSession() throws PKCS11Exception {
+        Session session = opSessions.poll();
+        if (session != null) {
+            return ensureValid(session);
+        }
+        // create a new session rather than re-using an obj session
+        // that avoids potential expensive cancels() for Signatures & RSACipher
+        if (maxSessions == Integer.MAX_VALUE ||
+                activeSessions.get() < maxSessions) {
+            session = openSession();
+            return ensureValid(session);
+        }
+        session = objSessions.poll();
+        if (session != null) {
+            return ensureValid(session);
+        }
+        throw new ProviderException("Could not obtain session");
+    }
+
+    private Session ensureValid(Session session) {
+        session.id();
+        return session;
+    }
+
+    Session killSession(Session session) {
+        if ((session == null) || (token.isValid() == false)) {
+            return null;
+        }
+        if (debug != null) {
+            String location = new Exception().getStackTrace()[2].toString();
+            System.out.println("Killing session (" + location + ") active: "
+                + activeSessions.get());
+        }
+        closeSession(session);
+        return null;
+    }
+
+    Session releaseSession(Session session) {
+        if ((session == null) || (token.isValid() == false)) {
+            return null;
+        }
+
+        if (session.hasObjects()) {
+            objSessions.release(session);
+        } else {
+            opSessions.release(session);
+        }
+        return null;
+    }
+
+    void demoteObjSession(Session session) {
+        if (token.isValid() == false) {
+            return;
+        }
+        if (debug != null) {
+            System.out.println("Demoting session, active: " +
+                activeSessions.get());
+        }
+        boolean present = objSessions.remove(session);
+        if (present == false) {
+            // session is currently in use
+            // will be added to correct pool on release, nothing to do now
+            return;
+        }
+        opSessions.release(session);
+    }
+
+    private Session openSession() throws PKCS11Exception {
+        if ((maxSessions != Integer.MAX_VALUE) &&
+                (activeSessions.get() >= maxSessions)) {
+            throw new ProviderException("No more sessions available");
+        }
+
+        long id = token.p11.C_OpenSession
+                    (token.provider.slotID, openSessionFlags, null, null);
+        Session session = new Session(token, id);
+        activeSessions.incrementAndGet();
+        if (debug != null) {
+            synchronized(maxActiveSessionsLock) {
+                if (activeSessions.get() > maxActiveSessions) {
+                    maxActiveSessions = activeSessions.get();
+                    if (maxActiveSessions % 10 == 0) {
+                        System.out.println("Open sessions: " + maxActiveSessions);
+                    }
+                }
+            }
+        }
+        return session;
+    }
+
+    private void closeSession(Session session) {
+        session.close();
+        activeSessions.decrementAndGet();
+    }
+
+    public static final class Pool {
+
+        private final SessionManager mgr;
+        private final AbstractQueue<Session> pool;
+        private final int SESSION_MAX = 5;
+
+        // Object session pools can contain unlimited sessions.
+        // Operation session pools are limited and enforced by the queue.
+        Pool(SessionManager mgr, boolean obj) {
+            this.mgr = mgr;
+            if (obj) {
+                pool = new LinkedBlockingQueue<Session>();
+            } else {
+                pool = new LinkedBlockingQueue<Session>(SESSION_MAX);
+            }
+        }
+
+        boolean remove(Session session) {
+            return pool.remove(session);
+        }
+
+        Session poll() {
+            return pool.poll();
+        }
+
+        void release(Session session) {
+            // Object session pools never return false, only Operation ones
+            if (!pool.offer(session)) {
+                mgr.closeSession(session);
+                free();
+            }
+        }
+
+        // Free any old operation session if this queue is full
+        void free() {
+            int n = SESSION_MAX;
+            int i = 0;
+            Session oldestSession;
+            long time = System.currentTimeMillis();
+            // Check if the session head is too old and continue through pool
+            // until only one is left.
+            do {
+                oldestSession = pool.peek();
+                if (oldestSession == null || oldestSession.isLive(time) ||
+                        !pool.remove(oldestSession)) {
+                    break;
+                }
+
+                i++;
+                mgr.closeSession(oldestSession);
+            } while ((n - i) > 1);
+
+            if (debug != null) {
+                System.out.println("Closing " + i + " idle sessions, active: "
+                        + mgr.activeSessions);
+            }
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,1506 @@
+/*
+ * Copyright (c) 2003, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.io.*;
+import java.util.*;
+
+import java.security.*;
+import java.security.interfaces.*;
+
+import javax.crypto.interfaces.*;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.ConfirmationCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.TextOutputCallback;
+
+import sun.security.util.Debug;
+import sun.security.util.ResourcesMgr;
+import static sun.security.util.SecurityConstants.PROVIDER_VER;
+
+import sun.security.pkcs11.Secmod.*;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * PKCS#11 provider main class.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+public final class SunPKCS11 extends AuthProvider {
+
+    private static final long serialVersionUID = -1354835039035306505L;
+
+    static final Debug debug = Debug.getInstance("sunpkcs11");
+
+    // the PKCS11 object through which we make the native calls
+    final PKCS11 p11;
+
+    // configuration information
+    final Config config;
+
+    // id of the PKCS#11 slot we are using
+    final long slotID;
+
+    private CallbackHandler pHandler;
+    private final Object LOCK_HANDLER = new Object();
+
+    final boolean removable;
+
+    final Module nssModule;
+
+    final boolean nssUseSecmodTrust;
+
+    private volatile Token token;
+
+    private TokenPoller poller;
+
+    Token getToken() {
+        return token;
+    }
+
+    public SunPKCS11() {
+        super("SunPKCS11", PROVIDER_VER,
+            "Unconfigured and unusable PKCS11 provider");
+        p11 = null;
+        config = null;
+        slotID = 0;
+        pHandler = null;
+        removable = false;
+        nssModule = null;
+        nssUseSecmodTrust = false;
+        token = null;
+        poller = null;
+    }
+
+    @Override
+    public Provider configure(String configArg) throws InvalidParameterException {
+        final String newConfigName = checkNull(configArg);
+        try {
+            return AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
+                @Override
+                public SunPKCS11 run() throws Exception {
+                    return new SunPKCS11(new Config(newConfigName));
+                }
+            });
+        } catch (PrivilegedActionException pae) {
+            InvalidParameterException ipe =
+                new InvalidParameterException("Error configuring SunPKCS11 provider");
+            throw (InvalidParameterException) ipe.initCause(pae.getException());
+        }
+    }
+
+    @Override
+    public boolean isConfigured() {
+        return (config != null);
+    }
+
+    private static <T> T checkNull(T obj) {
+        if (obj == null) {
+            throw new NullPointerException();
+        }
+        return obj;
+    }
+
+    // Used by Secmod
+    SunPKCS11(Config c) {
+        super("SunPKCS11-" + c.getName(), PROVIDER_VER, c.getDescription());
+        this.config = c;
+
+        if (debug != null) {
+            System.out.println("SunPKCS11 loading " + config.getFileName());
+        }
+
+        String library = config.getLibrary();
+        String functionList = config.getFunctionList();
+        long slotID = config.getSlotID();
+        int slotListIndex = config.getSlotListIndex();
+
+        boolean useSecmod = config.getNssUseSecmod();
+        boolean nssUseSecmodTrust = config.getNssUseSecmodTrust();
+        Module nssModule = null;
+
+        //
+        // Initialization via Secmod. The way this works is as follows:
+        // SunPKCS11 is either in normal mode or in NSS Secmod mode.
+        // Secmod is activated by specifying one or more of the following
+        // options in the config file:
+        // nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule
+        //
+        // XXX add more explanation here
+        //
+        // If we are in Secmod mode and configured to use either the
+        // nssKeyStore or the nssTrustAnchors module, we automatically
+        // switch to using the NSS trust attributes for trusted certs
+        // (KeyStore).
+        //
+
+        if (useSecmod) {
+            // note: Config ensures library/slot/slotListIndex not specified
+            // in secmod mode.
+            Secmod secmod = Secmod.getInstance();
+            DbMode nssDbMode = config.getNssDbMode();
+            try {
+                String nssLibraryDirectory = config.getNssLibraryDirectory();
+                String nssSecmodDirectory = config.getNssSecmodDirectory();
+                boolean nssOptimizeSpace = config.getNssOptimizeSpace();
+
+                if (secmod.isInitialized()) {
+                    if (nssSecmodDirectory != null) {
+                        String s = secmod.getConfigDir();
+                        if ((s != null) &&
+                                (s.equals(nssSecmodDirectory) == false)) {
+                            throw new ProviderException("Secmod directory "
+                                + nssSecmodDirectory
+                                + " invalid, NSS already initialized with "
+                                + s);
+                        }
+                    }
+                    if (nssLibraryDirectory != null) {
+                        String s = secmod.getLibDir();
+                        if ((s != null) &&
+                                (s.equals(nssLibraryDirectory) == false)) {
+                            throw new ProviderException("NSS library directory "
+                                + nssLibraryDirectory
+                                + " invalid, NSS already initialized with "
+                                + s);
+                        }
+                    }
+                } else {
+                    if (nssDbMode != DbMode.NO_DB) {
+                        if (nssSecmodDirectory == null) {
+                            throw new ProviderException(
+                                "Secmod not initialized and "
+                                 + "nssSecmodDirectory not specified");
+                        }
+                    } else {
+                        if (nssSecmodDirectory != null) {
+                            throw new ProviderException(
+                                "nssSecmodDirectory must not be "
+                                + "specified in noDb mode");
+                        }
+                    }
+                    secmod.initialize(nssDbMode, nssSecmodDirectory,
+                        nssLibraryDirectory, nssOptimizeSpace);
+                }
+            } catch (IOException e) {
+                // XXX which exception to throw
+                throw new ProviderException("Could not initialize NSS", e);
+            }
+            List<Module> modules = secmod.getModules();
+            if (config.getShowInfo()) {
+                System.out.println("NSS modules: " + modules);
+            }
+
+            String moduleName = config.getNssModule();
+            if (moduleName == null) {
+                nssModule = secmod.getModule(ModuleType.FIPS);
+                if (nssModule != null) {
+                    moduleName = "fips";
+                } else {
+                    moduleName = (nssDbMode == DbMode.NO_DB) ?
+                        "crypto" : "keystore";
+                }
+            }
+            if (moduleName.equals("fips")) {
+                nssModule = secmod.getModule(ModuleType.FIPS);
+                nssUseSecmodTrust = true;
+                functionList = "FC_GetFunctionList";
+            } else if (moduleName.equals("keystore")) {
+                nssModule = secmod.getModule(ModuleType.KEYSTORE);
+                nssUseSecmodTrust = true;
+            } else if (moduleName.equals("crypto")) {
+                nssModule = secmod.getModule(ModuleType.CRYPTO);
+            } else if (moduleName.equals("trustanchors")) {
+                // XXX should the option be called trustanchor or trustanchors??
+                nssModule = secmod.getModule(ModuleType.TRUSTANCHOR);
+                nssUseSecmodTrust = true;
+            } else if (moduleName.startsWith("external-")) {
+                int moduleIndex;
+                try {
+                    moduleIndex = Integer.parseInt
+                            (moduleName.substring("external-".length()));
+                } catch (NumberFormatException e) {
+                    moduleIndex = -1;
+                }
+                if (moduleIndex < 1) {
+                    throw new ProviderException
+                            ("Invalid external module: " + moduleName);
+                }
+                int k = 0;
+                for (Module module : modules) {
+                    if (module.getType() == ModuleType.EXTERNAL) {
+                        if (++k == moduleIndex) {
+                            nssModule = module;
+                            break;
+                        }
+                    }
+                }
+                if (nssModule == null) {
+                    throw new ProviderException("Invalid module " + moduleName
+                        + ": only " + k + " external NSS modules available");
+                }
+            } else {
+                throw new ProviderException(
+                    "Unknown NSS module: " + moduleName);
+            }
+            if (nssModule == null) {
+                throw new ProviderException(
+                    "NSS module not available: " + moduleName);
+            }
+            if (nssModule.hasInitializedProvider()) {
+                throw new ProviderException("Secmod module already configured");
+            }
+            library = nssModule.libraryName;
+            slotListIndex = nssModule.slot;
+        }
+        this.nssUseSecmodTrust = nssUseSecmodTrust;
+        this.nssModule = nssModule;
+
+        File libraryFile = new File(library);
+        // if the filename is a simple filename without path
+        // (e.g. "libpkcs11.so"), it may refer to a library somewhere on the
+        // OS library search path. Omit the test for file existance as that
+        // only looks in the current directory.
+        if (libraryFile.getName().equals(library) == false) {
+            if (new File(library).isFile() == false) {
+                String msg = "Library " + library + " does not exist";
+                if (config.getHandleStartupErrors() == Config.ERR_HALT) {
+                    throw new ProviderException(msg);
+                } else {
+                    throw new UnsupportedOperationException(msg);
+                }
+            }
+        }
+
+        try {
+            if (debug != null) {
+                debug.println("Initializing PKCS#11 library " + library);
+            }
+            CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
+            String nssArgs = config.getNssArgs();
+            if (nssArgs != null) {
+                initArgs.pReserved = nssArgs;
+            }
+            // request multithreaded access first
+            initArgs.flags = CKF_OS_LOCKING_OK;
+            PKCS11 tmpPKCS11;
+            try {
+                tmpPKCS11 = PKCS11.getInstance(
+                    library, functionList, initArgs,
+                    config.getOmitInitialize());
+            } catch (PKCS11Exception e) {
+                if (debug != null) {
+                    debug.println("Multi-threaded initialization failed: " + e);
+                }
+                if (config.getAllowSingleThreadedModules() == false) {
+                    throw e;
+                }
+                // fall back to single threaded access
+                if (nssArgs == null) {
+                    // if possible, use null initArgs for better compatibility
+                    initArgs = null;
+                } else {
+                    initArgs.flags = 0;
+                }
+                tmpPKCS11 = PKCS11.getInstance(library,
+                    functionList, initArgs, config.getOmitInitialize());
+            }
+            p11 = tmpPKCS11;
+
+            CK_INFO p11Info = p11.C_GetInfo();
+            if (p11Info.cryptokiVersion.major < 2) {
+                throw new ProviderException("Only PKCS#11 v2.0 and later "
+                + "supported, library version is v" + p11Info.cryptokiVersion);
+            }
+            boolean showInfo = config.getShowInfo();
+            if (showInfo) {
+                System.out.println("Information for provider " + getName());
+                System.out.println("Library info:");
+                System.out.println(p11Info);
+            }
+
+            if ((slotID < 0) || showInfo) {
+                long[] slots = p11.C_GetSlotList(false);
+                if (showInfo) {
+                    System.out.println("All slots: " + toString(slots));
+                    slots = p11.C_GetSlotList(true);
+                    System.out.println("Slots with tokens: " + toString(slots));
+                }
+                if (slotID < 0) {
+                    if ((slotListIndex < 0)
+                            || (slotListIndex >= slots.length)) {
+                        throw new ProviderException("slotListIndex is "
+                            + slotListIndex
+                            + " but token only has " + slots.length + " slots");
+                    }
+                    slotID = slots[slotListIndex];
+                }
+            }
+            this.slotID = slotID;
+            CK_SLOT_INFO slotInfo = p11.C_GetSlotInfo(slotID);
+            removable = (slotInfo.flags & CKF_REMOVABLE_DEVICE) != 0;
+            initToken(slotInfo);
+            if (nssModule != null) {
+                nssModule.setProvider(this);
+            }
+        } catch (Exception e) {
+            if (config.getHandleStartupErrors() == Config.ERR_IGNORE_ALL) {
+                throw new UnsupportedOperationException
+                        ("Initialization failed", e);
+            } else {
+                throw new ProviderException
+                        ("Initialization failed", e);
+            }
+        }
+    }
+
+    private static String toString(long[] longs) {
+        if (longs.length == 0) {
+            return "(none)";
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append(longs[0]);
+        for (int i = 1; i < longs.length; i++) {
+            sb.append(", ");
+            sb.append(longs[i]);
+        }
+        return sb.toString();
+    }
+
+    public boolean equals(Object obj) {
+        return this == obj;
+    }
+
+    public int hashCode() {
+        return System.identityHashCode(this);
+    }
+
+    private static String[] s(String ...aliases) {
+        return aliases;
+    }
+
+    private static final class Descriptor {
+        final String type;
+        final String algorithm;
+        final String className;
+        final String[] aliases;
+        final int[] mechanisms;
+
+        private Descriptor(String type, String algorithm, String className,
+                String[] aliases, int[] mechanisms) {
+            this.type = type;
+            this.algorithm = algorithm;
+            this.className = className;
+            this.aliases = aliases;
+            this.mechanisms = mechanisms;
+        }
+        private P11Service service(Token token, int mechanism) {
+            return new P11Service
+                (token, type, algorithm, className, aliases, mechanism);
+        }
+        public String toString() {
+            return type + "." + algorithm;
+        }
+    }
+
+    // Map from mechanism to List of Descriptors that should be
+    // registered if the mechanism is supported
+    private final static Map<Integer,List<Descriptor>> descriptors =
+        new HashMap<Integer,List<Descriptor>>();
+
+    private static int[] m(long m1) {
+        return new int[] {(int)m1};
+    }
+
+    private static int[] m(long m1, long m2) {
+        return new int[] {(int)m1, (int)m2};
+    }
+
+    private static int[] m(long m1, long m2, long m3) {
+        return new int[] {(int)m1, (int)m2, (int)m3};
+    }
+
+    private static int[] m(long m1, long m2, long m3, long m4) {
+        return new int[] {(int)m1, (int)m2, (int)m3, (int)m4};
+    }
+
+    private static void d(String type, String algorithm, String className,
+            int[] m) {
+        register(new Descriptor(type, algorithm, className, null, m));
+    }
+
+    private static void d(String type, String algorithm, String className,
+            String[] aliases, int[] m) {
+        register(new Descriptor(type, algorithm, className, aliases, m));
+    }
+
+    private static void register(Descriptor d) {
+        for (int i = 0; i < d.mechanisms.length; i++) {
+            int m = d.mechanisms[i];
+            Integer key = Integer.valueOf(m);
+            List<Descriptor> list = descriptors.get(key);
+            if (list == null) {
+                list = new ArrayList<Descriptor>();
+                descriptors.put(key, list);
+            }
+            list.add(d);
+        }
+    }
+
+    private final static String MD  = "MessageDigest";
+
+    private final static String SIG = "Signature";
+
+    private final static String KPG = "KeyPairGenerator";
+
+    private final static String KG  = "KeyGenerator";
+
+    private final static String AGP = "AlgorithmParameters";
+
+    private final static String KF  = "KeyFactory";
+
+    private final static String SKF = "SecretKeyFactory";
+
+    private final static String CIP = "Cipher";
+
+    private final static String MAC = "Mac";
+
+    private final static String KA  = "KeyAgreement";
+
+    private final static String KS  = "KeyStore";
+
+    private final static String SR  = "SecureRandom";
+
+    static {
+        // names of all the implementation classes
+        // use local variables, only used here
+        String P11Digest           = "sun.security.pkcs11.P11Digest";
+        String P11MAC              = "sun.security.pkcs11.P11MAC";
+        String P11KeyPairGenerator = "sun.security.pkcs11.P11KeyPairGenerator";
+        String P11KeyGenerator     = "sun.security.pkcs11.P11KeyGenerator";
+        String P11RSAKeyFactory    = "sun.security.pkcs11.P11RSAKeyFactory";
+        String P11DSAKeyFactory    = "sun.security.pkcs11.P11DSAKeyFactory";
+        String P11DHKeyFactory     = "sun.security.pkcs11.P11DHKeyFactory";
+        String P11KeyAgreement     = "sun.security.pkcs11.P11KeyAgreement";
+        String P11SecretKeyFactory = "sun.security.pkcs11.P11SecretKeyFactory";
+        String P11Cipher           = "sun.security.pkcs11.P11Cipher";
+        String P11RSACipher        = "sun.security.pkcs11.P11RSACipher";
+        String P11Signature        = "sun.security.pkcs11.P11Signature";
+
+        // XXX register all aliases
+
+        d(MD, "MD2",            P11Digest,
+                m(CKM_MD2));
+        d(MD, "MD5",            P11Digest,
+                m(CKM_MD5));
+        d(MD, "SHA1",           P11Digest,
+                s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"),
+                m(CKM_SHA_1));
+
+        d(MD, "SHA-224",        P11Digest,
+                s("2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4"),
+                m(CKM_SHA224));
+        d(MD, "SHA-256",        P11Digest,
+                s("2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"),
+                m(CKM_SHA256));
+        d(MD, "SHA-384",        P11Digest,
+                s("2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"),
+                m(CKM_SHA384));
+        d(MD, "SHA-512",        P11Digest,
+                s("2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"),
+                m(CKM_SHA512));
+
+        d(MAC, "HmacMD5",       P11MAC,
+                m(CKM_MD5_HMAC));
+        d(MAC, "HmacSHA1",      P11MAC,
+                s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"),
+                m(CKM_SHA_1_HMAC));
+        d(MAC, "HmacSHA224",    P11MAC,
+                s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"),
+                m(CKM_SHA224_HMAC));
+        d(MAC, "HmacSHA256",    P11MAC,
+                s("1.2.840.113549.2.9", "OID.1.2.840.113549.2.9"),
+                m(CKM_SHA256_HMAC));
+        d(MAC, "HmacSHA384",    P11MAC,
+                s("1.2.840.113549.2.10", "OID.1.2.840.113549.2.10"),
+                m(CKM_SHA384_HMAC));
+        d(MAC, "HmacSHA512",    P11MAC,
+                s("1.2.840.113549.2.11", "OID.1.2.840.113549.2.11"),
+                m(CKM_SHA512_HMAC));
+        d(MAC, "SslMacMD5",     P11MAC,
+                m(CKM_SSL3_MD5_MAC));
+        d(MAC, "SslMacSHA1",    P11MAC,
+                m(CKM_SSL3_SHA1_MAC));
+
+        d(KPG, "RSA",           P11KeyPairGenerator,
+                m(CKM_RSA_PKCS_KEY_PAIR_GEN));
+        d(KPG, "DSA",           P11KeyPairGenerator,
+                s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
+                m(CKM_DSA_KEY_PAIR_GEN));
+        d(KPG, "DH",            P11KeyPairGenerator,    s("DiffieHellman"),
+                m(CKM_DH_PKCS_KEY_PAIR_GEN));
+        d(KPG, "EC",            P11KeyPairGenerator,
+                m(CKM_EC_KEY_PAIR_GEN));
+
+        d(KG,  "ARCFOUR",       P11KeyGenerator,        s("RC4"),
+                m(CKM_RC4_KEY_GEN));
+        d(KG,  "DES",           P11KeyGenerator,
+                m(CKM_DES_KEY_GEN));
+        d(KG,  "DESede",        P11KeyGenerator,
+                m(CKM_DES3_KEY_GEN, CKM_DES2_KEY_GEN));
+        d(KG,  "AES",           P11KeyGenerator,
+                m(CKM_AES_KEY_GEN));
+        d(KG,  "Blowfish",      P11KeyGenerator,
+                m(CKM_BLOWFISH_KEY_GEN));
+
+        // register (Secret)KeyFactories if there are any mechanisms
+        // for a particular algorithm that we support
+        d(KF, "RSA",            P11RSAKeyFactory,
+                m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509));
+        d(KF, "DSA",            P11DSAKeyFactory,
+                s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
+                m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1));
+        d(KF, "DH",             P11DHKeyFactory,        s("DiffieHellman"),
+                m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
+        d(KF, "EC",             P11DHKeyFactory,
+                m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
+                    CKM_ECDSA, CKM_ECDSA_SHA1));
+
+        // AlgorithmParameters for EC.
+        // Only needed until we have an EC implementation in the SUN provider.
+        d(AGP, "EC",            "sun.security.util.ECParameters",
+                                                s("1.2.840.10045.2.1"),
+                m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
+                    CKM_ECDSA, CKM_ECDSA_SHA1));
+
+        d(KA, "DH",             P11KeyAgreement,        s("DiffieHellman"),
+                m(CKM_DH_PKCS_DERIVE));
+        d(KA, "ECDH",           "sun.security.pkcs11.P11ECDHKeyAgreement",
+                m(CKM_ECDH1_DERIVE));
+
+        d(SKF, "ARCFOUR",       P11SecretKeyFactory,    s("RC4"),
+                m(CKM_RC4));
+        d(SKF, "DES",           P11SecretKeyFactory,
+                m(CKM_DES_CBC));
+        d(SKF, "DESede",        P11SecretKeyFactory,
+                m(CKM_DES3_CBC));
+        d(SKF, "AES",           P11SecretKeyFactory,
+                s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"),
+                m(CKM_AES_CBC));
+        d(SKF, "Blowfish",      P11SecretKeyFactory,
+                m(CKM_BLOWFISH_CBC));
+
+        // XXX attributes for Ciphers (supported modes, padding)
+        d(CIP, "ARCFOUR",                       P11Cipher,      s("RC4"),
+                m(CKM_RC4));
+        d(CIP, "DES/CBC/NoPadding",             P11Cipher,
+                m(CKM_DES_CBC));
+        d(CIP, "DES/CBC/PKCS5Padding",          P11Cipher,
+                m(CKM_DES_CBC_PAD, CKM_DES_CBC));
+        d(CIP, "DES/ECB/NoPadding",             P11Cipher,
+                m(CKM_DES_ECB));
+        d(CIP, "DES/ECB/PKCS5Padding",          P11Cipher,      s("DES"),
+                m(CKM_DES_ECB));
+
+        d(CIP, "DESede/CBC/NoPadding",          P11Cipher,
+                m(CKM_DES3_CBC));
+        d(CIP, "DESede/CBC/PKCS5Padding",       P11Cipher,
+                m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
+        d(CIP, "DESede/ECB/NoPadding",          P11Cipher,
+                m(CKM_DES3_ECB));
+        d(CIP, "DESede/ECB/PKCS5Padding",       P11Cipher,      s("DESede"),
+                m(CKM_DES3_ECB));
+        d(CIP, "AES/CBC/NoPadding",             P11Cipher,
+                m(CKM_AES_CBC));
+        d(CIP, "AES_128/CBC/NoPadding",          P11Cipher,
+                s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
+                m(CKM_AES_CBC));
+        d(CIP, "AES_192/CBC/NoPadding",          P11Cipher,
+                s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
+                m(CKM_AES_CBC));
+        d(CIP, "AES_256/CBC/NoPadding",          P11Cipher,
+                s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"),
+                m(CKM_AES_CBC));
+        d(CIP, "AES/CBC/PKCS5Padding",          P11Cipher,
+                m(CKM_AES_CBC_PAD, CKM_AES_CBC));
+        d(CIP, "AES/ECB/NoPadding",             P11Cipher,
+                m(CKM_AES_ECB));
+        d(CIP, "AES_128/ECB/NoPadding",          P11Cipher,
+                s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
+                m(CKM_AES_ECB));
+        d(CIP, "AES_192/ECB/NoPadding",          P11Cipher,
+                s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
+                m(CKM_AES_ECB));
+        d(CIP, "AES_256/ECB/NoPadding",          P11Cipher,
+                s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"),
+                m(CKM_AES_ECB));
+        d(CIP, "AES/ECB/PKCS5Padding",          P11Cipher,      s("AES"),
+                m(CKM_AES_ECB));
+        d(CIP, "AES/CTR/NoPadding",             P11Cipher,
+                m(CKM_AES_CTR));
+        d(CIP, "Blowfish/CBC/NoPadding",        P11Cipher,
+                m(CKM_BLOWFISH_CBC));
+        d(CIP, "Blowfish/CBC/PKCS5Padding",     P11Cipher,
+                m(CKM_BLOWFISH_CBC));
+
+        // XXX RSA_X_509, RSA_OAEP not yet supported
+        d(CIP, "RSA/ECB/PKCS1Padding",          P11RSACipher,   s("RSA"),
+                m(CKM_RSA_PKCS));
+        d(CIP, "RSA/ECB/NoPadding",             P11RSACipher,
+                m(CKM_RSA_X_509));
+
+        d(SIG, "RawDSA",        P11Signature,   s("NONEwithDSA"),
+                m(CKM_DSA));
+        d(SIG, "DSA",           P11Signature,
+                s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27",
+                  "1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"),
+                m(CKM_DSA_SHA1, CKM_DSA));
+        d(SIG, "RawDSAinP1363Format",   P11Signature,
+                s("NONEwithDSAinP1363Format"),
+                m(CKM_DSA));
+        d(SIG, "DSAinP1363Format",      P11Signature,
+                s("SHA1withDSAinP1363Format"),
+                m(CKM_DSA_SHA1, CKM_DSA));
+        d(SIG, "NONEwithECDSA", P11Signature,
+                m(CKM_ECDSA));
+        d(SIG, "SHA1withECDSA", P11Signature,
+                s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"),
+                m(CKM_ECDSA_SHA1, CKM_ECDSA));
+        d(SIG, "SHA224withECDSA",       P11Signature,
+                s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"),
+                m(CKM_ECDSA));
+        d(SIG, "SHA256withECDSA",       P11Signature,
+                s("1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"),
+                m(CKM_ECDSA));
+        d(SIG, "SHA384withECDSA",       P11Signature,
+                s("1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"),
+                m(CKM_ECDSA));
+        d(SIG, "SHA512withECDSA",       P11Signature,
+                s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
+                m(CKM_ECDSA));
+        d(SIG, "NONEwithECDSAinP1363Format",   P11Signature,
+                m(CKM_ECDSA));
+        d(SIG, "SHA1withECDSAinP1363Format",   P11Signature,
+                m(CKM_ECDSA_SHA1, CKM_ECDSA));
+        d(SIG, "SHA224withECDSAinP1363Format", P11Signature,
+                m(CKM_ECDSA));
+        d(SIG, "SHA256withECDSAinP1363Format", P11Signature,
+                m(CKM_ECDSA));
+        d(SIG, "SHA384withECDSAinP1363Format", P11Signature,
+                m(CKM_ECDSA));
+        d(SIG, "SHA512withECDSAinP1363Format", P11Signature,
+                m(CKM_ECDSA));
+        d(SIG, "MD2withRSA",    P11Signature,
+                s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"),
+                m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+        d(SIG, "MD5withRSA",    P11Signature,
+                s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"),
+                m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+        d(SIG, "SHA1withRSA",   P11Signature,
+                s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
+                  "1.3.14.3.2.29"),
+                m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+        d(SIG, "SHA224withRSA", P11Signature,
+                s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"),
+                m(CKM_SHA224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+        d(SIG, "SHA256withRSA", P11Signature,
+                s("1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11"),
+                m(CKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+        d(SIG, "SHA384withRSA", P11Signature,
+                s("1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12"),
+                m(CKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+        d(SIG, "SHA512withRSA", P11Signature,
+                s("1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13"),
+                m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+
+        /*
+         * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the
+         * PRF calculations.  As of 2010, there is no PKCS11-level
+         * support for TLS 1.2 PRF calculations, and no known OS's have
+         * an internal variant we could use.  Therefore for TLS 1.2, we
+         * are updating JSSE to request different provider algorithms
+         * (e.g. "SunTls12Prf"), and currently only SunJCE has these
+         * TLS 1.2 algorithms.
+         *
+         * If we reused the names such as "SunTlsPrf", the PKCS11
+         * providers would need be updated to fail correctly when
+         * presented with the wrong version number (via
+         * Provider.Service.supportsParameters()), and we would also
+         * need to add the appropriate supportsParamters() checks into
+         * KeyGenerators (not currently there).
+         *
+         * In the future, if PKCS11 support is added, we will restructure
+         * this.
+         */
+        d(KG, "SunTlsRsaPremasterSecret",
+                    "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
+                m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN));
+        d(KG, "SunTlsMasterSecret",
+                    "sun.security.pkcs11.P11TlsMasterSecretGenerator",
+                m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE,
+                    CKM_SSL3_MASTER_KEY_DERIVE_DH,
+                    CKM_TLS_MASTER_KEY_DERIVE_DH));
+        d(KG, "SunTlsKeyMaterial",
+                    "sun.security.pkcs11.P11TlsKeyMaterialGenerator",
+                m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE));
+        d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator",
+                m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL));
+    }
+
+    // background thread that periodically checks for token insertion
+    // if no token is present. We need to do that in a separate thread because
+    // the insertion check may block for quite a long time on some tokens.
+    private static class TokenPoller implements Runnable {
+        private final SunPKCS11 provider;
+        private volatile boolean enabled;
+        private TokenPoller(SunPKCS11 provider) {
+            this.provider = provider;
+            enabled = true;
+        }
+        public void run() {
+            int interval = provider.config.getInsertionCheckInterval();
+            while (enabled) {
+                try {
+                    Thread.sleep(interval);
+                } catch (InterruptedException e) {
+                    break;
+                }
+                if (enabled == false) {
+                    break;
+                }
+                try {
+                    provider.initToken(null);
+                } catch (PKCS11Exception e) {
+                    // ignore
+                }
+            }
+        }
+        void disable() {
+            enabled = false;
+        }
+    }
+
+    // create the poller thread, if not already active
+    private void createPoller() {
+        if (poller != null) {
+            return;
+        }
+        final TokenPoller poller = new TokenPoller(this);
+        Thread t = new Thread(null, poller, "Poller " + getName(), 0, false);
+        t.setContextClassLoader(null);
+        t.setDaemon(true);
+        t.setPriority(Thread.MIN_PRIORITY);
+        t.start();
+        this.poller = poller;
+    }
+
+    // destroy the poller thread, if active
+    private void destroyPoller() {
+        if (poller != null) {
+            poller.disable();
+            poller = null;
+        }
+    }
+
+    private boolean hasValidToken() {
+        /* Commented out to work with Solaris softtoken impl which
+           returns 0-value flags, e.g. both REMOVABLE_DEVICE and
+           TOKEN_PRESENT are false, when it can't access the token.
+        if (removable == false) {
+            return true;
+        }
+        */
+        Token token = this.token;
+        return (token != null) && token.isValid();
+    }
+
+    // destroy the token. Called if we detect that it has been removed
+    synchronized void uninitToken(Token token) {
+        if (this.token != token) {
+            // mismatch, our token must already be destroyed
+            return;
+        }
+        destroyPoller();
+        this.token = null;
+        // unregister all algorithms
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+                clear();
+                return null;
+            }
+        });
+        createPoller();
+    }
+
+    // test if a token is present and initialize this provider for it if so.
+    // does nothing if no token is found
+    // called from constructor and by poller
+    private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception {
+        if (slotInfo == null) {
+            slotInfo = p11.C_GetSlotInfo(slotID);
+        }
+        if (removable && (slotInfo.flags & CKF_TOKEN_PRESENT) == 0) {
+            createPoller();
+            return;
+        }
+        destroyPoller();
+        boolean showInfo = config.getShowInfo();
+        if (showInfo) {
+            System.out.println("Slot info for slot " + slotID + ":");
+            System.out.println(slotInfo);
+        }
+        final Token token = new Token(this);
+        if (showInfo) {
+            System.out.println
+                ("Token info for token in slot " + slotID + ":");
+            System.out.println(token.tokenInfo);
+        }
+        long[] supportedMechanisms = p11.C_GetMechanismList(slotID);
+
+        // Create a map from the various Descriptors to the "most
+        // preferred" mechanism that was defined during the
+        // static initialization.  For example, DES/CBC/PKCS5Padding
+        // could be mapped to CKM_DES_CBC_PAD or CKM_DES_CBC.  Prefer
+        // the earliest entry.  When asked for "DES/CBC/PKCS5Padding", we
+        // return a CKM_DES_CBC_PAD.
+        final Map<Descriptor,Integer> supportedAlgs =
+                                        new HashMap<Descriptor,Integer>();
+        for (int i = 0; i < supportedMechanisms.length; i++) {
+            long longMech = supportedMechanisms[i];
+            boolean isEnabled = config.isEnabled(longMech);
+            if (showInfo) {
+                CK_MECHANISM_INFO mechInfo =
+                        p11.C_GetMechanismInfo(slotID, longMech);
+                System.out.println("Mechanism " +
+                        Functions.getMechanismName(longMech) + ":");
+                if (isEnabled == false) {
+                    System.out.println("DISABLED in configuration");
+                }
+                System.out.println(mechInfo);
+            }
+            if (isEnabled == false) {
+                continue;
+            }
+            // we do not know of mechs with the upper 32 bits set
+            if (longMech >>> 32 != 0) {
+                continue;
+            }
+            int mech = (int)longMech;
+            Integer integerMech = Integer.valueOf(mech);
+            List<Descriptor> ds = descriptors.get(integerMech);
+            if (ds == null) {
+                continue;
+            }
+            for (Descriptor d : ds) {
+                Integer oldMech = supportedAlgs.get(d);
+                if (oldMech == null) {
+                    supportedAlgs.put(d, integerMech);
+                    continue;
+                }
+                // See if there is something "more preferred"
+                // than what we currently have in the supportedAlgs
+                // map.
+                int intOldMech = oldMech.intValue();
+                for (int j = 0; j < d.mechanisms.length; j++) {
+                    int nextMech = d.mechanisms[j];
+                    if (mech == nextMech) {
+                        supportedAlgs.put(d, integerMech);
+                        break;
+                    } else if (intOldMech == nextMech) {
+                        break;
+                    }
+                }
+            }
+
+        }
+
+        // register algorithms in provider
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+                for (Map.Entry<Descriptor,Integer> entry
+                        : supportedAlgs.entrySet()) {
+                    Descriptor d = entry.getKey();
+                    int mechanism = entry.getValue().intValue();
+                    Service s = d.service(token, mechanism);
+                    putService(s);
+                }
+                if (((token.tokenInfo.flags & CKF_RNG) != 0)
+                        && config.isEnabled(PCKM_SECURERANDOM)
+                        && !token.sessionManager.lowMaxSessions()) {
+                    // do not register SecureRandom if the token does
+                    // not support many sessions. if we did, we might
+                    // run out of sessions in the middle of a
+                    // nextBytes() call where we cannot fail over.
+                    putService(new P11Service(token, SR, "PKCS11",
+                        "sun.security.pkcs11.P11SecureRandom", null,
+                        PCKM_SECURERANDOM));
+                }
+                if (config.isEnabled(PCKM_KEYSTORE)) {
+                    putService(new P11Service(token, KS, "PKCS11",
+                        "sun.security.pkcs11.P11KeyStore",
+                        s("PKCS11-" + config.getName()),
+                        PCKM_KEYSTORE));
+                }
+                return null;
+            }
+        });
+
+        this.token = token;
+    }
+
+    private static final class P11Service extends Service {
+
+        private final Token token;
+
+        private final long mechanism;
+
+        P11Service(Token token, String type, String algorithm,
+                String className, String[] al, long mechanism) {
+            super(token.provider, type, algorithm, className, toList(al),
+                    type.equals(SR) ? Map.of("ThreadSafe", "true") : null);
+            this.token = token;
+            this.mechanism = mechanism & 0xFFFFFFFFL;
+        }
+
+        private static List<String> toList(String[] aliases) {
+            return (aliases == null) ? null : Arrays.asList(aliases);
+        }
+
+        public Object newInstance(Object param)
+                throws NoSuchAlgorithmException {
+            if (token.isValid() == false) {
+                throw new NoSuchAlgorithmException("Token has been removed");
+            }
+            try {
+                return newInstance0(param);
+            } catch (PKCS11Exception e) {
+                throw new NoSuchAlgorithmException(e);
+            }
+        }
+
+        public Object newInstance0(Object param) throws
+                PKCS11Exception, NoSuchAlgorithmException {
+            String algorithm = getAlgorithm();
+            String type = getType();
+            if (type == MD) {
+                return new P11Digest(token, algorithm, mechanism);
+            } else if (type == CIP) {
+                if (algorithm.startsWith("RSA")) {
+                    return new P11RSACipher(token, algorithm, mechanism);
+                } else {
+                    return new P11Cipher(token, algorithm, mechanism);
+                }
+            } else if (type == SIG) {
+                return new P11Signature(token, algorithm, mechanism);
+            } else if (type == MAC) {
+                return new P11Mac(token, algorithm, mechanism);
+            } else if (type == KPG) {
+                return new P11KeyPairGenerator(token, algorithm, mechanism);
+            } else if (type == KA) {
+                if (algorithm.equals("ECDH")) {
+                    return new P11ECDHKeyAgreement(token, algorithm, mechanism);
+                } else {
+                    return new P11KeyAgreement(token, algorithm, mechanism);
+                }
+            } else if (type == KF) {
+                return token.getKeyFactory(algorithm);
+            } else if (type == SKF) {
+                return new P11SecretKeyFactory(token, algorithm);
+            } else if (type == KG) {
+                // reference equality
+                if (algorithm == "SunTlsRsaPremasterSecret") {
+                    return new P11TlsRsaPremasterSecretGenerator(
+                        token, algorithm, mechanism);
+                } else if (algorithm == "SunTlsMasterSecret") {
+                    return new P11TlsMasterSecretGenerator(
+                        token, algorithm, mechanism);
+                } else if (algorithm == "SunTlsKeyMaterial") {
+                    return new P11TlsKeyMaterialGenerator(
+                        token, algorithm, mechanism);
+                } else if (algorithm == "SunTlsPrf") {
+                    return new P11TlsPrfGenerator(token, algorithm, mechanism);
+                } else {
+                    return new P11KeyGenerator(token, algorithm, mechanism);
+                }
+            } else if (type == SR) {
+                return token.getRandom();
+            } else if (type == KS) {
+                return token.getKeyStore();
+            } else if (type == AGP) {
+                return new sun.security.util.ECParameters();
+            } else {
+                throw new NoSuchAlgorithmException("Unknown type: " + type);
+            }
+        }
+
+        public boolean supportsParameter(Object param) {
+            if ((param == null) || (token.isValid() == false)) {
+                return false;
+            }
+            if (param instanceof Key == false) {
+                throw new InvalidParameterException("Parameter must be a Key");
+            }
+            String algorithm = getAlgorithm();
+            String type = getType();
+            Key key = (Key)param;
+            String keyAlgorithm = key.getAlgorithm();
+            // RSA signatures and cipher
+            if (((type == CIP) && algorithm.startsWith("RSA"))
+                    || (type == SIG) && algorithm.endsWith("RSA")) {
+                if (keyAlgorithm.equals("RSA") == false) {
+                    return false;
+                }
+                return isLocalKey(key)
+                        || (key instanceof RSAPrivateKey)
+                        || (key instanceof RSAPublicKey);
+            }
+            // EC
+            if (((type == KA) && algorithm.equals("ECDH"))
+                    || ((type == SIG) && algorithm.contains("ECDSA"))) {
+                if (keyAlgorithm.equals("EC") == false) {
+                    return false;
+                }
+                return isLocalKey(key)
+                        || (key instanceof ECPrivateKey)
+                        || (key instanceof ECPublicKey);
+            }
+            // DSA signatures
+            if ((type == SIG) && algorithm.contains("DSA") &&
+                    !algorithm.contains("ECDSA")) {
+                if (keyAlgorithm.equals("DSA") == false) {
+                    return false;
+                }
+                return isLocalKey(key)
+                        || (key instanceof DSAPrivateKey)
+                        || (key instanceof DSAPublicKey);
+            }
+            // MACs and symmetric ciphers
+            if ((type == CIP) || (type == MAC)) {
+                // do not check algorithm name, mismatch is unlikely anyway
+                return isLocalKey(key) || "RAW".equals(key.getFormat());
+            }
+            // DH key agreement
+            if (type == KA) {
+                if (keyAlgorithm.equals("DH") == false) {
+                    return false;
+                }
+                return isLocalKey(key)
+                        || (key instanceof DHPrivateKey)
+                        || (key instanceof DHPublicKey);
+            }
+            // should not reach here,
+            // unknown engine type or algorithm
+            throw new AssertionError
+                ("SunPKCS11 error: " + type + ", " + algorithm);
+        }
+
+        private boolean isLocalKey(Key key) {
+            return (key instanceof P11Key) && (((P11Key)key).token == token);
+        }
+
+        public String toString() {
+            return super.toString() +
+                " (" + Functions.getMechanismName(mechanism) + ")";
+        }
+
+    }
+
+    /**
+     * Log in to this provider.
+     *
+     * <p> If the token expects a PIN to be supplied by the caller,
+     * the <code>handler</code> implementation must support
+     * a <code>PasswordCallback</code>.
+     *
+     * <p> To determine if the token supports a protected authentication path,
+     * the CK_TOKEN_INFO flag, CKF_PROTECTED_AUTHENTICATION_PATH, is consulted.
+     *
+     * @param subject this parameter is ignored
+     * @param handler the <code>CallbackHandler</code> used by
+     *  this provider to communicate with the caller
+     *
+     * @throws IllegalStateException if the provider requires configuration
+     * and Provider.configure has not been called
+     * @throws LoginException if the login operation fails
+     * @throws SecurityException if the does not pass a security check for
+     *  <code>SecurityPermission("authProvider.<i>name</i>")</code>,
+     *  where <i>name</i> is the value returned by
+     *  this provider's <code>getName</code> method
+     */
+    public void login(Subject subject, CallbackHandler handler)
+        throws LoginException {
+
+        if (!isConfigured()) {
+            throw new IllegalStateException("Configuration is required");
+        }
+
+        // security check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            if (debug != null) {
+                debug.println("checking login permission");
+            }
+            sm.checkPermission(new SecurityPermission
+                        ("authProvider." + this.getName()));
+        }
+
+        if (hasValidToken() == false) {
+            throw new LoginException("No token present");
+        }
+
+        // see if a login is required
+
+        if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) {
+            if (debug != null) {
+                debug.println("login operation not required for token - " +
+                                "ignoring login request");
+            }
+            return;
+        }
+
+        // see if user already logged in
+
+        try {
+            if (token.isLoggedInNow(null)) {
+                // user already logged in
+                if (debug != null) {
+                    debug.println("user already logged in");
+                }
+                return;
+            }
+        } catch (PKCS11Exception e) {
+            // ignore - fall thru and attempt login
+        }
+
+        // get the pin if necessary
+
+        char[] pin = null;
+        if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
+
+            // get password
+
+            CallbackHandler myHandler = getCallbackHandler(handler);
+            if (myHandler == null) {
+                // XXX PolicyTool is dependent on this message text
+                throw new LoginException
+                        ("no password provided, and no callback handler " +
+                        "available for retrieving password");
+            }
+
+            java.text.MessageFormat form = new java.text.MessageFormat
+                        (ResourcesMgr.getString
+                        ("PKCS11.Token.providerName.Password."));
+            Object[] source = { getName() };
+
+            PasswordCallback pcall = new PasswordCallback(form.format(source),
+                                                        false);
+            Callback[] callbacks = { pcall };
+            try {
+                myHandler.handle(callbacks);
+            } catch (Exception e) {
+                LoginException le = new LoginException
+                        ("Unable to perform password callback");
+                le.initCause(e);
+                throw le;
+            }
+
+            pin = pcall.getPassword();
+            pcall.clearPassword();
+            if (pin == null) {
+                if (debug != null) {
+                    debug.println("caller passed NULL pin");
+                }
+            }
+        }
+
+        // perform token login
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+
+            // pin is NULL if using CKF_PROTECTED_AUTHENTICATION_PATH
+            p11.C_Login(session.id(), CKU_USER, pin);
+            if (debug != null) {
+                debug.println("login succeeded");
+            }
+        } catch (PKCS11Exception pe) {
+            if (pe.getErrorCode() == CKR_USER_ALREADY_LOGGED_IN) {
+                // let this one go
+                if (debug != null) {
+                    debug.println("user already logged in");
+                }
+                return;
+            } else if (pe.getErrorCode() == CKR_PIN_INCORRECT) {
+                FailedLoginException fle = new FailedLoginException();
+                fle.initCause(pe);
+                throw fle;
+            } else {
+                LoginException le = new LoginException();
+                le.initCause(pe);
+                throw le;
+            }
+        } finally {
+            token.releaseSession(session);
+            if (pin != null) {
+                Arrays.fill(pin, ' ');
+            }
+        }
+
+        // we do not store the PIN in the subject for now
+    }
+
+    /**
+     * Log out from this provider
+     *
+     * @throws IllegalStateException if the provider requires configuration
+     * and Provider.configure has not been called
+     * @throws LoginException if the logout operation fails
+     * @throws SecurityException if the does not pass a security check for
+     *  <code>SecurityPermission("authProvider.<i>name</i>")</code>,
+     *  where <i>name</i> is the value returned by
+     *  this provider's <code>getName</code> method
+     */
+    public void logout() throws LoginException {
+
+        if (!isConfigured()) {
+            throw new IllegalStateException("Configuration is required");
+        }
+
+        // security check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission
+                (new SecurityPermission("authProvider." + this.getName()));
+        }
+
+        if (hasValidToken() == false) {
+            // app may call logout for cleanup, allow
+            return;
+        }
+
+        if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) {
+            if (debug != null) {
+                debug.println("logout operation not required for token - " +
+                                "ignoring logout request");
+            }
+            return;
+        }
+
+        try {
+            if (token.isLoggedInNow(null) == false) {
+                if (debug != null) {
+                    debug.println("user not logged in");
+                }
+                return;
+            }
+        } catch (PKCS11Exception e) {
+            // ignore
+        }
+
+        // perform token logout
+
+        Session session = null;
+        try {
+            session = token.getOpSession();
+            p11.C_Logout(session.id());
+            if (debug != null) {
+                debug.println("logout succeeded");
+            }
+        } catch (PKCS11Exception pe) {
+            if (pe.getErrorCode() == CKR_USER_NOT_LOGGED_IN) {
+                // let this one go
+                if (debug != null) {
+                    debug.println("user not logged in");
+                }
+                return;
+            }
+            LoginException le = new LoginException();
+            le.initCause(pe);
+            throw le;
+        } finally {
+            token.releaseSession(session);
+        }
+    }
+
+    /**
+     * Set a <code>CallbackHandler</code>
+     *
+     * <p> The provider uses this handler if one is not passed to the
+     * <code>login</code> method.  The provider also uses this handler
+     * if it invokes <code>login</code> on behalf of callers.
+     * In either case if a handler is not set via this method,
+     * the provider queries the
+     * <i>auth.login.defaultCallbackHandler</i> security property
+     * for the fully qualified class name of a default handler implementation.
+     * If the security property is not set,
+     * the provider is assumed to have alternative means
+     * for obtaining authentication information.
+     *
+     * @param handler a <code>CallbackHandler</code> for obtaining
+     *          authentication information, which may be <code>null</code>
+     *
+     * @throws IllegalStateException if the provider requires configuration
+     * and Provider.configure has not been called
+     * @throws SecurityException if the caller does not pass a
+     *  security check for
+     *  <code>SecurityPermission("authProvider.<i>name</i>")</code>,
+     *  where <i>name</i> is the value returned by
+     *  this provider's <code>getName</code> method
+     */
+    public void setCallbackHandler(CallbackHandler handler) {
+
+        if (!isConfigured()) {
+            throw new IllegalStateException("Configuration is required");
+        }
+
+        // security check
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission
+                (new SecurityPermission("authProvider." + this.getName()));
+        }
+
+        synchronized (LOCK_HANDLER) {
+            pHandler = handler;
+        }
+    }
+
+    private CallbackHandler getCallbackHandler(CallbackHandler handler) {
+
+        // get default handler if necessary
+
+        if (handler != null) {
+            return handler;
+        }
+
+        if (debug != null) {
+            debug.println("getting provider callback handler");
+        }
+
+        synchronized (LOCK_HANDLER) {
+            // see if handler was set via setCallbackHandler
+            if (pHandler != null) {
+                return pHandler;
+            }
+
+            try {
+                if (debug != null) {
+                    debug.println("getting default callback handler");
+                }
+
+                CallbackHandler myHandler = AccessController.doPrivileged
+                    (new PrivilegedExceptionAction<CallbackHandler>() {
+                    public CallbackHandler run() throws Exception {
+
+                        String defaultHandler =
+                                java.security.Security.getProperty
+                                ("auth.login.defaultCallbackHandler");
+
+                        if (defaultHandler == null ||
+                            defaultHandler.length() == 0) {
+
+                            // ok
+                            if (debug != null) {
+                                debug.println("no default handler set");
+                            }
+                            return null;
+                        }
+
+                        Class<?> c = Class.forName
+                                   (defaultHandler,
+                                   true,
+                                   Thread.currentThread().getContextClassLoader());
+                        if (!javax.security.auth.callback.CallbackHandler.class.isAssignableFrom(c)) {
+                            // not the right subtype
+                            if (debug != null) {
+                                debug.println("default handler " + defaultHandler +
+                                              " is not a CallbackHandler");
+                            }
+                            return null;
+                        }
+                        @SuppressWarnings("deprecation")
+                        Object result = c.newInstance();
+                        return (CallbackHandler)result;
+                    }
+                });
+                // save it
+                pHandler = myHandler;
+                return myHandler;
+
+            } catch (PrivilegedActionException pae) {
+                // ok
+                if (debug != null) {
+                    debug.println("Unable to load default callback handler");
+                    pae.printStackTrace();
+                }
+            }
+        }
+        return null;
+    }
+
+    private Object writeReplace() throws ObjectStreamException {
+        return new SunPKCS11Rep(this);
+    }
+
+    /**
+     * Serialized representation of the SunPKCS11 provider.
+     */
+    private static class SunPKCS11Rep implements Serializable {
+
+        static final long serialVersionUID = -2896606995897745419L;
+
+        private final String providerName;
+
+        private final String configName;
+
+        SunPKCS11Rep(SunPKCS11 provider) throws NotSerializableException {
+            providerName = provider.getName();
+            configName = provider.config.getFileName();
+            if (Security.getProvider(providerName) != provider) {
+                throw new NotSerializableException("Only SunPKCS11 providers "
+                    + "installed in java.security.Security can be serialized");
+            }
+        }
+
+        private Object readResolve() throws ObjectStreamException {
+            SunPKCS11 p = (SunPKCS11)Security.getProvider(providerName);
+            if ((p == null) || (p.config.getFileName().equals(configName) == false)) {
+                throw new NotSerializableException("Could not find "
+                        + providerName + " in installed providers");
+            }
+            return p;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/TemplateManager.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2003, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * TemplateManager class.
+ *
+ * Not all PKCS#11 tokens are created equal. One token may require that one
+ * value is specified when creating a certain type of object. Another token
+ * may require a different value. Yet another token may only work if the
+ * attribute is not specified at all.
+ *
+ * In order to allow an application to work unmodified with all those
+ * different tokens, the SunPKCS11 provider makes the attributes that are
+ * specified and their value configurable. Hence, only the SunPKCS11
+ * configuration file has to be tweaked at deployment time to allow all
+ * existing applications to be used.
+ *
+ * The template manager is responsible for reading the attribute configuration
+ * information and to make it available to the various internal components
+ * of the SunPKCS11 provider.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+final class TemplateManager {
+
+    private final static boolean DEBUG = false;
+
+    // constant for any operation (either O_IMPORT or O_GENERATE)
+    final static String O_ANY      = "*";
+    // constant for operation create ("importing" existing key material)
+    final static String O_IMPORT   = "import";
+    // constant for operation generate (generating new key material)
+    final static String O_GENERATE = "generate";
+
+    private static class KeyAndTemplate {
+        final TemplateKey key;
+        final Template template;
+
+        KeyAndTemplate(TemplateKey key, Template template) {
+            this.key = key;
+            this.template = template;
+        }
+    }
+
+    // primitive templates contains the individual template configuration
+    // entries from the configuration file
+    private final List<KeyAndTemplate> primitiveTemplates;
+
+    // composite templates is a cache of the exact configuration template for
+    // each specific TemplateKey (no wildcards). the entries are created
+    // on demand during first use by compositing all applicable
+    // primitive template entries. the result is then stored in this map
+    // for performance
+    private final Map<TemplateKey,Template> compositeTemplates;
+
+    TemplateManager() {
+        primitiveTemplates = new ArrayList<KeyAndTemplate>();
+        compositeTemplates = new ConcurrentHashMap<TemplateKey,Template>();
+    }
+
+    // add a template. Called by Config.
+    void addTemplate(String op, long objectClass, long keyAlgorithm,
+            CK_ATTRIBUTE[] attrs) {
+        TemplateKey key = new TemplateKey(op, objectClass, keyAlgorithm);
+        Template template = new Template(attrs);
+        if (DEBUG) {
+            System.out.println("Adding " + key + " -> " + template);
+        }
+        primitiveTemplates.add(new KeyAndTemplate(key, template));
+    }
+
+    private Template getTemplate(TemplateKey key) {
+        Template template = compositeTemplates.get(key);
+        if (template == null) {
+            template = buildCompositeTemplate(key);
+            compositeTemplates.put(key, template);
+        }
+        return template;
+    }
+
+    // Get the attributes for the requested op and combine them with attrs.
+    // This is the method called by the implementation to obtain the
+    // attributes.
+    CK_ATTRIBUTE[] getAttributes(String op, long type, long alg,
+            CK_ATTRIBUTE[] attrs) {
+        TemplateKey key = new TemplateKey(op, type, alg);
+        Template template = getTemplate(key);
+        CK_ATTRIBUTE[] newAttrs = template.getAttributes(attrs);
+        if (DEBUG) {
+            System.out.println(key + " -> " + Arrays.asList(newAttrs));
+        }
+        return newAttrs;
+    }
+
+    // build a composite template for the given key
+    private Template buildCompositeTemplate(TemplateKey key) {
+        Template comp = new Template();
+        // iterate through primitive templates and add all that apply
+        for (KeyAndTemplate entry : primitiveTemplates) {
+            if (entry.key.appliesTo(key)) {
+                comp.add(entry.template);
+            }
+        }
+        return comp;
+    }
+
+    /**
+     * Nested class representing a template identifier.
+     */
+    private static final class TemplateKey {
+        final String operation;
+        final long keyType;
+        final long keyAlgorithm;
+        TemplateKey(String operation, long keyType, long keyAlgorithm) {
+            this.operation = operation;
+            this.keyType = keyType;
+            this.keyAlgorithm = keyAlgorithm;
+        }
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof TemplateKey == false) {
+                return false;
+            }
+            TemplateKey other = (TemplateKey)obj;
+            boolean match = this.operation.equals(other.operation)
+                        && (this.keyType == other.keyType)
+                        && (this.keyAlgorithm == other.keyAlgorithm);
+            return match;
+        }
+        public int hashCode() {
+            return operation.hashCode() + (int)keyType + (int)keyAlgorithm;
+        }
+        boolean appliesTo(TemplateKey key) {
+            if (operation.equals(O_ANY) || operation.equals(key.operation)) {
+                if ((keyType == PCKO_ANY) || (keyType == key.keyType)) {
+                    if ((keyAlgorithm == PCKK_ANY)
+                                || (keyAlgorithm == key.keyAlgorithm)) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+        public String toString() {
+            return "(" + operation + ","
+                + Functions.getObjectClassName(keyType)
+                + "," + Functions.getKeyName(keyAlgorithm) + ")";
+        }
+    }
+
+    /**
+     * Nested class representing template attributes.
+     */
+    private static final class Template {
+
+        private final static CK_ATTRIBUTE[] A0 = new CK_ATTRIBUTE[0];
+
+        private CK_ATTRIBUTE[] attributes;
+
+        Template() {
+            attributes = A0;
+        }
+
+        Template(CK_ATTRIBUTE[] attributes) {
+            this.attributes = attributes;
+        }
+
+        void add(Template template) {
+            attributes = getAttributes(template.attributes);
+        }
+
+        CK_ATTRIBUTE[] getAttributes(CK_ATTRIBUTE[] attrs) {
+            return combine(attributes, attrs);
+        }
+
+        /**
+         * Combine two sets of attributes. The second set has precedence
+         * over the first and overrides its settings.
+         */
+        private static CK_ATTRIBUTE[] combine(CK_ATTRIBUTE[] attrs1,
+                CK_ATTRIBUTE[] attrs2) {
+            List<CK_ATTRIBUTE> attrs = new ArrayList<CK_ATTRIBUTE>();
+            for (CK_ATTRIBUTE attr : attrs1) {
+                if (attr.pValue != null) {
+                    attrs.add(attr);
+                }
+            }
+            for (CK_ATTRIBUTE attr2 : attrs2) {
+                long type = attr2.type;
+                for (CK_ATTRIBUTE attr1 : attrs1) {
+                    if (attr1.type == type) {
+                        attrs.remove(attr1);
+                    }
+                }
+                if (attr2.pValue != null) {
+                    attrs.add(attr2);
+                }
+            }
+            return attrs.toArray(A0);
+        }
+
+        public String toString() {
+            return Arrays.asList(attributes).toString();
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Token.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2003, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.io.*;
+import java.lang.ref.*;
+
+import java.security.*;
+import javax.security.auth.login.LoginException;
+
+import sun.security.jca.JCAUtil;
+
+import sun.security.pkcs11.wrapper.*;
+import static sun.security.pkcs11.TemplateManager.*;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * PKCS#11 token.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.5
+ */
+class Token implements Serializable {
+
+    // need to be serializable to allow SecureRandom to be serialized
+    private static final long serialVersionUID = 2541527649100571747L;
+
+    // how often to check if the token is still present (in ms)
+    // this is different from checking if a token has been inserted,
+    // that is done in SunPKCS11. Currently 50 ms.
+    private final static long CHECK_INTERVAL = 50;
+
+    final SunPKCS11 provider;
+
+    final PKCS11 p11;
+
+    final Config config;
+
+    final CK_TOKEN_INFO tokenInfo;
+
+    // session manager to pool sessions
+    final SessionManager sessionManager;
+
+    // template manager to customize the attributes used when creating objects
+    private final TemplateManager templateManager;
+
+    // flag indicating whether we need to explicitly cancel operations
+    // we started on the token. If false, we assume operations are
+    // automatically cancelled once we start another one
+    final boolean explicitCancel;
+
+    // translation cache for secret keys
+    final KeyCache secretCache;
+
+    // translation cache for asymmetric keys (public and private)
+    final KeyCache privateCache;
+
+    // cached instances of the various key factories, initialized on demand
+    private volatile P11KeyFactory rsaFactory, dsaFactory, dhFactory, ecFactory;
+
+    // table which maps mechanisms to the corresponding cached
+    // MechanismInfo objects
+    private final Map<Long, CK_MECHANISM_INFO> mechInfoMap;
+
+    // single SecureRandomSpi instance we use per token
+    // initialized on demand (if supported)
+    private volatile P11SecureRandom secureRandom;
+
+    // single KeyStoreSpi instance we use per provider
+    // initialized on demand
+    private volatile P11KeyStore keyStore;
+
+    // whether this token is a removable token
+    private final boolean removable;
+
+    // for removable tokens: whether this token is valid or has been removed
+    private volatile boolean valid;
+
+    // for removable tokens: time last checked for token presence
+    private long lastPresentCheck;
+
+    // unique token id, used for serialization only
+    private byte[] tokenId;
+
+    // flag indicating whether the token is write protected
+    private boolean writeProtected;
+
+    // flag indicating whether we are logged in
+    private volatile boolean loggedIn;
+
+    // time we last checked login status
+    private long lastLoginCheck;
+
+    // mutex for token-present-check
+    private final static Object CHECK_LOCK = new Object();
+
+    // object for indicating unsupported mechanism in 'mechInfoMap'
+    private final static CK_MECHANISM_INFO INVALID_MECH =
+        new CK_MECHANISM_INFO(0, 0, 0);
+
+    // flag indicating whether the token supports raw secret key material import
+    private Boolean supportsRawSecretKeyImport;
+
+    Token(SunPKCS11 provider) throws PKCS11Exception {
+        this.provider = provider;
+        this.removable = provider.removable;
+        this.valid = true;
+        p11 = provider.p11;
+        config = provider.config;
+        tokenInfo = p11.C_GetTokenInfo(provider.slotID);
+        writeProtected = (tokenInfo.flags & CKF_WRITE_PROTECTED) != 0;
+        // create session manager and open a test session
+        SessionManager sessionManager;
+        try {
+            sessionManager = new SessionManager(this);
+            Session s = sessionManager.getOpSession();
+            sessionManager.releaseSession(s);
+        } catch (PKCS11Exception e) {
+            if (writeProtected) {
+                throw e;
+            }
+            // token might not permit RW sessions even though
+            // CKF_WRITE_PROTECTED is not set
+            writeProtected = true;
+            sessionManager = new SessionManager(this);
+            Session s = sessionManager.getOpSession();
+            sessionManager.releaseSession(s);
+        }
+        this.sessionManager = sessionManager;
+        secretCache = new KeyCache();
+        privateCache = new KeyCache();
+        templateManager = config.getTemplateManager();
+        explicitCancel = config.getExplicitCancel();
+        mechInfoMap =
+            new ConcurrentHashMap<Long, CK_MECHANISM_INFO>(10);
+    }
+
+    boolean isWriteProtected() {
+        return writeProtected;
+    }
+
+    // return whether the token supports raw secret key material import
+    boolean supportsRawSecretKeyImport() {
+        if (supportsRawSecretKeyImport == null) {
+            SecureRandom random = JCAUtil.getSecureRandom();
+            byte[] encoded = new byte[48];
+            random.nextBytes(encoded);
+
+            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[3];
+            attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
+            attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET);
+            attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
+
+            Session session = null;
+            try {
+                attributes = getAttributes(O_IMPORT,
+                        CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
+                session = getObjSession();
+                long keyID = p11.C_CreateObject(session.id(), attributes);
+
+                supportsRawSecretKeyImport = Boolean.TRUE;
+            } catch (PKCS11Exception e) {
+                supportsRawSecretKeyImport = Boolean.FALSE;
+            } finally {
+                releaseSession(session);
+            }
+        }
+
+        return supportsRawSecretKeyImport;
+    }
+
+    // return whether we are logged in
+    // uses cached result if current. session is optional and may be null
+    boolean isLoggedIn(Session session) throws PKCS11Exception {
+        // volatile load first
+        boolean loggedIn = this.loggedIn;
+        long time = System.currentTimeMillis();
+        if (time - lastLoginCheck > CHECK_INTERVAL) {
+            loggedIn = isLoggedInNow(session);
+            lastLoginCheck = time;
+        }
+        return loggedIn;
+    }
+
+    // return whether we are logged in now
+    // does not use cache
+    boolean isLoggedInNow(Session session) throws PKCS11Exception {
+        boolean allocSession = (session == null);
+        try {
+            if (allocSession) {
+                session = getOpSession();
+            }
+            CK_SESSION_INFO info = p11.C_GetSessionInfo(session.id());
+            boolean loggedIn = (info.state == CKS_RO_USER_FUNCTIONS) ||
+                                (info.state == CKS_RW_USER_FUNCTIONS);
+            this.loggedIn = loggedIn;
+            return loggedIn;
+        } finally {
+            if (allocSession) {
+                releaseSession(session);
+            }
+        }
+    }
+
+    // ensure that we are logged in
+    // call provider.login() if not
+    void ensureLoggedIn(Session session) throws PKCS11Exception, LoginException {
+        if (isLoggedIn(session) == false) {
+            provider.login(null, null);
+        }
+    }
+
+    // return whether this token object is valid (i.e. token not removed)
+    // returns value from last check, does not perform new check
+    boolean isValid() {
+        if (removable == false) {
+            return true;
+        }
+        return valid;
+    }
+
+    void ensureValid() {
+        if (isValid() == false) {
+            throw new ProviderException("Token has been removed");
+        }
+    }
+
+    // return whether a token is present (i.e. token not removed)
+    // returns cached value if current, otherwise performs new check
+    boolean isPresent(long sessionID) {
+        if (removable == false) {
+            return true;
+        }
+        if (valid == false) {
+            return false;
+        }
+        long time = System.currentTimeMillis();
+        if ((time - lastPresentCheck) >= CHECK_INTERVAL) {
+            synchronized (CHECK_LOCK) {
+                if ((time - lastPresentCheck) >= CHECK_INTERVAL) {
+                    boolean ok = false;
+                    try {
+                        // check if token still present
+                        CK_SLOT_INFO slotInfo =
+                                provider.p11.C_GetSlotInfo(provider.slotID);
+                        if ((slotInfo.flags & CKF_TOKEN_PRESENT) != 0) {
+                            // if the token has been removed and re-inserted,
+                            // the token should return an error
+                            CK_SESSION_INFO sessInfo =
+                                    provider.p11.C_GetSessionInfo
+                                    (sessionID);
+                            ok = true;
+                        }
+                    } catch (PKCS11Exception e) {
+                        // empty
+                    }
+                    valid = ok;
+                    lastPresentCheck = System.currentTimeMillis();
+                    if (ok == false) {
+                        destroy();
+                    }
+                }
+            }
+        }
+        return valid;
+    }
+
+    void destroy() {
+        valid = false;
+        provider.uninitToken(this);
+    }
+
+    Session getObjSession() throws PKCS11Exception {
+        return sessionManager.getObjSession();
+    }
+
+    Session getOpSession() throws PKCS11Exception {
+        return sessionManager.getOpSession();
+    }
+
+    Session releaseSession(Session session) {
+        return sessionManager.releaseSession(session);
+    }
+
+    Session killSession(Session session) {
+        return sessionManager.killSession(session);
+    }
+
+    CK_ATTRIBUTE[] getAttributes(String op, long type, long alg,
+            CK_ATTRIBUTE[] attrs) throws PKCS11Exception {
+        CK_ATTRIBUTE[] newAttrs =
+                    templateManager.getAttributes(op, type, alg, attrs);
+        for (CK_ATTRIBUTE attr : newAttrs) {
+            if (attr.type == CKA_TOKEN) {
+                if (attr.getBoolean()) {
+                    try {
+                        ensureLoggedIn(null);
+                    } catch (LoginException e) {
+                        throw new ProviderException("Login failed", e);
+                    }
+                }
+                // break once we have found a CKA_TOKEN attribute
+                break;
+            }
+        }
+        return newAttrs;
+    }
+
+    P11KeyFactory getKeyFactory(String algorithm) {
+        P11KeyFactory f;
+        if (algorithm.equals("RSA")) {
+            f = rsaFactory;
+            if (f == null) {
+                f = new P11RSAKeyFactory(this, algorithm);
+                rsaFactory = f;
+            }
+        } else if (algorithm.equals("DSA")) {
+            f = dsaFactory;
+            if (f == null) {
+                f = new P11DSAKeyFactory(this, algorithm);
+                dsaFactory = f;
+            }
+        } else if (algorithm.equals("DH")) {
+            f = dhFactory;
+            if (f == null) {
+                f = new P11DHKeyFactory(this, algorithm);
+                dhFactory = f;
+            }
+        } else if (algorithm.equals("EC")) {
+            f = ecFactory;
+            if (f == null) {
+                f = new P11ECKeyFactory(this, algorithm);
+                ecFactory = f;
+            }
+        } else {
+            throw new ProviderException("Unknown algorithm " + algorithm);
+        }
+        return f;
+    }
+
+    P11SecureRandom getRandom() {
+        if (secureRandom == null) {
+            secureRandom = new P11SecureRandom(this);
+        }
+        return secureRandom;
+    }
+
+    P11KeyStore getKeyStore() {
+        if (keyStore == null) {
+            keyStore = new P11KeyStore(this);
+        }
+        return keyStore;
+    }
+
+    CK_MECHANISM_INFO getMechanismInfo(long mechanism) throws PKCS11Exception {
+        CK_MECHANISM_INFO result = mechInfoMap.get(mechanism);
+        if (result == null) {
+            try {
+                result = p11.C_GetMechanismInfo(provider.slotID,
+                                                mechanism);
+                mechInfoMap.put(mechanism, result);
+            } catch (PKCS11Exception e) {
+                if (e.getErrorCode() != PKCS11Constants.CKR_MECHANISM_INVALID) {
+                    throw e;
+                } else {
+                    mechInfoMap.put(mechanism, INVALID_MECH);
+                }
+            }
+        } else if (result == INVALID_MECH) {
+            result = null;
+        }
+        return result;
+    }
+
+    private synchronized byte[] getTokenId() {
+        if (tokenId == null) {
+            SecureRandom random = JCAUtil.getSecureRandom();
+            tokenId = new byte[20];
+            random.nextBytes(tokenId);
+            serializedTokens.add(new WeakReference<Token>(this));
+        }
+        return tokenId;
+    }
+
+    // list of all tokens that have been serialized within this VM
+    // NOTE that elements are never removed from this list
+    // the assumption is that the number of tokens that are serialized
+    // is relatively small
+    private static final List<Reference<Token>> serializedTokens =
+        new ArrayList<Reference<Token>>();
+
+    private Object writeReplace() throws ObjectStreamException {
+        if (isValid() == false) {
+            throw new NotSerializableException("Token has been removed");
+        }
+        return new TokenRep(this);
+    }
+
+    // serialized representation of a token
+    // tokens can only be de-serialized within the same VM invocation
+    // and if the token has not been removed in the meantime
+    private static class TokenRep implements Serializable {
+
+        private static final long serialVersionUID = 3503721168218219807L;
+
+        private final byte[] tokenId;
+
+        TokenRep(Token token) {
+            tokenId = token.getTokenId();
+        }
+
+        private Object readResolve() throws ObjectStreamException {
+            for (Reference<Token> tokenRef : serializedTokens) {
+                Token token = tokenRef.get();
+                if ((token != null) && token.isValid()) {
+                    if (Arrays.equals(token.getTokenId(), tokenId)) {
+                        return token;
+                    }
+                }
+            }
+            throw new NotSerializableException("Could not find token");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+/**
+ * This class represents the necessary parameters required by
+ * the CKM_AES_CTR mechanism as defined in CK_AES_CTR_PARAMS structure.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_AES_CTR_PARAMS {
+ *   CK_ULONG ulCounterBits;
+ *   CK_BYTE cb[16];
+ * } CK_AES_CTR_PARAMS;
+ * </PRE>
+ *
+ * @author Yu-Ching Valerie Peng
+ * @since   1.7
+ */
+public class CK_AES_CTR_PARAMS {
+
+    private final long ulCounterBits;
+    private final byte[] cb;
+
+    public CK_AES_CTR_PARAMS(byte[] cb) {
+        ulCounterBits = 128;
+        this.cb = cb.clone();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("ulCounterBits: ");
+        sb.append(ulCounterBits);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("cb: ");
+        sb.append(Functions.toHexString(cb));
+
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ATTRIBUTE.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+import java.math.BigInteger;
+
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * class CK_ATTRIBUTE includes the type, value and length of an attribute.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_ATTRIBUTE {&nbsp;&nbsp;
+ *   CK_ATTRIBUTE_TYPE type;&nbsp;&nbsp;
+ *   CK_VOID_PTR pValue;&nbsp;&nbsp;
+ *   CK_ULONG ulValueLen;
+ * } CK_ATTRIBUTE;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_ATTRIBUTE {
+
+    // common attributes
+    // NOTE that CK_ATTRIBUTE is a mutable classes but these attributes
+    // *MUST NEVER* be modified, e.g. by using them in a
+    // C_GetAttributeValue() call!
+
+    public final static CK_ATTRIBUTE TOKEN_FALSE =
+                                    new CK_ATTRIBUTE(CKA_TOKEN, false);
+
+    public final static CK_ATTRIBUTE SENSITIVE_FALSE =
+                                    new CK_ATTRIBUTE(CKA_SENSITIVE, false);
+
+    public final static CK_ATTRIBUTE EXTRACTABLE_TRUE =
+                                    new CK_ATTRIBUTE(CKA_EXTRACTABLE, true);
+
+    public final static CK_ATTRIBUTE ENCRYPT_TRUE =
+                                    new CK_ATTRIBUTE(CKA_ENCRYPT, true);
+
+    public final static CK_ATTRIBUTE DECRYPT_TRUE =
+                                    new CK_ATTRIBUTE(CKA_DECRYPT, true);
+
+    public final static CK_ATTRIBUTE WRAP_TRUE =
+                                    new CK_ATTRIBUTE(CKA_WRAP, true);
+
+    public final static CK_ATTRIBUTE UNWRAP_TRUE =
+                                    new CK_ATTRIBUTE(CKA_UNWRAP, true);
+
+    public final static CK_ATTRIBUTE SIGN_TRUE =
+                                    new CK_ATTRIBUTE(CKA_SIGN, true);
+
+    public final static CK_ATTRIBUTE VERIFY_TRUE =
+                                    new CK_ATTRIBUTE(CKA_VERIFY, true);
+
+    public final static CK_ATTRIBUTE SIGN_RECOVER_TRUE =
+                                    new CK_ATTRIBUTE(CKA_SIGN_RECOVER, true);
+
+    public final static CK_ATTRIBUTE VERIFY_RECOVER_TRUE =
+                                    new CK_ATTRIBUTE(CKA_VERIFY_RECOVER, true);
+
+    public final static CK_ATTRIBUTE DERIVE_TRUE =
+                                    new CK_ATTRIBUTE(CKA_DERIVE, true);
+
+    public final static CK_ATTRIBUTE ENCRYPT_NULL =
+                                    new CK_ATTRIBUTE(CKA_ENCRYPT);
+
+    public final static CK_ATTRIBUTE DECRYPT_NULL =
+                                    new CK_ATTRIBUTE(CKA_DECRYPT);
+
+    public final static CK_ATTRIBUTE WRAP_NULL =
+                                    new CK_ATTRIBUTE(CKA_WRAP);
+
+    public final static CK_ATTRIBUTE UNWRAP_NULL =
+                                    new CK_ATTRIBUTE(CKA_UNWRAP);
+
+    public CK_ATTRIBUTE() {
+        // empty
+    }
+
+    public CK_ATTRIBUTE(long type) {
+        this.type = type;
+    }
+
+    public CK_ATTRIBUTE(long type, Object pValue) {
+        this.type = type;
+        this.pValue = pValue;
+    }
+
+    public CK_ATTRIBUTE(long type, boolean value) {
+        this.type = type;
+        this.pValue = Boolean.valueOf(value);
+    }
+
+    public CK_ATTRIBUTE(long type, long value) {
+        this.type = type;
+        this.pValue = Long.valueOf(value);
+    }
+
+    public CK_ATTRIBUTE(long type, BigInteger value) {
+        this.type = type;
+        this.pValue = sun.security.pkcs11.P11Util.getMagnitude(value);
+    }
+
+    public BigInteger getBigInteger() {
+        if (pValue instanceof byte[] == false) {
+            throw new RuntimeException("Not a byte[]");
+        }
+        return new BigInteger(1, (byte[])pValue);
+    }
+
+    public boolean getBoolean() {
+        if (pValue instanceof Boolean == false) {
+            throw new RuntimeException
+                ("Not a Boolean: " + pValue.getClass().getName());
+        }
+        return ((Boolean)pValue).booleanValue();
+    }
+
+    public char[] getCharArray() {
+        if (pValue instanceof char[] == false) {
+            throw new RuntimeException("Not a char[]");
+        }
+        return (char[])pValue;
+    }
+
+    public byte[] getByteArray() {
+        if (pValue instanceof byte[] == false) {
+            throw new RuntimeException("Not a byte[]");
+        }
+        return (byte[])pValue;
+    }
+
+    public long getLong() {
+        if (pValue instanceof Long == false) {
+            throw new RuntimeException
+                ("Not a Long: " + pValue.getClass().getName());
+        }
+        return ((Long)pValue).longValue();
+    }
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ATTRIBUTE_TYPE type;
+     * </PRE>
+     */
+    public long type;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VOID_PTR pValue;
+     *   CK_ULONG ulValueLen;
+     * </PRE>
+     */
+    public Object pValue;
+
+    /**
+     * Returns the string representation of CK_ATTRIBUTE.
+     *
+     * @return the string representation of CK_ATTRIBUTE
+     */
+    public String toString() {
+        String prefix = Functions.getAttributeName(type) + " = ";
+        if (type == CKA_CLASS) {
+            return prefix + Functions.getObjectClassName(getLong());
+        } else if (type == CKA_KEY_TYPE) {
+            return prefix + Functions.getKeyName(getLong());
+        } else {
+            String s;
+            if (pValue instanceof char[]) {
+                s = new String((char[])pValue);
+            } else if (pValue instanceof byte[]) {
+                s = Functions.toHexString((byte[])pValue);
+            } else {
+                s = String.valueOf(pValue);
+            }
+            return prefix + s;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_CREATEMUTEX.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,68 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * interface CK_CREATEMUTEX.
+ *
+ * @author Karl Scheibelhofer &lt;Karl.Scheibelhofer@iaik.at&gt;
+ * @author Martin Schlaeffer &lt;schlaeff@sbox.tugraz.at&gt;
+ */
+public interface CK_CREATEMUTEX {
+
+    /**
+     * Method CK_CREATEMUTEX
+     *
+     * @return The mutex (lock) object.
+     * @exception PKCS11Exception
+     */
+    public Object CK_CREATEMUTEX() throws PKCS11Exception;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_C_INITIALIZE_ARGS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,120 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_C_INITIALIZE_ARGS contains the optional arguments for the
+ * C_Initialize function.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_C_INITIALIZE_ARGS {&nbsp;&nbsp;
+ *   CK_CREATEMUTEX CreateMutex;&nbsp;&nbsp;
+ *   CK_DESTROYMUTEX DestroyMutex;&nbsp;&nbsp;
+ *   CK_LOCKMUTEX LockMutex;&nbsp;&nbsp;
+ *   CK_UNLOCKMUTEX UnlockMutex;&nbsp;&nbsp;
+ *   CK_FLAGS flags;&nbsp;&nbsp;
+ *   CK_VOID_PTR pReserved;&nbsp;&nbsp;
+ * } CK_C_INITIALIZE_ARGS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_C_INITIALIZE_ARGS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CREATEMUTEX CreateMutex;
+     * </PRE>
+     */
+    public CK_CREATEMUTEX  CreateMutex;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_DESTROYMUTEX DestroyMutex;
+     * </PRE>
+     */
+    public CK_DESTROYMUTEX DestroyMutex;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_LOCKMUTEX LockMutex;
+     * </PRE>
+     */
+    public CK_LOCKMUTEX    LockMutex;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_UNLOCKMUTEX UnlockMutex;
+     * </PRE>
+     */
+    public CK_UNLOCKMUTEX  UnlockMutex;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_FLAGS flags;
+     * </PRE>
+     */
+    public long            flags;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VOID_PTR pReserved;
+     * </PRE>
+     */
+    public Object          pReserved;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_DATE.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,137 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class .<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_DATE {&nbsp;&nbsp;
+ *   CK_CHAR year[4];&nbsp;&nbsp;
+ *   CK_CHAR month[2];&nbsp;&nbsp;
+ *   CK_CHAR day[2];&nbsp;&nbsp;
+ * } CK_DATE;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_DATE implements Cloneable {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CHAR year[4];   - the year ("1900" - "9999")
+     * </PRE>
+     */
+    public char[] year;    /* the year ("1900" - "9999") */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CHAR month[2];  - the month ("01" - "12")
+     * </PRE>
+     */
+    public char[] month;   /* the month ("01" - "12") */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CHAR day[2];    - the day ("01" - "31")
+     * </PRE>
+     */
+    public char[] day;     /* the day ("01" - "31") */
+
+    public CK_DATE(char[] year, char[] month, char[] day) {
+        this.year = year;
+        this.month = month;
+        this.day = day;
+    }
+
+    /**
+     * Create a (deep) clone of this object.
+     *
+     * @return A clone of this object.
+     */
+    public Object clone() {
+        CK_DATE copy = null;
+        try {
+            copy = (CK_DATE) super.clone();
+        } catch (CloneNotSupportedException cnse) {
+            // re-throw as RuntimeException
+            throw (RuntimeException)
+                (new RuntimeException("Clone error").initCause(cnse));
+        }
+        copy.year = this.year.clone();
+        copy.month = this.month.clone();
+        copy.day =  this.day.clone();
+
+        return copy;
+    }
+
+    /**
+     * Returns the string representation of CK_DATE.
+     *
+     * @return the string representation of CK_DATE
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(new String(day));
+        sb.append('.');
+        sb.append(new String(month));
+        sb.append('.');
+        sb.append(new String(year));
+        sb.append(" (DD.MM.YYYY)");
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_DESTROYMUTEX.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,68 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * interface CK_DESTROYMUTEX.<p>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public interface CK_DESTROYMUTEX {
+
+    /**
+     * Method CK_DESTROYMUTEX
+     *
+     * @param pMutex The mutex (lock) object.
+     * @exception PKCS11Exception
+     */
+    public void CK_DESTROYMUTEX(Object pMutex) throws PKCS11Exception;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_ECDH1_DERIVE_PARAMS {
+ *   CK_EC_KDF_TYPE kdf;
+ *   CK_ULONG ulSharedDataLen;
+ *   CK_BYTE_PTR pSharedData;
+ *   CK_ULONG ulPublicDataLen;
+ *   CK_BYTE_PTR pPublicData;
+ * } CK_ECDH1_DERIVE_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+public class CK_ECDH1_DERIVE_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_EC_KDF_TYPE kdf;
+     * </PRE>
+     */
+    public long kdf;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulSharedDataLen;
+     *   CK_BYTE_PTR pSharedData;
+     * </PRE>
+     */
+    public byte[] pSharedData;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulPublicDataLen;
+     *   CK_BYTE_PTR pPublicData;
+     * </PRE>
+     */
+    public byte[] pPublicData;
+
+    public CK_ECDH1_DERIVE_PARAMS(long kdf, byte[] pSharedData, byte[] pPublicData) {
+        this.kdf = kdf;
+        this.pSharedData = pSharedData;
+        this.pPublicData = pPublicData;
+    }
+
+    /**
+     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
+     *
+     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("kdf: 0x");
+        sb.append(Functions.toFullHexString(kdf));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pSharedDataLen: ");
+        sb.append(pSharedData.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pSharedData: ");
+        sb.append(Functions.toHexString(pSharedData));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicDataLen: ");
+        sb.append(pPublicData.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicData: ");
+        sb.append(Functions.toHexString(pPublicData));
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_ECDH2_DERIVE_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,181 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECMQV_DERIVE mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_ECDH2_DERIVE_PARAMS {
+ *   CK_EC_KDF_TYPE kdf;
+ *   CK_ULONG ulSharedDataLen;
+ *   CK_BYTE_PTR pSharedData;
+ *   CK_ULONG ulPublicDataLen;
+ *   CK_BYTE_PTR pPublicData;
+ *   CK_ULONG ulPrivateDataLen;
+ *   CK_OBJECT_HANDLE hPrivateData;
+ *   CK_ULONG ulPublicDataLen2;
+ *   CK_BYTE_PTR pPublicData2;
+ * } CK_ECDH2_DERIVE_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+public class CK_ECDH2_DERIVE_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_EC_KDF_TYPE kdf;
+     * </PRE>
+     */
+    public long kdf;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulSharedDataLen;
+     *   CK_BYTE_PTR pSharedData;
+     * </PRE>
+     */
+    public byte[] pSharedData;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulPublicDataLen;
+     *   CK_BYTE_PTR pPublicData;
+     * </PRE>
+     */
+    public byte[] pPublicData;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulPrivateDataLen;
+     * </PRE>
+     */
+    public long ulPrivateDataLen;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_OBJECT_HANDLE hPrivateData;
+     * </PRE>
+     */
+    public long hPrivateData;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulPublicDataLen2;
+     *   CK_BYTE_PTR pPublicData2;
+     * </PRE>
+     */
+    public byte[] pPublicData2;
+
+    /**
+     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
+     *
+     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("kdf: 0x");
+        sb.append(Functions.toFullHexString(kdf));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pSharedDataLen: ");
+        sb.append(pSharedData.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pSharedData: ");
+        sb.append(Functions.toHexString(pSharedData));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicDataLen: ");
+        sb.append(pPublicData.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicData: ");
+        sb.append(Functions.toHexString(pPublicData));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulPrivateDataLen: ");
+        sb.append(ulPrivateDataLen);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("hPrivateData: ");
+        sb.append(hPrivateData);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicDataLen2: ");
+        sb.append(pPublicData2.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicData2: ");
+        sb.append(Functions.toHexString(pPublicData2));
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_INFO.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,164 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class  CK_INFO provides general information about Cryptoki.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ *  typedef struct CK_INFO {&nbsp;&nbsp;
+ *    CK_VERSION cryptokiVersion;&nbsp;&nbsp;
+ *    CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
+ *    CK_FLAGS flags;&nbsp;&nbsp;
+ *    CK_UTF8CHAR libraryDescription[32];&nbsp;&nbsp;
+ *    CK_VERSION libraryVersion;&nbsp;&nbsp;
+ *  } CK_INFO;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_INFO {
+
+    /**
+     * Cryptoki interface version number<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VERSION cryptokiVersion;
+     * </PRE>
+     */
+    public CK_VERSION cryptokiVersion;
+
+    /**
+     * ID of the Cryptoki library manufacturer. must be blank
+     * padded - only the first 32 chars will be used<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_UTF8CHAR manufacturerID[32];
+     * </PRE>
+     */
+    public char[] manufacturerID;
+
+    /**
+     * bit flags reserved for future versions. must be zero<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_FLAGS flags;
+     * </PRE>
+     */
+    public long flags;
+
+
+/* libraryDescription and libraryVersion are new for v2.0 */
+
+    /**
+     * must be blank padded - only the first 32 chars will be used<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_UTF8CHAR libraryDescription[32];
+     * </PRE>
+     */
+    public char[] libraryDescription;
+
+    /**
+     * Cryptoki library version number<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VERSION libraryVersion;
+     * </PRE>
+     */
+    public CK_VERSION libraryVersion;
+
+    public CK_INFO(CK_VERSION cryptoVer, char[] vendor, long flags,
+                   char[] libDesc, CK_VERSION libVer) {
+        this.cryptokiVersion = cryptoVer;
+        this.manufacturerID = vendor;
+        this.flags = flags;
+        this.libraryDescription = libDesc;
+        this.libraryVersion = libVer;
+    }
+
+    /**
+     * Returns the string representation of CK_INFO.
+     *
+     * @return the string representation of CK_INFO
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("cryptokiVersion: ");
+        sb.append(cryptokiVersion.toString());
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("manufacturerID: ");
+        sb.append(new String(manufacturerID));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("flags: ");
+        sb.append(Functions.toBinaryString(flags));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("libraryDescription: ");
+        sb.append(new String(libraryDescription));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("libraryVersion: ");
+        sb.append(libraryVersion.toString());
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString() ;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_LOCKMUTEX.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,68 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * interface CK_LOCKMUTEX<p>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public interface CK_LOCKMUTEX {
+
+    /**
+     * Method CK_LOCKMUTEX
+     *
+     * @param pMutex The mutex (lock) object to lock.
+     * @exception PKCS11Exception
+     */
+    public void CK_LOCKMUTEX(Object pMutex) throws PKCS11Exception;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+import java.math.BigInteger;
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * class CK_MECHANISM specifies a particular mechanism and any parameters it
+ * requires.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ *  typedef struct CK_MECHANISM {&nbsp;&nbsp;
+ *    CK_MECHANISM_TYPE mechanism;&nbsp;&nbsp;
+ *    CK_VOID_PTR pParameter;&nbsp;&nbsp;
+ *    CK_ULONG ulParameterLen;&nbsp;&nbsp;
+ *  } CK_MECHANISM;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_MECHANISM {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_MECHANISM_TYPE mechanism;
+     * </PRE>
+     */
+    public long mechanism;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VOID_PTR pParameter;
+     *   CK_ULONG ulParameterLen;
+     * </PRE>
+     */
+    public Object pParameter;
+
+    public CK_MECHANISM() {
+        // empty
+    }
+
+    public CK_MECHANISM(long mechanism) {
+        this.mechanism = mechanism;
+    }
+
+    // We don't have a (long,Object) constructor to force type checking.
+    // This makes sure we don't accidentally pass a class that the native
+    // code cannot handle.
+
+    public CK_MECHANISM(long mechanism, byte[] pParameter) {
+        init(mechanism, pParameter);
+    }
+
+    public CK_MECHANISM(long mechanism, BigInteger b) {
+        init(mechanism, sun.security.pkcs11.P11Util.getMagnitude(b));
+    }
+
+    public CK_MECHANISM(long mechanism, CK_VERSION version) {
+        init(mechanism, version);
+    }
+
+    public CK_MECHANISM(long mechanism, CK_SSL3_MASTER_KEY_DERIVE_PARAMS params) {
+        init(mechanism, params);
+    }
+
+    public CK_MECHANISM(long mechanism, CK_SSL3_KEY_MAT_PARAMS params) {
+        init(mechanism, params);
+    }
+
+    public CK_MECHANISM(long mechanism, CK_TLS_PRF_PARAMS params) {
+        init(mechanism, params);
+    }
+
+    public CK_MECHANISM(long mechanism, CK_ECDH1_DERIVE_PARAMS params) {
+        init(mechanism, params);
+    }
+
+    public CK_MECHANISM(long mechanism, Long params) {
+        init(mechanism, params);
+    }
+
+    public CK_MECHANISM(long mechanism, CK_AES_CTR_PARAMS params) {
+        init(mechanism, params);
+    }
+
+    private void init(long mechanism, Object pParameter) {
+        this.mechanism = mechanism;
+        this.pParameter = pParameter;
+    }
+
+    /**
+     * Returns the string representation of CK_MECHANISM.
+     *
+     * @return the string representation of CK_MECHANISM
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("mechanism: ");
+        sb.append(mechanism);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pParameter: ");
+        sb.append(pParameter.toString());
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulParameterLen: ??");
+        //buffer.append(pParameter.length);
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString() ;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM_INFO.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,127 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_MECHANISM_INFO provides information about a particular mechanism.
+ * <p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_MECHANISM_INFO {&nbsp;&nbsp;
+ *   CK_ULONG ulMinKeySize;&nbsp;&nbsp;
+ *   CK_ULONG ulMaxKeySize;&nbsp;&nbsp;
+ *   CK_FLAGS flags;&nbsp;&nbsp;
+ * } CK_MECHANISM_INFO;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_MECHANISM_INFO {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulMinKeySize;
+     * </PRE>
+     */
+    public long ulMinKeySize;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulMaxKeySize;
+     * </PRE>
+     */
+    public long ulMaxKeySize;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_FLAGS flags;
+     * </PRE>
+     */
+    public long flags;
+
+    public CK_MECHANISM_INFO(long minKeySize, long maxKeySize,
+                             long flags) {
+        this.ulMinKeySize = minKeySize;
+        this.ulMaxKeySize = maxKeySize;
+        this.flags = flags;
+    }
+
+    /**
+     * Returns the string representation of CK_MECHANISM_INFO.
+     *
+     * @return the string representation of CK_MECHANISM_INFO
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("ulMinKeySize: ");
+        sb.append(String.valueOf(ulMinKeySize));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulMaxKeySize: ");
+        sb.append(String.valueOf(ulMaxKeySize));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("flags: ");
+        sb.append(String.valueOf(flags));
+        sb.append(" = ");
+        sb.append(Functions.mechanismInfoFlagsToString(flags));
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString() ;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_NOTIFY.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,70 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * interface CK_NOTIFY.<p>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public interface CK_NOTIFY {
+
+    /**
+     * Method CK_NOTIFY
+     *
+     * @param hSession
+     * @param event
+     * @param pApplication
+     * @exception PKCS11Exception
+     */
+    public void CK_NOTIFY(long hSession, long event, Object pApplication) throws PKCS11Exception;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,147 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_PBE_PARAMS provides all of the necessary information required byte
+ * the CKM_PBE mechanisms and the CKM_PBA_SHA1_WITH_SHA1_HMAC mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_PBE_PARAMS {
+ *   CK_CHAR_PTR pInitVector;
+ *   CK_CHAR_PTR pPassword;
+ *   CK_ULONG ulPasswordLen;
+ *   CK_CHAR_PTR pSalt;
+ *   CK_ULONG ulSaltLen;
+ *   CK_ULONG ulIteration;
+ * } CK_PBE_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_PBE_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CHAR_PTR pInitVector;
+     * </PRE>
+     */
+    public char[] pInitVector;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CHAR_PTR pPassword;
+     *   CK_ULONG ulPasswordLen;
+     * </PRE>
+     */
+    public char[] pPassword;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CHAR_PTR pSalt
+     *   CK_ULONG ulSaltLen;
+     * </PRE>
+     */
+    public char[] pSalt;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulIteration;
+     * </PRE>
+     */
+    public long ulIteration;
+
+    /**
+     * Returns the string representation of CK_PBE_PARAMS.
+     *
+     * @return the string representation of CK_PBE_PARAMS
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("pInitVector: ");
+        sb.append(pInitVector);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulPasswordLen: ");
+        sb.append(pPassword.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPassword: ");
+        sb.append(pPassword);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulSaltLen: ");
+        sb.append(pSalt.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pSalt: ");
+        sb.append(pSalt);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulIteration: ");
+        sb.append(ulIteration);
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,161 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_PKCS5_PBKD2_PARAMS provides the parameters to the CKM_PKCS5_PBKD2
+ * mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_PKCS5_PBKD2_PARAMS {
+ *   CK_PKCS5_PBKD2_SALT_SOURCE_TYPE saltSource;
+ *   CK_VOID_PTR pSaltSourceData;
+ *   CK_ULONG ulSaltSourceDataLen;
+ *   CK_ULONG iterations;
+ *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ *   CK_VOID_PTR pPrfData;
+ *   CK_ULONG ulPrfDataLen;
+ * } CK_PKCS5_PBKD2_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_PKCS5_PBKD2_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+     * </PRE>
+     */
+    public long saltSource;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VOID_PTR pSaltSourceData;
+     *   CK_ULONG ulSaltSourceDataLen;
+     * </PRE>
+     */
+    public byte[] pSaltSourceData;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG iterations;
+     * </PRE>
+     */
+    public long iterations;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+     * </PRE>
+     */
+    public long prf;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VOID_PTR pPrfData;
+     *   CK_ULONG ulPrfDataLen;
+     * </PRE>
+     */
+    public byte[] pPrfData;
+
+    /**
+     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
+     *
+     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("saltSource: ");
+        sb.append(saltSource);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pSaltSourceData: ");
+        sb.append(Functions.toHexString(pSaltSourceData));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulSaltSourceDataLen: ");
+        sb.append(pSaltSourceData.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("iterations: ");
+        sb.append(iterations);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("prf: ");
+        sb.append(prf);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPrfData: ");
+        sb.append(Functions.toHexString(pPrfData));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulPrfDataLen: ");
+        sb.append(pPrfData.length);
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_OAEP_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,143 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+ *   CK_MECHANISM_TYPE hashAlg;
+ *   CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
+ *   CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ *   CK_VOID_PTR pSourceData;
+ *   CK_ULONG ulSourceDataLen;
+ * } CK_RSA_PKCS_OAEP_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_RSA_PKCS_OAEP_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_MECHANISM_TYPE hashAlg;
+     * </PRE>
+     */
+    public long hashAlg;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
+     * </PRE>
+     */
+    public long mgf;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+     * </PRE>
+     */
+    public long source;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VOID_PTR pSourceData;
+     *   CK_ULONG ulSourceDataLen;
+     * </PRE>
+     */
+    public byte[] pSourceData;
+
+    //CK_ULONG ulSourceDataLen;
+    // ulSourceDataLen == pSourceData.length
+
+    /**
+     * Returns the string representation of CK_RSA_PKCS_OAEP_PARAMS.
+     *
+     * @return the string representation of CK_RSA_PKCS_OAEP_PARAMS
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("hashAlg: ");
+        sb.append(hashAlg);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("mgf: ");
+        sb.append(mgf);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("source: ");
+        sb.append(source);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pSourceData: ");
+        sb.append(pSourceData.toString());
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pSourceDataLen: ");
+        sb.append(Functions.toHexString(pSourceData));
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString() ;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,118 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_RSA_PKCS_PSS_PARAMS provides the parameters to the CKM_RSA_PKCS_OAEP
+ * mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ *   CK_MECHANISM_TYPE hashAlg;
+ *   CK_RSA_PKCS_MGF_TYPE mgf;
+ *   CK_ULONG sLen;
+ * } CK_RSA_PKCS_PSS_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+public class CK_RSA_PKCS_PSS_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_MECHANISM_TYPE hashAlg;
+     * </PRE>
+     */
+    public long hashAlg;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_RSA_PKCS_MGF_TYPE mgf;
+     * </PRE>
+     */
+    public long mgf;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG sLen;
+     * </PRE>
+     */
+    public long sLen;
+
+    /**
+     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
+     *
+     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("hashAlg: 0x");
+        sb.append(Functions.toFullHexString(hashAlg));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("mgf: 0x");
+        sb.append(Functions.toFullHexString(mgf));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("sLen: ");
+        sb.append(sLen);
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SESSION_INFO.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,142 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_SESSION_INFO provides information about a session.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_SESSION_INFO {&nbsp;&nbsp;
+ *   CK_SLOT_ID slotID;&nbsp;&nbsp;
+ *   CK_STATE state;&nbsp;&nbsp;
+ *   CK_FLAGS flags;&nbsp;&nbsp;
+ *   CK_ULONG ulDeviceError;&nbsp;&nbsp;
+ * } CK_SESSION_INFO;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_SESSION_INFO {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_SLOT_ID slotID;
+     * </PRE>
+     */
+    public long slotID;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_STATE state;
+     * </PRE>
+     */
+    public long state;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_FLAGS flags;
+     * </PRE>
+     */
+    public long flags;          /* see below */
+
+    /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
+     * v2.0 */
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulDeviceError;
+     * </PRE>
+     */
+    public long ulDeviceError;  /* device-dependent error code */
+
+    public CK_SESSION_INFO(long slotID, long state,
+                           long flags, long ulDeviceError) {
+        this.slotID = slotID;
+        this.state = state;
+        this.flags = flags;
+        this.ulDeviceError = ulDeviceError;
+    }
+
+    /**
+     * Returns the string representation of CK_SESSION_INFO.
+     *
+     * @return the string representation of CK_SESSION_INFO
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("slotID: ");
+        sb.append(String.valueOf(slotID));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("state: ");
+        sb.append(Functions.sessionStateToString(state));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("flags: ");
+        sb.append(Functions.sessionInfoFlagsToString(flags));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulDeviceError: ");
+        sb.append(Functions.toHexString(ulDeviceError));
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString() ;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SLOT_INFO.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,163 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_SLOT_INFO provides information about a slot.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ *  typedef struct CK_SLOT_INFO {&nbsp;&nbsp;
+ *    CK_UTF8CHAR slotDescription[64];&nbsp;&nbsp;
+ *    CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
+ *    CK_FLAGS flags;&nbsp;&nbsp;
+ *    CK_VERSION hardwareVersion;&nbsp;&nbsp;
+ *    CK_VERSION firmwareVersion;&nbsp;&nbsp;
+ *  } CK_SLOT_INFO;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_SLOT_INFO {
+
+    /* slotDescription and manufacturerID have been changed from
+     * CK_CHAR to CK_UTF8CHAR for v2.11. */
+
+    /**
+     * must be blank padded and only the first 64 chars will be used<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_UTF8CHAR slotDescription[64];
+     * </PRE>
+     */
+    public char[] slotDescription;
+
+    /**
+     * must be blank padded and only the first 32 chars will be used<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_UTF8CHAR manufacturerID[32];
+     * </PRE>
+     */
+    public char[] manufacturerID;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_FLAGS flags;
+     * </PRE>
+     */
+    public long flags;
+
+    /* hardwareVersion and firmwareVersion are new for v2.0 */
+    /**
+     * version of hardware<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VERSION hardwareVersion;
+     * </PRE>
+     */
+    public CK_VERSION hardwareVersion;
+
+    /**
+     * version of firmware<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VERSION firmwareVersion;
+     * </PRE>
+     */
+    public CK_VERSION firmwareVersion;
+
+    public CK_SLOT_INFO(char[] slotDesc, char[] vendor,
+                        long flags, CK_VERSION hwVer, CK_VERSION fwVer) {
+        this.slotDescription = slotDesc;
+        this.manufacturerID = vendor;
+        this.flags = flags;
+        this.hardwareVersion = hwVer;
+        this.firmwareVersion = fwVer;
+    }
+
+    /**
+     * Returns the string representation of CK_SLOT_INFO.
+     *
+     * @return the string representation of CK_SLOT_INFO
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("slotDescription: ");
+        sb.append(new String(slotDescription));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("manufacturerID: ");
+        sb.append(new String(manufacturerID));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("flags: ");
+        sb.append(Functions.slotInfoFlagsToString(flags));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("hardwareVersion: ");
+        sb.append(hardwareVersion.toString());
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("firmwareVersion: ");
+        sb.append(firmwareVersion.toString());
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString() ;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,162 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_SSL3_KEY_MAT_OUT contains the resulting key handles and
+ * initialization vectors after performing a C_DeriveKey function with the
+ * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_SSL3_KEY_MAT_OUT {
+ *   CK_OBJECT_HANDLE hClientMacSecret;
+ *   CK_OBJECT_HANDLE hServerMacSecret;
+ *   CK_OBJECT_HANDLE hClientKey;
+ *   CK_OBJECT_HANDLE hServerKey;
+ *   CK_BYTE_PTR pIVClient;
+ *   CK_BYTE_PTR pIVServer;
+ * } CK_SSL3_KEY_MAT_OUT;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_SSL3_KEY_MAT_OUT{
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_OBJECT_HANDLE hClientMacSecret;
+     * </PRE>
+     */
+    public long hClientMacSecret;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_OBJECT_HANDLE hServerMacSecret;
+     * </PRE>
+     */
+    public long hServerMacSecret;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_OBJECT_HANDLE hClientKey;
+     * </PRE>
+     */
+    public long hClientKey;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_OBJECT_HANDLE hServerKey;
+     * </PRE>
+     */
+    public long hServerKey;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_BYTE_PTR pIVClient;
+     * </PRE>
+     */
+    public byte[] pIVClient;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_BYTE_PTR pIVServer;
+     * </PRE>
+     */
+    public byte[] pIVServer;
+
+    /**
+     * Returns the string representation of CK_SSL3_KEY_MAT_OUT.
+     *
+     * @return the string representation of CK_SSL3_KEY_MAT_OUT
+     */
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(Constants.INDENT);
+        buffer.append("hClientMacSecret: ");
+        buffer.append(hClientMacSecret);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("hServerMacSecret: ");
+        buffer.append(hServerMacSecret);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("hClientKey: ");
+        buffer.append(hClientKey);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("hServerKey: ");
+        buffer.append(hServerKey);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("pIVClient: ");
+        buffer.append(Functions.toHexString(pIVClient));
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("pIVServer: ");
+        buffer.append(Functions.toHexString(pIVServer));
+        //buffer.append(Constants.NEWLINE);
+
+        return buffer.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_SSL3_KEY_MAT_PARAMS provides the parameters to the
+ * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_SSL3_KEY_MAT_PARAMS {
+ *   CK_ULONG ulMacSizeInBits;
+ *   CK_ULONG ulKeySizeInBits;
+ *   CK_ULONG ulIVSizeInBits;
+ *   CK_BBOOL bIsExport;
+ *   CK_SSL3_RANDOM_DATA RandomInfo;
+ *   CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+ * } CK_SSL3_KEY_MAT_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_SSL3_KEY_MAT_PARAMS{
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulMacSizeInBits;
+     * </PRE>
+     */
+    public long ulMacSizeInBits;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulKeySizeInBits;
+     * </PRE>
+     */
+    public long ulKeySizeInBits;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulIVSizeInBits;
+     * </PRE>
+     */
+    public long ulIVSizeInBits;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_BBOOL bIsExport;
+     * </PRE>
+     */
+    public boolean bIsExport;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_SSL3_RANDOM_DATA RandomInfo;
+     * </PRE>
+     */
+    public CK_SSL3_RANDOM_DATA RandomInfo;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+     * </PRE>
+     */
+    public CK_SSL3_KEY_MAT_OUT pReturnedKeyMaterial;
+
+    public CK_SSL3_KEY_MAT_PARAMS(int macSize, int keySize, int ivSize, boolean export, CK_SSL3_RANDOM_DATA random) {
+        ulMacSizeInBits = macSize;
+        ulKeySizeInBits = keySize;
+        ulIVSizeInBits = ivSize;
+        bIsExport = export;
+        RandomInfo = random;
+        pReturnedKeyMaterial = new CK_SSL3_KEY_MAT_OUT();
+        if (ivSize != 0) {
+            int n = ivSize >> 3;
+            pReturnedKeyMaterial.pIVClient = new byte[n];
+            pReturnedKeyMaterial.pIVServer = new byte[n];
+        }
+    }
+
+    /**
+     * Returns the string representation of CK_SSL3_KEY_MAT_PARAMS.
+     *
+     * @return the string representation of CK_SSL3_KEY_MAT_PARAMS
+     */
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(Constants.INDENT);
+        buffer.append("ulMacSizeInBits: ");
+        buffer.append(ulMacSizeInBits);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("ulKeySizeInBits: ");
+        buffer.append(ulKeySizeInBits);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("ulIVSizeInBits: ");
+        buffer.append(ulIVSizeInBits);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("bIsExport: ");
+        buffer.append(bIsExport);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("RandomInfo: ");
+        buffer.append(RandomInfo);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("pReturnedKeyMaterial: ");
+        buffer.append(pReturnedKeyMaterial);
+        //buffer.append(Constants.NEWLINE);
+
+        return buffer.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_MASTER_KEY_DERIVE_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_SSL3_MASTER_KEY_DERIVE_PARAMS provides the parameters to the
+ * CKM_SSL3_MASTER_KEY_DERIVE mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ *   CK_SSL3_RANDOM_DATA RandomInfo;
+ *   CK_VERSION_PTR pVersion;
+ * } CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_SSL3_RANDOM_DATA RandomInfo;
+     * </PRE>
+     */
+    public CK_SSL3_RANDOM_DATA RandomInfo;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VERSION_PTR pVersion;
+     * </PRE>
+     */
+    public CK_VERSION pVersion;
+
+    public CK_SSL3_MASTER_KEY_DERIVE_PARAMS(CK_SSL3_RANDOM_DATA random, CK_VERSION version) {
+        RandomInfo = random;
+        pVersion = version;
+    }
+
+    /**
+     * Returns the string representation of CK_SSL3_MASTER_KEY_DERIVE_PARAMS.
+     *
+     * @return the string representation of CK_SSL3_MASTER_KEY_DERIVE_PARAMS
+     */
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(Constants.INDENT);
+        buffer.append("RandomInfo: ");
+        buffer.append(RandomInfo);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("pVersion: ");
+        buffer.append(pVersion);
+        //buffer.append(Constants.NEWLINE);
+
+        return buffer.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_SSL3_RANDOM_DATA provides information about the random data of a
+ * client and a server in an SSL context. This class is used by both the
+ * CKM_SSL3_MASTER_KEY_DERIVE and the CKM_SSL3_KEY_AND_MAC_DERIVE mechanisms.
+ * <p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_SSL3_RANDOM_DATA {
+ *   CK_BYTE_PTR pClientRandom;
+ *   CK_ULONG ulClientRandomLen;
+ *   CK_BYTE_PTR pServerRandom;
+ *   CK_ULONG ulServerRandomLen;
+ * } CK_SSL3_RANDOM_DATA;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_SSL3_RANDOM_DATA {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_BYTE_PTR pClientRandom;
+     *   CK_ULONG ulClientRandomLen;
+     * </PRE>
+     */
+    public byte[] pClientRandom;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_BYTE_PTR pServerRandom;
+     *   CK_ULONG ulServerRandomLen;
+     * </PRE>
+     */
+    public byte[] pServerRandom;
+
+    public CK_SSL3_RANDOM_DATA(byte[] clientRandom, byte[] serverRandom) {
+        pClientRandom = clientRandom;
+        pServerRandom = serverRandom;
+    }
+
+    /**
+     * Returns the string representation of CK_SSL3_RANDOM_DATA.
+     *
+     * @return the string representation of CK_SSL3_RANDOM_DATA
+     */
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(Constants.INDENT);
+        buffer.append("pClientRandom: ");
+        buffer.append(Functions.toHexString(pClientRandom));
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("ulClientRandomLen: ");
+        buffer.append(pClientRandom.length);
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("pServerRandom: ");
+        buffer.append(Functions.toHexString(pServerRandom));
+        buffer.append(Constants.NEWLINE);
+
+        buffer.append(Constants.INDENT);
+        buffer.append("ulServerRandomLen: ");
+        buffer.append(pServerRandom.length);
+        //buffer.append(Constants.NEWLINE);
+
+        return buffer.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2005, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+/**
+ * CK_TLS_PRF_PARAMS from PKCS#11 v2.20.
+ *
+ * @author  Andreas Sterbenz
+ * @since   1.6
+ */
+public class CK_TLS_PRF_PARAMS {
+
+    public byte[] pSeed;
+    public byte[] pLabel;
+    public byte[] pOutput;
+
+    public CK_TLS_PRF_PARAMS(byte[] pSeed, byte[] pLabel, byte[] pOutput) {
+        this.pSeed = pSeed;
+        this.pLabel = pLabel;
+        this.pOutput = pOutput;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_TOKEN_INFO.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_TOKEN_INFO provides information about a token.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_TOKEN_INFO {&nbsp;&nbsp;
+ *   CK_UTF8CHAR label[32];&nbsp;&nbsp;
+ *   CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
+ *   CK_UTF8CHAR model[16];&nbsp;&nbsp;
+ *   CK_CHAR serialNumber[16];&nbsp;&nbsp;
+ *   CK_FLAGS flags;&nbsp;&nbsp;
+ *   CK_ULONG ulMaxSessionCount;&nbsp;&nbsp;
+ *   CK_ULONG ulSessionCount;&nbsp;&nbsp;
+ *   CK_ULONG ulMaxRwSessionCount;&nbsp;&nbsp;
+ *   CK_ULONG ulRwSessionCount;&nbsp;&nbsp;
+ *   CK_ULONG ulMaxPinLen;&nbsp;&nbsp;
+ *   CK_ULONG ulMinPinLen;&nbsp;&nbsp;
+ *   CK_ULONG ulTotalPublicMemory;&nbsp;&nbsp;
+ *   CK_ULONG ulFreePublicMemory;&nbsp;&nbsp;
+ *   CK_ULONG ulTotalPrivateMemory;&nbsp;&nbsp;
+ *   CK_ULONG ulFreePrivateMemory;&nbsp;&nbsp;
+ *   CK_VERSION hardwareVersion;&nbsp;&nbsp;
+ *   CK_VERSION firmwareVersion;&nbsp;&nbsp;
+ *   CK_CHAR utcTime[16];&nbsp;&nbsp;
+ * } CK_TOKEN_INFO;
+ * &nbsp;&nbsp;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_TOKEN_INFO {
+
+    /* label, manufacturerID, and model have been changed from
+     * CK_CHAR to CK_UTF8CHAR for v2.11. */
+    /**
+     * must be blank padded and only the first 32 chars will be used<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_UTF8CHAR label[32];
+     * </PRE>
+     */
+    public char[] label;           /* blank padded */
+
+    /**
+     * must be blank padded and only the first 32 chars will be used<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_UTF8CHAR manufacturerID[32];
+     * </PRE>
+     */
+    public char[] manufacturerID;  /* blank padded */
+
+    /**
+     * must be blank padded and only the first 16 chars will be used<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_UTF8CHAR model[16];
+     * </PRE>
+     */
+    public char[] model;           /* blank padded */
+
+    /**
+     * must be blank padded and only the first 16 chars will be used<p>
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CHAR serialNumber[16];
+     * </PRE>
+     */
+    public char[] serialNumber;    /* blank padded */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_FLAGS flags;
+     * </PRE>
+     */
+    public long flags;               /* see below */
+
+    /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
+     * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
+     * changed from CK_USHORT to CK_ULONG for v2.0 */
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulMaxSessionCount;
+     * </PRE>
+     */
+    public long ulMaxSessionCount;     /* max open sessions */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulSessionCount;
+     * </PRE>
+     */
+    public long ulSessionCount;        /* sess. now open */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulMaxRwSessionCount;
+     * </PRE>
+     */
+    public long ulMaxRwSessionCount;   /* max R/W sessions */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulRwSessionCount;
+     * </PRE>
+     */
+    public long ulRwSessionCount;      /* R/W sess. now open */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulMaxPinLen;
+     * </PRE>
+     */
+    public long ulMaxPinLen;           /* in bytes */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulMinPinLen;
+     * </PRE>
+     */
+    public long ulMinPinLen;           /* in bytes */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulTotalPublicMemory;
+     * </PRE>
+     */
+    public long ulTotalPublicMemory;   /* in bytes */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulFreePublicMemory;
+     * </PRE>
+     */
+    public long ulFreePublicMemory;    /* in bytes */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulTotalPrivateMemory;
+     * </PRE>
+     */
+    public long ulTotalPrivateMemory;  /* in bytes */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulFreePrivateMemory;
+     * </PRE>
+     */
+    public long ulFreePrivateMemory;   /* in bytes */
+
+    /* hardwareVersion, firmwareVersion, and time are new for
+     * v2.0 */
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VERSION hardwareVersion;
+     * </PRE>
+     */
+    public CK_VERSION    hardwareVersion;       /* version of hardware */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_VERSION firmwareVersion;
+     * </PRE>
+     */
+    public CK_VERSION    firmwareVersion;       /* version of firmware */
+
+    /**
+     * only the first 16 chars will be used
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_CHAR utcTime[16];
+     * </PRE>
+     */
+    public char[] utcTime;           /* time */
+
+    public CK_TOKEN_INFO(char[] label, char[] vendor, char[] model,
+                         char[] serialNo, long flags,
+                         long sessionMax, long session,
+                         long rwSessionMax, long rwSession,
+                         long pinLenMax, long pinLenMin,
+                         long totalPubMem, long freePubMem,
+                         long totalPrivMem, long freePrivMem,
+                         CK_VERSION hwVer, CK_VERSION fwVer, char[] utcTime) {
+        this.label = label;
+        this.manufacturerID = vendor;
+        this.model = model;
+        this.serialNumber = serialNo;
+        this.flags = flags;
+        this.ulMaxSessionCount = sessionMax;
+        this.ulSessionCount = session;
+        this.ulMaxRwSessionCount = rwSessionMax;
+        this.ulRwSessionCount = rwSession;
+        this.ulMaxPinLen = pinLenMax;
+        this.ulMinPinLen = pinLenMin;
+        this.ulTotalPublicMemory = totalPubMem;
+        this.ulFreePublicMemory = freePubMem;
+        this.ulTotalPrivateMemory = totalPrivMem;
+        this.ulFreePrivateMemory = freePrivMem;
+        this.hardwareVersion = hwVer;
+        this.firmwareVersion = fwVer;
+        this.utcTime = utcTime;
+    }
+
+    /**
+     * Returns the string representation of CK_TOKEN_INFO.
+     *
+     * @return the string representation of CK_TOKEN_INFO
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("label: ");
+        sb.append(new String(label));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("manufacturerID: ");
+        sb.append(new String(manufacturerID));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("model: ");
+        sb.append(new String(model));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("serialNumber: ");
+        sb.append(new String(serialNumber));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("flags: ");
+        sb.append(Functions.tokenInfoFlagsToString(flags));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulMaxSessionCount: ");
+        sb.append((ulMaxSessionCount == PKCS11Constants.CK_EFFECTIVELY_INFINITE)
+                  ? "CK_EFFECTIVELY_INFINITE"
+                  : (ulMaxSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
+                    ? "CK_UNAVAILABLE_INFORMATION"
+                    : String.valueOf(ulMaxSessionCount));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulSessionCount: ");
+        sb.append((ulSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
+                  ? "CK_UNAVAILABLE_INFORMATION"
+                  : String.valueOf(ulSessionCount));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulMaxRwSessionCount: ");
+        sb.append((ulMaxRwSessionCount == PKCS11Constants.CK_EFFECTIVELY_INFINITE)
+                  ? "CK_EFFECTIVELY_INFINITE"
+                  : (ulMaxRwSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
+                    ? "CK_UNAVAILABLE_INFORMATION"
+                    : String.valueOf(ulMaxRwSessionCount));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulRwSessionCount: ");
+        sb.append((ulRwSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
+                  ? "CK_UNAVAILABLE_INFORMATION"
+                  : String.valueOf(ulRwSessionCount));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulMaxPinLen: ");
+        sb.append(String.valueOf(ulMaxPinLen));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulMinPinLen: ");
+        sb.append(String.valueOf(ulMinPinLen));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulTotalPublicMemory: ");
+        sb.append((ulTotalPublicMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
+                  ? "CK_UNAVAILABLE_INFORMATION"
+                  : String.valueOf(ulTotalPublicMemory));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulFreePublicMemory: ");
+        sb.append((ulFreePublicMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
+                  ? "CK_UNAVAILABLE_INFORMATION"
+                  : String.valueOf(ulFreePublicMemory));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulTotalPrivateMemory: ");
+        sb.append((ulTotalPrivateMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
+                  ? "CK_UNAVAILABLE_INFORMATION"
+                  : String.valueOf(ulTotalPrivateMemory));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulFreePrivateMemory: ");
+        sb.append((ulFreePrivateMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
+                  ? "CK_UNAVAILABLE_INFORMATION"
+                  : String.valueOf(ulFreePrivateMemory));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("hardwareVersion: ");
+        sb.append(hardwareVersion.toString());
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("firmwareVersion: ");
+        sb.append(firmwareVersion.toString());
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("utcTime: ");
+        sb.append(new String(utcTime));
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString() ;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_UNLOCKMUTEX.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,68 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * interface CK_UNLOCKMUTEX<p>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public interface CK_UNLOCKMUTEX {
+
+    /**
+     * Method CK_UNLOCKMUTEX
+     *
+     * @param pMutex The mutex (lock) object to unlock.
+     * @exception PKCS11Exception
+     */
+    public void CK_UNLOCKMUTEX(Object pMutex) throws PKCS11Exception;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_VERSION.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_VERSION describes the version of a Cryptoki interface, a Cryptoki
+ * library, or an SSL implementation, or the hardware or firmware version of a
+ * slot or token.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_VERSION {&nbsp;&nbsp;
+ *   CK_BYTE major;&nbsp;&nbsp;
+ *   CK_BYTE minor;&nbsp;&nbsp;
+ * } CK_VERSION;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class CK_VERSION {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_BYTE major;
+     * </PRE>
+     */
+    public byte major;  /* integer portion of version number */
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_BYTE minor;
+     * </PRE>
+     */
+    public byte minor;  /* 1/100ths portion of version number */
+
+    public CK_VERSION(int major, int minor) {
+        this.major = (byte)major;
+        this.minor = (byte)minor;
+    }
+
+    /**
+     * Returns the string representation of CK_VERSION.
+     *
+     * @return the string representation of CK_VERSION
+     */
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+
+        buffer.append(major & 0xff);
+        buffer.append('.');
+        int m = minor & 0xff;
+        if (m < 10) {
+            buffer.append('0');
+        }
+        buffer.append(m);
+
+        return buffer.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,132 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_DERIVE mechanism.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
+ *   CK_X9_42_DH_KDF_TYPE kdf;
+ *   CK_ULONG ulOtherInfoLen;
+ *   CK_BYTE_PTR pOtherInfo;
+ *   CK_ULONG ulPublicDataLen;
+ *   CK_BYTE_PTR pPublicData;
+ * } CK_X9_42_DH1_DERIVE_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+public class CK_X9_42_DH1_DERIVE_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+    *   CK_X9_42_DH_KDF_TYPE kdf;
+     * </PRE>
+     */
+    public long kdf;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulOtherInfoLen;
+     *   CK_BYTE_PTR pOtherInfo;
+     * </PRE>
+     */
+    public byte[] pOtherInfo;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulPublicDataLen;
+     *   CK_BYTE_PTR pPublicData;
+     * </PRE>
+     */
+    public byte[] pPublicData;
+
+    /**
+     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
+     *
+     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("kdf: 0x");
+        sb.append(Functions.toFullHexString(kdf));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pOtherInfoLen: ");
+        sb.append(pOtherInfo.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pOtherInfo: ");
+        sb.append(Functions.toHexString(pOtherInfo));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicDataLen: ");
+        sb.append(pPublicData.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicData: ");
+        sb.append(Functions.toHexString(pPublicData));
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH2_DERIVE_PARAMS.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,181 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * class CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE mechanisms.<p>
+ * <B>PKCS#11 structure:</B>
+ * <PRE>
+ * typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
+ *   CK_X9_42_DH_KDF_TYPE kdf;
+ *   CK_ULONG ulOtherInfoLen;
+ *   CK_BYTE_PTR pOtherInfo;
+ *   CK_ULONG ulPublicDataLen;
+ *   CK_BYTE_PTR pPublicData;
+ *   CK_ULONG ulPrivateDataLen;
+ *   CK_OBJECT_HANDLE hPrivateData;
+ *   CK_ULONG ulPublicDataLen2;
+ *   CK_BYTE_PTR pPublicData2;
+ * } CK_X9_42_DH2_DERIVE_PARAMS;
+ * </PRE>
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+public class CK_X9_42_DH2_DERIVE_PARAMS {
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_X9_42_DH_KDF_TYPE kdf;
+     * </PRE>
+     */
+    public long kdf;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulOtherInfoLen;
+     *   CK_BYTE_PTR pOtherInfo;
+     * </PRE>
+     */
+    public byte[] pOtherInfo;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulPublicDataLen;
+     *   CK_BYTE_PTR pPublicData;
+     * </PRE>
+     */
+    public byte[] pPublicData;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulPrivateDataLen;
+     * </PRE>
+     */
+    public long ulPrivateDataLen;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_OBJECT_HANDLE hPrivateData;
+     * </PRE>
+     */
+    public long hPrivateData;
+
+    /**
+     * <B>PKCS#11:</B>
+     * <PRE>
+     *   CK_ULONG ulPublicDataLen2;
+     *   CK_BYTE_PTR pPublicData2;
+     * </PRE>
+     */
+    public byte[] pPublicData2;
+
+    /**
+     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
+     *
+     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(Constants.INDENT);
+        sb.append("kdf: 0x");
+        sb.append(Functions.toFullHexString(kdf));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pOtherInfoLen: ");
+        sb.append(pOtherInfo.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pOtherInfo: ");
+        sb.append(Functions.toHexString(pOtherInfo));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicDataLen: ");
+        sb.append(pPublicData.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicData: ");
+        sb.append(Functions.toHexString(pPublicData));
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("ulPrivateDataLen: ");
+        sb.append(ulPrivateDataLen);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("hPrivateData: ");
+        sb.append(hPrivateData);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicDataLen2: ");
+        sb.append(pPublicData2.length);
+        sb.append(Constants.NEWLINE);
+
+        sb.append(Constants.INDENT);
+        sb.append("pPublicData2: ");
+        sb.append(Functions.toHexString(pPublicData2));
+        //buffer.append(Constants.NEWLINE);
+
+        return sb.toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/Constants.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,65 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+
+/**
+ * This class holds only final static member variables that are constants
+ * in this package.
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class Constants {
+
+    public static final String NEWLINE = System.lineSeparator();
+
+    public static final String INDENT = "  ";
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/Functions.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,905 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+import java.math.BigInteger;
+
+import java.util.*;
+
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * This class contains onyl static methods. It is the place for all functions
+ * that are used by several classes in this package.
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+public class Functions {
+
+    // maps between ids and their names, forward and reverse
+    // ids are stored as Integers to save space
+    // since only the lower 32 bits are ever used anyway
+
+    // mechanisms (CKM_*)
+    private static final Map<Integer,String> mechNames =
+        new HashMap<Integer,String>();
+
+    private static final Map<String,Integer> mechIds =
+        new HashMap<String,Integer>();
+
+    // key types (CKK_*)
+    private static final Map<Integer,String> keyNames =
+        new HashMap<Integer,String>();
+
+    private static final Map<String,Integer> keyIds =
+        new HashMap<String,Integer>();
+
+    // attributes (CKA_*)
+    private static final Map<Integer,String> attributeNames =
+        new HashMap<Integer,String>();
+
+    private static final Map<String,Integer> attributeIds =
+        new HashMap<String,Integer>();
+
+    // object classes (CKO_*)
+    private static final Map<Integer,String> objectClassNames =
+        new HashMap<Integer,String>();
+
+    private static final Map<String,Integer> objectClassIds =
+        new HashMap<String,Integer>();
+
+
+    /**
+     * For converting numbers to their hex presentation.
+     */
+    private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+
+    /**
+     * Converts a long value to a hexadecimal String of length 16. Includes
+     * leading zeros if necessary.
+     *
+     * @param value The long value to be converted.
+     * @return The hexadecimal string representation of the long value.
+     */
+    public static String toFullHexString(long value) {
+        long currentValue = value;
+        StringBuilder sb = new StringBuilder(16);
+        for(int j = 0; j < 16; j++) {
+            int currentDigit = (int) currentValue & 0xf;
+            sb.append(HEX_DIGITS[currentDigit]);
+            currentValue >>>= 4;
+        }
+
+        return sb.reverse().toString();
+    }
+
+    /**
+     * Converts a int value to a hexadecimal String of length 8. Includes
+     * leading zeros if necessary.
+     *
+     * @param value The int value to be converted.
+     * @return The hexadecimal string representation of the int value.
+     */
+    public static String toFullHexString(int value) {
+        int currentValue = value;
+        StringBuilder sb = new StringBuilder(8);
+        for(int i = 0; i < 8; i++) {
+            int currentDigit = currentValue & 0xf;
+            sb.append(HEX_DIGITS[currentDigit]);
+            currentValue >>>= 4;
+        }
+
+        return sb.reverse().toString();
+    }
+
+    /**
+     * converts a long value to a hexadecimal String
+     *
+     * @param value the long value to be converted
+     * @return the hexadecimal string representation of the long value
+     */
+    public static String toHexString(long value) {
+        return Long.toHexString(value);
+    }
+
+    /**
+     * Converts a byte array to a hexadecimal String. Each byte is presented by
+     * its two digit hex-code; 0x0A -> "0a", 0x00 -> "00". No leading "0x" is
+     * included in the result.
+     *
+     * @param value the byte array to be converted
+     * @return the hexadecimal string representation of the byte array
+     */
+    public static String toHexString(byte[] value) {
+        if (value == null) {
+            return null;
+        }
+
+        StringBuilder sb = new StringBuilder(2 * value.length);
+        int          single;
+
+        for (int i = 0; i < value.length; i++) {
+            single = value[i] & 0xFF;
+
+            if (single < 0x10) {
+                sb.append('0');
+            }
+
+            sb.append(Integer.toString(single, 16));
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * converts a long value to a binary String
+     *
+     * @param value the long value to be converted
+     * @return the binary string representation of the long value
+     */
+    public static String toBinaryString(long value) {
+        return Long.toString(value, 2);
+    }
+
+    /**
+     * converts a byte array to a binary String
+     *
+     * @param value the byte array to be converted
+     * @return the binary string representation of the byte array
+     */
+    public static String toBinaryString(byte[] value) {
+        BigInteger helpBigInteger = new BigInteger(1, value);
+
+        return helpBigInteger.toString(2);
+    }
+
+    private static class Flags {
+        private final long[] flagIds;
+        private final String[] flagNames;
+        Flags(long[] flagIds, String[] flagNames) {
+            if (flagIds.length != flagNames.length) {
+                throw new AssertionError("Array lengths do not match");
+            }
+            this.flagIds = flagIds;
+            this.flagNames = flagNames;
+        }
+        String toString(long val) {
+            StringBuilder sb = new StringBuilder();
+            boolean first = true;
+            for (int i = 0; i < flagIds.length; i++) {
+                if ((val & flagIds[i]) != 0) {
+                    if (first == false) {
+                        sb.append(" | ");
+                    }
+                    sb.append(flagNames[i]);
+                    first = false;
+                }
+            }
+            return sb.toString();
+        }
+    }
+
+    private static final Flags slotInfoFlags = new Flags(new long[] {
+        CKF_TOKEN_PRESENT,
+        CKF_REMOVABLE_DEVICE,
+        CKF_HW_SLOT,
+    }, new String[] {
+        "CKF_TOKEN_PRESENT",
+        "CKF_REMOVABLE_DEVICE",
+        "CKF_HW_SLOT",
+    });
+
+    /**
+     * converts the long value flags to a SlotInfoFlag string
+     *
+     * @param flags the flags to be converted
+     * @return the SlotInfoFlag string representation of the flags
+     */
+    public static String slotInfoFlagsToString(long flags) {
+        return slotInfoFlags.toString(flags);
+    }
+
+    private static final Flags tokenInfoFlags = new Flags(new long[] {
+        CKF_RNG,
+        CKF_WRITE_PROTECTED,
+        CKF_LOGIN_REQUIRED,
+        CKF_USER_PIN_INITIALIZED,
+        CKF_RESTORE_KEY_NOT_NEEDED,
+        CKF_CLOCK_ON_TOKEN,
+        CKF_PROTECTED_AUTHENTICATION_PATH,
+        CKF_DUAL_CRYPTO_OPERATIONS,
+        CKF_TOKEN_INITIALIZED,
+        CKF_SECONDARY_AUTHENTICATION,
+        CKF_USER_PIN_COUNT_LOW,
+        CKF_USER_PIN_FINAL_TRY,
+        CKF_USER_PIN_LOCKED,
+        CKF_USER_PIN_TO_BE_CHANGED,
+        CKF_SO_PIN_COUNT_LOW,
+        CKF_SO_PIN_FINAL_TRY,
+        CKF_SO_PIN_LOCKED,
+        CKF_SO_PIN_TO_BE_CHANGED,
+    }, new String[] {
+        "CKF_RNG",
+        "CKF_WRITE_PROTECTED",
+        "CKF_LOGIN_REQUIRED",
+        "CKF_USER_PIN_INITIALIZED",
+        "CKF_RESTORE_KEY_NOT_NEEDED",
+        "CKF_CLOCK_ON_TOKEN",
+        "CKF_PROTECTED_AUTHENTICATION_PATH",
+        "CKF_DUAL_CRYPTO_OPERATIONS",
+        "CKF_TOKEN_INITIALIZED",
+        "CKF_SECONDARY_AUTHENTICATION",
+        "CKF_USER_PIN_COUNT_LOW",
+        "CKF_USER_PIN_FINAL_TRY",
+        "CKF_USER_PIN_LOCKED",
+        "CKF_USER_PIN_TO_BE_CHANGED",
+        "CKF_SO_PIN_COUNT_LOW",
+        "CKF_SO_PIN_FINAL_TRY",
+        "CKF_SO_PIN_LOCKED",
+        "CKF_SO_PIN_TO_BE_CHANGED",
+    });
+
+    /**
+     * converts long value flags to a TokenInfoFlag string
+     *
+     * @param flags the flags to be converted
+     * @return the TokenInfoFlag string representation of the flags
+     */
+    public static String tokenInfoFlagsToString(long flags) {
+        return tokenInfoFlags.toString(flags);
+    }
+
+    private static final Flags sessionInfoFlags = new Flags(new long[] {
+        CKF_RW_SESSION,
+        CKF_SERIAL_SESSION,
+    }, new String[] {
+        "CKF_RW_SESSION",
+        "CKF_SERIAL_SESSION",
+    });
+
+    /**
+     * converts the long value flags to a SessionInfoFlag string
+     *
+     * @param flags the flags to be converted
+     * @return the SessionInfoFlag string representation of the flags
+     */
+    public static String sessionInfoFlagsToString(long flags) {
+        return sessionInfoFlags.toString(flags);
+    }
+
+    /**
+     * converts the long value state to a SessionState string
+     *
+     * @param state the state to be converted
+     * @return the SessionState string representation of the state
+     */
+    public static String sessionStateToString(long state) {
+        String name;
+
+        if (state == CKS_RO_PUBLIC_SESSION) {
+            name = "CKS_RO_PUBLIC_SESSION";
+        } else if (state == CKS_RO_USER_FUNCTIONS) {
+            name = "CKS_RO_USER_FUNCTIONS";
+        } else if (state == CKS_RW_PUBLIC_SESSION) {
+            name = "CKS_RW_PUBLIC_SESSION";
+        } else if (state == CKS_RW_USER_FUNCTIONS) {
+            name = "CKS_RW_USER_FUNCTIONS";
+        } else if (state == CKS_RW_SO_FUNCTIONS) {
+            name = "CKS_RW_SO_FUNCTIONS";
+        } else {
+            name = "ERROR: unknown session state 0x" + toFullHexString(state);
+        }
+
+        return name;
+    }
+
+    private static final Flags mechanismInfoFlags = new Flags(new long[] {
+        CKF_HW,
+        CKF_ENCRYPT,
+        CKF_DECRYPT,
+        CKF_DIGEST,
+        CKF_SIGN,
+        CKF_SIGN_RECOVER,
+        CKF_VERIFY,
+        CKF_VERIFY_RECOVER,
+        CKF_GENERATE,
+        CKF_GENERATE_KEY_PAIR,
+        CKF_WRAP,
+        CKF_UNWRAP,
+        CKF_DERIVE,
+        CKF_EC_F_P,
+        CKF_EC_F_2M,
+        CKF_EC_ECPARAMETERS,
+        CKF_EC_NAMEDCURVE,
+        CKF_EC_UNCOMPRESS,
+        CKF_EC_COMPRESS,
+        CKF_EXTENSION,
+    }, new String[] {
+        "CKF_HW",
+        "CKF_ENCRYPT",
+        "CKF_DECRYPT",
+        "CKF_DIGEST",
+        "CKF_SIGN",
+        "CKF_SIGN_RECOVER",
+        "CKF_VERIFY",
+        "CKF_VERIFY_RECOVER",
+        "CKF_GENERATE",
+        "CKF_GENERATE_KEY_PAIR",
+        "CKF_WRAP",
+        "CKF_UNWRAP",
+        "CKF_DERIVE",
+        "CKF_EC_F_P",
+        "CKF_EC_F_2M",
+        "CKF_EC_ECPARAMETERS",
+        "CKF_EC_NAMEDCURVE",
+        "CKF_EC_UNCOMPRESS",
+        "CKF_EC_COMPRESS",
+        "CKF_EXTENSION",
+    });
+
+    /**
+     * converts the long value flags to a MechanismInfoFlag string
+     *
+     * @param flags the flags to be converted
+     * @return the MechanismInfoFlag string representation of the flags
+     */
+    public static String mechanismInfoFlagsToString(long flags) {
+        return mechanismInfoFlags.toString(flags);
+    }
+
+    private static String getName(Map<Integer,String> nameMap, long id) {
+        String name = null;
+        if ((id >>> 32) == 0) {
+            name = nameMap.get(Integer.valueOf((int)id));
+        }
+        if (name == null) {
+            name = "Unknown 0x" + toFullHexString(id);
+        }
+        return name;
+    }
+
+    public static long getId(Map<String,Integer> idMap, String name) {
+        Integer mech = idMap.get(name);
+        if (mech == null) {
+            throw new IllegalArgumentException("Unknown name " + name);
+        }
+        return mech.intValue() & 0xffffffffL;
+    }
+
+    public static String getMechanismName(long id) {
+        return getName(mechNames, id);
+    }
+
+    public static long getMechanismId(String name) {
+        return getId(mechIds, name);
+    }
+
+    public static String getKeyName(long id) {
+        return getName(keyNames, id);
+    }
+
+    public static long getKeyId(String name) {
+        return getId(keyIds, name);
+    }
+
+    public static String getAttributeName(long id) {
+        return getName(attributeNames, id);
+    }
+
+    public static long getAttributeId(String name) {
+        return getId(attributeIds, name);
+    }
+
+    public static String getObjectClassName(long id) {
+        return getName(objectClassNames, id);
+    }
+
+    public static long getObjectClassId(String name) {
+        return getId(objectClassIds, name);
+    }
+
+    /**
+     * Check the given arrays for equalitiy. This method considers both arrays as
+     * equal, if both are <code>null</code> or both have the same length and
+     * contain exactly the same char values.
+     *
+     * @param array1 The first array.
+     * @param array2 The second array.
+     * @return True, if both arrays are <code>null</code> or both have the same
+     *         length and contain exactly the same char values. False, otherwise.
+     * @preconditions
+     * @postconditions
+     */
+    private static boolean equals(char[] array1, char[] array2) {
+        return Arrays.equals(array1, array2);
+    }
+
+    /**
+     * Check the given dates for equalitiy. This method considers both dates as
+     * equal, if both are <code>null</code> or both contain exactly the same char
+     * values.
+     *
+     * @param date1 The first date.
+     * @param date2 The second date.
+     * @return True, if both dates are <code>null</code> or both contain the same
+     *         char values. False, otherwise.
+     * @preconditions
+     * @postconditions
+     */
+    public static boolean equals(CK_DATE date1, CK_DATE date2) {
+        boolean equal = false;
+
+        if (date1 == date2) {
+            equal = true;
+        } else if ((date1 != null) && (date2 != null)) {
+            equal = equals(date1.year, date2.year)
+              && equals(date1.month, date2.month)
+              && equals(date1.day, date2.day);
+        } else {
+            equal = false;
+        }
+
+        return equal ;
+    }
+
+    /**
+     * Calculate a hash code for the given byte array.
+     *
+     * @param array The byte array.
+     * @return A hash code for the given array.
+     * @preconditions
+     * @postconditions
+     */
+    public static int hashCode(byte[] array) {
+        int hash = 0;
+
+        if (array != null) {
+            for (int i = 0; (i < 4) && (i < array.length); i++) {
+                hash ^= (0xFF & array[i]) << ((i%4) << 3);
+            }
+        }
+
+        return hash ;
+    }
+
+    /**
+     * Calculate a hash code for the given char array.
+     *
+     * @param array The char array.
+     * @return A hash code for the given array.
+     * @preconditions
+     * @postconditions
+     */
+    public static int hashCode(char[] array) {
+        int hash = 0;
+
+        if (array != null) {
+            for (int i = 0; (i < 4) && (i < array.length); i++) {
+                hash ^= (0xFFFF & array[i]) << ((i%2) << 4);
+            }
+        }
+
+        return hash ;
+    }
+
+    /**
+     * Calculate a hash code for the given date object.
+     *
+     * @param date The date object.
+     * @return A hash code for the given date.
+     * @preconditions
+     * @postconditions
+     */
+    public static int hashCode(CK_DATE date) {
+        int hash = 0;
+
+        if (date != null) {
+            if (date.year.length == 4) {
+                hash ^= (0xFFFF & date.year[0]) << 16;
+                hash ^= 0xFFFF & date.year[1];
+                hash ^= (0xFFFF & date.year[2]) << 16;
+                hash ^= 0xFFFF & date.year[3];
+            }
+            if (date.month.length == 2) {
+                hash ^= (0xFFFF & date.month[0]) << 16;
+                hash ^= 0xFFFF & date.month[1];
+            }
+            if (date.day.length == 2) {
+                hash ^= (0xFFFF & date.day[0]) << 16;
+                hash ^= 0xFFFF & date.day[1];
+            }
+        }
+
+        return hash ;
+    }
+
+    private static void addMapping(Map<Integer,String> nameMap,
+            Map<String,Integer> idMap, long id, String name) {
+        if ((id >>> 32) != 0) {
+            throw new AssertionError("Id has high bits set: " + id + ", " + name);
+        }
+        Integer intId = Integer.valueOf((int)id);
+        if (nameMap.put(intId, name) != null) {
+            throw new AssertionError("Duplicate id: " + id + ", " + name);
+        }
+        if (idMap.put(name, intId) != null) {
+            throw new AssertionError("Duplicate name: " + id + ", " + name);
+        }
+    }
+
+    private static void addMech(long id, String name) {
+        addMapping(mechNames, mechIds, id, name);
+    }
+
+    private static void addKeyType(long id, String name) {
+        addMapping(keyNames, keyIds, id, name);
+    }
+
+    private static void addAttribute(long id, String name) {
+        addMapping(attributeNames, attributeIds, id, name);
+    }
+
+    private static void addObjectClass(long id, String name) {
+        addMapping(objectClassNames, objectClassIds, id, name);
+    }
+
+    static {
+        addMech(CKM_RSA_PKCS_KEY_PAIR_GEN,      "CKM_RSA_PKCS_KEY_PAIR_GEN");
+        addMech(CKM_RSA_PKCS,                   "CKM_RSA_PKCS");
+        addMech(CKM_RSA_9796,                   "CKM_RSA_9796");
+        addMech(CKM_RSA_X_509,                  "CKM_RSA_X_509");
+        addMech(CKM_MD2_RSA_PKCS,               "CKM_MD2_RSA_PKCS");
+        addMech(CKM_MD5_RSA_PKCS,               "CKM_MD5_RSA_PKCS");
+        addMech(CKM_SHA1_RSA_PKCS,              "CKM_SHA1_RSA_PKCS");
+        addMech(CKM_RIPEMD128_RSA_PKCS,         "CKM_RIPEMD128_RSA_PKCS");
+        addMech(CKM_RIPEMD160_RSA_PKCS,         "CKM_RIPEMD160_RSA_PKCS");
+        addMech(CKM_RSA_PKCS_OAEP,              "CKM_RSA_PKCS_OAEP");
+        addMech(CKM_RSA_X9_31_KEY_PAIR_GEN,     "CKM_RSA_X9_31_KEY_PAIR_GEN");
+        addMech(CKM_RSA_X9_31,                  "CKM_RSA_X9_31");
+        addMech(CKM_SHA1_RSA_X9_31,             "CKM_SHA1_RSA_X9_31");
+        addMech(CKM_RSA_PKCS_PSS,               "CKM_RSA_PKCS_PSS");
+        addMech(CKM_SHA1_RSA_PKCS_PSS,          "CKM_SHA1_RSA_PKCS_PSS");
+        addMech(CKM_DSA_KEY_PAIR_GEN,           "CKM_DSA_KEY_PAIR_GEN");
+        addMech(CKM_DSA,                        "CKM_DSA");
+        addMech(CKM_DSA_SHA1,                   "CKM_DSA_SHA1");
+        addMech(CKM_DH_PKCS_KEY_PAIR_GEN,       "CKM_DH_PKCS_KEY_PAIR_GEN");
+        addMech(CKM_DH_PKCS_DERIVE,             "CKM_DH_PKCS_DERIVE");
+        addMech(CKM_X9_42_DH_KEY_PAIR_GEN,      "CKM_X9_42_DH_KEY_PAIR_GEN");
+        addMech(CKM_X9_42_DH_DERIVE,            "CKM_X9_42_DH_DERIVE");
+        addMech(CKM_X9_42_DH_HYBRID_DERIVE,     "CKM_X9_42_DH_HYBRID_DERIVE");
+        addMech(CKM_X9_42_MQV_DERIVE,           "CKM_X9_42_MQV_DERIVE");
+        addMech(CKM_SHA224_RSA_PKCS,            "CKM_SHA224_RSA_PKCS");
+        addMech(CKM_SHA256_RSA_PKCS,            "CKM_SHA256_RSA_PKCS");
+        addMech(CKM_SHA384_RSA_PKCS,            "CKM_SHA384_RSA_PKCS");
+        addMech(CKM_SHA512_RSA_PKCS,            "CKM_SHA512_RSA_PKCS");
+        addMech(CKM_RC2_KEY_GEN,                "CKM_RC2_KEY_GEN");
+        addMech(CKM_RC2_ECB,                    "CKM_RC2_ECB");
+        addMech(CKM_RC2_CBC,                    "CKM_RC2_CBC");
+        addMech(CKM_RC2_MAC,                    "CKM_RC2_MAC");
+        addMech(CKM_RC2_MAC_GENERAL,            "CKM_RC2_MAC_GENERAL");
+        addMech(CKM_RC2_CBC_PAD,                "CKM_RC2_CBC_PAD");
+        addMech(CKM_RC4_KEY_GEN,                "CKM_RC4_KEY_GEN");
+        addMech(CKM_RC4,                        "CKM_RC4");
+        addMech(CKM_DES_KEY_GEN,                "CKM_DES_KEY_GEN");
+        addMech(CKM_DES_ECB,                    "CKM_DES_ECB");
+        addMech(CKM_DES_CBC,                    "CKM_DES_CBC");
+        addMech(CKM_DES_MAC,                    "CKM_DES_MAC");
+        addMech(CKM_DES_MAC_GENERAL,            "CKM_DES_MAC_GENERAL");
+        addMech(CKM_DES_CBC_PAD,                "CKM_DES_CBC_PAD");
+        addMech(CKM_DES2_KEY_GEN,               "CKM_DES2_KEY_GEN");
+        addMech(CKM_DES3_KEY_GEN,               "CKM_DES3_KEY_GEN");
+        addMech(CKM_DES3_ECB,                   "CKM_DES3_ECB");
+        addMech(CKM_DES3_CBC,                   "CKM_DES3_CBC");
+        addMech(CKM_DES3_MAC,                   "CKM_DES3_MAC");
+        addMech(CKM_DES3_MAC_GENERAL,           "CKM_DES3_MAC_GENERAL");
+        addMech(CKM_DES3_CBC_PAD,               "CKM_DES3_CBC_PAD");
+        addMech(CKM_CDMF_KEY_GEN,               "CKM_CDMF_KEY_GEN");
+        addMech(CKM_CDMF_ECB,                   "CKM_CDMF_ECB");
+        addMech(CKM_CDMF_CBC,                   "CKM_CDMF_CBC");
+        addMech(CKM_CDMF_MAC,                   "CKM_CDMF_MAC");
+        addMech(CKM_CDMF_MAC_GENERAL,           "CKM_CDMF_MAC_GENERAL");
+        addMech(CKM_CDMF_CBC_PAD,               "CKM_CDMF_CBC_PAD");
+        addMech(CKM_MD2,                        "CKM_MD2");
+        addMech(CKM_MD2_HMAC,                   "CKM_MD2_HMAC");
+        addMech(CKM_MD2_HMAC_GENERAL,           "CKM_MD2_HMAC_GENERAL");
+        addMech(CKM_MD5,                        "CKM_MD5");
+        addMech(CKM_MD5_HMAC,                   "CKM_MD5_HMAC");
+        addMech(CKM_MD5_HMAC_GENERAL,           "CKM_MD5_HMAC_GENERAL");
+        addMech(CKM_SHA_1,                      "CKM_SHA_1");
+        addMech(CKM_SHA_1_HMAC,                 "CKM_SHA_1_HMAC");
+        addMech(CKM_SHA_1_HMAC_GENERAL,         "CKM_SHA_1_HMAC_GENERAL");
+        addMech(CKM_RIPEMD128,                  "CKM_RIPEMD128");
+        addMech(CKM_RIPEMD128_HMAC,             "CKM_RIPEMD128_HMAC");
+        addMech(CKM_RIPEMD128_HMAC_GENERAL,     "CKM_RIPEMD128_HMAC_GENERAL");
+        addMech(CKM_RIPEMD160,                  "CKM_RIPEMD160");
+        addMech(CKM_RIPEMD160_HMAC,             "CKM_RIPEMD160_HMAC");
+        addMech(CKM_RIPEMD160_HMAC_GENERAL,     "CKM_RIPEMD160_HMAC_GENERAL");
+        addMech(CKM_SHA224,                     "CKM_SHA224");
+        addMech(CKM_SHA224_HMAC,                "CKM_SHA224_HMAC");
+        addMech(CKM_SHA224_HMAC_GENERAL,        "CKM_SHA224_HMAC_GENERAL");
+        addMech(CKM_SHA256,                     "CKM_SHA256");
+        addMech(CKM_SHA256_HMAC,                "CKM_SHA256_HMAC");
+        addMech(CKM_SHA256_HMAC_GENERAL,        "CKM_SHA256_HMAC_GENERAL");
+        addMech(CKM_SHA384,                     "CKM_SHA384");
+        addMech(CKM_SHA384_HMAC,                "CKM_SHA384_HMAC");
+        addMech(CKM_SHA384_HMAC_GENERAL,        "CKM_SHA384_HMAC_GENERAL");
+        addMech(CKM_SHA512,                     "CKM_SHA512");
+        addMech(CKM_SHA512_HMAC,                "CKM_SHA512_HMAC");
+        addMech(CKM_SHA512_HMAC_GENERAL,        "CKM_SHA512_HMAC_GENERAL");
+        addMech(CKM_CAST_KEY_GEN,               "CKM_CAST_KEY_GEN");
+        addMech(CKM_CAST_ECB,                   "CKM_CAST_ECB");
+        addMech(CKM_CAST_CBC,                   "CKM_CAST_CBC");
+        addMech(CKM_CAST_MAC,                   "CKM_CAST_MAC");
+        addMech(CKM_CAST_MAC_GENERAL,           "CKM_CAST_MAC_GENERAL");
+        addMech(CKM_CAST_CBC_PAD,               "CKM_CAST_CBC_PAD");
+        addMech(CKM_CAST3_KEY_GEN,              "CKM_CAST3_KEY_GEN");
+        addMech(CKM_CAST3_ECB,                  "CKM_CAST3_ECB");
+        addMech(CKM_CAST3_CBC,                  "CKM_CAST3_CBC");
+        addMech(CKM_CAST3_MAC,                  "CKM_CAST3_MAC");
+        addMech(CKM_CAST3_MAC_GENERAL,          "CKM_CAST3_MAC_GENERAL");
+        addMech(CKM_CAST3_CBC_PAD,              "CKM_CAST3_CBC_PAD");
+        addMech(CKM_CAST128_KEY_GEN,            "CKM_CAST128_KEY_GEN");
+        addMech(CKM_CAST128_ECB,                "CKM_CAST128_ECB");
+        addMech(CKM_CAST128_CBC,                "CKM_CAST128_CBC");
+        addMech(CKM_CAST128_MAC,                "CKM_CAST128_MAC");
+        addMech(CKM_CAST128_MAC_GENERAL,        "CKM_CAST128_MAC_GENERAL");
+        addMech(CKM_CAST128_CBC_PAD,            "CKM_CAST128_CBC_PAD");
+        addMech(CKM_RC5_KEY_GEN,                "CKM_RC5_KEY_GEN");
+        addMech(CKM_RC5_ECB,                    "CKM_RC5_ECB");
+        addMech(CKM_RC5_CBC,                    "CKM_RC5_CBC");
+        addMech(CKM_RC5_MAC,                    "CKM_RC5_MAC");
+        addMech(CKM_RC5_MAC_GENERAL,            "CKM_RC5_MAC_GENERAL");
+        addMech(CKM_RC5_CBC_PAD,                "CKM_RC5_CBC_PAD");
+        addMech(CKM_IDEA_KEY_GEN,               "CKM_IDEA_KEY_GEN");
+        addMech(CKM_IDEA_ECB,                   "CKM_IDEA_ECB");
+        addMech(CKM_IDEA_CBC,                   "CKM_IDEA_CBC");
+        addMech(CKM_IDEA_MAC,                   "CKM_IDEA_MAC");
+        addMech(CKM_IDEA_MAC_GENERAL,           "CKM_IDEA_MAC_GENERAL");
+        addMech(CKM_IDEA_CBC_PAD,               "CKM_IDEA_CBC_PAD");
+        addMech(CKM_GENERIC_SECRET_KEY_GEN,     "CKM_GENERIC_SECRET_KEY_GEN");
+        addMech(CKM_CONCATENATE_BASE_AND_KEY,   "CKM_CONCATENATE_BASE_AND_KEY");
+        addMech(CKM_CONCATENATE_BASE_AND_DATA,  "CKM_CONCATENATE_BASE_AND_DATA");
+        addMech(CKM_CONCATENATE_DATA_AND_BASE,  "CKM_CONCATENATE_DATA_AND_BASE");
+        addMech(CKM_XOR_BASE_AND_DATA,          "CKM_XOR_BASE_AND_DATA");
+        addMech(CKM_EXTRACT_KEY_FROM_KEY,       "CKM_EXTRACT_KEY_FROM_KEY");
+        addMech(CKM_SSL3_PRE_MASTER_KEY_GEN,    "CKM_SSL3_PRE_MASTER_KEY_GEN");
+        addMech(CKM_SSL3_MASTER_KEY_DERIVE,     "CKM_SSL3_MASTER_KEY_DERIVE");
+        addMech(CKM_SSL3_KEY_AND_MAC_DERIVE,    "CKM_SSL3_KEY_AND_MAC_DERIVE");
+        addMech(CKM_SSL3_MASTER_KEY_DERIVE_DH,  "CKM_SSL3_MASTER_KEY_DERIVE_DH");
+        addMech(CKM_TLS_PRE_MASTER_KEY_GEN,     "CKM_TLS_PRE_MASTER_KEY_GEN");
+        addMech(CKM_TLS_MASTER_KEY_DERIVE,      "CKM_TLS_MASTER_KEY_DERIVE");
+        addMech(CKM_TLS_KEY_AND_MAC_DERIVE,     "CKM_TLS_KEY_AND_MAC_DERIVE");
+        addMech(CKM_TLS_MASTER_KEY_DERIVE_DH,   "CKM_TLS_MASTER_KEY_DERIVE_DH");
+        addMech(CKM_TLS_PRF,                    "CKM_TLS_PRF");
+        addMech(CKM_SSL3_MD5_MAC,               "CKM_SSL3_MD5_MAC");
+        addMech(CKM_SSL3_SHA1_MAC,              "CKM_SSL3_SHA1_MAC");
+        addMech(CKM_MD5_KEY_DERIVATION,         "CKM_MD5_KEY_DERIVATION");
+        addMech(CKM_MD2_KEY_DERIVATION,         "CKM_MD2_KEY_DERIVATION");
+        addMech(CKM_SHA1_KEY_DERIVATION,        "CKM_SHA1_KEY_DERIVATION");
+        addMech(CKM_SHA224_KEY_DERIVATION,      "CKM_SHA224_KEY_DERIVATION");
+        addMech(CKM_SHA256_KEY_DERIVATION,      "CKM_SHA256_KEY_DERIVATION");
+        addMech(CKM_SHA384_KEY_DERIVATION,      "CKM_SHA384_KEY_DERIVATION");
+        addMech(CKM_SHA512_KEY_DERIVATION,      "CKM_SHA512_KEY_DERIVATION");
+        addMech(CKM_PBE_MD2_DES_CBC,            "CKM_PBE_MD2_DES_CBC");
+        addMech(CKM_PBE_MD5_DES_CBC,            "CKM_PBE_MD5_DES_CBC");
+        addMech(CKM_PBE_MD5_CAST_CBC,           "CKM_PBE_MD5_CAST_CBC");
+        addMech(CKM_PBE_MD5_CAST3_CBC,          "CKM_PBE_MD5_CAST3_CBC");
+        addMech(CKM_PBE_MD5_CAST128_CBC,        "CKM_PBE_MD5_CAST128_CBC");
+        addMech(CKM_PBE_SHA1_CAST128_CBC,       "CKM_PBE_SHA1_CAST128_CBC");
+        addMech(CKM_PBE_SHA1_RC4_128,           "CKM_PBE_SHA1_RC4_128");
+        addMech(CKM_PBE_SHA1_RC4_40,            "CKM_PBE_SHA1_RC4_40");
+        addMech(CKM_PBE_SHA1_DES3_EDE_CBC,      "CKM_PBE_SHA1_DES3_EDE_CBC");
+        addMech(CKM_PBE_SHA1_DES2_EDE_CBC,      "CKM_PBE_SHA1_DES2_EDE_CBC");
+        addMech(CKM_PBE_SHA1_RC2_128_CBC,       "CKM_PBE_SHA1_RC2_128_CBC");
+        addMech(CKM_PBE_SHA1_RC2_40_CBC,        "CKM_PBE_SHA1_RC2_40_CBC");
+        addMech(CKM_PKCS5_PBKD2,                "CKM_PKCS5_PBKD2");
+        addMech(CKM_PBA_SHA1_WITH_SHA1_HMAC,    "CKM_PBA_SHA1_WITH_SHA1_HMAC");
+        addMech(CKM_KEY_WRAP_LYNKS,             "CKM_KEY_WRAP_LYNKS");
+        addMech(CKM_KEY_WRAP_SET_OAEP,          "CKM_KEY_WRAP_SET_OAEP");
+        addMech(CKM_SKIPJACK_KEY_GEN,           "CKM_SKIPJACK_KEY_GEN");
+        addMech(CKM_SKIPJACK_ECB64,             "CKM_SKIPJACK_ECB64");
+        addMech(CKM_SKIPJACK_CBC64,             "CKM_SKIPJACK_CBC64");
+        addMech(CKM_SKIPJACK_OFB64,             "CKM_SKIPJACK_OFB64");
+        addMech(CKM_SKIPJACK_CFB64,             "CKM_SKIPJACK_CFB64");
+        addMech(CKM_SKIPJACK_CFB32,             "CKM_SKIPJACK_CFB32");
+        addMech(CKM_SKIPJACK_CFB16,             "CKM_SKIPJACK_CFB16");
+        addMech(CKM_SKIPJACK_CFB8,              "CKM_SKIPJACK_CFB8");
+        addMech(CKM_SKIPJACK_WRAP,              "CKM_SKIPJACK_WRAP");
+        addMech(CKM_SKIPJACK_PRIVATE_WRAP,      "CKM_SKIPJACK_PRIVATE_WRAP");
+        addMech(CKM_SKIPJACK_RELAYX,            "CKM_SKIPJACK_RELAYX");
+        addMech(CKM_KEA_KEY_PAIR_GEN,           "CKM_KEA_KEY_PAIR_GEN");
+        addMech(CKM_KEA_KEY_DERIVE,             "CKM_KEA_KEY_DERIVE");
+        addMech(CKM_FORTEZZA_TIMESTAMP,         "CKM_FORTEZZA_TIMESTAMP");
+        addMech(CKM_BATON_KEY_GEN,              "CKM_BATON_KEY_GEN");
+        addMech(CKM_BATON_ECB128,               "CKM_BATON_ECB128");
+        addMech(CKM_BATON_ECB96,                "CKM_BATON_ECB96");
+        addMech(CKM_BATON_CBC128,               "CKM_BATON_CBC128");
+        addMech(CKM_BATON_COUNTER,              "CKM_BATON_COUNTER");
+        addMech(CKM_BATON_SHUFFLE,              "CKM_BATON_SHUFFLE");
+        addMech(CKM_BATON_WRAP,                 "CKM_BATON_WRAP");
+        addMech(CKM_EC_KEY_PAIR_GEN,            "CKM_EC_KEY_PAIR_GEN");
+        addMech(CKM_ECDSA,                      "CKM_ECDSA");
+        addMech(CKM_ECDSA_SHA1,                 "CKM_ECDSA_SHA1");
+        addMech(CKM_ECDH1_DERIVE,               "CKM_ECDH1_DERIVE");
+        addMech(CKM_ECDH1_COFACTOR_DERIVE,      "CKM_ECDH1_COFACTOR_DERIVE");
+        addMech(CKM_ECMQV_DERIVE,               "CKM_ECMQV_DERIVE");
+        addMech(CKM_JUNIPER_KEY_GEN,            "CKM_JUNIPER_KEY_GEN");
+        addMech(CKM_JUNIPER_ECB128,             "CKM_JUNIPER_ECB128");
+        addMech(CKM_JUNIPER_CBC128,             "CKM_JUNIPER_CBC128");
+        addMech(CKM_JUNIPER_COUNTER,            "CKM_JUNIPER_COUNTER");
+        addMech(CKM_JUNIPER_SHUFFLE,            "CKM_JUNIPER_SHUFFLE");
+        addMech(CKM_JUNIPER_WRAP,               "CKM_JUNIPER_WRAP");
+        addMech(CKM_FASTHASH,                   "CKM_FASTHASH");
+        addMech(CKM_AES_KEY_GEN,                "CKM_AES_KEY_GEN");
+        addMech(CKM_AES_ECB,                    "CKM_AES_ECB");
+        addMech(CKM_AES_CBC,                    "CKM_AES_CBC");
+        addMech(CKM_AES_MAC,                    "CKM_AES_MAC");
+        addMech(CKM_AES_MAC_GENERAL,            "CKM_AES_MAC_GENERAL");
+        addMech(CKM_AES_CBC_PAD,                "CKM_AES_CBC_PAD");
+        addMech(CKM_BLOWFISH_KEY_GEN,           "CKM_BLOWFISH_KEY_GEN");
+        addMech(CKM_BLOWFISH_CBC,               "CKM_BLOWFISH_CBC");
+        addMech(CKM_DSA_PARAMETER_GEN,          "CKM_DSA_PARAMETER_GEN");
+        addMech(CKM_DH_PKCS_PARAMETER_GEN,      "CKM_DH_PKCS_PARAMETER_GEN");
+        addMech(CKM_X9_42_DH_PARAMETER_GEN,     "CKM_X9_42_DH_PARAMETER_GEN");
+        addMech(CKM_VENDOR_DEFINED,             "CKM_VENDOR_DEFINED");
+
+        addMech(CKM_NSS_TLS_PRF_GENERAL,        "CKM_NSS_TLS_PRF_GENERAL");
+
+        addMech(PCKM_SECURERANDOM,              "SecureRandom");
+        addMech(PCKM_KEYSTORE,                  "KeyStore");
+
+        addKeyType(CKK_RSA,                     "CKK_RSA");
+        addKeyType(CKK_DSA,                     "CKK_DSA");
+        addKeyType(CKK_DH,                      "CKK_DH");
+        addKeyType(CKK_EC,                      "CKK_EC");
+        addKeyType(CKK_X9_42_DH,                "CKK_X9_42_DH");
+        addKeyType(CKK_KEA,                     "CKK_KEA");
+        addKeyType(CKK_GENERIC_SECRET,          "CKK_GENERIC_SECRET");
+        addKeyType(CKK_RC2,                     "CKK_RC2");
+        addKeyType(CKK_RC4,                     "CKK_RC4");
+        addKeyType(CKK_DES,                     "CKK_DES");
+        addKeyType(CKK_DES2,                    "CKK_DES2");
+        addKeyType(CKK_DES3,                    "CKK_DES3");
+        addKeyType(CKK_CAST,                    "CKK_CAST");
+        addKeyType(CKK_CAST3,                   "CKK_CAST3");
+        addKeyType(CKK_CAST128,                 "CKK_CAST128");
+        addKeyType(CKK_RC5,                     "CKK_RC5");
+        addKeyType(CKK_IDEA,                    "CKK_IDEA");
+        addKeyType(CKK_SKIPJACK,                "CKK_SKIPJACK");
+        addKeyType(CKK_BATON,                   "CKK_BATON");
+        addKeyType(CKK_JUNIPER,                 "CKK_JUNIPER");
+        addKeyType(CKK_CDMF,                    "CKK_CDMF");
+        addKeyType(CKK_AES,                     "CKK_AES");
+        addKeyType(CKK_BLOWFISH,                "CKK_BLOWFISH");
+        addKeyType(CKK_VENDOR_DEFINED,          "CKK_VENDOR_DEFINED");
+
+        addKeyType(PCKK_ANY,                    "*");
+
+        addAttribute(CKA_CLASS,                 "CKA_CLASS");
+        addAttribute(CKA_TOKEN,                 "CKA_TOKEN");
+        addAttribute(CKA_PRIVATE,               "CKA_PRIVATE");
+        addAttribute(CKA_LABEL,                 "CKA_LABEL");
+        addAttribute(CKA_APPLICATION,           "CKA_APPLICATION");
+        addAttribute(CKA_VALUE,                 "CKA_VALUE");
+        addAttribute(CKA_OBJECT_ID,             "CKA_OBJECT_ID");
+        addAttribute(CKA_CERTIFICATE_TYPE,      "CKA_CERTIFICATE_TYPE");
+        addAttribute(CKA_ISSUER,                "CKA_ISSUER");
+        addAttribute(CKA_SERIAL_NUMBER,         "CKA_SERIAL_NUMBER");
+        addAttribute(CKA_AC_ISSUER,             "CKA_AC_ISSUER");
+        addAttribute(CKA_OWNER,                 "CKA_OWNER");
+        addAttribute(CKA_ATTR_TYPES,            "CKA_ATTR_TYPES");
+        addAttribute(CKA_TRUSTED,               "CKA_TRUSTED");
+        addAttribute(CKA_KEY_TYPE,              "CKA_KEY_TYPE");
+        addAttribute(CKA_SUBJECT,               "CKA_SUBJECT");
+        addAttribute(CKA_ID,                    "CKA_ID");
+        addAttribute(CKA_SENSITIVE,             "CKA_SENSITIVE");
+        addAttribute(CKA_ENCRYPT,               "CKA_ENCRYPT");
+        addAttribute(CKA_DECRYPT,               "CKA_DECRYPT");
+        addAttribute(CKA_WRAP,                  "CKA_WRAP");
+        addAttribute(CKA_UNWRAP,                "CKA_UNWRAP");
+        addAttribute(CKA_SIGN,                  "CKA_SIGN");
+        addAttribute(CKA_SIGN_RECOVER,          "CKA_SIGN_RECOVER");
+        addAttribute(CKA_VERIFY,                "CKA_VERIFY");
+        addAttribute(CKA_VERIFY_RECOVER,        "CKA_VERIFY_RECOVER");
+        addAttribute(CKA_DERIVE,                "CKA_DERIVE");
+        addAttribute(CKA_START_DATE,            "CKA_START_DATE");
+        addAttribute(CKA_END_DATE,              "CKA_END_DATE");
+        addAttribute(CKA_MODULUS,               "CKA_MODULUS");
+        addAttribute(CKA_MODULUS_BITS,          "CKA_MODULUS_BITS");
+        addAttribute(CKA_PUBLIC_EXPONENT,       "CKA_PUBLIC_EXPONENT");
+        addAttribute(CKA_PRIVATE_EXPONENT,      "CKA_PRIVATE_EXPONENT");
+        addAttribute(CKA_PRIME_1,               "CKA_PRIME_1");
+        addAttribute(CKA_PRIME_2,               "CKA_PRIME_2");
+        addAttribute(CKA_EXPONENT_1,            "CKA_EXPONENT_1");
+        addAttribute(CKA_EXPONENT_2,            "CKA_EXPONENT_2");
+        addAttribute(CKA_COEFFICIENT,           "CKA_COEFFICIENT");
+        addAttribute(CKA_PRIME,                 "CKA_PRIME");
+        addAttribute(CKA_SUBPRIME,              "CKA_SUBPRIME");
+        addAttribute(CKA_BASE,                  "CKA_BASE");
+        addAttribute(CKA_PRIME_BITS,            "CKA_PRIME_BITS");
+        addAttribute(CKA_SUB_PRIME_BITS,        "CKA_SUB_PRIME_BITS");
+        addAttribute(CKA_VALUE_BITS,            "CKA_VALUE_BITS");
+        addAttribute(CKA_VALUE_LEN,             "CKA_VALUE_LEN");
+        addAttribute(CKA_EXTRACTABLE,           "CKA_EXTRACTABLE");
+        addAttribute(CKA_LOCAL,                 "CKA_LOCAL");
+        addAttribute(CKA_NEVER_EXTRACTABLE,     "CKA_NEVER_EXTRACTABLE");
+        addAttribute(CKA_ALWAYS_SENSITIVE,      "CKA_ALWAYS_SENSITIVE");
+        addAttribute(CKA_KEY_GEN_MECHANISM,     "CKA_KEY_GEN_MECHANISM");
+        addAttribute(CKA_MODIFIABLE,            "CKA_MODIFIABLE");
+        addAttribute(CKA_EC_PARAMS,             "CKA_EC_PARAMS");
+        addAttribute(CKA_EC_POINT,              "CKA_EC_POINT");
+        addAttribute(CKA_SECONDARY_AUTH,        "CKA_SECONDARY_AUTH");
+        addAttribute(CKA_AUTH_PIN_FLAGS,        "CKA_AUTH_PIN_FLAGS");
+        addAttribute(CKA_HW_FEATURE_TYPE,       "CKA_HW_FEATURE_TYPE");
+        addAttribute(CKA_RESET_ON_INIT,         "CKA_RESET_ON_INIT");
+        addAttribute(CKA_HAS_RESET,             "CKA_HAS_RESET");
+        addAttribute(CKA_VENDOR_DEFINED,        "CKA_VENDOR_DEFINED");
+        addAttribute(CKA_NETSCAPE_DB,           "CKA_NETSCAPE_DB");
+
+        addAttribute(CKA_NETSCAPE_TRUST_SERVER_AUTH,      "CKA_NETSCAPE_TRUST_SERVER_AUTH");
+        addAttribute(CKA_NETSCAPE_TRUST_CLIENT_AUTH,      "CKA_NETSCAPE_TRUST_CLIENT_AUTH");
+        addAttribute(CKA_NETSCAPE_TRUST_CODE_SIGNING,     "CKA_NETSCAPE_TRUST_CODE_SIGNING");
+        addAttribute(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, "CKA_NETSCAPE_TRUST_EMAIL_PROTECTION");
+        addAttribute(CKA_NETSCAPE_CERT_SHA1_HASH,         "CKA_NETSCAPE_CERT_SHA1_HASH");
+        addAttribute(CKA_NETSCAPE_CERT_MD5_HASH,          "CKA_NETSCAPE_CERT_MD5_HASH");
+
+        addObjectClass(CKO_DATA,                "CKO_DATA");
+        addObjectClass(CKO_CERTIFICATE,         "CKO_CERTIFICATE");
+        addObjectClass(CKO_PUBLIC_KEY,          "CKO_PUBLIC_KEY");
+        addObjectClass(CKO_PRIVATE_KEY,         "CKO_PRIVATE_KEY");
+        addObjectClass(CKO_SECRET_KEY,          "CKO_SECRET_KEY");
+        addObjectClass(CKO_HW_FEATURE,          "CKO_HW_FEATURE");
+        addObjectClass(CKO_DOMAIN_PARAMETERS,   "CKO_DOMAIN_PARAMETERS");
+        addObjectClass(CKO_VENDOR_DEFINED,      "CKO_VENDOR_DEFINED");
+
+        addObjectClass(PCKO_ANY,                "*");
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,1827 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import sun.security.util.Debug;
+
+import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+
+/**
+ * This is the default implementation of the PKCS11 interface. IT connects to
+ * the pkcs11wrapper.dll file, which is the native part of this library.
+ * The strange and awkward looking initialization was chosen to avoid calling
+ * loadLibrary from a static initialization block, because this would complicate
+ * the use in applets.
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ * @invariants (pkcs11ModulePath_ <> null)
+ */
+public class PKCS11 {
+
+    /**
+     * The name of the native part of the wrapper; i.e. the filename without
+     * the extension (e.g. ".DLL" or ".so").
+     */
+    private static final String PKCS11_WRAPPER = "j2pkcs11";
+
+    static {
+        // cannot use LoadLibraryAction because that would make the native
+        // library available to the bootclassloader, but we run in the
+        // extension classloader.
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
+            public Object run() {
+                System.loadLibrary(PKCS11_WRAPPER);
+                return null;
+            }
+        });
+        boolean enableDebug = Debug.getInstance("sunpkcs11") != null;
+        initializeLibrary(enableDebug);
+    }
+
+    public static void loadNative() {
+        // dummy method that can be called to make sure the native
+        // portion has been loaded. actual loading happens in the
+        // static initializer, hence this method is empty.
+    }
+
+    /**
+     * The PKCS#11 module to connect to. This is the PKCS#11 driver of the token;
+     * e.g. pk2priv.dll.
+     */
+    private final String pkcs11ModulePath;
+
+    private long pNativeData;
+
+    /**
+     * This method does the initialization of the native library. It is called
+     * exactly once for this class.
+     *
+     * @preconditions
+     * @postconditions
+     */
+    private static native void initializeLibrary(boolean debug);
+
+    // XXX
+    /**
+     * This method does the finalization of the native library. It is called
+     * exactly once for this class. The library uses this method for a clean-up
+     * of any resources.
+     *
+     * @preconditions
+     * @postconditions
+     */
+    private static native void finalizeLibrary();
+
+    private static final Map<String,PKCS11> moduleMap =
+        new HashMap<String,PKCS11>();
+
+    /**
+     * Connects to the PKCS#11 driver given. The filename must contain the
+     * path, if the driver is not in the system's search path.
+     *
+     * @param pkcs11ModulePath the PKCS#11 library path
+     * @preconditions (pkcs11ModulePath <> null)
+     * @postconditions
+     */
+    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 {
+        // 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);
+        if (pkcs11 == null) {
+            if ((pInitArgs != null)
+                    && ((pInitArgs.flags & CKF_OS_LOCKING_OK) != 0)) {
+                pkcs11 = new PKCS11(pkcs11ModulePath, functionList);
+            } else {
+                pkcs11 = new SynchronizedPKCS11(pkcs11ModulePath, functionList);
+            }
+            if (omitInitialize == false) {
+                try {
+                    pkcs11.C_Initialize(pInitArgs);
+                } catch (PKCS11Exception e) {
+                    // ignore already-initialized error code
+                    // rethrow all other errors
+                    if (e.getErrorCode() != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
+                        throw e;
+                    }
+                }
+            }
+            moduleMap.put(pkcs11ModulePath, pkcs11);
+        }
+        return pkcs11;
+    }
+
+    /**
+     * Connects this object to the specified PKCS#11 library. This method is for
+     * internal use only.
+     * Declared private, because incorrect handling may result in errors in the
+     * native part.
+     *
+     * @param pkcs11ModulePath The PKCS#11 library path.
+     * @preconditions (pkcs11ModulePath <> null)
+     * @postconditions
+     */
+    private native void connect(String pkcs11ModulePath, String functionListName)
+            throws IOException;
+
+    /**
+     * Disconnects the PKCS#11 library from this object. After calling this
+     * method, this object is no longer connected to a native PKCS#11 module
+     * and any subsequent calls to C_ methods will fail. This method is for
+     * internal use only.
+     * Declared private, because incorrect handling may result in errors in the
+     * native part.
+     *
+     * @preconditions
+     * @postconditions
+     */
+    private native void disconnect();
+
+
+    // Implementation of PKCS11 methods delegated to native pkcs11wrapper library
+
+/* *****************************************************************************
+ * General-purpose
+ ******************************************************************************/
+
+    /**
+     * C_Initialize initializes the Cryptoki library.
+     * (General-purpose)
+     *
+     * @param pInitArgs if pInitArgs is not NULL it gets casted to
+     *         CK_C_INITIALIZE_ARGS_PTR and dereferenced
+     *         (PKCS#11 param: CK_VOID_PTR pInitArgs)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    native void C_Initialize(Object pInitArgs) throws PKCS11Exception;
+
+    /**
+     * C_Finalize indicates that an application is done with the
+     * Cryptoki library
+     * (General-purpose)
+     *
+     * @param pReserved is reserved. Should be NULL_PTR
+     *         (PKCS#11 param: CK_VOID_PTR pReserved)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pReserved == null)
+     * @postconditions
+     */
+    public native void C_Finalize(Object pReserved) throws PKCS11Exception;
+
+
+    /**
+     * C_GetInfo returns general information about Cryptoki.
+     * (General-purpose)
+     *
+     * @return the information.
+     *         (PKCS#11 param: CK_INFO_PTR pInfo)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native CK_INFO C_GetInfo() throws PKCS11Exception;
+
+
+/* *****************************************************************************
+ * Slot and token management
+ ******************************************************************************/
+
+    /**
+     * C_GetSlotList obtains a list of slots in the system.
+     * (Slot and token management)
+     *
+     * @param tokenPresent if true only Slot IDs with a token are returned
+     *         (PKCS#11 param: CK_BBOOL tokenPresent)
+     * @return a long array of slot IDs and number of Slot IDs
+     *         (PKCS#11 param: CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native long[] C_GetSlotList(boolean tokenPresent)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_GetSlotInfo obtains information about a particular slot in
+     * the system.
+     * (Slot and token management)
+     *
+     * @param slotID the ID of the slot
+     *         (PKCS#11 param: CK_SLOT_ID slotID)
+     * @return the slot information
+     *         (PKCS#11 param: CK_SLOT_INFO_PTR pInfo)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native CK_SLOT_INFO C_GetSlotInfo(long slotID) throws PKCS11Exception;
+
+
+    /**
+     * C_GetTokenInfo obtains information about a particular token
+     * in the system.
+     * (Slot and token management)
+     *
+     * @param slotID ID of the token's slot
+     *         (PKCS#11 param: CK_SLOT_ID slotID)
+     * @return the token information
+     *         (PKCS#11 param: CK_TOKEN_INFO_PTR pInfo)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native CK_TOKEN_INFO C_GetTokenInfo(long slotID)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_GetMechanismList obtains a list of mechanism types
+     * supported by a token.
+     * (Slot and token management)
+     *
+     * @param slotID ID of the token's slot
+     *         (PKCS#11 param: CK_SLOT_ID slotID)
+     * @return a long array of mechanism types and number of mechanism types
+     *         (PKCS#11 param: CK_MECHANISM_TYPE_PTR pMechanismList,
+     *                         CK_ULONG_PTR pulCount)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native long[] C_GetMechanismList(long slotID) throws PKCS11Exception;
+
+
+    /**
+     * C_GetMechanismInfo obtains information about a particular
+     * mechanism possibly supported by a token.
+     * (Slot and token management)
+     *
+     * @param slotID ID of the token's slot
+     *         (PKCS#11 param: CK_SLOT_ID slotID)
+     * @param type type of mechanism
+     *         (PKCS#11 param: CK_MECHANISM_TYPE type)
+     * @return the mechanism info
+     *         (PKCS#11 param: CK_MECHANISM_INFO_PTR pInfo)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native CK_MECHANISM_INFO C_GetMechanismInfo(long slotID, long type)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_InitToken initializes a token.
+     * (Slot and token management)
+     *
+     * @param slotID ID of the token's slot
+     *         (PKCS#11 param: CK_SLOT_ID slotID)
+     * @param pPin the SO's initial PIN and the length in bytes of the PIN
+     *         (PKCS#11 param: CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
+     * @param pLabel 32-byte token label (blank padded)
+     *         (PKCS#11 param: CK_UTF8CHAR_PTR pLabel)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+//    public native void C_InitToken(long slotID, char[] pPin, char[] pLabel)
+//            throws PKCS11Exception;
+
+
+    /**
+     * C_InitPIN initializes the normal user's PIN.
+     * (Slot and token management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pPin the normal user's PIN and the length in bytes of the PIN
+     *         (PKCS#11 param: CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+//    public native void C_InitPIN(long hSession, char[] pPin)
+//            throws PKCS11Exception;
+
+
+    /**
+     * C_SetPIN modifies the PIN of the user who is logged in.
+     * (Slot and token management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pOldPin the old PIN and the length of the old PIN
+     *         (PKCS#11 param: CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen)
+     * @param pNewPin the new PIN and the length of the new PIN
+     *         (PKCS#11 param: CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+//    public native void C_SetPIN(long hSession, char[] pOldPin, char[] pNewPin)
+//            throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Session management
+ ******************************************************************************/
+
+    /**
+     * C_OpenSession opens a session between an application and a
+     * token.
+     * (Session management)
+     *
+     * @param slotID the slot's ID
+     *         (PKCS#11 param: CK_SLOT_ID slotID)
+     * @param flags of CK_SESSION_INFO
+     *         (PKCS#11 param: CK_FLAGS flags)
+     * @param pApplication passed to callback
+     *         (PKCS#11 param: CK_VOID_PTR pApplication)
+     * @param Notify the callback function
+     *         (PKCS#11 param: CK_NOTIFY Notify)
+     * @return the session handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE_PTR phSession)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native long C_OpenSession(long slotID, long flags,
+            Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception;
+
+
+    /**
+     * C_CloseSession closes a session between an application and a
+     * token.
+     * (Session management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_CloseSession(long hSession) throws PKCS11Exception;
+
+
+    /**
+     * C_CloseAllSessions closes all sessions with a token.
+     * (Session management)
+     *
+     * @param slotID the ID of the token's slot
+     *         (PKCS#11 param: CK_SLOT_ID slotID)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+//    public native void C_CloseAllSessions(long slotID) throws PKCS11Exception;
+
+
+    /**
+     * C_GetSessionInfo obtains information about the session.
+     * (Session management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @return the session info
+     *         (PKCS#11 param: CK_SESSION_INFO_PTR pInfo)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native CK_SESSION_INFO C_GetSessionInfo(long hSession)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_GetOperationState obtains the state of the cryptographic operation
+     * in a session.
+     * (Session management)
+     *
+     * @param hSession session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @return the state and the state length
+     *         (PKCS#11 param: CK_BYTE_PTR pOperationState,
+     *                         CK_ULONG_PTR pulOperationStateLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native byte[] C_GetOperationState(long hSession)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_SetOperationState restores the state of the cryptographic
+     * operation in a session.
+     * (Session management)
+     *
+     * @param hSession session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pOperationState the state and the state length
+     *         (PKCS#11 param: CK_BYTE_PTR pOperationState,
+     *                         CK_ULONG ulOperationStateLen)
+     * @param hEncryptionKey en/decryption key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hEncryptionKey)
+     * @param hAuthenticationKey sign/verify key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hAuthenticationKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_SetOperationState(long hSession, byte[] pOperationState,
+            long hEncryptionKey, long hAuthenticationKey) throws PKCS11Exception;
+
+
+    /**
+     * C_Login logs a user into a token.
+     * (Session management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param userType the user type
+     *         (PKCS#11 param: CK_USER_TYPE userType)
+     * @param pPin the user's PIN and the length of the PIN
+     *         (PKCS#11 param: CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_Login(long hSession, long userType, char[] pPin)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_Logout logs a user out from a token.
+     * (Session management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_Logout(long hSession) throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Object management
+ ******************************************************************************/
+
+    /**
+     * C_CreateObject creates a new object.
+     * (Object management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pTemplate the object's template and number of attributes in
+     *         template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+     * @return the object's handle
+     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phObject)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native long C_CreateObject(long hSession, CK_ATTRIBUTE[] pTemplate)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_CopyObject copies an object, creating a new object for the
+     * copy.
+     * (Object management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param hObject the object's handle
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
+     * @param pTemplate the template for the new object and number of attributes
+     *         in template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+     * @return the handle of the copy
+     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phNewObject)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native long C_CopyObject(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+
+
+    /**
+     * C_DestroyObject destroys an object.
+     * (Object management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param hObject the object's handle
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_DestroyObject(long hSession, long hObject)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_GetObjectSize gets the size of an object in bytes.
+     * (Object management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param hObject the object's handle
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
+     * @return the size of the object
+     *         (PKCS#11 param: CK_ULONG_PTR pulSize)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+//    public native long C_GetObjectSize(long hSession, long hObject)
+//            throws PKCS11Exception;
+
+
+    /**
+     * C_GetAttributeValue obtains the value of one or more object
+     * attributes. The template attributes also receive the values.
+     * (Object management)
+     * note: in PKCS#11 pTemplate and the result template are the same
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param hObject the object's handle
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
+     * @param pTemplate specifies the attributes and number of attributes to get
+     *                  The template attributes also receive the values.
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pTemplate <> null)
+     * @postconditions (result <> null)
+     */
+    public native void C_GetAttributeValue(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+
+
+    /**
+     * C_SetAttributeValue modifies the value of one or more object
+     * attributes
+     * (Object management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param hObject the object's handle
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
+     * @param pTemplate specifies the attributes and values to get; number of
+     *         attributes in the template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pTemplate <> null)
+     * @postconditions
+     */
+    public native void C_SetAttributeValue(long hSession, long hObject,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+
+
+    /**
+     * C_FindObjectsInit initializes a search for token and session
+     * objects that match a template.
+     * (Object management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pTemplate the object's attribute values to match and the number of
+     *         attributes in search template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_FindObjectsInit(long hSession, CK_ATTRIBUTE[] pTemplate)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_FindObjects continues a search for token and session
+     * objects that match a template, obtaining additional object
+     * handles.
+     * (Object management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param ulMaxObjectCount the max. object handles to get
+     *         (PKCS#11 param: CK_ULONG ulMaxObjectCount)
+     * @return the object's handles and the actual number of objects returned
+     *         (PKCS#11 param: CK_ULONG_PTR pulObjectCount)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native long[] C_FindObjects(long hSession, long ulMaxObjectCount)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_FindObjectsFinal finishes a search for token and session
+     * objects.
+     * (Object management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_FindObjectsFinal(long hSession) throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Encryption and decryption
+ ******************************************************************************/
+
+    /**
+     * C_EncryptInit initializes an encryption operation.
+     * (Encryption and decryption)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the encryption mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hKey the handle of the encryption key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_EncryptInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
+
+
+    /**
+     * C_Encrypt encrypts single-part data.
+     * (Encryption and decryption)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pData the data to get encrypted and the data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
+     * @return the encrypted data and the encrypted data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedData,
+     *                         CK_ULONG_PTR pulEncryptedDataLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @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;
+
+
+    /**
+     * C_EncryptUpdate continues a multiple-part encryption
+     * operation.
+     * (Encryption and decryption)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pPart the data part to get encrypted and the data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+     * @return the encrypted data part and the encrypted data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
+                             CK_ULONG_PTR pulEncryptedPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @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;
+
+
+    /**
+     * C_EncryptFinal finishes a multiple-part encryption
+     * operation.
+     * (Encryption and decryption)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @return the last encrypted data part and the last data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pLastEncryptedPart,
+                             CK_ULONG_PTR pulLastEncryptedPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native int C_EncryptFinal(long hSession, long directOut, byte[] out,
+            int outOfs, int outLen) throws PKCS11Exception;
+
+
+    /**
+     * C_DecryptInit initializes a decryption operation.
+     * (Encryption and decryption)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the decryption mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hKey the handle of the decryption key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_DecryptInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
+
+
+    /**
+     * C_Decrypt decrypts encrypted data in a single part.
+     * (Encryption and decryption)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pEncryptedData the encrypted data to get decrypted and the
+     *         encrypted data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedData,
+     *                         CK_ULONG ulEncryptedDataLen)
+     * @return the decrypted data and the data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @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;
+
+
+    /**
+     * C_DecryptUpdate continues a multiple-part decryption
+     * operation.
+     * (Encryption and decryption)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pEncryptedPart the encrypted data part to get decrypted and the
+     *         encrypted data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
+     *                         CK_ULONG ulEncryptedPartLen)
+     * @return the decrypted data part and the data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @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;
+
+
+    /**
+     * C_DecryptFinal finishes a multiple-part decryption
+     * operation.
+     * (Encryption and decryption)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @return the last decrypted data part and the last data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pLastPart,
+     *                         CK_ULONG_PTR pulLastPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native int C_DecryptFinal(long hSession, long directOut, byte[] out,
+            int outOfs, int outLen) throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Message digesting
+ ******************************************************************************/
+
+    /**
+     * C_DigestInit initializes a message-digesting operation.
+     * (Message digesting)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the digesting mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_DigestInit(long hSession, CK_MECHANISM pMechanism)
+            throws PKCS11Exception;
+
+
+    // note that C_DigestSingle does not exist in PKCS#11
+    // we combined the C_DigestInit and C_Digest into a single function
+    // to save on Java<->C transitions and save 5-10% on small digests
+    // this made the C_Digest method redundant, it has been removed
+    /**
+     * C_Digest digests data in a single part.
+     * (Message digesting)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param data the data to get digested and the data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
+     * @return the message digest and the length of the message digest
+     *         (PKCS#11 param: CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @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;
+
+
+    /**
+     * C_DigestUpdate continues a multiple-part message-digesting
+     * operation.
+     * (Message digesting)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pPart the data to get digested and the data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pPart <> null)
+     * @postconditions
+     */
+    public native void C_DigestUpdate(long hSession, long directIn, byte[] in,
+            int inOfs, int inLen) throws PKCS11Exception;
+
+
+    /**
+     * C_DigestKey continues a multi-part message-digesting
+     * operation, by digesting the value of a secret key as part of
+     * the data already digested.
+     * (Message digesting)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param hKey the handle of the secret key to be digested
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_DigestKey(long hSession, long hKey)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_DigestFinal finishes a multiple-part message-digesting
+     * operation.
+     * (Message digesting)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @return the message digest and the length of the message digest
+     *         (PKCS#11 param: CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native int C_DigestFinal(long hSession, byte[] pDigest, int digestOfs,
+            int digestLen) throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Signing and MACing
+ ******************************************************************************/
+
+    /**
+     * C_SignInit initializes a signature (private key encryption)
+     * operation, where the signature is (will be) an appendix to
+     * the data, and plaintext cannot be recovered from the
+     * signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the signature mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hKey the handle of the signature key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_SignInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
+
+
+    /**
+     * C_Sign signs (encrypts with private key) data in a single
+     * part, where the signature is (will be) an appendix to the
+     * data, and plaintext cannot be recovered from the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pData the data to sign and the data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
+     * @return the signature and the signature's length
+     *         (PKCS#11 param: CK_BYTE_PTR pSignature,
+     *                         CK_ULONG_PTR pulSignatureLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pData <> null)
+     * @postconditions (result <> null)
+     */
+    public native byte[] C_Sign(long hSession, byte[] pData)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_SignUpdate continues a multiple-part signature operation,
+     * where the signature is (will be) an appendix to the data,
+     * and plaintext cannot be recovered from the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pPart the data part to sign and the data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pPart <> null)
+     * @postconditions
+     */
+    public native void C_SignUpdate(long hSession, long directIn, byte[] in,
+            int inOfs, int inLen) throws PKCS11Exception;
+
+
+    /**
+     * C_SignFinal finishes a multiple-part signature operation,
+     * returning the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @return the signature and the signature's length
+     *         (PKCS#11 param: CK_BYTE_PTR pSignature,
+     *                         CK_ULONG_PTR pulSignatureLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native byte[] C_SignFinal(long hSession, int expectedLen)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_SignRecoverInit initializes a signature operation, where
+     * the data can be recovered from the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the signature mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hKey the handle of the signature key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_SignRecoverInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
+
+
+    /**
+     * C_SignRecover signs data in a single operation, where the
+     * data can be recovered from the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pData the data to sign and the data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
+     * @return the signature and the signature's length
+     *         (PKCS#11 param: CK_BYTE_PTR pSignature,
+     *                         CK_ULONG_PTR pulSignatureLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @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;
+
+
+
+/* *****************************************************************************
+ * Verifying signatures and MACs
+ ******************************************************************************/
+
+    /**
+     * C_VerifyInit initializes a verification operation, where the
+     * signature is an appendix to the data, and plaintext cannot
+     * cannot be recovered from the signature (e.g. DSA).
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the verification mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hKey the handle of the verification key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_VerifyInit(long hSession, CK_MECHANISM pMechanism,
+            long hKey) throws PKCS11Exception;
+
+
+    /**
+     * C_Verify verifies a signature in a single-part operation,
+     * where the signature is an appendix to the data, and plaintext
+     * cannot be recovered from the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pData the signed data and the signed data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
+     * @param pSignature the signature to verify and the signature's length
+     *         (PKCS#11 param: CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pData <> null) and (pSignature <> null)
+     * @postconditions
+     */
+    public native void C_Verify(long hSession, byte[] pData, byte[] pSignature)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_VerifyUpdate continues a multiple-part verification
+     * operation, where the signature is an appendix to the data,
+     * and plaintext cannot be recovered from the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pPart the signed data part and the signed data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pPart <> null)
+     * @postconditions
+     */
+    public native void C_VerifyUpdate(long hSession, long directIn, byte[] in,
+            int inOfs, int inLen) throws PKCS11Exception;
+
+
+    /**
+     * C_VerifyFinal finishes a multiple-part verification
+     * operation, checking the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pSignature the signature to verify and the signature's length
+     *         (PKCS#11 param: CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pSignature <> null)
+     * @postconditions
+     */
+    public native void C_VerifyFinal(long hSession, byte[] pSignature)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_VerifyRecoverInit initializes a signature verification
+     * operation, where the data is recovered from the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the verification mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hKey the handle of the verification key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native void C_VerifyRecoverInit(long hSession,
+            CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
+
+
+    /**
+     * C_VerifyRecover verifies a signature in a single-part
+     * operation, where the data is recovered from the signature.
+     * (Signing and MACing)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pSignature the signature to verify and the signature's length
+     *         (PKCS#11 param: CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
+     * @return the recovered data and the recovered data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @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;
+
+
+
+/* *****************************************************************************
+ * Dual-function cryptographic operations
+ ******************************************************************************/
+
+    /**
+     * C_DigestEncryptUpdate continues a multiple-part digesting
+     * and encryption operation.
+     * (Dual-function cryptographic operations)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pPart the data part to digest and to encrypt and the data's length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+     * @return the digested and encrypted data part and the data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
+     *                         CK_ULONG_PTR pulEncryptedPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pPart <> null)
+     * @postconditions
+     */
+//    public native byte[] C_DigestEncryptUpdate(long hSession, byte[] pPart)
+//            throws PKCS11Exception;
+
+
+    /**
+     * C_DecryptDigestUpdate continues a multiple-part decryption and
+     * digesting operation.
+     * (Dual-function cryptographic operations)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pEncryptedPart the encrypted data part to decrypt and to digest
+     *         and encrypted data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
+     *                         CK_ULONG ulEncryptedPartLen)
+     * @return the decrypted and digested data part and the data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pEncryptedPart <> null)
+     * @postconditions
+     */
+//    public native byte[] C_DecryptDigestUpdate(long hSession,
+//            byte[] pEncryptedPart) throws PKCS11Exception;
+
+
+    /**
+     * C_SignEncryptUpdate continues a multiple-part signing and
+     * encryption operation.
+     * (Dual-function cryptographic operations)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pPart the data part to sign and to encrypt and the data part's
+     *         length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+     * @return the signed and encrypted data part and the data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
+     *                         CK_ULONG_PTR pulEncryptedPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pPart <> null)
+     * @postconditions
+     */
+//    public native byte[] C_SignEncryptUpdate(long hSession, byte[] pPart)
+//            throws PKCS11Exception;
+
+
+    /**
+     * C_DecryptVerifyUpdate continues a multiple-part decryption and
+     * verify operation.
+     * (Dual-function cryptographic operations)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pEncryptedPart the encrypted data part to decrypt and to verify
+     *         and the data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
+     *                         CK_ULONG ulEncryptedPartLen)
+     * @return the decrypted and verified data part and the data part's length
+     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pEncryptedPart <> null)
+     * @postconditions
+     */
+//    public native byte[] C_DecryptVerifyUpdate(long hSession,
+//            byte[] pEncryptedPart) throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Key management
+ ******************************************************************************/
+
+    /**
+     * C_GenerateKey generates a secret key, creating a new key
+     * object.
+     * (Key management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the key generation mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param pTemplate the template for the new key and the number of
+     *         attributes in the template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+     * @return the handle of the new key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native long C_GenerateKey(long hSession, CK_MECHANISM pMechanism,
+            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+
+
+    /**
+     * C_GenerateKeyPair generates a public-key/private-key pair,
+     * creating new key objects.
+     * (Key management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the key generation mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param pPublicKeyTemplate the template for the new public key and the
+     *         number of attributes in the template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+     *                         CK_ULONG ulPublicKeyAttributeCount)
+     * @param pPrivateKeyTemplate the template for the new private key and the
+     *         number of attributes in the template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pPrivateKeyTemplate
+     *                         CK_ULONG ulPrivateKeyAttributeCount)
+     * @return a long array with exactly two elements and the public key handle
+     *         as the first element and the private key handle as the second
+     *         element
+     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phPublicKey,
+     *                         CK_OBJECT_HANDLE_PTR phPrivateKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pMechanism <> null)
+     * @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;
+
+
+
+    /**
+     * C_WrapKey wraps (i.e., encrypts) a key.
+     * (Key management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the wrapping mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hWrappingKey the handle of the wrapping key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hWrappingKey)
+     * @param hKey the handle of the key to be wrapped
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
+     * @return the wrapped key and the length of the wrapped key
+     *         (PKCS#11 param: CK_BYTE_PTR pWrappedKey,
+     *                         CK_ULONG_PTR pulWrappedKeyLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public native byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism,
+            long hWrappingKey, long hKey) throws PKCS11Exception;
+
+
+    /**
+     * C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+     * key object.
+     * (Key management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the unwrapping mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hUnwrappingKey the handle of the unwrapping key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hUnwrappingKey)
+     * @param pWrappedKey the wrapped key to unwrap and the wrapped key's length
+     *         (PKCS#11 param: CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen)
+     * @param pTemplate the template for the new key and the number of
+     *         attributes in the template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+     * @return the handle of the unwrapped key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pWrappedKey <> null)
+     * @postconditions
+     */
+    public native long C_UnwrapKey(long hSession, CK_MECHANISM pMechanism,
+            long hUnwrappingKey, byte[] pWrappedKey, CK_ATTRIBUTE[] pTemplate)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_DeriveKey derives a key from a base key, creating a new key
+     * object.
+     * (Key management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pMechanism the key derivation mechanism
+     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
+     * @param hBaseKey the handle of the base key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE hBaseKey)
+     * @param pTemplate the template for the new key and the number of
+     *         attributes in the template
+     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+     * @return the handle of the derived key
+     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phKey)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+    public native long C_DeriveKey(long hSession, CK_MECHANISM pMechanism,
+            long hBaseKey, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Random number generation
+ ******************************************************************************/
+
+    /**
+     * C_SeedRandom mixes additional seed material into the token's
+     * random number generator.
+     * (Random number generation)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param pSeed the seed material and the seed material's length
+     *         (PKCS#11 param: CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pSeed <> null)
+     * @postconditions
+     */
+    public native void C_SeedRandom(long hSession, byte[] pSeed)
+            throws PKCS11Exception;
+
+
+    /**
+     * C_GenerateRandom generates random data.
+     * (Random number generation)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @param RandomData receives the random data and the length of RandomData
+     *         is the length of random data to be generated
+     *         (PKCS#11 param: CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (randomData <> null)
+     * @postconditions
+     */
+    public native void C_GenerateRandom(long hSession, byte[] randomData)
+            throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Parallel function management
+ ******************************************************************************/
+
+    /**
+     * C_GetFunctionStatus is a legacy function; it obtains an
+     * updated status of a function running in parallel with an
+     * application.
+     * (Parallel function management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+//    public native void C_GetFunctionStatus(long hSession)
+//            throws PKCS11Exception;
+
+
+    /**
+     * C_CancelFunction is a legacy function; it cancels a function
+     * running in parallel.
+     * (Parallel function management)
+     *
+     * @param hSession the session's handle
+     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions
+     * @postconditions
+     */
+//    public native void C_CancelFunction(long hSession) throws PKCS11Exception;
+
+
+
+/* *****************************************************************************
+ * Functions added in for Cryptoki Version 2.01 or later
+ ******************************************************************************/
+
+    /**
+     * C_WaitForSlotEvent waits for a slot event (token insertion,
+     * removal, etc.) to occur.
+     * (General-purpose)
+     *
+     * @param flags blocking/nonblocking flag
+     *         (PKCS#11 param: CK_FLAGS flags)
+     * @param pReserved reserved. Should be null
+     *         (PKCS#11 param: CK_VOID_PTR pReserved)
+     * @return the slot ID where the event occurred
+     *         (PKCS#11 param: CK_SLOT_ID_PTR pSlot)
+     * @exception PKCS11Exception If function returns other value than CKR_OK.
+     * @preconditions (pRserved == null)
+     * @postconditions
+     */
+//    public native long C_WaitForSlotEvent(long flags, Object pRserved)
+//            throws PKCS11Exception;
+
+    /**
+     * Returns the string representation of this object.
+     *
+     * @return The string representation of object
+     */
+    public String toString() {
+        return "Module name: " + pkcs11ModulePath;
+    }
+
+    /**
+     * Calls disconnect() to cleanup the native part of the wrapper. Once this
+     * method is called, this object cannot be used any longer. Any subsequent
+     * call to a C_* method will result in a runtime exception.
+     *
+     * @exception Throwable If finalization fails.
+     */
+    protected void finalize() throws Throwable {
+        disconnect();
+    }
+
+// PKCS11 subclass that has all methods synchronized and delegating to the
+// parent. Used for tokens that only support single threaded access
+static class SynchronizedPKCS11 extends PKCS11 {
+
+    SynchronizedPKCS11(String pkcs11ModulePath, String functionListName)
+            throws IOException {
+        super(pkcs11ModulePath, functionListName);
+    }
+
+    synchronized void C_Initialize(Object pInitArgs) throws PKCS11Exception {
+        super.C_Initialize(pInitArgs);
+    }
+
+    public synchronized void C_Finalize(Object pReserved)
+            throws PKCS11Exception {
+        super.C_Finalize(pReserved);
+    }
+
+    public synchronized CK_INFO C_GetInfo() throws PKCS11Exception {
+        return super.C_GetInfo();
+    }
+
+    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 {
+        return super.C_GetSlotInfo(slotID);
+    }
+
+    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 {
+        return super.C_GetMechanismList(slotID);
+    }
+
+    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 {
+        return super.C_OpenSession(slotID, flags, pApplication, Notify);
+    }
+
+    public synchronized void C_CloseSession(long hSession)
+            throws PKCS11Exception {
+        super.C_CloseSession(hSession);
+    }
+
+    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 {
+        super.C_Login(hSession, userType, pPin);
+    }
+
+    public synchronized void C_Logout(long hSession) throws PKCS11Exception {
+        super.C_Logout(hSession);
+    }
+
+    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 {
+        return super.C_CopyObject(hSession, hObject, pTemplate);
+    }
+
+    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 {
+        super.C_GetAttributeValue(hSession, hObject, pTemplate);
+    }
+
+    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 {
+        super.C_FindObjectsInit(hSession, pTemplate);
+    }
+
+    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 {
+        super.C_FindObjectsFinal(hSession);
+    }
+
+    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 {
+        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_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 {
+        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 {
+        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_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 {
+        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 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 {
+        super.C_DigestKey(hSession, hKey);
+    }
+
+    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 {
+        super.C_SignInit(hSession, pMechanism, hKey);
+    }
+
+    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 {
+        super.C_SignUpdate(hSession, directIn, in, inOfs, inLen);
+    }
+
+    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 {
+        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 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 {
+        super.C_Verify(hSession, pData, pSignature);
+    }
+
+    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 {
+        super.C_VerifyFinal(hSession, pSignature);
+    }
+
+    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 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);
+    }
+
+    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);
+    }
+
+    public synchronized long C_DeriveKey(long hSession, CK_MECHANISM pMechanism,
+    long hBaseKey, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
+        return super.C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate);
+    }
+
+    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 {
+        super.C_GenerateRandom(hSession, randomData);
+    }
+}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+/**
+ * This interface holds constants of the PKCS#11 v2.11 standard.
+ * This is mainly the content of the 'pkcs11t.h' header file.
+ *
+ * Mapping of primitiv data types to Java types:
+ * <pre>
+ *   TRUE .......................................... true
+ *   FALSE ......................................... false
+ *   CK_BYTE ....................................... byte
+ *   CK_CHAR ....................................... char
+ *   CK_UTF8CHAR ................................... char
+ *   CK_BBOOL ...................................... boolean
+ *   CK_ULONG ...................................... long
+ *   CK_LONG ....................................... long
+ *   CK_FLAGS ...................................... long
+ *   CK_NOTIFICATION ............................... long
+ *   CK_SLOT_ID .................................... long
+ *   CK_SESSION_HANDLE ............................. long
+ *   CK_USER_TYPE .................................. long
+ *   CK_SESSION_HANDLE ............................. long
+ *   CK_STATE ...................................... long
+ *   CK_OBJECT_HANDLE .............................. long
+ *   CK_OBJECT_CLASS ............................... long
+ *   CK_HW_FEATURE_TYPE ............................ long
+ *   CK_KEY_TYPE ................................... long
+ *   CK_CERTIFICATE_TYPE ........................... long
+ *   CK_ATTRIBUTE_TYPE ............................. long
+ *   CK_VOID_PTR ................................... Object[]
+ *   CK_BYTE_PTR ................................... byte[]
+ *   CK_CHAR_PTR ................................... char[]
+ *   CK_UTF8CHAR_PTR ............................... char[]
+ *   CK_MECHANISM_TYPE ............................. long
+ *   CK_RV ......................................... long
+ *   CK_RSA_PKCS_OAEP_MGF_TYPE ..................... long
+ *   CK_RSA_PKCS_OAEP_SOURCE_TYPE .................. long
+ *   CK_RC2_PARAMS ................................. long
+ *   CK_MAC_GENERAL_PARAMS ......................... long
+ *   CK_EXTRACT_PARAMS ............................. long
+ *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE .... long
+ *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE .............. long
+ *   CK_EC_KDF_TYPE ................................ long
+ *   CK_X9_42_DH_KDF_TYPE .......................... long
+ * </pre>
+ *
+ * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
+ * @invariants
+ */
+public interface PKCS11Constants {
+
+    public static final boolean TRUE = true;
+
+    public static final boolean FALSE = false;
+
+    public static final Object NULL_PTR = null;
+
+    /* some special values for certain CK_ULONG variables */
+
+    // Cryptoki defines CK_UNAVAILABLE_INFORMATION as (~0UL)
+    // This means it is 0xffffffff in ILP32/LLP64 but 0xffffffffffffffff in LP64.
+    // To avoid these differences on the Java side, the native code treats
+    // CK_UNAVAILABLE_INFORMATION specially and always returns (long)-1 for it.
+    // See ckULongSpecialToJLong() in pkcs11wrapper.h
+    public static final long CK_UNAVAILABLE_INFORMATION = -1;
+    public static final long CK_EFFECTIVELY_INFINITE = 0L;
+
+    /* The following value is always invalid if used as a session */
+    /* handle or object handle */
+    public static final long CK_INVALID_HANDLE = 0L;
+
+    /* CK_NOTIFICATION enumerates the types of notifications that
+     * Cryptoki provides to an application */
+    /* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
+     * for v2.0 */
+    public static final long CKN_SURRENDER = 0L;
+
+    /* flags: bit flags that provide capabilities of the slot
+     *      Bit Flag              Mask        Meaning
+     */
+    public static final long CKF_TOKEN_PRESENT = 0x00000001L;
+    public static final long CKF_REMOVABLE_DEVICE = 0x00000002L;
+    public static final long CKF_HW_SLOT = 0x00000004L;
+
+    /* The flags parameter is defined as follows:
+     *      Bit Flag                    Mask        Meaning
+     */
+    /* has random # generator */
+    public static final long  CKF_RNG                     = 0x00000001L;
+
+    /* token is write-protected */
+    public static final long  CKF_WRITE_PROTECTED         = 0x00000002L;
+
+    /* user must login */
+    public static final long  CKF_LOGIN_REQUIRED          = 0x00000004L;
+
+    /* normal user's PIN is set */
+    public static final long  CKF_USER_PIN_INITIALIZED    = 0x00000008L;
+
+    /* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
+     * that means that *every* time the state of cryptographic
+     * operations of a session is successfully saved, all keys
+     * needed to continue those operations are stored in the state */
+    public static final long  CKF_RESTORE_KEY_NOT_NEEDED  = 0x00000020L;
+
+    /* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
+     * that the token has some sort of clock.  The time on that
+     * clock is returned in the token info structure */
+    public static final long  CKF_CLOCK_ON_TOKEN          = 0x00000040L;
+
+    /* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
+     * set, that means that there is some way for the user to login
+     * without sending a PIN through the Cryptoki library itself */
+    public static final long  CKF_PROTECTED_AUTHENTICATION_PATH = 0x00000100L;
+
+    /* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
+     * that means that a single session with the token can perform
+     * dual simultaneous cryptographic operations (digest and
+     * encrypt; decrypt and digest; sign and encrypt; and decrypt
+     * and sign) */
+    public static final long  CKF_DUAL_CRYPTO_OPERATIONS  = 0x00000200L;
+
+    /* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
+     * token has been initialized using C_InitializeToken or an
+     * equivalent mechanism outside the scope of PKCS #11.
+     * Calling C_InitializeToken when this flag is set will cause
+     * the token to be reinitialized. */
+    public static final long  CKF_TOKEN_INITIALIZED       = 0x00000400L;
+
+    /* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
+     * true, the token supports secondary authentication for
+     * private key objects. */
+    public static final long  CKF_SECONDARY_AUTHENTICATION  = 0x00000800L;
+
+    /* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
+     * incorrect user login PIN has been entered at least once
+     * since the last successful authentication. */
+    public static final long  CKF_USER_PIN_COUNT_LOW       = 0x00010000L;
+
+    /* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
+     * supplying an incorrect user PIN will it to become locked. */
+    public static final long  CKF_USER_PIN_FINAL_TRY       = 0x00020000L;
+
+    /* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
+     * user PIN has been locked. User login to the token is not
+     * possible. */
+    public static final long  CKF_USER_PIN_LOCKED          = 0x00040000L;
+
+    /* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+     * the user PIN value is the default value set by token
+     * initialization or manufacturing. */
+    public static final long  CKF_USER_PIN_TO_BE_CHANGED   = 0x00080000L;
+
+    /* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
+     * incorrect SO login PIN has been entered at least once since
+     * the last successful authentication. */
+    public static final long  CKF_SO_PIN_COUNT_LOW         = 0x00100000L;
+
+    /* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
+     * supplying an incorrect SO PIN will it to become locked. */
+    public static final long  CKF_SO_PIN_FINAL_TRY         = 0x00200000L;
+
+    /* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
+     * PIN has been locked. SO login to the token is not possible.
+     */
+    public static final long  CKF_SO_PIN_LOCKED            = 0x00400000L;
+
+    /* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+     * the SO PIN value is the default value set by token
+     * initialization or manufacturing. */
+    public static final long  CKF_SO_PIN_TO_BE_CHANGED     = 0x00800000L;
+
+
+    /* CK_USER_TYPE enumerates the types of Cryptoki users */
+    /* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
+     * v2.0 */
+    /* Security Officer */
+    public static final long CKU_SO = 0L;
+    /* Normal user */
+    public static final long CKU_USER = 1L;
+
+    /* CK_STATE enumerates the session states */
+    /* CK_STATE has been changed from an enum to a CK_ULONG for
+     * v2.0 */
+    public static final long  CKS_RO_PUBLIC_SESSION = 0L;
+    public static final long  CKS_RO_USER_FUNCTIONS = 1L;
+    public static final long  CKS_RW_PUBLIC_SESSION = 2L;
+    public static final long  CKS_RW_USER_FUNCTIONS = 3L;
+    public static final long  CKS_RW_SO_FUNCTIONS   = 4L;
+
+
+    /* The flags are defined in the following table:
+     *      Bit Flag                Mask        Meaning
+     */
+    /* session is r/w */
+    public static final long  CKF_RW_SESSION        = 0x00000002L;
+    /* no parallel */
+    public static final long  CKF_SERIAL_SESSION    = 0x00000004L;
+
+
+    /* The following classes of objects are defined: */
+    /* CKO_HW_FEATURE is new for v2.10 */
+    /* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+    public static final long  CKO_DATA              = 0x00000000L;
+    public static final long  CKO_CERTIFICATE       = 0x00000001L;
+    public static final long  CKO_PUBLIC_KEY        = 0x00000002L;
+    public static final long  CKO_PRIVATE_KEY       = 0x00000003L;
+    public static final long  CKO_SECRET_KEY        = 0x00000004L;
+    public static final long  CKO_HW_FEATURE        = 0x00000005L;
+    public static final long  CKO_DOMAIN_PARAMETERS = 0x00000006L;
+    public static final long  CKO_VENDOR_DEFINED    = 0x80000000L;
+
+    // pseudo object class ANY (for template manager)
+    public static final long  PCKO_ANY              = 0x7FFFFF23L;
+
+
+    /* The following hardware feature types are defined */
+    public static final long  CKH_MONOTONIC_COUNTER = 0x00000001L;
+    public static final long  CKH_CLOCK             = 0x00000002L;
+    public static final long  CKH_VENDOR_DEFINED    = 0x80000000L;
+
+    /* the following key types are defined: */
+    public static final long  CKK_RSA             = 0x00000000L;
+    public static final long  CKK_DSA             = 0x00000001L;
+    public static final long  CKK_DH              = 0x00000002L;
+
+    /* CKK_ECDSA and CKK_KEA are new for v2.0 */
+    /* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
+    public static final long  CKK_ECDSA           = 0x00000003L;
+    public static final long  CKK_EC              = 0x00000003L;
+    public static final long  CKK_X9_42_DH        = 0x00000004L;
+    public static final long  CKK_KEA             = 0x00000005L;
+
+    public static final long  CKK_GENERIC_SECRET  = 0x00000010L;
+    public static final long  CKK_RC2             = 0x00000011L;
+    public static final long  CKK_RC4             = 0x00000012L;
+    public static final long  CKK_DES             = 0x00000013L;
+    public static final long  CKK_DES2            = 0x00000014L;
+    public static final long  CKK_DES3            = 0x00000015L;
+
+    /* all these key types are new for v2.0 */
+    public static final long  CKK_CAST            = 0x00000016L;
+    public static final long  CKK_CAST3           = 0x00000017L;
+    /* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
+    public static final long  CKK_CAST5           = 0x00000018L;
+    /* CAST128=CAST5 */
+    public static final long  CKK_CAST128         = 0x00000018L;
+    public static final long  CKK_RC5             = 0x00000019L;
+    public static final long  CKK_IDEA            = 0x0000001AL;
+    public static final long  CKK_SKIPJACK        = 0x0000001BL;
+    public static final long  CKK_BATON           = 0x0000001CL;
+    public static final long  CKK_JUNIPER         = 0x0000001DL;
+    public static final long  CKK_CDMF            = 0x0000001EL;
+    public static final long  CKK_AES             = 0x0000001FL;
+    // v2.20
+    public static final long  CKK_BLOWFISH        = 0x00000020L;
+
+    public static final long  CKK_VENDOR_DEFINED  = 0x80000000L;
+
+    // new for v2.20 amendment 3
+    //public static final long  CKK_CAMELLIA          = 0x00000025L;
+    //public static final long  CKK_ARIA              = 0x00000026L;
+
+    // pseudo key type ANY (for template manager)
+    public static final long  PCKK_ANY            = 0x7FFFFF22L;
+
+    public static final long  PCKK_HMAC            = 0x7FFFFF23L;
+    public static final long  PCKK_SSLMAC          = 0x7FFFFF24L;
+    public static final long  PCKK_TLSPREMASTER    = 0x7FFFFF25L;
+    public static final long  PCKK_TLSRSAPREMASTER = 0x7FFFFF26L;
+    public static final long  PCKK_TLSMASTER       = 0x7FFFFF27L;
+
+    /* The following certificate types are defined: */
+    /* CKC_X_509_ATTR_CERT is new for v2.10 */
+    public static final long  CKC_X_509           = 0x00000000L;
+    public static final long  CKC_X_509_ATTR_CERT = 0x00000001L;
+    public static final long  CKC_VENDOR_DEFINED  = 0x80000000L;
+
+
+    /* The following attribute types are defined: */
+    public static final long  CKA_CLASS              = 0x00000000L;
+    public static final long  CKA_TOKEN              = 0x00000001L;
+    public static final long  CKA_PRIVATE            = 0x00000002L;
+    public static final long  CKA_LABEL              = 0x00000003L;
+    public static final long  CKA_APPLICATION        = 0x00000010L;
+    public static final long  CKA_VALUE              = 0x00000011L;
+
+    /* CKA_OBJECT_ID is new for v2.10 */
+    public static final long  CKA_OBJECT_ID          = 0x00000012L;
+
+    public static final long  CKA_CERTIFICATE_TYPE   = 0x00000080L;
+    public static final long  CKA_ISSUER             = 0x00000081L;
+    public static final long  CKA_SERIAL_NUMBER      = 0x00000082L;
+
+    /* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new L;
+     * for v2.10 */
+    public static final long  CKA_AC_ISSUER          = 0x00000083L;
+    public static final long  CKA_OWNER              = 0x00000084L;
+    public static final long  CKA_ATTR_TYPES         = 0x00000085L;
+
+    /* CKA_TRUSTED is new for v2.11 */
+    public static final long  CKA_TRUSTED            = 0x00000086L;
+
+    public static final long  CKA_KEY_TYPE           = 0x00000100L;
+    public static final long  CKA_SUBJECT            = 0x00000101L;
+    public static final long  CKA_ID                 = 0x00000102L;
+    public static final long  CKA_SENSITIVE          = 0x00000103L;
+    public static final long  CKA_ENCRYPT            = 0x00000104L;
+    public static final long  CKA_DECRYPT            = 0x00000105L;
+    public static final long  CKA_WRAP               = 0x00000106L;
+    public static final long  CKA_UNWRAP             = 0x00000107L;
+    public static final long  CKA_SIGN               = 0x00000108L;
+    public static final long  CKA_SIGN_RECOVER       = 0x00000109L;
+    public static final long  CKA_VERIFY             = 0x0000010AL;
+    public static final long  CKA_VERIFY_RECOVER     = 0x0000010BL;
+    public static final long  CKA_DERIVE             = 0x0000010CL;
+    public static final long  CKA_START_DATE         = 0x00000110L;
+    public static final long  CKA_END_DATE           = 0x00000111L;
+    public static final long  CKA_MODULUS            = 0x00000120L;
+    public static final long  CKA_MODULUS_BITS       = 0x00000121L;
+    public static final long  CKA_PUBLIC_EXPONENT    = 0x00000122L;
+    public static final long  CKA_PRIVATE_EXPONENT   = 0x00000123L;
+    public static final long  CKA_PRIME_1            = 0x00000124L;
+    public static final long  CKA_PRIME_2            = 0x00000125L;
+    public static final long  CKA_EXPONENT_1         = 0x00000126L;
+    public static final long  CKA_EXPONENT_2         = 0x00000127L;
+    public static final long  CKA_COEFFICIENT        = 0x00000128L;
+    public static final long  CKA_PRIME              = 0x00000130L;
+    public static final long  CKA_SUBPRIME           = 0x00000131L;
+    public static final long  CKA_BASE               = 0x00000132L;
+
+    /* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+    public static final long  CKA_PRIME_BITS         = 0x00000133L;
+    public static final long  CKA_SUB_PRIME_BITS     = 0x00000134L;
+
+    public static final long  CKA_VALUE_BITS         = 0x00000160L;
+    public static final long  CKA_VALUE_LEN          = 0x00000161L;
+
+    /* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
+     * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+     * and CKA_EC_POINT are new for v2.0 */
+    public static final long  CKA_EXTRACTABLE        = 0x00000162L;
+    public static final long  CKA_LOCAL              = 0x00000163L;
+    public static final long  CKA_NEVER_EXTRACTABLE  = 0x00000164L;
+    public static final long  CKA_ALWAYS_SENSITIVE   = 0x00000165L;
+
+    /* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+    public static final long  CKA_KEY_GEN_MECHANISM  = 0x00000166L;
+
+    public static final long  CKA_MODIFIABLE         = 0x00000170L;
+
+    /* CKA_ECDSA_PARAMS is deprecated in v2.11,
+     * CKA_EC_PARAMS is preferred. */
+    public static final long  CKA_ECDSA_PARAMS       = 0x00000180L;
+    public static final long  CKA_EC_PARAMS          = 0x00000180L;
+    public static final long  CKA_EC_POINT           = 0x00000181L;
+
+    /* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
+     * CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+     * are new for v2.10 */
+    public static final long  CKA_SECONDARY_AUTH     = 0x00000200L;
+    public static final long  CKA_AUTH_PIN_FLAGS     = 0x00000201L;
+    public static final long  CKA_HW_FEATURE_TYPE    = 0x00000300L;
+    public static final long  CKA_RESET_ON_INIT      = 0x00000301L;
+    public static final long  CKA_HAS_RESET          = 0x00000302L;
+
+    public static final long  CKA_VENDOR_DEFINED     = 0x80000000L;
+
+    /* the following mechanism types are defined: */
+    public static final long  CKM_RSA_PKCS_KEY_PAIR_GEN      = 0x00000000L;
+    public static final long  CKM_RSA_PKCS                   = 0x00000001L;
+    public static final long  CKM_RSA_9796                   = 0x00000002L;
+    public static final long  CKM_RSA_X_509                  = 0x00000003L;
+
+    /* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
+     * are new for v2.0.  They are mechanisms which hash and sign */
+    public static final long  CKM_MD2_RSA_PKCS               = 0x00000004L;
+    public static final long  CKM_MD5_RSA_PKCS               = 0x00000005L;
+    public static final long  CKM_SHA1_RSA_PKCS              = 0x00000006L;
+
+    /* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
+     * CKM_RSA_PKCS_OAEP are new for v2.10 */
+    public static final long  CKM_RIPEMD128_RSA_PKCS         = 0x00000007L;
+    public static final long  CKM_RIPEMD160_RSA_PKCS         = 0x00000008L;
+    public static final long  CKM_RSA_PKCS_OAEP              = 0x00000009L;
+
+    /* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
+     * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
+    public static final long  CKM_RSA_X9_31_KEY_PAIR_GEN     = 0x0000000AL;
+    public static final long  CKM_RSA_X9_31                  = 0x0000000BL;
+    public static final long  CKM_SHA1_RSA_X9_31             = 0x0000000CL;
+    public static final long  CKM_RSA_PKCS_PSS               = 0x0000000DL;
+    public static final long  CKM_SHA1_RSA_PKCS_PSS          = 0x0000000EL;
+
+    public static final long  CKM_DSA_KEY_PAIR_GEN           = 0x00000010L;
+    public static final long  CKM_DSA                        = 0x00000011L;
+    public static final long  CKM_DSA_SHA1                   = 0x00000012L;
+    public static final long  CKM_DH_PKCS_KEY_PAIR_GEN       = 0x00000020L;
+    public static final long  CKM_DH_PKCS_DERIVE             = 0x00000021L;
+
+    /* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+     * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
+     * v2.11 */
+    public static final long  CKM_X9_42_DH_KEY_PAIR_GEN      = 0x00000030L;
+    public static final long  CKM_X9_42_DH_DERIVE            = 0x00000031L;
+    public static final long  CKM_X9_42_DH_HYBRID_DERIVE     = 0x00000032L;
+    public static final long  CKM_X9_42_MQV_DERIVE           = 0x00000033L;
+
+    // v2.20
+    public static final long  CKM_SHA256_RSA_PKCS            = 0x00000040L;
+    public static final long  CKM_SHA384_RSA_PKCS            = 0x00000041L;
+    public static final long  CKM_SHA512_RSA_PKCS            = 0x00000042L;
+
+    public static final long  CKM_RC2_KEY_GEN                = 0x00000100L;
+    public static final long  CKM_RC2_ECB                    = 0x00000101L;
+    public static final long  CKM_RC2_CBC                    = 0x00000102L;
+    public static final long  CKM_RC2_MAC                    = 0x00000103L;
+
+    /* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
+    public static final long  CKM_RC2_MAC_GENERAL            = 0x00000104L;
+    public static final long  CKM_RC2_CBC_PAD                = 0x00000105L;
+
+    public static final long  CKM_RC4_KEY_GEN                = 0x00000110L;
+    public static final long  CKM_RC4                        = 0x00000111L;
+    public static final long  CKM_DES_KEY_GEN                = 0x00000120L;
+    public static final long  CKM_DES_ECB                    = 0x00000121L;
+    public static final long  CKM_DES_CBC                    = 0x00000122L;
+    public static final long  CKM_DES_MAC                    = 0x00000123L;
+
+    /* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
+    public static final long  CKM_DES_MAC_GENERAL            = 0x00000124L;
+    public static final long  CKM_DES_CBC_PAD                = 0x00000125L;
+
+    public static final long  CKM_DES2_KEY_GEN               = 0x00000130L;
+    public static final long  CKM_DES3_KEY_GEN               = 0x00000131L;
+    public static final long  CKM_DES3_ECB                   = 0x00000132L;
+    public static final long  CKM_DES3_CBC                   = 0x00000133L;
+    public static final long  CKM_DES3_MAC                   = 0x00000134L;
+
+    /* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
+     * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
+     * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
+    public static final long  CKM_DES3_MAC_GENERAL           = 0x00000135L;
+    public static final long  CKM_DES3_CBC_PAD               = 0x00000136L;
+    public static final long  CKM_CDMF_KEY_GEN               = 0x00000140L;
+    public static final long  CKM_CDMF_ECB                   = 0x00000141L;
+    public static final long  CKM_CDMF_CBC                   = 0x00000142L;
+    public static final long  CKM_CDMF_MAC                   = 0x00000143L;
+    public static final long  CKM_CDMF_MAC_GENERAL           = 0x00000144L;
+    public static final long  CKM_CDMF_CBC_PAD               = 0x00000145L;
+
+    public static final long  CKM_MD2                        = 0x00000200L;
+
+    /* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
+    public static final long  CKM_MD2_HMAC                   = 0x00000201L;
+    public static final long  CKM_MD2_HMAC_GENERAL           = 0x00000202L;
+
+    public static final long  CKM_MD5                        = 0x00000210L;
+
+    /* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
+    public static final long  CKM_MD5_HMAC                   = 0x00000211L;
+    public static final long  CKM_MD5_HMAC_GENERAL           = 0x00000212L;
+
+    public static final long  CKM_SHA_1                      = 0x00000220L;
+
+    /* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
+    public static final long  CKM_SHA_1_HMAC                 = 0x00000221L;
+    public static final long  CKM_SHA_1_HMAC_GENERAL         = 0x00000222L;
+
+    /* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
+     * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
+     * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
+    public static final long  CKM_RIPEMD128                  = 0x00000230L;
+    public static final long  CKM_RIPEMD128_HMAC             = 0x00000231L;
+    public static final long  CKM_RIPEMD128_HMAC_GENERAL     = 0x00000232L;
+    public static final long  CKM_RIPEMD160                  = 0x00000240L;
+    public static final long  CKM_RIPEMD160_HMAC             = 0x00000241L;
+    public static final long  CKM_RIPEMD160_HMAC_GENERAL     = 0x00000242L;
+
+    // v2.20
+    public static final long  CKM_SHA256                     = 0x00000250L;
+    public static final long  CKM_SHA256_HMAC                = 0x00000251L;
+    public static final long  CKM_SHA256_HMAC_GENERAL        = 0x00000252L;
+
+    public static final long  CKM_SHA384                     = 0x00000260L;
+    public static final long  CKM_SHA384_HMAC                = 0x00000261L;
+    public static final long  CKM_SHA384_HMAC_GENERAL        = 0x00000262L;
+
+    public static final long  CKM_SHA512                     = 0x00000270L;
+    public static final long  CKM_SHA512_HMAC                = 0x00000271L;
+    public static final long  CKM_SHA512_HMAC_GENERAL        = 0x00000272L;
+
+    /* All of the following mechanisms are new for v2.0 */
+    /* Note that CAST128 and CAST5 are the same algorithm */
+    public static final long  CKM_CAST_KEY_GEN               = 0x00000300L;
+    public static final long  CKM_CAST_ECB                   = 0x00000301L;
+    public static final long  CKM_CAST_CBC                   = 0x00000302L;
+    public static final long  CKM_CAST_MAC                   = 0x00000303L;
+    public static final long  CKM_CAST_MAC_GENERAL           = 0x00000304L;
+    public static final long  CKM_CAST_CBC_PAD               = 0x00000305L;
+    public static final long  CKM_CAST3_KEY_GEN              = 0x00000310L;
+    public static final long  CKM_CAST3_ECB                  = 0x00000311L;
+    public static final long  CKM_CAST3_CBC                  = 0x00000312L;
+    public static final long  CKM_CAST3_MAC                  = 0x00000313L;
+    public static final long  CKM_CAST3_MAC_GENERAL          = 0x00000314L;
+    public static final long  CKM_CAST3_CBC_PAD              = 0x00000315L;
+    public static final long  CKM_CAST5_KEY_GEN              = 0x00000320L;
+    public static final long  CKM_CAST128_KEY_GEN            = 0x00000320L;
+    public static final long  CKM_CAST5_ECB                  = 0x00000321L;
+    public static final long  CKM_CAST128_ECB                = 0x00000321L;
+    public static final long  CKM_CAST5_CBC                  = 0x00000322L;
+    public static final long  CKM_CAST128_CBC                = 0x00000322L;
+    public static final long  CKM_CAST5_MAC                  = 0x00000323L;
+    public static final long  CKM_CAST128_MAC                = 0x00000323L;
+    public static final long  CKM_CAST5_MAC_GENERAL          = 0x00000324L;
+    public static final long  CKM_CAST128_MAC_GENERAL        = 0x00000324L;
+    public static final long  CKM_CAST5_CBC_PAD              = 0x00000325L;
+    public static final long  CKM_CAST128_CBC_PAD            = 0x00000325L;
+    public static final long  CKM_RC5_KEY_GEN                = 0x00000330L;
+    public static final long  CKM_RC5_ECB                    = 0x00000331L;
+    public static final long  CKM_RC5_CBC                    = 0x00000332L;
+    public static final long  CKM_RC5_MAC                    = 0x00000333L;
+    public static final long  CKM_RC5_MAC_GENERAL            = 0x00000334L;
+    public static final long  CKM_RC5_CBC_PAD                = 0x00000335L;
+    public static final long  CKM_IDEA_KEY_GEN               = 0x00000340L;
+    public static final long  CKM_IDEA_ECB                   = 0x00000341L;
+    public static final long  CKM_IDEA_CBC                   = 0x00000342L;
+    public static final long  CKM_IDEA_MAC                   = 0x00000343L;
+    public static final long  CKM_IDEA_MAC_GENERAL           = 0x00000344L;
+    public static final long  CKM_IDEA_CBC_PAD               = 0x00000345L;
+    public static final long  CKM_GENERIC_SECRET_KEY_GEN     = 0x00000350L;
+    public static final long  CKM_CONCATENATE_BASE_AND_KEY   = 0x00000360L;
+    public static final long  CKM_CONCATENATE_BASE_AND_DATA  = 0x00000362L;
+    public static final long  CKM_CONCATENATE_DATA_AND_BASE  = 0x00000363L;
+    public static final long  CKM_XOR_BASE_AND_DATA          = 0x00000364L;
+    public static final long  CKM_EXTRACT_KEY_FROM_KEY       = 0x00000365L;
+    public static final long  CKM_SSL3_PRE_MASTER_KEY_GEN    = 0x00000370L;
+    public static final long  CKM_SSL3_MASTER_KEY_DERIVE     = 0x00000371L;
+    public static final long  CKM_SSL3_KEY_AND_MAC_DERIVE    = 0x00000372L;
+
+    /* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
+     * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
+     * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
+    public static final long  CKM_SSL3_MASTER_KEY_DERIVE_DH  = 0x00000373L;
+    public static final long  CKM_TLS_PRE_MASTER_KEY_GEN     = 0x00000374L;
+    public static final long  CKM_TLS_MASTER_KEY_DERIVE      = 0x00000375L;
+    public static final long  CKM_TLS_KEY_AND_MAC_DERIVE     = 0x00000376L;
+    public static final long  CKM_TLS_MASTER_KEY_DERIVE_DH   = 0x00000377L;
+    public static final long  CKM_TLS_PRF                    = 0x00000378L;
+
+    public static final long  CKM_SSL3_MD5_MAC               = 0x00000380L;
+    public static final long  CKM_SSL3_SHA1_MAC              = 0x00000381L;
+    public static final long  CKM_MD5_KEY_DERIVATION         = 0x00000390L;
+    public static final long  CKM_MD2_KEY_DERIVATION         = 0x00000391L;
+    public static final long  CKM_SHA1_KEY_DERIVATION        = 0x00000392L;
+
+    // v2.20
+    public static final long  CKM_SHA256_KEY_DERIVATION      = 0x00000393L;
+    public static final long  CKM_SHA384_KEY_DERIVATION      = 0x00000394L;
+    public static final long  CKM_SHA512_KEY_DERIVATION      = 0x00000395L;
+
+    public static final long  CKM_PBE_MD2_DES_CBC            = 0x000003A0L;
+    public static final long  CKM_PBE_MD5_DES_CBC            = 0x000003A1L;
+    public static final long  CKM_PBE_MD5_CAST_CBC           = 0x000003A2L;
+    public static final long  CKM_PBE_MD5_CAST3_CBC          = 0x000003A3L;
+    public static final long  CKM_PBE_MD5_CAST5_CBC          = 0x000003A4L;
+    public static final long  CKM_PBE_MD5_CAST128_CBC        = 0x000003A4L;
+    public static final long  CKM_PBE_SHA1_CAST5_CBC         = 0x000003A5L;
+    public static final long  CKM_PBE_SHA1_CAST128_CBC       = 0x000003A5L;
+    public static final long  CKM_PBE_SHA1_RC4_128           = 0x000003A6L;
+    public static final long  CKM_PBE_SHA1_RC4_40            = 0x000003A7L;
+    public static final long  CKM_PBE_SHA1_DES3_EDE_CBC      = 0x000003A8L;
+    public static final long  CKM_PBE_SHA1_DES2_EDE_CBC      = 0x000003A9L;
+    public static final long  CKM_PBE_SHA1_RC2_128_CBC       = 0x000003AAL;
+    public static final long  CKM_PBE_SHA1_RC2_40_CBC        = 0x000003ABL;
+
+    /* CKM_PKCS5_PBKD2 is new for v2.10 */
+    public static final long  CKM_PKCS5_PBKD2                = 0x000003B0L;
+
+    public static final long  CKM_PBA_SHA1_WITH_SHA1_HMAC    = 0x000003C0L;
+    public static final long  CKM_KEY_WRAP_LYNKS             = 0x00000400L;
+    public static final long  CKM_KEY_WRAP_SET_OAEP          = 0x00000401L;
+
+    /* Fortezza mechanisms */
+    public static final long  CKM_SKIPJACK_KEY_GEN           = 0x00001000L;
+    public static final long  CKM_SKIPJACK_ECB64             = 0x00001001L;
+    public static final long  CKM_SKIPJACK_CBC64             = 0x00001002L;
+    public static final long  CKM_SKIPJACK_OFB64             = 0x00001003L;
+    public static final long  CKM_SKIPJACK_CFB64             = 0x00001004L;
+    public static final long  CKM_SKIPJACK_CFB32             = 0x00001005L;
+    public static final long  CKM_SKIPJACK_CFB16             = 0x00001006L;
+    public static final long  CKM_SKIPJACK_CFB8              = 0x00001007L;
+    public static final long  CKM_SKIPJACK_WRAP              = 0x00001008L;
+    public static final long  CKM_SKIPJACK_PRIVATE_WRAP      = 0x00001009L;
+    public static final long  CKM_SKIPJACK_RELAYX            = 0x0000100AL;
+    public static final long  CKM_KEA_KEY_PAIR_GEN           = 0x00001010L;
+    public static final long  CKM_KEA_KEY_DERIVE             = 0x00001011L;
+    public static final long  CKM_FORTEZZA_TIMESTAMP         = 0x00001020L;
+    public static final long  CKM_BATON_KEY_GEN              = 0x00001030L;
+    public static final long  CKM_BATON_ECB128               = 0x00001031L;
+    public static final long  CKM_BATON_ECB96                = 0x00001032L;
+    public static final long  CKM_BATON_CBC128               = 0x00001033L;
+    public static final long  CKM_BATON_COUNTER              = 0x00001034L;
+    public static final long  CKM_BATON_SHUFFLE              = 0x00001035L;
+    public static final long  CKM_BATON_WRAP                 = 0x00001036L;
+
+    /* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
+     * CKM_EC_KEY_PAIR_GEN is preferred */
+    public static final long  CKM_ECDSA_KEY_PAIR_GEN         = 0x00001040L;
+    public static final long  CKM_EC_KEY_PAIR_GEN            = 0x00001040L;
+
+    public static final long  CKM_ECDSA                      = 0x00001041L;
+    public static final long  CKM_ECDSA_SHA1                 = 0x00001042L;
+
+    /* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
+     * are new for v2.11 */
+    public static final long  CKM_ECDH1_DERIVE               = 0x00001050L;
+    public static final long  CKM_ECDH1_COFACTOR_DERIVE      = 0x00001051L;
+    public static final long  CKM_ECMQV_DERIVE               = 0x00001052L;
+
+    public static final long  CKM_JUNIPER_KEY_GEN            = 0x00001060L;
+    public static final long  CKM_JUNIPER_ECB128             = 0x00001061L;
+    public static final long  CKM_JUNIPER_CBC128             = 0x00001062L;
+    public static final long  CKM_JUNIPER_COUNTER            = 0x00001063L;
+    public static final long  CKM_JUNIPER_SHUFFLE            = 0x00001064L;
+    public static final long  CKM_JUNIPER_WRAP               = 0x00001065L;
+    public static final long  CKM_FASTHASH                   = 0x00001070L;
+
+    /* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
+     * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
+     * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
+     * new for v2.11 */
+    public static final long  CKM_AES_KEY_GEN                = 0x00001080L;
+    public static final long  CKM_AES_ECB                    = 0x00001081L;
+    public static final long  CKM_AES_CBC                    = 0x00001082L;
+    public static final long  CKM_AES_MAC                    = 0x00001083L;
+    public static final long  CKM_AES_MAC_GENERAL            = 0x00001084L;
+    public static final long  CKM_AES_CBC_PAD                = 0x00001085L;
+    // v2.20
+    public static final long  CKM_BLOWFISH_KEY_GEN           = 0x00001090L;
+    public static final long  CKM_BLOWFISH_CBC               = 0x00001091L;
+    public static final long  CKM_DSA_PARAMETER_GEN          = 0x00002000L;
+    public static final long  CKM_DH_PKCS_PARAMETER_GEN      = 0x00002001L;
+    public static final long  CKM_X9_42_DH_PARAMETER_GEN     = 0x00002002L;
+
+    public static final long  CKM_VENDOR_DEFINED             = 0x80000000L;
+
+    // new for v2.20 amendment 3
+    public static final long  CKM_SHA224                     = 0x00000255L;
+    public static final long  CKM_SHA224_HMAC                = 0x00000256L;
+    public static final long  CKM_SHA224_HMAC_GENERAL        = 0x00000257L;
+    public static final long  CKM_SHA224_KEY_DERIVATION      = 0x00000396L;
+    public static final long  CKM_SHA224_RSA_PKCS            = 0x00000046L;
+    public static final long  CKM_SHA224_RSA_PKCS_PSS        = 0x00000047L;
+    public static final long  CKM_AES_CTR                    = 0x00001086L;
+    /*
+    public static final long  CKM_CAMELLIA_KEY_GEN           = 0x00000550L;
+    public static final long  CKM_CAMELLIA_ECB               = 0x00000551L;
+    public static final long  CKM_CAMELLIA_CBC               = 0x00000552L;
+    public static final long  CKM_CAMELLIA_MAC               = 0x00000553L;
+    public static final long  CKM_CAMELLIA_MAC_GENERAL       = 0x00000554L;
+    public static final long  CKM_CAMELLIA_CBC_PAD           = 0x00000555L;
+    public static final long  CKM_CAMELLIA_ECB_ENCRYPT_DATA  = 0x00000556L;
+    public static final long  CKM_CAMELLIA_CBC_ENCRYPT_DATA  = 0x00000557L;
+    public static final long  CKM_CAMELLIA_CTR               = 0x00000558L;
+    public static final long  CKM_ARIA_KEY_GEN               = 0x00000560L;
+    public static final long  CKM_ARIA_ECB                   = 0x00000561L;
+    public static final long  CKM_ARIA_CBC                   = 0x00000562L;
+    public static final long  CKM_ARIA_MAC                   = 0x00000563L;
+    public static final long  CKM_ARIA_MAC_GENERAL           = 0x00000564L;
+    public static final long  CKM_ARIA_CBC_PAD               = 0x00000565L;
+    public static final long  CKM_ARIA_ECB_ENCRYPT_DATA      = 0x00000566L;
+    public static final long  CKM_ARIA_CBC_ENCRYPT_DATA      = 0x00000567L;
+    */
+
+    // NSS private
+    public static final long  CKM_NSS_TLS_PRF_GENERAL        = 0x80000373L;
+
+    // ids for our pseudo mechanisms SecureRandom and KeyStore
+    public static final long  PCKM_SECURERANDOM              = 0x7FFFFF20L;
+    public static final long  PCKM_KEYSTORE                  = 0x7FFFFF21L;
+
+    /* The flags are defined as follows:
+     *      Bit Flag               Mask        Meaning */
+    /* performed by HW */
+    public static final long  CKF_HW                 = 0x00000001L;
+
+    /* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
+     * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
+     * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
+     * and CKF_DERIVE are new for v2.0.  They specify whether or not
+     * a mechanism can be used for a particular task */
+    public static final long  CKF_ENCRYPT            = 0x00000100L;
+    public static final long  CKF_DECRYPT            = 0x00000200L;
+    public static final long  CKF_DIGEST             = 0x00000400L;
+    public static final long  CKF_SIGN               = 0x00000800L;
+    public static final long  CKF_SIGN_RECOVER       = 0x00001000L;
+    public static final long  CKF_VERIFY             = 0x00002000L;
+    public static final long  CKF_VERIFY_RECOVER     = 0x00004000L;
+    public static final long  CKF_GENERATE           = 0x00008000L;
+    public static final long  CKF_GENERATE_KEY_PAIR  = 0x00010000L;
+    public static final long  CKF_WRAP               = 0x00020000L;
+    public static final long  CKF_UNWRAP             = 0x00040000L;
+    public static final long  CKF_DERIVE             = 0x00080000L;
+
+    /* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+     * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
+     * describe a token's EC capabilities not available in mechanism
+     * information. */
+    public static final long  CKF_EC_F_P              = 0x00100000L;
+    public static final long  CKF_EC_F_2M           = 0x00200000L;
+    public static final long  CKF_EC_ECPARAMETERS   = 0x00400000L;
+    public static final long  CKF_EC_NAMEDCURVE     = 0x00800000L;
+    public static final long  CKF_EC_UNCOMPRESS     = 0x01000000L;
+    public static final long  CKF_EC_COMPRESS       = 0x02000000L;
+
+    /* FALSE for 2.01 */
+    public static final long  CKF_EXTENSION          = 0x80000000L;
+
+
+    /* CK_RV is a value that identifies the return value of a
+     * Cryptoki function */
+    /* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
+    public static final long  CKR_OK                                = 0x00000000L;
+    public static final long  CKR_CANCEL                            = 0x00000001L;
+    public static final long  CKR_HOST_MEMORY                       = 0x00000002L;
+    public static final long  CKR_SLOT_ID_INVALID                   = 0x00000003L;
+
+    /* CKR_FLAGS_INVALID was removed for v2.0 */
+
+    /* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
+    public static final long  CKR_GENERAL_ERROR                     = 0x00000005L;
+    public static final long  CKR_FUNCTION_FAILED                   = 0x00000006L;
+
+    /* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
+     * and CKR_CANT_LOCK are new for v2.01 */
+    public static final long  CKR_ARGUMENTS_BAD                     = 0x00000007L;
+    public static final long  CKR_NO_EVENT                          = 0x00000008L;
+    public static final long  CKR_NEED_TO_CREATE_THREADS            = 0x00000009L;
+    public static final long  CKR_CANT_LOCK                         = 0x0000000AL;
+
+    public static final long  CKR_ATTRIBUTE_READ_ONLY               = 0x00000010L;
+    public static final long  CKR_ATTRIBUTE_SENSITIVE               = 0x00000011L;
+    public static final long  CKR_ATTRIBUTE_TYPE_INVALID            = 0x00000012L;
+    public static final long  CKR_ATTRIBUTE_VALUE_INVALID           = 0x00000013L;
+    public static final long  CKR_DATA_INVALID                      = 0x00000020L;
+    public static final long  CKR_DATA_LEN_RANGE                    = 0x00000021L;
+    public static final long  CKR_DEVICE_ERROR                      = 0x00000030L;
+    public static final long  CKR_DEVICE_MEMORY                     = 0x00000031L;
+    public static final long  CKR_DEVICE_REMOVED                    = 0x00000032L;
+    public static final long  CKR_ENCRYPTED_DATA_INVALID            = 0x00000040L;
+    public static final long  CKR_ENCRYPTED_DATA_LEN_RANGE          = 0x00000041L;
+    public static final long  CKR_FUNCTION_CANCELED                 = 0x00000050L;
+    public static final long  CKR_FUNCTION_NOT_PARALLEL             = 0x00000051L;
+
+    /* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
+    public static final long  CKR_FUNCTION_NOT_SUPPORTED            = 0x00000054L;
+
+    public static final long  CKR_KEY_HANDLE_INVALID                = 0x00000060L;
+
+    /* CKR_KEY_SENSITIVE was removed for v2.0 */
+
+    public static final long  CKR_KEY_SIZE_RANGE                    = 0x00000062L;
+    public static final long  CKR_KEY_TYPE_INCONSISTENT             = 0x00000063L;
+
+    /* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
+     * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
+     * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
+     * v2.0 */
+    public static final long  CKR_KEY_NOT_NEEDED                    = 0x00000064L;
+    public static final long  CKR_KEY_CHANGED                       = 0x00000065L;
+    public static final long  CKR_KEY_NEEDED                        = 0x00000066L;
+    public static final long  CKR_KEY_INDIGESTIBLE                  = 0x00000067L;
+    public static final long  CKR_KEY_FUNCTION_NOT_PERMITTED        = 0x00000068L;
+    public static final long  CKR_KEY_NOT_WRAPPABLE                 = 0x00000069L;
+    public static final long  CKR_KEY_UNEXTRACTABLE                 = 0x0000006AL;
+
+    public static final long  CKR_MECHANISM_INVALID                 = 0x00000070L;
+    public static final long  CKR_MECHANISM_PARAM_INVALID           = 0x00000071L;
+
+    /* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
+     * were removed for v2.0 */
+    public static final long  CKR_OBJECT_HANDLE_INVALID             = 0x00000082L;
+    public static final long  CKR_OPERATION_ACTIVE                  = 0x00000090L;
+    public static final long  CKR_OPERATION_NOT_INITIALIZED         = 0x00000091L;
+    public static final long  CKR_PIN_INCORRECT                     = 0x000000A0L;
+    public static final long  CKR_PIN_INVALID                       = 0x000000A1L;
+    public static final long  CKR_PIN_LEN_RANGE                     = 0x000000A2L;
+
+    /* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
+    public static final long  CKR_PIN_EXPIRED                       = 0x000000A3L;
+    public static final long  CKR_PIN_LOCKED                        = 0x000000A4L;
+
+    public static final long  CKR_SESSION_CLOSED                    = 0x000000B0L;
+    public static final long  CKR_SESSION_COUNT                     = 0x000000B1L;
+    public static final long  CKR_SESSION_HANDLE_INVALID            = 0x000000B3L;
+    public static final long  CKR_SESSION_PARALLEL_NOT_SUPPORTED    = 0x000000B4L;
+    public static final long  CKR_SESSION_READ_ONLY                 = 0x000000B5L;
+    public static final long  CKR_SESSION_EXISTS                    = 0x000000B6L;
+
+    /* CKR_SESSION_READ_ONLY_EXISTS and
+     * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
+    public static final long  CKR_SESSION_READ_ONLY_EXISTS          = 0x000000B7L;
+    public static final long  CKR_SESSION_READ_WRITE_SO_EXISTS      = 0x000000B8L;
+
+    public static final long  CKR_SIGNATURE_INVALID                 = 0x000000C0L;
+    public static final long  CKR_SIGNATURE_LEN_RANGE               = 0x000000C1L;
+    public static final long  CKR_TEMPLATE_INCOMPLETE               = 0x000000D0L;
+    public static final long  CKR_TEMPLATE_INCONSISTENT             = 0x000000D1L;
+    public static final long  CKR_TOKEN_NOT_PRESENT                 = 0x000000E0L;
+    public static final long  CKR_TOKEN_NOT_RECOGNIZED              = 0x000000E1L;
+    public static final long  CKR_TOKEN_WRITE_PROTECTED             = 0x000000E2L;
+    public static final long  CKR_UNWRAPPING_KEY_HANDLE_INVALID     = 0x000000F0L;
+    public static final long  CKR_UNWRAPPING_KEY_SIZE_RANGE         = 0x000000F1L;
+    public static final long  CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  = 0x000000F2L;
+    public static final long  CKR_USER_ALREADY_LOGGED_IN            = 0x00000100L;
+    public static final long  CKR_USER_NOT_LOGGED_IN                = 0x00000101L;
+    public static final long  CKR_USER_PIN_NOT_INITIALIZED          = 0x00000102L;
+    public static final long  CKR_USER_TYPE_INVALID                 = 0x00000103L;
+
+    /* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
+     * are new to v2.01 */
+    public static final long  CKR_USER_ANOTHER_ALREADY_LOGGED_IN    = 0x00000104L;
+    public static final long  CKR_USER_TOO_MANY_TYPES               = 0x00000105L;
+
+    public static final long  CKR_WRAPPED_KEY_INVALID               = 0x00000110L;
+    public static final long  CKR_WRAPPED_KEY_LEN_RANGE             = 0x00000112L;
+    public static final long  CKR_WRAPPING_KEY_HANDLE_INVALID       = 0x00000113L;
+    public static final long  CKR_WRAPPING_KEY_SIZE_RANGE           = 0x00000114L;
+    public static final long  CKR_WRAPPING_KEY_TYPE_INCONSISTENT    = 0x00000115L;
+    public static final long  CKR_RANDOM_SEED_NOT_SUPPORTED         = 0x00000120L;
+
+    /* These are new to v2.0 */
+    public static final long  CKR_RANDOM_NO_RNG                     = 0x00000121L;
+
+    /* These are new to v2.11 */
+    public static final long  CKR_DOMAIN_PARAMS_INVALID             = 0x00000130L;
+
+    /* These are new to v2.0 */
+    public static final long  CKR_BUFFER_TOO_SMALL                  = 0x00000150L;
+    public static final long  CKR_SAVED_STATE_INVALID               = 0x00000160L;
+    public static final long  CKR_INFORMATION_SENSITIVE             = 0x00000170L;
+    public static final long  CKR_STATE_UNSAVEABLE                  = 0x00000180L;
+
+    /* These are new to v2.01 */
+    public static final long  CKR_CRYPTOKI_NOT_INITIALIZED          = 0x00000190L;
+    public static final long  CKR_CRYPTOKI_ALREADY_INITIALIZED      = 0x00000191L;
+    public static final long  CKR_MUTEX_BAD                         = 0x000001A0L;
+    public static final long  CKR_MUTEX_NOT_LOCKED                  = 0x000001A1L;
+
+    public static final long  CKR_VENDOR_DEFINED                    = 0x80000000L;
+
+
+    /* flags: bit flags that provide capabilities of the slot
+     *        Bit Flag = Mask
+     */
+    public static final long  CKF_LIBRARY_CANT_CREATE_OS_THREADS = 0x00000001L;
+    public static final long  CKF_OS_LOCKING_OK                  = 0x00000002L;
+
+
+    /* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+    public static final long  CKF_DONT_BLOCK =    1L;
+
+
+    /* The following MGFs are defined */
+    public static final long  CKG_MGF1_SHA1       =  0x00000001L;
+    // new for v2.20 amendment 3
+    public static final long  CKG_MGF1_SHA224     = 0x00000005L;
+
+    /* The following encoding parameter sources are defined */
+    public static final long  CKZ_DATA_SPECIFIED   = 0x00000001L;
+
+
+    /* The following PRFs are defined in PKCS #5 v2.0. */
+    public static final long  CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001L;
+
+
+    /* The following salt value sources are defined in PKCS #5 v2.0. */
+    public static final long CKZ_SALT_SPECIFIED        = 0x00000001L;
+
+    /* the following EC Key Derivation Functions are defined */
+    public static final long CKD_NULL                 = 0x00000001L;
+    public static final long CKD_SHA1_KDF             = 0x00000002L;
+
+    /* the following X9.42 Diffie-Hellman Key Derivation Functions are defined */
+    public static final long CKD_SHA1_KDF_ASN1        = 0x00000003L;
+    public static final long CKD_SHA1_KDF_CONCATENATE = 0x00000004L;
+
+
+    // private NSS attribute (for DSA and DH private keys)
+    public static final long  CKA_NETSCAPE_DB         = 0xD5A0DB00L;
+
+    // base number of NSS private attributes
+    public static final long  CKA_NETSCAPE_BASE       = 0x80000000L + 0x4E534350L;
+
+    // object type for NSS trust
+    public static final long  CKO_NETSCAPE_TRUST      = CKA_NETSCAPE_BASE + 3;
+
+    // base number for NSS trust attributes
+    public static final long  CKA_NETSCAPE_TRUST_BASE = CKA_NETSCAPE_BASE + 0x2000;
+
+    // attributes for NSS trust
+    public static final long  CKA_NETSCAPE_TRUST_SERVER_AUTH      = CKA_NETSCAPE_TRUST_BASE +   8;
+    public static final long  CKA_NETSCAPE_TRUST_CLIENT_AUTH      = CKA_NETSCAPE_TRUST_BASE +   9;
+    public static final long  CKA_NETSCAPE_TRUST_CODE_SIGNING     = CKA_NETSCAPE_TRUST_BASE +  10;
+    public static final long  CKA_NETSCAPE_TRUST_EMAIL_PROTECTION = CKA_NETSCAPE_TRUST_BASE +  11;
+    public static final long  CKA_NETSCAPE_CERT_SHA1_HASH         = CKA_NETSCAPE_TRUST_BASE + 100;
+    public static final long  CKA_NETSCAPE_CERT_MD5_HASH          = CKA_NETSCAPE_TRUST_BASE + 101;
+
+    // trust values for each of the NSS trust attributes
+    public static final long  CKT_NETSCAPE_TRUSTED           = CKA_NETSCAPE_BASE + 1;
+    public static final long  CKT_NETSCAPE_TRUSTED_DELEGATOR = CKA_NETSCAPE_BASE + 2;
+    public static final long  CKT_NETSCAPE_UNTRUSTED         = CKA_NETSCAPE_BASE + 3;
+    public static final long  CKT_NETSCAPE_MUST_VERIFY       = CKA_NETSCAPE_BASE + 4;
+    public static final long  CKT_NETSCAPE_TRUST_UNKNOWN     = CKA_NETSCAPE_BASE + 5; /* default */
+    public static final long  CKT_NETSCAPE_VALID             = CKA_NETSCAPE_BASE + 10;
+    public static final long  CKT_NETSCAPE_VALID_DELEGATOR   = CKA_NETSCAPE_BASE + 11;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+import java.util.*;
+
+
+/**
+ * This is the superclass of all checked exceptions used by this package. An
+ * exception of this class indicates that a function call to the underlying
+ * PKCS#11 module returned a value not equal to CKR_OK. The application can get
+ * the returned value by calling getErrorCode(). A return value not equal to
+ * CKR_OK is the only reason for such an exception to be thrown.
+ * PKCS#11 defines the meaning of an error-code, which may depend on the
+ * context in which the error occurs.
+ *
+ * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
+ * @invariants
+ */
+public class PKCS11Exception extends Exception {
+    private static final long serialVersionUID = 4877072363729195L;
+
+    /**
+     * The code of the error which was the reason for this exception.
+     */
+    protected long errorCode_;
+
+    private static final Map<Long,String> errorMap;
+
+    static {
+        int[] errorCodes = new int[] {
+            0x00000000,
+            0x00000001,
+            0x00000002,
+            0x00000003,
+            0x00000005,
+            0x00000006,
+            0x00000007,
+            0x00000008,
+            0x00000009,
+            0x0000000A,
+            0x00000010,
+            0x00000011,
+            0x00000012,
+            0x00000013,
+            0x00000020,
+            0x00000021,
+            0x00000030,
+            0x00000031,
+            0x00000032,
+            0x00000040,
+            0x00000041,
+            0x00000050,
+            0x00000051,
+            0x00000054,
+            0x00000060,
+            0x00000062,
+            0x00000063,
+            0x00000064,
+            0x00000065,
+            0x00000066,
+            0x00000067,
+            0x00000068,
+            0x00000069,
+            0x0000006A,
+            0x00000070,
+            0x00000071,
+            0x00000082,
+            0x00000090,
+            0x00000091,
+            0x000000A0,
+            0x000000A1,
+            0x000000A2,
+            0x000000A3,
+            0x000000A4,
+            0x000000B0,
+            0x000000B1,
+            0x000000B3,
+            0x000000B4,
+            0x000000B5,
+            0x000000B6,
+            0x000000B7,
+            0x000000B8,
+            0x000000C0,
+            0x000000C1,
+            0x000000D0,
+            0x000000D1,
+            0x000000E0,
+            0x000000E1,
+            0x000000E2,
+            0x000000F0,
+            0x000000F1,
+            0x000000F2,
+            0x00000100,
+            0x00000101,
+            0x00000102,
+            0x00000103,
+            0x00000104,
+            0x00000105,
+            0x00000110,
+            0x00000112,
+            0x00000113,
+            0x00000114,
+            0x00000115,
+            0x00000120,
+            0x00000121,
+            0x00000130,
+            0x00000150,
+            0x00000160,
+            0x00000170,
+            0x00000180,
+            0x00000190,
+            0x00000191,
+            0x000001A0,
+            0x000001A1,
+            0x00000200,
+            0x80000000,
+        };
+        String[] errorMessages = new String[] {
+            "CKR_OK",
+            "CKR_CANCEL",
+            "CKR_HOST_MEMORY",
+            "CKR_SLOT_ID_INVALID",
+            "CKR_GENERAL_ERROR",
+            "CKR_FUNCTION_FAILED",
+            "CKR_ARGUMENTS_BAD",
+            "CKR_NO_EVENT",
+            "CKR_NEED_TO_CREATE_THREADS",
+            "CKR_CANT_LOCK",
+            "CKR_ATTRIBUTE_READ_ONLY",
+            "CKR_ATTRIBUTE_SENSITIVE",
+            "CKR_ATTRIBUTE_TYPE_INVALID",
+            "CKR_ATTRIBUTE_VALUE_INVALID",
+            "CKR_DATA_INVALID",
+            "CKR_DATA_LEN_RANGE",
+            "CKR_DEVICE_ERROR",
+            "CKR_DEVICE_MEMORY",
+            "CKR_DEVICE_REMOVED",
+            "CKR_ENCRYPTED_DATA_INVALID",
+            "CKR_ENCRYPTED_DATA_LEN_RANGE",
+            "CKR_FUNCTION_CANCELED",
+            "CKR_FUNCTION_NOT_PARALLEL",
+            "CKR_FUNCTION_NOT_SUPPORTED",
+            "CKR_KEY_HANDLE_INVALID",
+            "CKR_KEY_SIZE_RANGE",
+            "CKR_KEY_TYPE_INCONSISTENT",
+            "CKR_KEY_NOT_NEEDED",
+            "CKR_KEY_CHANGED",
+            "CKR_KEY_NEEDED",
+            "CKR_KEY_INDIGESTIBLE",
+            "CKR_KEY_FUNCTION_NOT_PERMITTED",
+            "CKR_KEY_NOT_WRAPPABLE",
+            "CKR_KEY_UNEXTRACTABLE",
+            "CKR_MECHANISM_INVALID",
+            "CKR_MECHANISM_PARAM_INVALID",
+            "CKR_OBJECT_HANDLE_INVALID",
+            "CKR_OPERATION_ACTIVE",
+            "CKR_OPERATION_NOT_INITIALIZED",
+            "CKR_PIN_INCORRECT",
+            "CKR_PIN_INVALID",
+            "CKR_PIN_LEN_RANGE",
+            "CKR_PIN_EXPIRED",
+            "CKR_PIN_LOCKED",
+            "CKR_SESSION_CLOSED",
+            "CKR_SESSION_COUNT",
+            "CKR_SESSION_HANDLE_INVALID",
+            "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
+            "CKR_SESSION_READ_ONLY",
+            "CKR_SESSION_EXISTS",
+            "CKR_SESSION_READ_ONLY_EXISTS",
+            "CKR_SESSION_READ_WRITE_SO_EXISTS",
+            "CKR_SIGNATURE_INVALID",
+            "CKR_SIGNATURE_LEN_RANGE",
+            "CKR_TEMPLATE_INCOMPLETE",
+            "CKR_TEMPLATE_INCONSISTENT",
+            "CKR_TOKEN_NOT_PRESENT",
+            "CKR_TOKEN_NOT_RECOGNIZED",
+            "CKR_TOKEN_WRITE_PROTECTED",
+            "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
+            "CKR_UNWRAPPING_KEY_SIZE_RANGE",
+            "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT",
+            "CKR_USER_ALREADY_LOGGED_IN",
+            "CKR_USER_NOT_LOGGED_IN",
+            "CKR_USER_PIN_NOT_INITIALIZED",
+            "CKR_USER_TYPE_INVALID",
+            "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
+            "CKR_USER_TOO_MANY_TYPES",
+            "CKR_WRAPPED_KEY_INVALID",
+            "CKR_WRAPPED_KEY_LEN_RANGE",
+            "CKR_WRAPPING_KEY_HANDLE_INVALID",
+            "CKR_WRAPPING_KEY_SIZE_RANGE",
+            "CKR_WRAPPING_KEY_TYPE_INCONSISTENT",
+            "CKR_RANDOM_SEED_NOT_SUPPORTED",
+            "CKR_RANDOM_NO_RNG",
+            "CKR_DOMAIN_PARAMS_INVALID",
+            "CKR_BUFFER_TOO_SMALL",
+            "CKR_SAVED_STATE_INVALID",
+            "CKR_INFORMATION_SENSITIVE",
+            "CKR_STATE_UNSAVEABLE",
+            "CKR_CRYPTOKI_NOT_INITIALIZED",
+            "CKR_CRYPTOKI_ALREADY_INITIALIZED",
+            "CKR_MUTEX_BAD",
+            "CKR_MUTEX_NOT_LOCKED",
+            "CKR_FUNCTION_REJECTED",
+            "CKR_VENDOR_DEFINED",
+        };
+        errorMap = new HashMap<Long,String>();
+        for (int i = 0; i < errorCodes.length; i++) {
+            errorMap.put(Long.valueOf(errorCodes[i]), errorMessages[i]);
+        }
+    }
+
+
+    /**
+     * Constructor taking the error code as defined for the CKR_* constants
+     * in PKCS#11.
+     */
+    public PKCS11Exception(long errorCode) {
+        errorCode_ = errorCode;
+    }
+
+    /**
+     * This method gets the corresponding text error message from
+     * a property file. If this file is not available, it returns the error
+     * code as a hex-string.
+     *
+     * @return The message or the error code; e.g. "CKR_DEVICE_ERROR" or
+     *         "0x00000030".
+     * @preconditions
+     * @postconditions (result <> null)
+     */
+    public String getMessage() {
+        String message = errorMap.get(Long.valueOf(errorCode_));
+        if (message == null) {
+            message = "0x" + Functions.toFullHexString((int)errorCode_);
+        }
+        return message;
+    }
+
+    /**
+     * Returns the PKCS#11 error code.
+     *
+     * @return The error code; e.g. 0x00000030.
+     * @preconditions
+     * @postconditions
+     */
+    public long getErrorCode() {
+        return errorCode_ ;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11RuntimeException.java	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,109 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+package sun.security.pkcs11.wrapper;
+
+
+/**
+ * This is the superclass of all runtime exception used by this library.
+ * For instance, Runtime exceptions occur, if an internal error in the native
+ * part of the wrapper occurs.
+ *
+ * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
+ * @invariants
+ */
+public class PKCS11RuntimeException extends RuntimeException {
+    private static final long serialVersionUID = 7889842162743590564L;
+
+    /**
+     * Empty constructor.
+     *
+     * @preconditions
+     * @postconditions
+     */
+    public PKCS11RuntimeException() {
+        super();
+    }
+
+    /**
+     * Constructor taking a string that describes the reason of the exception
+     * in more detail.
+     *
+     * @param message A descrption of the reason for this exception.
+     * @preconditions
+     * @postconditions
+     */
+    public PKCS11RuntimeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor taking an other exception to wrap.
+     *
+     * @param encapsulatedException The other exception the wrap into this.
+     * @preconditions
+     * @postconditions
+     */
+    public PKCS11RuntimeException(Exception encapsulatedException) {
+        super(encapsulatedException);
+    }
+
+    /**
+     * Constructor taking a message for this exception and an other exception to
+     * wrap.
+     *
+     * @param message The message giving details about the exception to ease
+     *                debugging.
+     * @param encapsulatedException The other exception the wrap into this.
+     * @preconditions
+     * @postconditions
+     */
+    public PKCS11RuntimeException(String message, Exception encapsulatedException) {
+        super(message, encapsulatedException);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/legal/pkcs11cryptotoken.md	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,20 @@
+## PKCS #11 Cryptographic Token Interface, v2.20 amendment 3 Header Files
+
+### PKCS #11 Cryptographic Token Interface License
+<pre>
+
+License to copy and use this software is granted provided that it is
+identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+(Cryptoki)" in all material mentioning or referencing this software.
+
+License is also granted to make and use derivative works provided that
+such works are identified as "derived from the RSA Security Inc. PKCS #11
+Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+referencing the derived work.
+
+RSA Security Inc. makes no representations concerning either the
+merchantability of this software or the suitability of this software for
+any particular purpose. It is provided "as is" without express or implied
+warranty of any kind.
+
+</pre>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/legal/pkcs11wrapper.md	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,46 @@
+## IAIK (Institute for Applied Information Processing and Communication) PKCS#11 wrapper files v1
+
+### IAIK License
+<pre>
+
+Copyright (c) 2002 Graz University of Technology. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+3. The end-user documentation included with the redistribution, if any, must
+   include the following acknowledgment:
+
+   "This product includes software developed by IAIK of Graz University of
+    Technology."
+
+   Alternately, this acknowledgment may appear in the software itself, if and
+   wherever such third-party acknowledgments normally appear.
+
+4. The names "Graz University of Technology" and "IAIK of Graz University of
+   Technology" must not be used to endorse or promote products derived from this
+   software without prior written permission.
+
+5. Products derived from this software may not be called "IAIK PKCS Wrapper",
+   nor may "IAIK" appear in their name, without prior written permission of
+   Graz University of Technology.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+</pre>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2005, 2014, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// #define SECMOD_DEBUG
+
+#include "j2secmod.h"
+#include "jni_util.h"
+
+
+JNIEXPORT jboolean JNICALL Java_sun_security_pkcs11_Secmod_nssVersionCheck
+  (JNIEnv *env, jclass thisClass, jlong jHandle, jstring jVersion)
+{
+    int res = 0;
+    FPTR_VersionCheck versionCheck;
+    const char *requiredVersion;
+
+    versionCheck = (FPTR_VersionCheck)findFunction(env, jHandle,
+        "NSS_VersionCheck");
+    if (versionCheck == NULL) {
+        return JNI_FALSE;
+    }
+
+    requiredVersion = (*env)->GetStringUTFChars(env, jVersion, NULL);
+    if (requiredVersion == NULL)  {
+        return JNI_FALSE;
+    }
+
+    res = versionCheck(requiredVersion);
+    dprintf2("-version >=%s: %d\n", requiredVersion, res);
+    (*env)->ReleaseStringUTFChars(env, jVersion, requiredVersion);
+
+    return (res == 0) ? JNI_FALSE : JNI_TRUE;
+}
+
+/*
+ * Initializes NSS.
+ * The NSS_INIT_OPTIMIZESPACE flag is supplied by the caller.
+ * The NSS_Init* functions are mapped to the NSS_Initialize function.
+ */
+JNIEXPORT jboolean JNICALL Java_sun_security_pkcs11_Secmod_nssInitialize
+  (JNIEnv *env, jclass thisClass, jstring jFunctionName, jlong jHandle, jstring jConfigDir, jboolean jNssOptimizeSpace)
+{
+    int res = 0;
+    FPTR_Initialize initialize =
+        (FPTR_Initialize)findFunction(env, jHandle, "NSS_Initialize");
+    unsigned int flags = 0x00;
+    const char *configDir = NULL;
+    const char *functionName = NULL;
+
+    /* If we cannot initialize, exit now */
+    if (initialize == NULL) {
+        res = 1;
+        goto cleanup;
+    }
+
+    functionName = (*env)->GetStringUTFChars(env, jFunctionName, NULL);
+    if (functionName == NULL) {
+        res = 1;
+        goto cleanup;
+    }
+
+    if (jConfigDir != NULL) {
+        configDir = (*env)->GetStringUTFChars(env, jConfigDir, NULL);
+        if (!configDir) {
+            res = 1;
+            goto cleanup;
+        }
+    }
+
+    if (jNssOptimizeSpace == JNI_TRUE) {
+        flags = 0x20; // NSS_INIT_OPTIMIZESPACE flag
+    }
+
+    /*
+     * If the NSS_Init function is requested then call NSS_Initialize to
+     * open the Cert, Key and Security Module databases, read only.
+     */
+    if (strcmp("NSS_Init", functionName) == 0) {
+        flags = flags | 0x01; // NSS_INIT_READONLY flag
+        res = initialize(configDir, "", "", "secmod.db", flags);
+
+    /*
+     * If the NSS_InitReadWrite function is requested then call
+     * NSS_Initialize to open the Cert, Key and Security Module databases,
+     * read/write.
+     */
+    } else if (strcmp("NSS_InitReadWrite", functionName) == 0) {
+        res = initialize(configDir, "", "", "secmod.db", flags);
+
+    /*
+     * If the NSS_NoDB_Init function is requested then call
+     * NSS_Initialize without creating Cert, Key or Security Module
+     * databases.
+     */
+    } else if (strcmp("NSS_NoDB_Init", functionName) == 0) {
+        flags = flags | 0x02  // NSS_INIT_NOCERTDB flag
+                      | 0x04  // NSS_INIT_NOMODDB flag
+                      | 0x08  // NSS_INIT_FORCEOPEN flag
+                      | 0x10; // NSS_INIT_NOROOTINIT flag
+        res = initialize("", "", "", "", flags);
+
+    } else {
+        res = 2;
+    }
+
+cleanup:
+    if (functionName != NULL) {
+        (*env)->ReleaseStringUTFChars(env, jFunctionName, functionName);
+    }
+    if (configDir != NULL) {
+        (*env)->ReleaseStringUTFChars(env, jConfigDir, configDir);
+    }
+    dprintf1("-res: %d\n", res);
+
+    return (res == 0) ? JNI_TRUE : JNI_FALSE;
+}
+
+JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_Secmod_nssGetModuleList
+  (JNIEnv *env, jclass thisClass, jlong jHandle, jstring jLibDir)
+{
+    FPTR_GetDBModuleList getModuleList =
+        (FPTR_GetDBModuleList)findFunction(env, jHandle, "SECMOD_GetDefaultModuleList");
+
+    SECMODModuleList *list;
+    SECMODModule *module;
+    jclass jListClass, jModuleClass;
+    jobject jList, jModule;
+    jmethodID jListConstructor, jAdd, jModuleConstructor;
+    jstring jCommonName, jDllName;
+    jboolean jFIPS;
+    jint i;
+
+    if (getModuleList == NULL) {
+        dprintf("-getmodulelist function not found\n");
+        return NULL;
+    }
+    list = getModuleList();
+    if (list == NULL) {
+        dprintf("-module list is null\n");
+        return NULL;
+    }
+
+    jListClass = (*env)->FindClass(env, "java/util/ArrayList");
+    if (jListClass == NULL) {
+        return NULL;
+    }
+    jListConstructor = (*env)->GetMethodID(env, jListClass, "<init>", "()V");
+    if (jListConstructor == NULL) {
+        return NULL;
+    }
+    jAdd = (*env)->GetMethodID(env, jListClass, "add", "(Ljava/lang/Object;)Z");
+    if (jAdd == NULL) {
+        return NULL;
+    }
+    jList = (*env)->NewObject(env, jListClass, jListConstructor);
+    if (jList == NULL) {
+        return NULL;
+    }
+    jModuleClass = (*env)->FindClass(env, "sun/security/pkcs11/Secmod$Module");
+    if (jModuleClass == NULL) {
+        return NULL;
+    }
+    jModuleConstructor = (*env)->GetMethodID(env, jModuleClass, "<init>",
+        "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V");
+    if (jModuleConstructor == NULL) {
+        return NULL;
+    }
+
+    while (list != NULL) {
+        module = list->module;
+        // assert module != null
+        dprintf1("-commonname: %s\n", module->commonName);
+        dprintf1("-dllname: %s\n", (module->dllName != NULL) ? module->dllName : "NULL");
+        dprintf1("-slots: %d\n", module->slotCount);
+        dprintf1("-loaded: %d\n", module->loaded);
+        dprintf1("-internal: %d\n", module->internal);
+        dprintf1("-fips: %d\n", module->isFIPS);
+        jCommonName = (*env)->NewStringUTF(env, module->commonName);
+        if (jCommonName == NULL) {
+            return NULL;
+        }
+        if (module->dllName == NULL) {
+            jDllName = NULL;
+        } else {
+            jDllName = (*env)->NewStringUTF(env, module->dllName);
+            if (jDllName == NULL) {
+                return NULL;
+            }
+        }
+        jFIPS = module->isFIPS;
+        for (i = 0; i < module->slotCount; i++ ) {
+            jModule = (*env)->NewObject(env, jModuleClass, jModuleConstructor,
+                jLibDir, jDllName, jCommonName, jFIPS, i);
+            if (jModule == NULL) {
+                return NULL;
+            }
+            (*env)->CallVoidMethod(env, jList, jAdd, jModule);
+            if ((*env)->ExceptionCheck(env)) {
+                return NULL;
+            }
+        }
+        list = list->next;
+    }
+    dprintf("-ok\n");
+
+    return jList;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2005, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#include <jni.h>
+
+#include "sun_security_pkcs11_Secmod.h"
+
+// #define SECMOD_DEBUG
+
+#include "j2secmod_md.h"
+
+#include "p11_md.h"
+
+
+void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName);
+
+#ifdef SECMOD_DEBUG
+#define dprintf(s) printf(s)
+#define dprintf1(s, p1) printf(s, p1)
+#define dprintf2(s, p1, p2) printf(s, p1, p2)
+#define dprintf3(s, p1, p2, p3) printf(s, p1, p2, p3)
+#else
+#define dprintf(s)
+#define dprintf1(s, p1)
+#define dprintf2(s, p1, p2)
+#define dprintf3(s, p1, p2, p3)
+#endif
+
+// NSS types
+
+typedef int PRBool;
+
+typedef struct SECMODModuleStr SECMODModule;
+typedef struct SECMODModuleListStr SECMODModuleList;
+
+struct SECMODModuleStr {
+    void        *v1;
+    PRBool      internal;       /* true of internally linked modules, false
+                                 * for the loaded modules */
+    PRBool      loaded;         /* Set to true if module has been loaded */
+    PRBool      isFIPS;         /* Set to true if module is finst internal */
+    char        *dllName;       /* name of the shared library which implements
+                                 * this module */
+    char        *commonName;    /* name of the module to display to the user */
+    void        *library;       /* pointer to the library. opaque. used only by
+                                 * pk11load.c */
+
+    void        *functionList; /* The PKCS #11 function table */
+    void        *refLock;       /* only used pk11db.c */
+    int         refCount;       /* Module reference count */
+    void        **slots;        /* array of slot points attached to this mod*/
+    int         slotCount;      /* count of slot in above array */
+    void        *slotInfo;      /* special info about slots default settings */
+    int         slotInfoCount;  /* count */
+    // incomplete, sizeof() is wrong
+};
+
+struct SECMODModuleListStr {
+    SECMODModuleList    *next;
+    SECMODModule        *module;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,1842 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+/*
+ * pkcs11wrapper.c
+ * 18.05.2001
+ *
+ * This is the implementation of the native functions of the Java to PKCS#11 interface.
+ * All function use some helper functions to convert the JNI types to PKCS#11 types.
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+/* declare file private functions */
+
+void jMechanismParameterToCKMechanismParameterSlow(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength);
+
+
+/*
+ * converts a pointer to a CK_DATE structure into a Java CK_DATE Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpValue - the pointer to the CK_DATE structure
+ * @return - the new Java CK_DATE object
+ */
+jobject ckDatePtrToJDateObject(JNIEnv *env, const CK_DATE *ckpDate)
+{
+    jclass jDateClass;
+    jmethodID jCtrId;
+    jobject jDateObject;
+    jcharArray jYear;
+    jcharArray jMonth;
+    jcharArray jDay;
+
+    /* load CK_DATE class */
+    jDateClass = (*env)->FindClass(env, CLASS_DATE);
+    if (jDateClass == NULL) { return NULL; }
+
+    /* load CK_DATE constructor */
+    jCtrId = (*env)->GetMethodID(env, jDateClass, "<init>", "([C[C[C)V");
+    if (jCtrId == NULL) { return NULL; }
+
+    /* prep all fields */
+    jYear = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpDate->year), 4);
+    if (jYear == NULL) { return NULL; }
+    jMonth = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpDate->month), 2);
+    if (jMonth == NULL) { return NULL; }
+    jDay = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpDate->day), 2);
+    if (jDay == NULL) { return NULL; }
+
+    /* create new CK_DATE object */
+    jDateObject =
+      (*env)->NewObject(env, jDateClass, jCtrId, jYear, jMonth, jDay);
+    if (jDateObject == NULL) { return NULL; }
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jDateClass);
+    (*env)->DeleteLocalRef(env, jYear);
+    (*env)->DeleteLocalRef(env, jMonth);
+    (*env)->DeleteLocalRef(env, jDay);
+
+    return jDateObject ;
+}
+
+/*
+ * converts a pointer to a CK_VERSION structure into a Java CK_VERSION Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpVersion - the pointer to the CK_VERSION structure
+ * @return - the new Java CK_VERSION object
+ */
+jobject ckVersionPtrToJVersion(JNIEnv *env, const CK_VERSION_PTR ckpVersion)
+{
+    jclass jVersionClass;
+    jmethodID jCtrId;
+    jobject jVersionObject;
+    jint jMajor;
+    jint jMinor;
+
+    /* load CK_VERSION class */
+    jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
+    if (jVersionClass == NULL) { return NULL; }
+
+    /* load CK_VERSION constructor */
+    jCtrId = (*env)->GetMethodID(env, jVersionClass, "<init>", "(II)V");
+    if (jCtrId == NULL) { return NULL; }
+
+    /* prep both fields */
+    jMajor = ckpVersion->major;
+    jMinor = ckpVersion->minor;
+
+    /* create new CK_VERSION object */
+    jVersionObject =
+      (*env)->NewObject(env, jVersionClass, jCtrId, jMajor, jMinor);
+    if (jVersionObject == NULL) { return NULL; }
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jVersionClass);
+
+    return jVersionObject ;
+}
+
+/*
+ * converts a pointer to a CK_SESSION_INFO structure into a Java CK_SESSION_INFO Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpSessionInfo - the pointer to the CK_SESSION_INFO structure
+ * @return - the new Java CK_SESSION_INFO object
+ */
+jobject ckSessionInfoPtrToJSessionInfo(JNIEnv *env, const CK_SESSION_INFO_PTR ckpSessionInfo)
+{
+    jclass jSessionInfoClass;
+    jmethodID jCtrId;
+    jobject jSessionInfoObject;
+    jlong jSlotID;
+    jlong jState;
+    jlong jFlags;
+    jlong jDeviceError;
+
+    /* load CK_SESSION_INFO class */
+    jSessionInfoClass = (*env)->FindClass(env, CLASS_SESSION_INFO);
+    if (jSessionInfoClass == NULL) { return NULL; }
+
+    /* load CK_SESSION_INFO constructor */
+    jCtrId = (*env)->GetMethodID(env, jSessionInfoClass, "<init>", "(JJJJ)V");
+    if (jCtrId == NULL) { return NULL; }
+
+    /* prep all fields */
+    jSlotID = ckULongToJLong(ckpSessionInfo->slotID);
+    jState = ckULongToJLong(ckpSessionInfo->state);
+    jFlags = ckULongToJLong(ckpSessionInfo->flags);
+    jDeviceError = ckULongToJLong(ckpSessionInfo->ulDeviceError);
+
+    /* create new CK_SESSION_INFO object */
+    jSessionInfoObject =
+      (*env)->NewObject(env, jSessionInfoClass, jCtrId, jSlotID, jState,
+                        jFlags, jDeviceError);
+    if (jSessionInfoObject == NULL) { return NULL; }
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jSessionInfoClass);
+
+    return jSessionInfoObject ;
+}
+
+/*
+ * converts a pointer to a CK_ATTRIBUTE structure into a Java CK_ATTRIBUTE Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpAttribute - the pointer to the CK_ATTRIBUTE structure
+ * @return - the new Java CK_ATTRIBUTE object
+ */
+jobject ckAttributePtrToJAttribute(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute)
+{
+    jclass jAttributeClass;
+    jmethodID jCtrId;
+    jobject jAttributeObject;
+    jlong jType;
+    jobject jPValue = NULL;
+
+    jAttributeClass = (*env)->FindClass(env, CLASS_ATTRIBUTE);
+    if (jAttributeClass == NULL) { return NULL; }
+
+    /* load CK_INFO constructor */
+    jCtrId = (*env)->GetMethodID(env, jAttributeClass, "<init>", "(JLjava/lang/Object;)V");
+    if (jCtrId == NULL) { return NULL; }
+
+    /* prep both fields */
+    jType = ckULongToJLong(ckpAttribute->type);
+    jPValue = ckAttributeValueToJObject(env, ckpAttribute);
+    if ((*env)->ExceptionCheck(env)) { return NULL; }
+
+    /* create new CK_ATTRIBUTE object */
+    jAttributeObject =
+      (*env)->NewObject(env, jAttributeClass, jCtrId, jType, jPValue);
+    if (jAttributeObject == NULL) { return NULL; }
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jAttributeClass);
+    (*env)->DeleteLocalRef(env, jPValue);
+
+    return jAttributeObject;
+}
+
+
+/*
+ * converts a Java CK_VERSION object into a pointer to a CK_VERSION structure
+ *
+ * @param env - used to call JNI funktions to get the values out of the Java object
+ * @param jVersion - the Java CK_VERSION object to convert
+ * @return - the pointer to the new CK_VERSION structure
+ */
+CK_VERSION_PTR jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion)
+{
+    CK_VERSION_PTR ckpVersion;
+    jclass jVersionClass;
+    jfieldID jFieldID;
+    jbyte jMajor, jMinor;
+
+    if (jVersion == NULL) {
+        return NULL;
+    }
+
+    /* get CK_VERSION class */
+    jVersionClass = (*env)->GetObjectClass(env, jVersion);
+    if (jVersionClass == NULL) { return NULL; }
+
+    /* get Major */
+    jFieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
+    if (jFieldID == NULL) { return NULL; }
+    jMajor = (*env)->GetByteField(env, jVersion, jFieldID);
+
+    /* get Minor */
+    jFieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
+    if (jFieldID == NULL) { return NULL; }
+    jMinor = (*env)->GetByteField(env, jVersion, jFieldID);
+
+    /* allocate memory for CK_VERSION pointer */
+    ckpVersion = (CK_VERSION_PTR) malloc(sizeof(CK_VERSION));
+    if (ckpVersion == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    ckpVersion->major = jByteToCKByte(jMajor);
+    ckpVersion->minor = jByteToCKByte(jMinor);
+
+    return ckpVersion ;
+}
+
+
+/*
+ * converts a Java CK_DATE object into a pointer to a CK_DATE structure
+ *
+ * @param env - used to call JNI funktions to get the values out of the Java object
+ * @param jVersion - the Java CK_DATE object to convert
+ * @return - the pointer to the new CK_DATE structure
+ */
+CK_DATE * jDateObjectPtrToCKDatePtr(JNIEnv *env, jobject jDate)
+{
+    CK_DATE * ckpDate;
+    CK_ULONG ckLength;
+    jclass jDateClass;
+    jfieldID jFieldID;
+    jobject jYear, jMonth, jDay;
+    jchar *jTempChars;
+    CK_ULONG i;
+
+    if (jDate == NULL) {
+        return NULL;
+    }
+
+    /* get CK_DATE class */
+    jDateClass = (*env)->FindClass(env, CLASS_DATE);
+    if (jDateClass == NULL) { return NULL; }
+
+    /* get Year */
+    jFieldID = (*env)->GetFieldID(env, jDateClass, "year", "[C");
+    if (jFieldID == NULL) { return NULL; }
+    jYear = (*env)->GetObjectField(env, jDate, jFieldID);
+
+    /* get Month */
+    jFieldID = (*env)->GetFieldID(env, jDateClass, "month", "[C");
+    if (jFieldID == NULL) { return NULL; }
+    jMonth = (*env)->GetObjectField(env, jDate, jFieldID);
+
+    /* get Day */
+    jFieldID = (*env)->GetFieldID(env, jDateClass, "day", "[C");
+    if (jFieldID == NULL) { return NULL; }
+    jDay = (*env)->GetObjectField(env, jDate, jFieldID);
+
+    /* allocate memory for CK_DATE pointer */
+    ckpDate = (CK_DATE *) malloc(sizeof(CK_DATE));
+    if (ckpDate == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    if (jYear == NULL) {
+        ckpDate->year[0] = 0;
+        ckpDate->year[1] = 0;
+        ckpDate->year[2] = 0;
+        ckpDate->year[3] = 0;
+    } else {
+        ckLength = (*env)->GetArrayLength(env, jYear);
+        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
+        if (jTempChars == NULL) {
+            free(ckpDate);
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        (*env)->GetCharArrayRegion(env, jYear, 0, ckLength, jTempChars);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpDate);
+            free(jTempChars);
+            return NULL;
+        }
+
+        for (i = 0; (i < ckLength) && (i < 4) ; i++) {
+            ckpDate->year[i] = jCharToCKChar(jTempChars[i]);
+        }
+        free(jTempChars);
+    }
+
+    if (jMonth == NULL) {
+        ckpDate->month[0] = 0;
+        ckpDate->month[1] = 0;
+    } else {
+        ckLength = (*env)->GetArrayLength(env, jMonth);
+        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
+        if (jTempChars == NULL) {
+            free(ckpDate);
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        (*env)->GetCharArrayRegion(env, jMonth, 0, ckLength, jTempChars);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpDate);
+            free(jTempChars);
+            return NULL;
+        }
+
+        for (i = 0; (i < ckLength) && (i < 2) ; i++) {
+            ckpDate->month[i] = jCharToCKChar(jTempChars[i]);
+        }
+        free(jTempChars);
+    }
+
+    if (jDay == NULL) {
+        ckpDate->day[0] = 0;
+        ckpDate->day[1] = 0;
+    } else {
+        ckLength = (*env)->GetArrayLength(env, jDay);
+        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
+        if (jTempChars == NULL) {
+            free(ckpDate);
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        (*env)->GetCharArrayRegion(env, jDay, 0, ckLength, jTempChars);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpDate);
+            free(jTempChars);
+            return NULL;
+        }
+
+        for (i = 0; (i < ckLength) && (i < 2) ; i++) {
+            ckpDate->day[i] = jCharToCKChar(jTempChars[i]);
+        }
+        free(jTempChars);
+    }
+
+    return ckpDate ;
+}
+
+
+/*
+ * converts a Java CK_ATTRIBUTE object into a CK_ATTRIBUTE structure
+ *
+ * @param env - used to call JNI funktions to get the values out of the Java object
+ * @param jAttribute - the Java CK_ATTRIBUTE object to convert
+ * @return - the new CK_ATTRIBUTE structure
+ */
+CK_ATTRIBUTE jAttributeToCKAttribute(JNIEnv *env, jobject jAttribute)
+{
+    CK_ATTRIBUTE ckAttribute;
+    jclass jAttributeClass;
+    jfieldID jFieldID;
+    jlong jType;
+    jobject jPValue;
+    memset(&ckAttribute, 0, sizeof(CK_ATTRIBUTE));
+
+    // TBD: what if jAttribute == NULL?!
+
+    TRACE0("\nDEBUG: jAttributeToCKAttribute");
+    /* get CK_ATTRIBUTE class */
+    TRACE0(", getting attribute object class");
+    jAttributeClass = (*env)->GetObjectClass(env, jAttribute);
+    if (jAttributeClass == NULL) { return ckAttribute; }
+
+    /* get type */
+    TRACE0(", getting type field");
+    jFieldID = (*env)->GetFieldID(env, jAttributeClass, "type", "J");
+    if (jFieldID == NULL) { return ckAttribute; }
+    jType = (*env)->GetLongField(env, jAttribute, jFieldID);
+    TRACE1(", type=0x%X", jType);
+
+    /* get pValue */
+    TRACE0(", getting pValue field");
+    jFieldID = (*env)->GetFieldID(env, jAttributeClass, "pValue", "Ljava/lang/Object;");
+    if (jFieldID == NULL) { return ckAttribute; }
+    jPValue = (*env)->GetObjectField(env, jAttribute, jFieldID);
+    TRACE1(", pValue=%p", jPValue);
+
+    ckAttribute.type = jLongToCKULong(jType);
+    TRACE0(", converting pValue to primitive object");
+
+    /* convert the Java pValue object to a CK-type pValue pointer */
+    jObjectToPrimitiveCKObjectPtrPtr(env, jPValue, &(ckAttribute.pValue), &(ckAttribute.ulValueLen));
+
+    TRACE0("\nFINISHED\n");
+
+    return ckAttribute ;
+}
+
+/*
+ * converts the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to a
+ * CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to convert
+ * @return - the new CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
+ */
+CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam)
+{
+    // XXX don't return structs
+    // XXX prefetch class and field ids
+    jclass jSsl3MasterKeyDeriveParamsClass;
+    CK_SSL3_MASTER_KEY_DERIVE_PARAMS ckParam;
+    jfieldID fieldID;
+    jclass jSsl3RandomDataClass;
+    jobject jRandomInfo, jRIClientRandom, jRIServerRandom, jVersion;
+    memset(&ckParam, 0, sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
+
+    /* get RandomInfo */
+    jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
+    if (jSsl3MasterKeyDeriveParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jSsl3MasterKeyDeriveParamsClass, "RandomInfo", "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;");
+    if (fieldID == NULL) { return ckParam; }
+    jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pClientRandom and ulClientRandomLength out of RandomInfo */
+    jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA);
+    if (jSsl3RandomDataClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jRIClientRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
+
+    /* get pServerRandom and ulServerRandomLength out of RandomInfo */
+    fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jRIServerRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
+
+    /* get pVersion */
+    fieldID = (*env)->GetFieldID(env, jSsl3MasterKeyDeriveParamsClass, "pVersion",  "Lsun/security/pkcs11/wrapper/CK_VERSION;");
+    if (fieldID == NULL) { return ckParam; }
+    jVersion = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.pVersion = jVersionToCKVersionPtr(env, jVersion);
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    jByteArrayToCKByteArray(env, jRIClientRandom, &(ckParam.RandomInfo.pClientRandom), &(ckParam.RandomInfo.ulClientRandomLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pVersion);
+        return ckParam;
+    }
+    jByteArrayToCKByteArray(env, jRIServerRandom, &(ckParam.RandomInfo.pServerRandom), &(ckParam.RandomInfo.ulServerRandomLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pVersion);
+        free(ckParam.RandomInfo.pClientRandom);
+        return ckParam;
+    }
+
+    return ckParam ;
+}
+
+
+/*
+ * converts the Java CK_TLS_PRF_PARAMS object to a CK_TLS_PRF_PARAMS structure
+ */
+CK_TLS_PRF_PARAMS jTlsPrfParamsToCKTlsPrfParam(JNIEnv *env, jobject jParam)
+{
+    jclass jTlsPrfParamsClass;
+    CK_TLS_PRF_PARAMS ckParam;
+    jfieldID fieldID;
+    jobject jSeed, jLabel, jOutput;
+    memset(&ckParam, 0, sizeof(CK_TLS_PRF_PARAMS));
+
+    // TBD: what if jParam == NULL?!
+
+    /* get pSeed */
+    jTlsPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
+    if (jTlsPrfParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pSeed", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jSeed = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pLabel */
+    fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pLabel", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jLabel = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pOutput */
+    fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pOutput", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jOutput = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    jByteArrayToCKByteArray(env, jSeed, &(ckParam.pSeed), &(ckParam.ulSeedLen));
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    jByteArrayToCKByteArray(env, jLabel, &(ckParam.pLabel), &(ckParam.ulLabelLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pSeed);
+        return ckParam;
+    }
+    ckParam.pulOutputLen = malloc(sizeof(CK_ULONG));
+    if (ckParam.pulOutputLen == NULL) {
+        free(ckParam.pSeed);
+        free(ckParam.pLabel);
+        throwOutOfMemoryError(env, 0);
+        return ckParam;
+    }
+    jByteArrayToCKByteArray(env, jOutput, &(ckParam.pOutput), ckParam.pulOutputLen);
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pSeed);
+        free(ckParam.pLabel);
+        free(ckParam.pulOutputLen);
+        return ckParam;
+    }
+
+    return ckParam ;
+}
+
+/*
+ * converts the Java CK_SSL3_KEY_MAT_PARAMS object to a CK_SSL3_KEY_MAT_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_SSL3_KEY_MAT_PARAMS object to convert
+ * @return - the new CK_SSL3_KEY_MAT_PARAMS structure
+ */
+CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam)
+{
+    // XXX don't return structs
+    // XXX prefetch class and field ids
+    jclass jSsl3KeyMatParamsClass, jSsl3RandomDataClass, jSsl3KeyMatOutClass;
+    CK_SSL3_KEY_MAT_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jMacSizeInBits, jKeySizeInBits, jIVSizeInBits;
+    jboolean jIsExport;
+    jobject jRandomInfo, jRIClientRandom, jRIServerRandom;
+    jobject jReturnedKeyMaterial, jRMIvClient, jRMIvServer;
+    CK_ULONG ckTemp;
+    memset(&ckParam, 0, sizeof(CK_SSL3_KEY_MAT_PARAMS));
+
+    /* get ulMacSizeInBits */
+    jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
+    if (jSsl3KeyMatParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulMacSizeInBits", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jMacSizeInBits = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get ulKeySizeInBits */
+    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulKeySizeInBits", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jKeySizeInBits = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get ulIVSizeInBits */
+    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulIVSizeInBits", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jIVSizeInBits = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get bIsExport */
+    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "bIsExport", "Z");
+    if (fieldID == NULL) { return ckParam; }
+    jIsExport = (*env)->GetBooleanField(env, jParam, fieldID);
+
+    /* get RandomInfo */
+    jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA);
+    if (jSsl3RandomDataClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "RandomInfo",  "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;");
+    if (fieldID == NULL) { return ckParam; }
+    jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pClientRandom and ulClientRandomLength out of RandomInfo */
+    fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jRIClientRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
+
+    /* get pServerRandom and ulServerRandomLength out of RandomInfo */
+    fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jRIServerRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
+
+    /* get pReturnedKeyMaterial */
+    jSsl3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
+    if (jSsl3KeyMatOutClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "pReturnedKeyMaterial",  "Lsun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT;");
+    if (fieldID == NULL) { return ckParam; }
+    jReturnedKeyMaterial = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pIVClient out of pReturnedKeyMaterial */
+    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVClient", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jRMIvClient = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID);
+
+    /* get pIVServer out of pReturnedKeyMaterial */
+    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVServer", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jRMIvServer = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID);
+
+    /* populate java values */
+    ckParam.ulMacSizeInBits = jLongToCKULong(jMacSizeInBits);
+    ckParam.ulKeySizeInBits = jLongToCKULong(jKeySizeInBits);
+    ckParam.ulIVSizeInBits = jLongToCKULong(jIVSizeInBits);
+    ckParam.bIsExport = jBooleanToCKBBool(jIsExport);
+    jByteArrayToCKByteArray(env, jRIClientRandom, &(ckParam.RandomInfo.pClientRandom), &(ckParam.RandomInfo.ulClientRandomLen));
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    jByteArrayToCKByteArray(env, jRIServerRandom, &(ckParam.RandomInfo.pServerRandom), &(ckParam.RandomInfo.ulServerRandomLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.RandomInfo.pClientRandom);
+        return ckParam;
+    }
+    /* allocate memory for pRetrunedKeyMaterial */
+    ckParam.pReturnedKeyMaterial = (CK_SSL3_KEY_MAT_OUT_PTR) malloc(sizeof(CK_SSL3_KEY_MAT_OUT));
+    if (ckParam.pReturnedKeyMaterial == NULL) {
+        free(ckParam.RandomInfo.pClientRandom);
+        free(ckParam.RandomInfo.pServerRandom);
+        throwOutOfMemoryError(env, 0);
+        return ckParam;
+    }
+
+    // the handles are output params only, no need to fetch them from Java
+    ckParam.pReturnedKeyMaterial->hClientMacSecret = 0;
+    ckParam.pReturnedKeyMaterial->hServerMacSecret = 0;
+    ckParam.pReturnedKeyMaterial->hClientKey = 0;
+    ckParam.pReturnedKeyMaterial->hServerKey = 0;
+
+    jByteArrayToCKByteArray(env, jRMIvClient, &(ckParam.pReturnedKeyMaterial->pIVClient), &ckTemp);
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.RandomInfo.pClientRandom);
+        free(ckParam.RandomInfo.pServerRandom);
+        free(ckParam.pReturnedKeyMaterial);
+        return ckParam;
+    }
+    jByteArrayToCKByteArray(env, jRMIvServer, &(ckParam.pReturnedKeyMaterial->pIVServer), &ckTemp);
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.RandomInfo.pClientRandom);
+        free(ckParam.RandomInfo.pServerRandom);
+        free(ckParam.pReturnedKeyMaterial->pIVClient);
+        free(ckParam.pReturnedKeyMaterial);
+        return ckParam;
+    }
+
+    return ckParam ;
+}
+
+/*
+ * converts the Java CK_AES_CTR_PARAMS object to a CK_AES_CTR_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_AES_CTR_PARAMS object to convert
+ * @param ckpParam - pointer to the new CK_AES_CTR_PARAMS structure
+ */
+void jAesCtrParamsToCKAesCtrParam(JNIEnv *env, jobject jParam,
+                                  CK_AES_CTR_PARAMS_PTR ckpParam) {
+    jclass jAesCtrParamsClass;
+    jfieldID fieldID;
+    jlong jCounterBits;
+    jobject jCb;
+    CK_BYTE_PTR ckBytes;
+    CK_ULONG ckTemp;
+
+    /* get ulCounterBits */
+    jAesCtrParamsClass = (*env)->FindClass(env, CLASS_AES_CTR_PARAMS);
+    if (jAesCtrParamsClass == NULL) { return; }
+    fieldID = (*env)->GetFieldID(env, jAesCtrParamsClass, "ulCounterBits", "J");
+    if (fieldID == NULL) { return; }
+    jCounterBits = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get cb */
+    fieldID = (*env)->GetFieldID(env, jAesCtrParamsClass, "cb", "[B");
+    if (fieldID == NULL) { return; }
+    jCb = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckpParam->ulCounterBits = jLongToCKULong(jCounterBits);
+    jByteArrayToCKByteArray(env, jCb, &ckBytes, &ckTemp);
+    if ((*env)->ExceptionCheck(env)) { return; }
+    if (ckTemp != 16) {
+        TRACE1("ERROR: WRONG CTR IV LENGTH %d", ckTemp);
+    } else {
+        memcpy(ckpParam->cb, ckBytes, ckTemp);
+        free(ckBytes);
+    }
+}
+
+/*
+ * converts a Java CK_MECHANISM object into a CK_MECHANISM structure
+ *
+ * @param env - used to call JNI funktions to get the values out of the Java object
+ * @param jMechanism - the Java CK_MECHANISM object to convert
+ * @return - the new CK_MECHANISM structure
+ */
+void jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism, CK_MECHANISM_PTR ckMechanismPtr)
+{
+    jlong jMechanismType = (*env)->GetLongField(env, jMechanism, mech_mechanismID);
+    jobject jParameter = (*env)->GetObjectField(env, jMechanism, mech_pParameterID);
+
+    (*ckMechanismPtr).mechanism = jLongToCKULong(jMechanismType);
+
+    /* convert the specific Java mechanism parameter object to a pointer to a CK-type mechanism
+     * structure
+     */
+    if (jParameter == NULL) {
+        (*ckMechanismPtr).pParameter = NULL;
+        (*ckMechanismPtr).ulParameterLen = 0;
+    } else {
+        jMechanismParameterToCKMechanismParameter(env, jParameter, &(*ckMechanismPtr).pParameter, &(*ckMechanismPtr).ulParameterLen);
+    }
+}
+
+/*
+ * the following functions convert Attribute and Mechanism value pointers
+ *
+ * jobject ckAttributeValueToJObject(JNIEnv *env,
+ *                                   const CK_ATTRIBUTE_PTR ckpAttribute);
+ *
+ * void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env,
+ *                                       jobject jObject,
+ *                                       CK_VOID_PTR *ckpObjectPtr,
+ *                                       CK_ULONG *pLength);
+ *
+ * void jMechanismParameterToCKMechanismParameter(JNIEnv *env,
+ *                                                jobject jParam,
+ *                                                CK_VOID_PTR *ckpParamPtr,
+ *                                                CK_ULONG *ckpLength);
+ *
+ * These functions are used if a PKCS#11 mechanism or attribute structure gets
+ * convertet to a Java attribute or mechanism object or vice versa.
+ *
+ * ckAttributeValueToJObject converts a PKCS#11 attribute value pointer to a Java
+ * object depending on the type of the Attribute. A PKCS#11 attribute value can
+ * be a CK_ULONG, CK_BYTE[], CK_CHAR[], big integer, CK_BBOOL, CK_UTF8CHAR[],
+ * CK_DATE or CK_FLAGS that gets converted to a corresponding Java object.
+ *
+ * jObjectToPrimitiveCKObjectPtrPtr is used by jAttributeToCKAttributePtr for
+ * converting the Java attribute value to a PKCS#11 attribute value pointer.
+ * For now only primitive datatypes and arrays of primitive datatypes can get
+ * converted. Otherwise this function throws a PKCS#11Exception with the
+ * errorcode CKR_VENDOR_DEFINED.
+ *
+ * jMechanismParameterToCKMechanismParameter converts a Java mechanism parameter
+ * to a PKCS#11 mechanism parameter. First this function determines what mechanism
+ * parameter the Java object is, then it allocates the memory for the new PKCS#11
+ * structure and calls the corresponding function to convert the Java object to
+ * a PKCS#11 mechanism parameter structure.
+ */
+
+/*
+ * converts the pValue of a CK_ATTRIBUTE structure into a Java Object by checking the type
+ * of the attribute.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpAttribute - the pointer to the CK_ATTRIBUTE structure that contains the type
+ *                       and the pValue to convert
+ * @return - the new Java object of the CK-type pValue
+ */
+jobject ckAttributeValueToJObject(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute)
+{
+    jint jValueLength;
+    jobject jValueObject = NULL;
+
+    jValueLength = ckULongToJInt(ckpAttribute->ulValueLen);
+
+    if ((jValueLength <= 0) || (ckpAttribute->pValue == NULL)) {
+        return NULL ;
+    }
+
+    switch(ckpAttribute->type) {
+        case CKA_CLASS:
+            /* value CK_OBJECT_CLASS, defacto a CK_ULONG */
+        case CKA_KEY_TYPE:
+            /* value CK_KEY_TYPE, defacto a CK_ULONG */
+        case CKA_CERTIFICATE_TYPE:
+            /* value CK_CERTIFICATE_TYPE, defacto a CK_ULONG */
+        case CKA_HW_FEATURE_TYPE:
+            /* value CK_HW_FEATURE_TYPE, defacto a CK_ULONG */
+        case CKA_MODULUS_BITS:
+        case CKA_VALUE_BITS:
+        case CKA_VALUE_LEN:
+        case CKA_KEY_GEN_MECHANISM:
+        case CKA_PRIME_BITS:
+        case CKA_SUB_PRIME_BITS:
+            /* value CK_ULONG */
+            jValueObject = ckULongPtrToJLongObject(env, (CK_ULONG*) ckpAttribute->pValue);
+            break;
+
+            /* can be CK_BYTE[],CK_CHAR[] or big integer; defacto always CK_BYTE[] */
+        case CKA_VALUE:
+        case CKA_OBJECT_ID:
+        case CKA_SUBJECT:
+        case CKA_ID:
+        case CKA_ISSUER:
+        case CKA_SERIAL_NUMBER:
+        case CKA_OWNER:
+        case CKA_AC_ISSUER:
+        case CKA_ATTR_TYPES:
+        case CKA_ECDSA_PARAMS:
+            /* CKA_EC_PARAMS is the same, these two are equivalent */
+        case CKA_EC_POINT:
+        case CKA_PRIVATE_EXPONENT:
+        case CKA_PRIME_1:
+        case CKA_PRIME_2:
+        case CKA_EXPONENT_1:
+        case CKA_EXPONENT_2:
+        case CKA_COEFFICIENT:
+            /* value CK_BYTE[] */
+            jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
+            break;
+
+        case CKA_RESET_ON_INIT:
+        case CKA_HAS_RESET:
+        case CKA_TOKEN:
+        case CKA_PRIVATE:
+        case CKA_MODIFIABLE:
+        case CKA_DERIVE:
+        case CKA_LOCAL:
+        case CKA_ENCRYPT:
+        case CKA_VERIFY:
+        case CKA_VERIFY_RECOVER:
+        case CKA_WRAP:
+        case CKA_SENSITIVE:
+        case CKA_SECONDARY_AUTH:
+        case CKA_DECRYPT:
+        case CKA_SIGN:
+        case CKA_SIGN_RECOVER:
+        case CKA_UNWRAP:
+        case CKA_EXTRACTABLE:
+        case CKA_ALWAYS_SENSITIVE:
+        case CKA_NEVER_EXTRACTABLE:
+        case CKA_TRUSTED:
+            /* value CK_BBOOL */
+            jValueObject = ckBBoolPtrToJBooleanObject(env, (CK_BBOOL*) ckpAttribute->pValue);
+            break;
+
+        case CKA_LABEL:
+        case CKA_APPLICATION:
+            /* value RFC 2279 (UTF-8) string */
+            jValueObject = ckUTF8CharArrayToJCharArray(env, (CK_UTF8CHAR*) ckpAttribute->pValue, jValueLength);
+            break;
+
+        case CKA_START_DATE:
+        case CKA_END_DATE:
+            /* value CK_DATE */
+            jValueObject = ckDatePtrToJDateObject(env, (CK_DATE*) ckpAttribute->pValue);
+            break;
+
+        case CKA_MODULUS:
+        case CKA_PUBLIC_EXPONENT:
+        case CKA_PRIME:
+        case CKA_SUBPRIME:
+        case CKA_BASE:
+            /* value big integer, i.e. CK_BYTE[] */
+            jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
+            break;
+
+        case CKA_AUTH_PIN_FLAGS:
+            jValueObject = ckULongPtrToJLongObject(env, (CK_ULONG*) ckpAttribute->pValue);
+            /* value FLAGS, defacto a CK_ULONG */
+            break;
+
+        case CKA_VENDOR_DEFINED:
+            /* we make a CK_BYTE[] out of this */
+            jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
+            break;
+
+        // Netscape trust attributes
+        case CKA_NETSCAPE_TRUST_SERVER_AUTH:
+        case CKA_NETSCAPE_TRUST_CLIENT_AUTH:
+        case CKA_NETSCAPE_TRUST_CODE_SIGNING:
+        case CKA_NETSCAPE_TRUST_EMAIL_PROTECTION:
+            /* value CK_ULONG */
+            jValueObject = ckULongPtrToJLongObject(env, (CK_ULONG*) ckpAttribute->pValue);
+            break;
+
+        default:
+            /* we make a CK_BYTE[] out of this */
+            jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
+            break;
+    }
+
+    return jValueObject ;
+}
+
+/*
+ * the following functions convert a Java mechanism parameter object to a PKCS#11
+ * mechanism parameter structure
+ *
+ * CK_<Param>_PARAMS j<Param>ParamToCK<Param>Param(JNIEnv *env,
+ *                                                 jobject jParam);
+ *
+ * These functions get a Java object, that must be the right Java mechanism
+ * object and they return the new PKCS#11 mechanism parameter structure.
+ * Every field of the Java object is retrieved, gets converted to a corresponding
+ * PKCS#11 type and is set in the new PKCS#11 structure.
+ */
+
+/*
+ * converts the given Java mechanism parameter to a CK mechanism parameter structure
+ * and store the length in bytes in the length variable.
+ * The memory of *ckpParamPtr has to be freed after use!
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java mechanism parameter object to convert
+ * @param ckpParamPtr - the reference of the new pointer to the new CK mechanism parameter
+ *                      structure
+ * @param ckpLength - the reference of the length in bytes of the new CK mechanism parameter
+ *                    structure
+ */
+void jMechanismParameterToCKMechanismParameter(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength)
+{
+    if (jParam == NULL) {
+        *ckpParamPtr = NULL;
+        *ckpLength = 0;
+    } else if ((*env)->IsInstanceOf(env, jParam, jByteArrayClass)) {
+        jByteArrayToCKByteArray(env, jParam, (CK_BYTE_PTR *)ckpParamPtr, ckpLength);
+    } else if ((*env)->IsInstanceOf(env, jParam, jLongClass)) {
+        *ckpParamPtr = jLongObjectToCKULongPtr(env, jParam);
+        *ckpLength = sizeof(CK_ULONG);
+    } else {
+        TRACE0("\nSLOW PATH jMechanismParameterToCKMechanismParameter\n");
+        jMechanismParameterToCKMechanismParameterSlow(env, jParam, ckpParamPtr, ckpLength);
+    }
+}
+
+void jMechanismParameterToCKMechanismParameterSlow(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength)
+{
+    /* get all Java mechanism parameter classes */
+    jclass jVersionClass, jSsl3MasterKeyDeriveParamsClass, jSsl3KeyMatParamsClass;
+    jclass jTlsPrfParamsClass, jAesCtrParamsClass, jRsaPkcsOaepParamsClass;
+    jclass jPbeParamsClass, jPkcs5Pbkd2ParamsClass, jRsaPkcsPssParamsClass;
+    jclass jEcdh1DeriveParamsClass, jEcdh2DeriveParamsClass;
+    jclass jX942Dh1DeriveParamsClass, jX942Dh2DeriveParamsClass;
+    TRACE0("\nDEBUG: jMechanismParameterToCKMechanismParameter");
+
+    /* most common cases, i.e. NULL/byte[]/long, are already handled by
+     * jMechanismParameterToCKMechanismParameter before calling this method.
+     */
+    jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
+    if (jVersionClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jVersionClass)) {
+        /*
+         * CK_VERSION used by CKM_SSL3_PRE_MASTER_KEY_GEN
+         */
+        CK_VERSION_PTR ckpParam;
+
+        /* convert jParameter to CKParameter */
+        ckpParam = jVersionToCKVersionPtr(env, jParam);
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_VERSION);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
+    if (jSsl3MasterKeyDeriveParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jSsl3MasterKeyDeriveParamsClass)) {
+        /*
+         * CK_SSL3_MASTER_KEY_DERIVE_PARAMS
+         */
+        CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR) malloc(sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
+    if (jSsl3KeyMatParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jSsl3KeyMatParamsClass)) {
+        /*
+         * CK_SSL3_KEY_MAT_PARAMS
+         */
+        CK_SSL3_KEY_MAT_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_SSL3_KEY_MAT_PARAMS_PTR) malloc(sizeof(CK_SSL3_KEY_MAT_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jSsl3KeyMatParamToCKSsl3KeyMatParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_SSL3_KEY_MAT_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jTlsPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
+    if (jTlsPrfParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jTlsPrfParamsClass)) {
+        /*
+         * CK_TLS_PRF_PARAMS
+         */
+        CK_TLS_PRF_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_TLS_PRF_PARAMS_PTR) malloc(sizeof(CK_TLS_PRF_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jTlsPrfParamsToCKTlsPrfParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_TLS_PRF_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jAesCtrParamsClass = (*env)->FindClass(env, CLASS_AES_CTR_PARAMS);
+    if (jAesCtrParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jAesCtrParamsClass)) {
+        /*
+         * CK_AES_CTR_PARAMS
+         */
+        CK_AES_CTR_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_AES_CTR_PARAMS_PTR) malloc(sizeof(CK_AES_CTR_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        jAesCtrParamsToCKAesCtrParam(env, jParam, ckpParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_AES_CTR_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS);
+    if (jRsaPkcsOaepParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jRsaPkcsOaepParamsClass)) {
+        /*
+         * CK_RSA_PKCS_OAEP_PARAMS
+         */
+        CK_RSA_PKCS_OAEP_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_RSA_PKCS_OAEP_PARAMS_PTR) malloc(sizeof(CK_RSA_PKCS_OAEP_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jRsaPkcsOaepParamToCKRsaPkcsOaepParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
+    if (jPbeParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jPbeParamsClass)) {
+        /*
+         * CK_PBE_PARAMS
+         */
+        CK_PBE_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_PBE_PARAMS_PTR) malloc(sizeof(CK_PBE_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jPbeParamToCKPbeParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_PBE_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS);
+    if (jPkcs5Pbkd2ParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jPkcs5Pbkd2ParamsClass)) {
+        /*
+         * CK_PKCS5_PBKD2_PARAMS
+         */
+        CK_PKCS5_PBKD2_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_PKCS5_PBKD2_PARAMS_PTR) malloc(sizeof(CK_PKCS5_PBKD2_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_PKCS5_PBKD2_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jRsaPkcsPssParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_PSS_PARAMS);
+    if (jRsaPkcsPssParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jRsaPkcsPssParamsClass)) {
+        /*
+         * CK_RSA_PKCS_PSS_PARAMS
+         */
+        CK_RSA_PKCS_PSS_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_RSA_PKCS_PSS_PARAMS_PTR) malloc(sizeof(CK_RSA_PKCS_PSS_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jRsaPkcsPssParamToCKRsaPkcsPssParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_RSA_PKCS_PSS_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jEcdh1DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH1_DERIVE_PARAMS);
+    if (jEcdh1DeriveParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jEcdh1DeriveParamsClass)) {
+        /*
+         * CK_ECDH1_DERIVE_PARAMS
+         */
+        CK_ECDH1_DERIVE_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_ECDH1_DERIVE_PARAMS_PTR) malloc(sizeof(CK_ECDH1_DERIVE_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jEcdh1DeriveParamToCKEcdh1DeriveParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_ECDH1_DERIVE_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jEcdh2DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH2_DERIVE_PARAMS);
+    if (jEcdh2DeriveParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jEcdh2DeriveParamsClass)) {
+        /*
+         * CK_ECDH2_DERIVE_PARAMS
+         */
+        CK_ECDH2_DERIVE_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_ECDH2_DERIVE_PARAMS_PTR) malloc(sizeof(CK_ECDH2_DERIVE_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jEcdh2DeriveParamToCKEcdh2DeriveParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_ECDH2_DERIVE_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS);
+    if (jX942Dh1DeriveParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jX942Dh1DeriveParamsClass)) {
+        /*
+         * CK_X9_42_DH1_DERIVE_PARAMS
+         */
+        CK_X9_42_DH1_DERIVE_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_X9_42_DH1_DERIVE_PARAMS_PTR) malloc(sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jX942Dh1DeriveParamToCKX942Dh1DeriveParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_X9_42_DH1_DERIVE_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS);
+    if (jX942Dh2DeriveParamsClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jParam, jX942Dh2DeriveParamsClass)) {
+        /*
+         * CK_X9_42_DH2_DERIVE_PARAMS
+         */
+        CK_X9_42_DH2_DERIVE_PARAMS_PTR ckpParam;
+
+        ckpParam = (CK_X9_42_DH2_DERIVE_PARAMS_PTR) malloc(sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
+        if (ckpParam == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+
+        /* convert jParameter to CKParameter */
+        *ckpParam = jX942Dh2DeriveParamToCKX942Dh2DeriveParam(env, jParam);
+        if ((*env)->ExceptionCheck(env)) {
+            free(ckpParam);
+            return;
+        }
+
+        /* get length and pointer of parameter */
+        *ckpLength = sizeof(CK_X9_42_DH2_DERIVE_PARAMS);
+        *ckpParamPtr = ckpParam;
+        return;
+    }
+
+    /* if everything faild up to here */
+    /* try if the parameter is a primitive Java type */
+    jObjectToPrimitiveCKObjectPtrPtr(env, jParam, ckpParamPtr, ckpLength);
+    /* *ckpParamPtr = jObjectToCKVoidPtr(jParam); */
+    /* *ckpLength = 1; */
+
+    TRACE0("FINISHED\n");
+}
+
+
+/* the mechanism parameter convertion functions: */
+
+/*
+ * converts the Java CK_RSA_PKCS_OAEP_PARAMS object to a CK_RSA_PKCS_OAEP_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_RSA_PKCS_OAEP_PARAMS object to convert
+ * @return - the new CK_RSA_PKCS_OAEP_PARAMS structure
+ */
+CK_RSA_PKCS_OAEP_PARAMS jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobject jParam)
+{
+    jclass jRsaPkcsOaepParamsClass;
+    CK_RSA_PKCS_OAEP_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jHashAlg, jMgf, jSource;
+    jobject jSourceData;
+    CK_BYTE_PTR ckpByte;
+    memset(&ckParam, 0, sizeof(CK_RSA_PKCS_OAEP_PARAMS));
+
+    /* get hashAlg */
+    jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS);
+    if (jRsaPkcsOaepParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "hashAlg", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jHashAlg = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get mgf */
+    fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "mgf", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jMgf = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get source */
+    fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "source", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jSource = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get sourceData and sourceDataLength */
+    fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "pSourceData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jSourceData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.hashAlg = jLongToCKULong(jHashAlg);
+    ckParam.mgf = jLongToCKULong(jMgf);
+    ckParam.source = jLongToCKULong(jSource);
+    jByteArrayToCKByteArray(env, jSourceData, & ckpByte, &(ckParam.ulSourceDataLen));
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    ckParam.pSourceData = (CK_VOID_PTR) ckpByte;
+
+    return ckParam ;
+}
+
+/*
+ * converts the Java CK_PBE_PARAMS object to a CK_PBE_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_PBE_PARAMS object to convert
+ * @return - the new CK_PBE_PARAMS structure
+ */
+CK_PBE_PARAMS jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam)
+{
+    jclass jPbeParamsClass;
+    CK_PBE_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jIteration;
+    jobject jInitVector, jPassword, jSalt;
+    CK_ULONG ckTemp;
+    memset(&ckParam, 0, sizeof(CK_PBE_PARAMS));
+
+    /* get pInitVector */
+    jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
+    if (jPbeParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVector", "[C");
+    if (fieldID == NULL) { return ckParam; }
+    jInitVector = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pPassword and ulPasswordLength */
+    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pPassword", "[C");
+    if (fieldID == NULL) { return ckParam; }
+    jPassword = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pSalt and ulSaltLength */
+    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pSalt", "[C");
+    if (fieldID == NULL) { return ckParam; }
+    jSalt = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get ulIteration */
+    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "ulIteration", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jIteration = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.ulIteration = jLongToCKULong(jIteration);
+    jCharArrayToCKCharArray(env, jInitVector, &(ckParam.pInitVector), &ckTemp);
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    jCharArrayToCKCharArray(env, jPassword, &(ckParam.pPassword), &(ckParam.ulPasswordLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pInitVector);
+        return ckParam;
+    }
+    jCharArrayToCKCharArray(env, jSalt, &(ckParam.pSalt), &(ckParam.ulSaltLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pInitVector);
+        free(ckParam.pPassword);
+        return ckParam;
+    }
+
+    return ckParam ;
+}
+
+/*
+ * Copy back the initialization vector from the native structure to the
+ * Java object. This is only used for CKM_PBE_* mechanisms and their
+ * CK_PBE_PARAMS parameters.
+ *
+ */
+void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
+{
+    jclass jMechanismClass, jPbeParamsClass;
+    CK_PBE_PARAMS *ckParam;
+    jfieldID fieldID;
+    CK_MECHANISM_TYPE ckMechanismType;
+    jlong jMechanismType;
+    jobject jParameter;
+    jobject jInitVector;
+    jint jInitVectorLength;
+    CK_CHAR_PTR initVector;
+    int i;
+    jchar* jInitVectorChars;
+
+    /* get mechanism */
+    jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
+    if (jMechanismClass == NULL) { return; }
+    fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
+    if (fieldID == NULL) { return; }
+    jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
+    ckMechanismType = jLongToCKULong(jMechanismType);
+    if (ckMechanismType != ckMechanism->mechanism) {
+        /* we do not have maching types, this should not occur */
+        return;
+    }
+
+    jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
+    if (jPbeParamsClass == NULL) { return; }
+    ckParam = (CK_PBE_PARAMS *) ckMechanism->pParameter;
+    if (ckParam != NULL_PTR) {
+        initVector = ckParam->pInitVector;
+        if (initVector != NULL_PTR) {
+            /* get pParameter */
+            fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
+            if (fieldID == NULL) { return; }
+            jParameter = (*env)->GetObjectField(env, jMechanism, fieldID);
+            fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVektor", "[C");
+            if (fieldID == NULL) { return; }
+            jInitVector = (*env)->GetObjectField(env, jParameter, fieldID);
+
+            if (jInitVector != NULL) {
+                jInitVectorLength = (*env)->GetArrayLength(env, jInitVector);
+                jInitVectorChars = (*env)->GetCharArrayElements(env, jInitVector, NULL);
+                if (jInitVectorChars == NULL) { return; }
+
+                /* copy the chars to the Java buffer */
+                for (i=0; i < jInitVectorLength; i++) {
+                    jInitVectorChars[i] = ckCharToJChar(initVector[i]);
+                }
+                /* copy back the Java buffer to the object */
+                (*env)->ReleaseCharArrayElements(env, jInitVector, jInitVectorChars, 0);
+            }
+        }
+    }
+}
+
+/*
+ * converts the Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_PKCS5_PBKD2_PARAMS object to convert
+ * @return - the new CK_PKCS5_PBKD2_PARAMS structure
+ */
+CK_PKCS5_PBKD2_PARAMS jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject jParam)
+{
+    jclass jPkcs5Pbkd2ParamsClass;
+    CK_PKCS5_PBKD2_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jSaltSource, jIteration, jPrf;
+    jobject jSaltSourceData, jPrfData;
+    memset(&ckParam, 0, sizeof(CK_PKCS5_PBKD2_PARAMS));
+
+    /* get saltSource */
+    jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS);
+    if (jPkcs5Pbkd2ParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "saltSource", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jSaltSource = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get pSaltSourceData */
+    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pSaltSourceData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jSaltSourceData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get iterations */
+    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "iterations", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jIteration = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get prf */
+    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "prf", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jPrf = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get pPrfData and ulPrfDataLength in byte */
+    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pPrfData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jPrfData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.saltSource = jLongToCKULong(jSaltSource);
+    jByteArrayToCKByteArray(env, jSaltSourceData, (CK_BYTE_PTR *) &(ckParam.pSaltSourceData), &(ckParam.ulSaltSourceDataLen));
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    ckParam.iterations = jLongToCKULong(jIteration);
+    ckParam.prf = jLongToCKULong(jPrf);
+    jByteArrayToCKByteArray(env, jPrfData, (CK_BYTE_PTR *) &(ckParam.pPrfData), &(ckParam.ulPrfDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pSaltSourceData);
+        return ckParam;
+    }
+
+    return ckParam ;
+}
+
+/*
+ * converts the Java CK_RSA_PKCS_PSS_PARAMS object to a CK_RSA_PKCS_PSS_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_RSA_PKCS_PSS_PARAMS object to convert
+ * @return - the new CK_RSA_PKCS_PSS_PARAMS structure
+ */
+CK_RSA_PKCS_PSS_PARAMS jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam)
+{
+    jclass jRsaPkcsPssParamsClass;
+    CK_RSA_PKCS_PSS_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jHashAlg, jMgf, jSLen;
+    memset(&ckParam, 0, sizeof(CK_RSA_PKCS_PSS_PARAMS));
+
+    /* get hashAlg */
+    jRsaPkcsPssParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_PSS_PARAMS);
+    if (jRsaPkcsPssParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "hashAlg", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jHashAlg = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get mgf */
+    fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "mgf", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jMgf = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get sLen */
+    fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "sLen", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jSLen = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.hashAlg = jLongToCKULong(jHashAlg);
+    ckParam.mgf = jLongToCKULong(jMgf);
+    ckParam.sLen = jLongToCKULong(jSLen);
+
+    return ckParam ;
+}
+
+/*
+ * converts the Java CK_ECDH1_DERIVE_PARAMS object to a CK_ECDH1_DERIVE_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_ECDH1_DERIVE_PARAMS object to convert
+ * @return - the new CK_ECDH1_DERIVE_PARAMS structure
+ */
+CK_ECDH1_DERIVE_PARAMS jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam)
+{
+    jclass jEcdh1DeriveParamsClass;
+    CK_ECDH1_DERIVE_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jLong;
+    jobject jSharedData, jPublicData;
+    memset(&ckParam, 0, sizeof(CK_ECDH1_DERIVE_PARAMS));
+
+    /* get kdf */
+    jEcdh1DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH1_DERIVE_PARAMS);
+    if (jEcdh1DeriveParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "kdf", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jLong = (*env)->GetLongField(env, jParam, fieldID);
+    ckParam.kdf = jLongToCKULong(jLong);
+
+    /* get pSharedData and ulSharedDataLen */
+    fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "pSharedData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jSharedData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pPublicData and ulPublicDataLen */
+    fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "pPublicData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.kdf = jLongToCKULong(jLong);
+    jByteArrayToCKByteArray(env, jSharedData, &(ckParam.pSharedData), &(ckParam.ulSharedDataLen));
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    jByteArrayToCKByteArray(env, jPublicData, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pSharedData);
+        return ckParam;
+    }
+
+    return ckParam ;
+}
+
+/*
+ * converts the Java CK_ECDH2_DERIVE_PARAMS object to a CK_ECDH2_DERIVE_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_ECDH2_DERIVE_PARAMS object to convert
+ * @return - the new CK_ECDH2_DERIVE_PARAMS structure
+ */
+CK_ECDH2_DERIVE_PARAMS jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv *env, jobject jParam)
+{
+    jclass jEcdh2DeriveParamsClass;
+    CK_ECDH2_DERIVE_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jKdf, jPrivateDataLen, jPrivateData;
+    jobject jSharedData, jPublicData, jPublicData2;
+    memset(&ckParam, 0, sizeof(CK_ECDH2_DERIVE_PARAMS));
+
+    /* get kdf */
+    jEcdh2DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH2_DERIVE_PARAMS);
+    if (jEcdh2DeriveParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "kdf", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jKdf = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get pSharedData and ulSharedDataLen */
+    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pSharedData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jSharedData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pPublicData and ulPublicDataLen */
+    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pPublicData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get ulPrivateDataLen */
+    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "ulPrivateDataLen", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jPrivateDataLen = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get hPrivateData */
+    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "hPrivateData", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jPrivateData = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get pPublicData2 and ulPublicDataLen2 */
+    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pPublicData2", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jPublicData2 = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.kdf = jLongToCKULong(jKdf);
+    jByteArrayToCKByteArray(env, jSharedData, &(ckParam.pSharedData), &(ckParam.ulSharedDataLen));
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    jByteArrayToCKByteArray(env, jPublicData, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pSharedData);
+        return ckParam;
+    }
+    ckParam.ulPrivateDataLen = jLongToCKULong(jPrivateDataLen);
+    ckParam.hPrivateData = jLongToCKULong(jPrivateData);
+    jByteArrayToCKByteArray(env, jPublicData2, &(ckParam.pPublicData2), &(ckParam.ulPublicDataLen2));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pSharedData);
+        free(ckParam.pPublicData);
+        return ckParam;
+    }
+    return ckParam ;
+}
+
+/*
+ * converts the Java CK_X9_42_DH1_DERIVE_PARAMS object to a CK_X9_42_DH1_DERIVE_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_X9_42_DH1_DERIVE_PARAMS object to convert
+ * @return - the new CK_X9_42_DH1_DERIVE_PARAMS structure
+ */
+CK_X9_42_DH1_DERIVE_PARAMS jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env, jobject jParam)
+{
+    jclass jX942Dh1DeriveParamsClass;
+    CK_X9_42_DH1_DERIVE_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jKdf;
+    jobject jOtherInfo, jPublicData;
+    memset(&ckParam, 0, sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
+
+    /* get kdf */
+    jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS);
+    if (jX942Dh1DeriveParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "kdf", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jKdf = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get pOtherInfo and ulOtherInfoLen */
+    fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "pOtherInfo", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jOtherInfo = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pPublicData and ulPublicDataLen */
+    fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "pPublicData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.kdf = jLongToCKULong(jKdf);
+    jByteArrayToCKByteArray(env, jOtherInfo, &(ckParam.pOtherInfo), &(ckParam.ulOtherInfoLen));
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    jByteArrayToCKByteArray(env, jPublicData, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pOtherInfo);
+        return ckParam;
+    }
+
+    return ckParam ;
+}
+
+/*
+ * converts the Java CK_X9_42_DH2_DERIVE_PARAMS object to a CK_X9_42_DH2_DERIVE_PARAMS structure
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jParam - the Java CK_X9_42_DH2_DERIVE_PARAMS object to convert
+ * @return - the new CK_X9_42_DH2_DERIVE_PARAMS structure
+ */
+CK_X9_42_DH2_DERIVE_PARAMS jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env, jobject jParam)
+{
+    jclass jX942Dh2DeriveParamsClass;
+    CK_X9_42_DH2_DERIVE_PARAMS ckParam;
+    jfieldID fieldID;
+    jlong jKdf, jPrivateDataLen, jPrivateData;
+    jobject jOtherInfo, jPublicData, jPublicData2;
+    memset(&ckParam, 0, sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
+
+    /* get kdf */
+    jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS);
+    if (jX942Dh2DeriveParamsClass == NULL) { return ckParam; }
+    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "kdf", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jKdf = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get pOtherInfo and ulOtherInfoLen */
+    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pOtherInfo", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jOtherInfo = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get pPublicData and ulPublicDataLen */
+    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pPublicData", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* get ulPrivateDataLen */
+    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "ulPrivateDataLen", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jPrivateDataLen = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get hPrivateData */
+    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "hPrivateData", "J");
+    if (fieldID == NULL) { return ckParam; }
+    jPrivateData = (*env)->GetLongField(env, jParam, fieldID);
+
+    /* get pPublicData2 and ulPublicDataLen2 */
+    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pPublicData2", "[B");
+    if (fieldID == NULL) { return ckParam; }
+    jPublicData2 = (*env)->GetObjectField(env, jParam, fieldID);
+
+    /* populate java values */
+    ckParam.kdf = jLongToCKULong(jKdf);
+    jByteArrayToCKByteArray(env, jOtherInfo, &(ckParam.pOtherInfo), &(ckParam.ulOtherInfoLen));
+    if ((*env)->ExceptionCheck(env)) { return ckParam; }
+    jByteArrayToCKByteArray(env, jPublicData, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pOtherInfo);
+        return ckParam;
+    }
+    ckParam.ulPrivateDataLen = jLongToCKULong(jPrivateDataLen);
+    ckParam.hPrivateData = jLongToCKULong(jPrivateData);
+    jByteArrayToCKByteArray(env, jPublicData2, &(ckParam.pPublicData2), &(ckParam.ulPublicDataLen2));
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckParam.pOtherInfo);
+        free(ckParam.pPublicData);
+        return ckParam;
+    }
+
+    return ckParam ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ * ===========================================================================
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+#ifdef P11_ENABLE_C_ENCRYPTINIT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_EncryptInit
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptInit
+(JNIEnv *env, jobject obj, jlong jSessionHandle,
+ jobject jMechanism, jlong jKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckKeyHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckKeyHandle = jLongToCKULong(jKeyHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, &ckMechanism,
+                                        ckKeyHandle);
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_ENCRYPT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Encrypt
+ * Signature: (J[BII[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jData            CK_BYTE_PTR pData
+ *                                      CK_ULONG ulDataLen
+ * @return  jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
+ *                                      CK_ULONG_PTR pulEncryptedDataLen
+ */
+JNIEXPORT jint JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
+(JNIEnv *env, jobject obj, jlong jSessionHandle,
+ jbyteArray jIn, jint jInOfs, jint jInLen,
+ jbyteArray jOut, jint jOutOfs, jint jOutLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+
+    CK_BYTE_PTR inBufP;
+    CK_BYTE_PTR outBufP;
+    CK_ULONG ckEncryptedPartLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
+    if (inBufP == NULL) { return 0; }
+
+    outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
+    if (outBufP == NULL) {
+        // Make sure to release inBufP
+        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+        return 0;
+    }
+
+    ckEncryptedPartLen = jOutLen;
+
+    rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle,
+                                    (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
+                                    (CK_BYTE_PTR)(outBufP + jOutOfs),
+                                    &ckEncryptedPartLen);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+    (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+
+    ckAssertReturnValueOK(env, rv);
+    return ckEncryptedPartLen;
+}
+#endif
+
+#ifdef P11_ENABLE_C_ENCRYPTUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_EncryptUpdate
+ * Signature: (J[BII[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jPart            CK_BYTE_PTR pPart
+ *                                      CK_ULONG ulPartLen
+ * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
+ *                                      CK_ULONG_PTR pulEncryptedPartLen
+ */
+JNIEXPORT jint JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
+(JNIEnv *env, jobject obj, jlong jSessionHandle,
+ jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
+ jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+
+    CK_BYTE_PTR inBufP;
+    CK_BYTE_PTR outBufP;
+    CK_ULONG ckEncryptedPartLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (directIn != 0) {
+      inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
+    } else {
+      inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
+      if (inBufP == NULL) { return 0; }
+    }
+
+    if (directOut != 0) {
+      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
+    } else {
+      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
+      if (outBufP == NULL) {
+          // Make sure to release inBufP
+          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+          return 0;
+      }
+    }
+
+    ckEncryptedPartLen = jOutLen;
+
+    //printf("EU: inBufP=%i, jInOfs=%i, jInLen=%i, outBufP=%i\n",
+    //       inBufP, jInOfs, jInLen, outBufP);
+
+    rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle,
+                                          (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
+                                          (CK_BYTE_PTR)(outBufP + jOutOfs),
+                                          &ckEncryptedPartLen);
+
+    //printf("EU: ckEncryptedPartLen=%i\n", ckEncryptedPartLen);
+
+    if (directIn == 0) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+    }
+
+    if (directOut == 0) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+    }
+
+    ckAssertReturnValueOK(env, rv);
+
+    return ckEncryptedPartLen;
+}
+#endif
+
+#ifdef P11_ENABLE_C_ENCRYPTFINAL
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_EncryptFinal
+ * Signature: (J[BII)I
+ * Parametermapping:                        *PKCS11*
+ * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
+ * @return  jbyteArray jLastEncryptedPart   CK_BYTE_PTR pLastEncryptedDataPart
+ *                                          CK_ULONG_PTR pulLastEncryptedDataPartLen
+ */
+JNIEXPORT jint JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal
+(JNIEnv *env, jobject obj, jlong jSessionHandle,
+ jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE_PTR outBufP;
+    CK_ULONG ckLastEncryptedPartLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (directOut != 0) {
+      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
+    } else {
+      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
+      if (outBufP == NULL) { return 0; }
+    }
+
+    ckLastEncryptedPartLen = jOutLen;
+
+    //printf("EF: outBufP=%i\n", outBufP);
+
+    rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle,
+                                         (CK_BYTE_PTR)(outBufP + jOutOfs),
+                                         &ckLastEncryptedPartLen);
+
+    //printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen);
+
+    if (directOut == 0) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+    }
+
+    ckAssertReturnValueOK(env, rv);
+
+    return ckLastEncryptedPartLen;
+}
+#endif
+
+#ifdef P11_ENABLE_C_DECRYPTINIT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DecryptInit
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptInit
+(JNIEnv *env, jobject obj, jlong jSessionHandle,
+ jobject jMechanism, jlong jKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckKeyHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckKeyHandle = jLongToCKULong(jKeyHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, &ckMechanism,
+                                        ckKeyHandle);
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_DECRYPT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Decrypt
+ * Signature: (J[BII[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
+ *                                      CK_ULONG ulEncryptedDataLen
+ * @return  jbyteArray jData            CK_BYTE_PTR pData
+ *                                      CK_ULONG_PTR pulDataLen
+ */
+JNIEXPORT jint JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
+(JNIEnv *env, jobject obj, jlong jSessionHandle,
+ jbyteArray jIn, jint jInOfs, jint jInLen,
+ jbyteArray jOut, jint jOutOfs, jint jOutLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+
+    CK_BYTE_PTR inBufP;
+    CK_BYTE_PTR outBufP;
+    CK_ULONG ckPartLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
+    if (inBufP == NULL) { return 0; }
+
+    outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
+    if (outBufP == NULL) {
+        // Make sure to release inBufP
+        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+        return 0;
+    }
+
+    ckPartLen = jOutLen;
+
+    rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle,
+                                    (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
+                                    (CK_BYTE_PTR)(outBufP + jOutOfs),
+                                    &ckPartLen);
+
+    (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+    (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+
+    ckAssertReturnValueOK(env, rv);
+
+    return ckPartLen;
+}
+#endif
+
+#ifdef P11_ENABLE_C_DECRYPTUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DecryptUpdate
+ * Signature: (J[BII[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
+ *                                      CK_ULONG ulEncryptedPartLen
+ * @return  jbyteArray jPart            CK_BYTE_PTR pPart
+ *                                      CK_ULONG_PTR pulPartLen
+ */
+JNIEXPORT jint JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
+(JNIEnv *env, jobject obj, jlong jSessionHandle,
+ jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
+ jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+
+    CK_BYTE_PTR inBufP;
+    CK_BYTE_PTR outBufP;
+    CK_ULONG ckDecryptedPartLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (directIn != 0) {
+      inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
+    } else {
+      inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
+      if (inBufP == NULL) { return 0; }
+    }
+
+    if (directOut != 0) {
+      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
+    } else {
+      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
+      if (outBufP == NULL) {
+          // Make sure to release inBufP
+          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+          return 0;
+      }
+    }
+
+    ckDecryptedPartLen = jOutLen;
+
+    rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle,
+                                          (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
+                                          (CK_BYTE_PTR)(outBufP + jOutOfs),
+                                          &ckDecryptedPartLen);
+    if (directIn == 0) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+    }
+
+    if (directOut == 0) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+    }
+
+    ckAssertReturnValueOK(env, rv);
+
+    return ckDecryptedPartLen;
+}
+
+#endif
+
+#ifdef P11_ENABLE_C_DECRYPTFINAL
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DecryptFinal
+ * Signature: (J[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @return  jbyteArray jLastPart        CK_BYTE_PTR pLastPart
+ *                                      CK_ULONG_PTR pulLastPartLen
+ */
+JNIEXPORT jint JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal
+(JNIEnv *env, jobject obj, jlong jSessionHandle,
+ jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE_PTR outBufP;
+    CK_ULONG ckLastPartLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (directOut != 0) {
+      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
+    } else {
+      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
+      if (outBufP == NULL) { return 0; }
+    }
+
+    ckLastPartLen = jOutLen;
+
+    rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle,
+                                         (CK_BYTE_PTR)(outBufP + jOutOfs),
+                                         &ckLastPartLen);
+
+    if (directOut == 0) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
+
+    }
+
+    ckAssertReturnValueOK(env, rv);
+
+    return ckLastPartLen;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,348 @@
+/*
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "jlong.h"
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+#ifdef P11_ENABLE_C_DIGESTINIT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DigestInit
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestInit
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, &ckMechanism);
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_DIGEST
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Digest
+ * Signature: (J[BII[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jData            CK_BYTE_PTR pData
+ *                                      CK_ULONG ulDataLen
+ * @return  jbyteArray jDigest          CK_BYTE_PTR pDigest
+ *                                      CK_ULONG_PTR pulDigestLen
+ */
+JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestSingle
+  (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jDigest, jint jDigestOfs, jint jDigestLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE_PTR bufP;
+    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
+    CK_BYTE DIGESTBUF[MAX_DIGEST_LEN];
+    CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen);
+    CK_MECHANISM ckMechanism;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return 0; }
+
+    rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, &ckMechanism);
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0; }
+
+    if (jInLen <= MAX_STACK_BUFFER_LEN) {
+        bufP = BUF;
+    } else {
+        /* always use single part op, even for large data */
+        bufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
+        if (bufP == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return 0;
+        }
+    }
+
+    (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)bufP);
+    if ((*env)->ExceptionCheck(env)) {
+        if (bufP != BUF) { free(bufP); }
+        return 0;
+    }
+
+    rv = (*ckpFunctions->C_Digest)(ckSessionHandle, bufP, jInLen, DIGESTBUF, &ckDigestLength);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        (*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)DIGESTBUF);
+    }
+
+    if (bufP != BUF) { free(bufP); }
+
+    return ckDigestLength;
+}
+#endif
+
+#ifdef P11_ENABLE_C_DIGESTUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DigestUpdate
+ * Signature: (J[B)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jData            CK_BYTE_PTR pData
+ *                                      CK_ULONG ulDataLen
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestUpdate
+  (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE_PTR bufP;
+    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
+    jsize bufLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (directIn != 0) {
+        rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen);
+        ckAssertReturnValueOK(env, rv);
+        return;
+    }
+
+    if (jInLen <= MAX_STACK_BUFFER_LEN) {
+        bufLen = MAX_STACK_BUFFER_LEN;
+        bufP = BUF;
+    } else {
+        bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
+        bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
+        if (bufP == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+    }
+
+    while (jInLen > 0) {
+        jsize chunkLen = min(bufLen, jInLen);
+        (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
+        if ((*env)->ExceptionCheck(env)) {
+            if (bufP != BUF) { free(bufP); }
+            return;
+        }
+        rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, bufP, chunkLen);
+        if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+            if (bufP != BUF) { free(bufP); }
+            return;
+        }
+        jInOfs += chunkLen;
+        jInLen -= chunkLen;
+    }
+
+    if (bufP != BUF) {
+        free(bufP);
+    }
+}
+#endif
+
+#ifdef P11_ENABLE_C_DIGESTKEY
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DigestKey
+ * Signature: (JJ)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestKey
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_ULONG ckKeyHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckKeyHandle = jLongToCKULong(jKeyHandle);
+
+    rv = (*ckpFunctions->C_DigestKey)(ckSessionHandle, ckKeyHandle);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_DIGESTFINAL
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DigestFinal
+ * Signature: (J[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @return  jbyteArray jDigest          CK_BYTE_PTR pDigest
+ *                                      CK_ULONG_PTR pulDigestLen
+ */
+JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestFinal
+  (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jDigest, jint jDigestOfs, jint jDigestLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE BUF[MAX_DIGEST_LEN];
+    CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen);
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    rv = (*ckpFunctions->C_DigestFinal)(ckSessionHandle, BUF, &ckDigestLength);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        (*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)BUF);
+    }
+    return ckDigestLength;
+}
+#endif
+
+#ifdef P11_ENABLE_C_SEEDRANDOM
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SeedRandom
+ * Signature: (J[B)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jSeed            CK_BYTE_PTR pSeed
+ *                                      CK_ULONG ulSeedLen
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SeedRandom
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSeed)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpSeed = NULL_PTR;
+    CK_ULONG ckSeedLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jSeed, &ckpSeed, &ckSeedLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    rv = (*ckpFunctions->C_SeedRandom)(ckSessionHandle, ckpSeed, ckSeedLength);
+
+    free(ckpSeed);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_GENERATERANDOM
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GenerateRandom
+ * Signature: (J[B)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jRandomData      CK_BYTE_PTR pRandomData
+ *                                      CK_ULONG ulRandomDataLen
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateRandom
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jRandomData)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    jbyte *jRandomBuffer;
+    jlong jRandomBufferLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    jRandomBufferLength = (*env)->GetArrayLength(env, jRandomData);
+    jRandomBuffer = (*env)->GetByteArrayElements(env, jRandomData, NULL);
+    if (jRandomBuffer == NULL) { return; }
+
+    rv = (*ckpFunctions->C_GenerateRandom)(ckSessionHandle,
+                                         (CK_BYTE_PTR) jRandomBuffer,
+                                         jLongToCKULong(jRandomBufferLength));
+
+    /* copy back generated bytes */
+    (*env)->ReleaseByteArrayElements(env, jRandomData, jRandomBuffer, 0);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ * ===========================================================================
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+#ifdef P11_ENABLE_C_DIGESTENCRYPTUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DigestEncryptUpdate
+ * Signature: (J[B)[B
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jPart            CK_BYTE_PTR pPart
+ *                                      CK_ULONG ulPartLen
+ * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
+ *                                      CK_ULONG_PTR pulEncryptedPartLen
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestEncryptUpdate
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
+    CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
+    jbyteArray jEncryptedPart = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength);
+    if ((*env)->ExceptionCheck(env)) { return NULL; }
+
+    rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+        free(ckpPart);
+        return NULL;
+    }
+
+    ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
+    if (ckpEncryptedPart == NULL) {
+        free(ckpPart);
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
+    }
+    free(ckpPart);
+    free(ckpEncryptedPart);
+
+    return jEncryptedPart ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_DECRYPTDIGESTUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DecryptDigestUpdate
+ * Signature: (J[B)[B
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
+ *                                      CK_ULONG ulEncryptedPartLen
+ * @return  jbyteArray jPart            CK_BYTE_PTR pPart
+ *                                      CK_ULONG_PTR pulPartLen
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptDigestUpdate
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
+    CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
+    jbyteArray jPart = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength);
+    if ((*env)->ExceptionCheck(env)) { return NULL; }
+
+    rv = (*ckpFunctions->C_DecryptDigestUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+        free(ckpEncryptedPart);
+        return NULL;
+    }
+
+    ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
+    if (ckpPart == NULL) {
+        free(ckpEncryptedPart);
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    rv = (*ckpFunctions->C_DecryptDigestUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
+    }
+    free(ckpEncryptedPart);
+    free(ckpPart);
+
+    return jPart ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_SIGNENCRYPTUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SignEncryptUpdate
+ * Signature: (J[B)[B
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jPart            CK_BYTE_PTR pPart
+ *                                      CK_ULONG ulPartLen
+ * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
+ *                                      CK_ULONG_PTR pulEncryptedPartLen
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignEncryptUpdate
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
+    CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
+    jbyteArray jEncryptedPart = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength);
+    if ((*env)->ExceptionCheck(env)) { return NULL; }
+
+    rv = (*ckpFunctions->C_SignEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+        free(ckpPart);
+        return NULL;
+    }
+
+    ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
+    if (ckpEncryptedPart == NULL) {
+        free(ckpPart);
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    rv = (*ckpFunctions->C_SignEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
+    }
+    free(ckpPart);
+    free(ckpEncryptedPart);
+
+    return jEncryptedPart ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_DECRYPTVERIFYUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DecryptVerifyUpdate
+ * Signature: (J[B)[B
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
+ *                                      CK_ULONG ulEncryptedPartLen
+ * @return  jbyteArray jPart            CK_BYTE_PTR pPart
+ *                                      CK_ULONG_PTR pulPartLen
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptVerifyUpdate
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
+    CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
+    jbyteArray jPart = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength);
+    if ((*env)->ExceptionCheck(env)) { return NULL; }
+
+    rv = (*ckpFunctions->C_DecryptVerifyUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+        free(ckpEncryptedPart);
+        return NULL;
+    }
+
+    ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
+    if (ckpPart == NULL) {
+        free(ckpEncryptedPart);
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    rv = (*ckpFunctions->C_DecryptVerifyUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
+
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
+    }
+    free(ckpEncryptedPart);
+    free(ckpPart);
+
+    return jPart ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETFUNCTIONSTATUS
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetFunctionStatus
+ * Signature: (J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetFunctionStatus
+    (JNIEnv *env, jobject obj, jlong jSessionHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    /* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */
+    rv = (*ckpFunctions->C_GetFunctionStatus)(ckSessionHandle);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_CANCELFUNCTION
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_CancelFunction
+ * Signature: (J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CancelFunction
+    (JNIEnv *env, jobject obj, jlong jSessionHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    /* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */
+    rv = (*ckpFunctions->C_CancelFunction)(ckSessionHandle);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,881 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+/* declare file private functions */
+
+void prefetchFields(JNIEnv *env, jclass thisClass);
+jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo);
+jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo);
+jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo);
+jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo);
+
+/* define variables */
+
+jfieldID pNativeDataID;
+jfieldID mech_mechanismID;
+jfieldID mech_pParameterID;
+
+jclass jByteArrayClass;
+jclass jLongClass;
+
+JavaVM* jvm = NULL;
+
+jboolean debug = 0;
+
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
+    jvm = vm;
+    return JNI_VERSION_1_4;
+}
+
+/* ************************************************************************** */
+/* The native implementation of the methods of the PKCS11Implementation class */
+/* ************************************************************************** */
+
+/*
+ * This method is used to do static initialization. This method is static and
+ * synchronized. Summary: use this method like a static initialization block.
+ *
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    initializeLibrary
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_initializeLibrary
+(JNIEnv *env, jclass thisClass, jboolean enableDebug)
+{
+#ifndef NO_CALLBACKS
+    if (notifyListLock == NULL) {
+        notifyListLock = createLockObject(env);
+    }
+#endif
+
+    prefetchFields(env, thisClass);
+    debug = enableDebug;
+}
+
+jclass fetchClass(JNIEnv *env, const char *name) {
+    jclass tmpClass = (*env)->FindClass(env, name);
+    if (tmpClass == NULL) { return NULL; }
+    return (*env)->NewGlobalRef(env, tmpClass);
+}
+
+void prefetchFields(JNIEnv *env, jclass thisClass) {
+    jclass tmpClass;
+
+    /* PKCS11 */
+    pNativeDataID = (*env)->GetFieldID(env, thisClass, "pNativeData", "J");
+    if (pNativeDataID == NULL) { return; }
+
+    /* CK_MECHANISM */
+    tmpClass = (*env)->FindClass(env, CLASS_MECHANISM);
+    if (tmpClass == NULL) { return; }
+    mech_mechanismID = (*env)->GetFieldID(env, tmpClass, "mechanism", "J");
+    if (mech_mechanismID == NULL) { return; }
+    mech_pParameterID = (*env)->GetFieldID(env, tmpClass, "pParameter",
+                                           "Ljava/lang/Object;");
+    if (mech_pParameterID == NULL) { return; }
+    jByteArrayClass = fetchClass(env, "[B");
+    if (jByteArrayClass == NULL) { return; }
+    jLongClass = fetchClass(env, "java/lang/Long");
+}
+
+/* This method is designed to do a clean-up. It releases all global resources
+ * of this library. By now, this function is not called. Calling from
+ * JNI_OnUnload would be an option, but some VMs do not support JNI_OnUnload.
+ *
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    finalizeLibrary
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_finalizeLibrary
+(JNIEnv *env, jclass thisClass)
+{
+/* XXX
+    * remove all left lists and release the resources and the lock
+     * objects that synchroniz access to these lists.
+     *
+    removeAllModuleEntries(env);
+    if (moduleListHead == NULL) { * check, if we removed the last active module *
+        * remove also the moduleListLock, it is no longer used *
+        if (moduleListLock != NULL) {
+            destroyLockObject(env, moduleListLock);
+            moduleListLock = NULL;
+        }
+#ifndef NO_CALLBACKS
+        * remove all left notify callback entries *
+        while (removeFirstNotifyEntry(env));
+        * remove also the notifyListLock, it is no longer used *
+        if (notifyListLock != NULL) {
+            destroyLockObject(env, notifyListLock);
+            notifyListLock = NULL;
+        }
+        if (jInitArgsObject != NULL) {
+            (*env)->DeleteGlobalRef(env, jInitArgsObject);
+        }
+        if (ckpGlobalInitArgs != NULL_PTR) {
+            free(ckpGlobalInitArgs);
+        }
+#endif * NO_CALLBACKS *
+    }
+*/
+}
+
+#ifdef P11_ENABLE_C_INITIALIZE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Initialize
+ * Signature: (Ljava/lang/Object;)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jobject jInitArgs           CK_VOID_PTR pInitArgs
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1Initialize
+(JNIEnv *env, jobject obj, jobject jInitArgs)
+{
+    /*
+     * Initalize Cryptoki
+     */
+    CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
+    CK_RV rv;
+    CK_FUNCTION_LIST_PTR ckpFunctions;
+
+    TRACE0("DEBUG: initializing module... ");
+
+    ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) {
+        TRACE0("failed getting module entry");
+        return;
+    }
+
+    ckpInitArgs = (jInitArgs != NULL)
+                ? makeCKInitArgsAdapter(env, jInitArgs)
+                : NULL_PTR;
+
+    rv = (*ckpFunctions->C_Initialize)(ckpInitArgs);
+
+    free(ckpInitArgs);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+
+    TRACE0("FINISHED\n");
+}
+#endif
+
+#ifdef P11_ENABLE_C_FINALIZE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Finalize
+ * Signature: (Ljava/lang/Object;)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jobject jReserved           CK_VOID_PTR pReserved
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize
+(JNIEnv *env, jobject obj, jobject jReserved)
+{
+    /*
+     * Finalize Cryptoki
+     */
+    CK_VOID_PTR ckpReserved;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckpReserved = jObjectToCKVoidPtr(jReserved);
+
+    rv = (*ckpFunctions->C_Finalize)(ckpReserved);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetInfo
+ * Signature: ()Lsun/security/pkcs11/wrapper/CK_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @return  jobject jInfoObject         CK_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo
+(JNIEnv *env, jobject obj)
+{
+    CK_INFO ckLibInfo;
+    jobject jInfoObject=NULL;
+    CK_RV rv;
+    CK_FUNCTION_LIST_PTR ckpFunctions;
+    memset(&ckLibInfo, 0, sizeof(CK_INFO));
+
+    ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo);
+    }
+    return jInfoObject ;
+}
+
+/*
+ * converts a pointer to a CK_INFO structure into a Java CK_INFO Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpInfo - the pointer to the CK_INFO structure
+ * @return - the new Java CK_INFO object
+ */
+jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo)
+{
+    jclass jInfoClass;
+    jmethodID jCtrId;
+    jobject jInfoObject;
+    jobject jCryptokiVer;
+    jcharArray jVendor;
+    jlong jFlags;
+    jcharArray jLibraryDesc;
+    jobject jLibraryVer;
+
+    /* load CK_INFO class */
+    jInfoClass = (*env)->FindClass(env, CLASS_INFO);
+    if (jInfoClass == NULL) { return NULL; };
+
+    /* load CK_INFO constructor */
+    jCtrId = (*env)->GetMethodID
+      (env, jInfoClass, "<init>",
+       "(Lsun/security/pkcs11/wrapper/CK_VERSION;[CJ[CLsun/security/pkcs11/wrapper/CK_VERSION;)V");
+    if (jCtrId == NULL) { return NULL; }
+
+    /* prep all fields */
+    jCryptokiVer = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion));
+    if (jCryptokiVer == NULL) { return NULL; }
+    jVendor =
+      ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32);
+    if (jVendor == NULL) { return NULL; }
+    jFlags = ckULongToJLong(ckpInfo->flags);
+    jLibraryDesc =
+      ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]), 32);
+    if (jLibraryDesc == NULL) { return NULL; }
+    jLibraryVer = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion));
+    if (jLibraryVer == NULL) { return NULL; }
+
+    /* create new CK_INFO object */
+    jInfoObject = (*env)->NewObject(env, jInfoClass, jCtrId, jCryptokiVer,
+                                    jVendor, jFlags, jLibraryDesc, jLibraryVer);
+    if (jInfoObject == NULL) { return NULL; }
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jInfoClass);
+    (*env)->DeleteLocalRef(env, jCryptokiVer);
+    (*env)->DeleteLocalRef(env, jVendor);
+    (*env)->DeleteLocalRef(env, jLibraryDesc);
+    (*env)->DeleteLocalRef(env, jLibraryVer);
+
+    return jInfoObject ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETSLOTLIST
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetSlotList
+ * Signature: (Z)[J
+ * Parametermapping:                    *PKCS11*
+ * @param   jboolean jTokenPresent      CK_BBOOL tokenPresent
+ * @return  jlongArray jSlotList        CK_SLOT_ID_PTR pSlotList
+ *                                      CK_ULONG_PTR pulCount
+ */
+JNIEXPORT jlongArray JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList
+(JNIEnv *env, jobject obj, jboolean jTokenPresent)
+{
+    CK_ULONG ckTokenNumber;
+    CK_SLOT_ID_PTR ckpSlotList;
+    CK_BBOOL ckTokenPresent;
+    jlongArray jSlotList = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckTokenPresent = jBooleanToCKBBool(jTokenPresent);
+
+    rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR,
+                                        &ckTokenNumber);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID));
+    if (ckpSlotList == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList,
+                                        &ckTokenNumber);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber);
+    }
+    free(ckpSlotList);
+
+    return jSlotList ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETSLOTINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetSlotInfo
+ * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SLOT_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @return  jobject jSlotInfoObject     CK_SLOT_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo
+(JNIEnv *env, jobject obj, jlong jSlotID)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_SLOT_INFO ckSlotInfo;
+    jobject jSlotInfoObject=NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+
+    rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo);
+    }
+    return jSlotInfoObject;
+}
+
+/*
+ * converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO
+ * Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure
+ * @return - the new Java CK_SLOT_INFO object
+ */
+jobject
+ckSlotInfoPtrToJSlotInfo
+(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo)
+{
+    jclass jSlotInfoClass;
+    jmethodID jCtrId;
+    jobject jSlotInfoObject;
+    jcharArray jSlotDesc;
+    jcharArray jVendor;
+    jlong jFlags;
+    jobject jHardwareVer;
+    jobject jFirmwareVer;
+
+    /* load CK_SLOT_INFO class */
+    jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO);
+    if (jSlotInfoClass == NULL) { return NULL; };
+
+    /* load CK_SLOT_INFO constructor */
+    jCtrId = (*env)->GetMethodID
+      (env, jSlotInfoClass, "<init>",
+       "([C[CJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;)V");
+    if (jCtrId == NULL) { return NULL; }
+
+    /* prep all fields */
+    jSlotDesc =
+      ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]), 64);
+    if (jSlotDesc == NULL) { return NULL; }
+    jVendor =
+      ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]), 32);
+    if (jVendor == NULL) { return NULL; }
+    jFlags = ckULongToJLong(ckpSlotInfo->flags);
+    jHardwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion));
+    if (jHardwareVer == NULL) { return NULL; }
+    jFirmwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion));
+    if (jFirmwareVer == NULL) { return NULL; }
+
+    /* create new CK_SLOT_INFO object */
+    jSlotInfoObject = (*env)->NewObject
+      (env, jSlotInfoClass, jCtrId, jSlotDesc, jVendor, jFlags,
+       jHardwareVer, jFirmwareVer);
+    if (jSlotInfoObject == NULL) { return NULL; }
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jSlotInfoClass);
+    (*env)->DeleteLocalRef(env, jSlotDesc);
+    (*env)->DeleteLocalRef(env, jVendor);
+    (*env)->DeleteLocalRef(env, jHardwareVer);
+    (*env)->DeleteLocalRef(env, jFirmwareVer);
+
+    return jSlotInfoObject ;
+}
+
+#endif
+
+#ifdef P11_ENABLE_C_GETTOKENINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetTokenInfo
+ * Signature: (J)Lsun/security/pkcs11/wrapper/CK_TOKEN_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @return  jobject jInfoTokenObject    CK_TOKEN_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo
+(JNIEnv *env, jobject obj, jlong jSlotID)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_TOKEN_INFO ckTokenInfo;
+    jobject jInfoTokenObject = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+
+    rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo);
+    }
+    return jInfoTokenObject ;
+}
+
+/*
+ * converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO
+ * Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure
+ * @return - the new Java CK_TOKEN_INFO object
+ */
+jobject
+ckTokenInfoPtrToJTokenInfo
+(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo)
+{
+    jclass jTokenInfoClass;
+    jmethodID jCtrId;
+    jobject jTokenInfoObject;
+    jcharArray jLabel;
+    jcharArray jVendor;
+    jcharArray jModel;
+    jcharArray jSerialNo;
+    jlong jFlags;
+    jlong jMaxSnCnt;
+    jlong jSnCnt;
+    jlong jMaxRwSnCnt;
+    jlong jRwSnCnt;
+    jlong jMaxPinLen;
+    jlong jMinPinLen;
+    jlong jTotalPubMem;
+    jlong jFreePubMem;
+    jlong jTotalPrivMem;
+    jlong jFreePrivMem;
+    jobject jHardwareVer;
+    jobject jFirmwareVer;
+    jcharArray jUtcTime;
+
+    /* load CK_TOKEN_INFO class */
+    jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO);
+    if (jTokenInfoClass == NULL)  { return NULL; };
+
+    /* load CK_TOKEN_INFO constructor */
+    jCtrId = (*env)->GetMethodID
+      (env, jTokenInfoClass, "<init>",
+       "([C[C[C[CJJJJJJJJJJJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;[C)V");
+    if (jCtrId == NULL)  { return NULL; };
+
+    /* prep all fields */
+    jLabel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]), 32);
+    if (jLabel == NULL)  { return NULL; };
+    jVendor =
+      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]), 32);
+    if (jVendor == NULL)  { return NULL; };
+    jModel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]), 16);
+    if (jModel == NULL)  { return NULL; };
+    jSerialNo =
+      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]), 16);
+    if (jSerialNo == NULL)  { return NULL; };
+    jFlags = ckULongToJLong(ckpTokenInfo->flags);
+    jMaxSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxSessionCount);
+    jSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulSessionCount);
+    jMaxRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxRwSessionCount);
+    jRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulRwSessionCount);
+    jMaxPinLen = ckULongToJLong(ckpTokenInfo->ulMaxPinLen);
+    jMinPinLen = ckULongToJLong(ckpTokenInfo->ulMinPinLen);
+    jTotalPubMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPublicMemory);
+    jFreePubMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePublicMemory);
+    jTotalPrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPrivateMemory);
+    jFreePrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePrivateMemory);
+    jHardwareVer =
+      ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion));
+    if (jHardwareVer == NULL) { return NULL; }
+    jFirmwareVer =
+      ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion));
+    if (jFirmwareVer == NULL) { return NULL; }
+    jUtcTime =
+      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]), 16);
+    if (jUtcTime == NULL) { return NULL; }
+
+    /* create new CK_TOKEN_INFO object */
+    jTokenInfoObject =
+      (*env)->NewObject(env, jTokenInfoClass, jCtrId, jLabel, jVendor, jModel,
+                        jSerialNo, jFlags,
+                        jMaxSnCnt, jSnCnt, jMaxRwSnCnt, jRwSnCnt,
+                        jMaxPinLen, jMinPinLen,
+                        jTotalPubMem, jFreePubMem, jTotalPrivMem, jFreePrivMem,
+                        jHardwareVer, jFirmwareVer, jUtcTime);
+    if (jTokenInfoObject == NULL) { return NULL; }
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jTokenInfoClass);
+    (*env)->DeleteLocalRef(env, jLabel);
+    (*env)->DeleteLocalRef(env, jVendor);
+    (*env)->DeleteLocalRef(env, jModel);
+    (*env)->DeleteLocalRef(env, jSerialNo);
+    (*env)->DeleteLocalRef(env, jHardwareVer);
+    (*env)->DeleteLocalRef(env, jFirmwareVer);
+
+    return jTokenInfoObject ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_WAITFORSLOTEVENT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_WaitForSlotEvent
+ * Signature: (JLjava/lang/Object;)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jFlags                CK_FLAGS flags
+ * @param   jobject jReserved           CK_VOID_PTR pReserved
+ * @return  jlong jSlotID               CK_SLOT_ID_PTR pSlot
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent
+(JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved)
+{
+    CK_FLAGS ckFlags;
+    CK_SLOT_ID ckSlotID;
+    jlong jSlotID = 0L;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckFlags = jLongToCKULong(jFlags);
+
+    rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jSlotID = ckULongToJLong(ckSlotID);
+    }
+
+    return jSlotID ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETMECHANISMLIST
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetMechanismList
+ * Signature: (J)[J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @return  jlongArray jMechanismList   CK_MECHANISM_TYPE_PTR pMechanismList
+ *                                      CK_ULONG_PTR pulCount
+ */
+JNIEXPORT jlongArray JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList
+(JNIEnv *env, jobject obj, jlong jSlotID)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_ULONG ckMechanismNumber;
+    CK_MECHANISM_TYPE_PTR ckpMechanismList;
+    jlongArray jMechanismList = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+
+    rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR,
+                                             &ckMechanismNumber);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    ckpMechanismList = (CK_MECHANISM_TYPE_PTR)
+      malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE));
+    if (ckpMechanismList == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList,
+                                             &ckMechanismNumber);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList,
+                                                  ckMechanismNumber);
+    }
+    free(ckpMechanismList);
+
+    return jMechanismList ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETMECHANISMINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetMechanismInfo
+ * Signature: (JJ)Lsun/security/pkcs11/wrapper/CK_MECHANISM_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @param   jlong jType                 CK_MECHANISM_TYPE type
+ * @return  jobject jMechanismInfo      CK_MECHANISM_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo
+(JNIEnv *env, jobject obj, jlong jSlotID, jlong jType)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_MECHANISM_TYPE ckMechanismType;
+    CK_MECHANISM_INFO ckMechanismInfo;
+    jobject jMechanismInfo = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+    ckMechanismType = jLongToCKULong(jType);
+
+    rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType,
+                                             &ckMechanismInfo);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo);
+    }
+    return jMechanismInfo ;
+}
+
+/*
+ * converts a pointer to a CK_MECHANISM_INFO structure into a Java
+ * CK_MECHANISM_INFO Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure
+ * @return - the new Java CK_MECHANISM_INFO object
+ */
+jobject
+ckMechanismInfoPtrToJMechanismInfo
+(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo)
+{
+
+    jclass jMechanismInfoClass;
+    jmethodID jCtrId;
+    jobject jMechanismInfoObject;
+    jlong jMinKeySize;
+    jlong jMaxKeySize;
+    jlong jFlags;
+
+    /* load CK_MECHANISM_INFO class */
+    jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO);
+    if (jMechanismInfoClass == NULL) { return NULL; };
+
+    /* load CK_MECHANISM_INFO constructor */
+    jCtrId = (*env)->GetMethodID(env, jMechanismInfoClass, "<init>", "(JJJ)V");
+    if (jCtrId == NULL) { return NULL; };
+
+    /* prep all fields */
+    jMinKeySize = ckULongToJLong(ckpMechanismInfo->ulMinKeySize);
+    jMaxKeySize = ckULongToJLong(ckpMechanismInfo->ulMaxKeySize);
+    jFlags = ckULongToJLong(ckpMechanismInfo->flags);
+
+    /* create new CK_MECHANISM_INFO object */
+    jMechanismInfoObject = (*env)->NewObject(env, jMechanismInfoClass, jCtrId,
+                                             jMinKeySize, jMaxKeySize, jFlags);
+    if (jMechanismInfoObject == NULL) { return NULL; };
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jMechanismInfoClass);
+
+    return jMechanismInfoObject ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_INITTOKEN
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_InitToken
+ * Signature: (J[C[C)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @param   jcharArray jPin             CK_CHAR_PTR pPin
+ *                                      CK_ULONG ulPinLen
+ * @param   jcharArray jLabel           CK_UTF8CHAR_PTR pLabel
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken
+(JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_CHAR_PTR ckpPin = NULL_PTR;
+    CK_UTF8CHAR_PTR ckpLabel = NULL_PTR;
+    CK_ULONG ckPinLength;
+    CK_ULONG ckLabelLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+    jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+    /* ckLabelLength <= 32 !!! */
+    jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength);
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckpPin);
+        return;
+    }
+
+    rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel);
+    TRACE1("InitToken return code: %d", rv);
+
+    free(ckpPin);
+    free(ckpLabel);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_INITPIN
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_InitPIN
+ * Signature: (J[C)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE
+ * @param   jcharArray jPin             CK_CHAR_PTR pPin
+ *                                      CK_ULONG ulPinLen
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN
+(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_CHAR_PTR ckpPin = NULL_PTR;
+    CK_ULONG ckPinLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength);
+
+    free(ckpPin);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_SETPIN
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SetPIN
+ * Signature: (J[C[C)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jcharArray jOldPin          CK_CHAR_PTR pOldPin
+ *                                      CK_ULONG ulOldLen
+ * @param   jcharArray jNewPin          CK_CHAR_PTR pNewPin
+ *                                      CK_ULONG ulNewLen
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN
+(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin,
+jcharArray jNewPin)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_CHAR_PTR ckpOldPin = NULL_PTR;
+    CK_CHAR_PTR ckpNewPin = NULL_PTR;
+    CK_ULONG ckOldPinLength;
+    CK_ULONG ckNewPinLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+    jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength);
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckpOldPin);
+        return;
+    }
+
+    rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength,
+                                   ckpNewPin, ckNewPinLength);
+
+    free(ckpOldPin);
+    free(ckpNewPin);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,773 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+#ifdef P11_ENABLE_C_GENERATEKEY
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GenerateKey
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
+ *                                      CK_ULONG ulCount
+ * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
+ */
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKey
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jobjectArray jTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
+    CK_ULONG ckAttributesLength;
+    CK_OBJECT_HANDLE ckKeyHandle = 0;
+    jlong jKeyHandle = 0L;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return 0L ; }
+
+    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
+    if ((*env)->ExceptionCheck(env)) {
+        if (ckMechanism.pParameter != NULL_PTR) {
+            free(ckMechanism.pParameter);
+        }
+        return 0L;
+    }
+
+    rv = (*ckpFunctions->C_GenerateKey)(ckSessionHandle, &ckMechanism, ckpAttributes, ckAttributesLength, &ckKeyHandle);
+
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jKeyHandle = ckULongToJLong(ckKeyHandle);
+
+        /* cheack, if we must give a initialization vector back to Java */
+        switch (ckMechanism.mechanism) {
+        case CKM_PBE_MD2_DES_CBC:
+        case CKM_PBE_MD5_DES_CBC:
+        case CKM_PBE_MD5_CAST_CBC:
+        case CKM_PBE_MD5_CAST3_CBC:
+        case CKM_PBE_MD5_CAST128_CBC:
+        /* case CKM_PBE_MD5_CAST5_CBC:  the same as CKM_PBE_MD5_CAST128_CBC */
+        case CKM_PBE_SHA1_CAST128_CBC:
+        /* case CKM_PBE_SHA1_CAST5_CBC: the same as CKM_PBE_SHA1_CAST128_CBC */
+            /* we must copy back the initialization vector to the jMechanism object */
+            copyBackPBEInitializationVector(env, &ckMechanism, jMechanism);
+            break;
+        }
+    }
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+
+    return jKeyHandle ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GENERATEKEYPAIR
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GenerateKeyPair
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[J
+ * Parametermapping:                          *PKCS11*
+ * @param   jlong jSessionHandle              CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism                CK_MECHANISM_PTR pMechanism
+ * @param   jobjectArray jPublicKeyTemplate   CK_ATTRIBUTE_PTR pPublicKeyTemplate
+ *                                            CK_ULONG ulPublicKeyAttributeCount
+ * @param   jobjectArray jPrivateKeyTemplate  CK_ATTRIBUTE_PTR pPrivateKeyTemplate
+ *                                            CK_ULONG ulPrivateKeyAttributeCount
+ * @return  jlongArray jKeyHandles            CK_OBJECT_HANDLE_PTR phPublicKey
+ *                                            CK_OBJECT_HANDLE_PTR phPublicKey
+ */
+JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKeyPair
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism,
+     jobjectArray jPublicKeyTemplate, jobjectArray jPrivateKeyTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_ATTRIBUTE_PTR ckpPublicKeyAttributes = NULL_PTR;
+    CK_ATTRIBUTE_PTR ckpPrivateKeyAttributes = NULL_PTR;
+    CK_ULONG ckPublicKeyAttributesLength;
+    CK_ULONG ckPrivateKeyAttributesLength;
+    CK_OBJECT_HANDLE_PTR ckpPublicKeyHandle;  /* pointer to Public Key */
+    CK_OBJECT_HANDLE_PTR ckpPrivateKeyHandle; /* pointer to Private Key */
+    CK_OBJECT_HANDLE_PTR ckpKeyHandles;     /* pointer to array with Public and Private Key */
+    jlongArray jKeyHandles = NULL;
+    CK_RV rv;
+    int attempts;
+    const int MAX_ATTEMPTS = 3;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return NULL; }
+
+    ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) malloc(2 * sizeof(CK_OBJECT_HANDLE));
+    if (ckpKeyHandles == NULL) {
+        if (ckMechanism.pParameter != NULL_PTR) {
+            free(ckMechanism.pParameter);
+        }
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    ckpPublicKeyHandle = ckpKeyHandles;   /* first element of array is Public Key */
+    ckpPrivateKeyHandle = (ckpKeyHandles + 1);  /* second element of array is Private Key */
+
+    jAttributeArrayToCKAttributeArray(env, jPublicKeyTemplate, &ckpPublicKeyAttributes, &ckPublicKeyAttributesLength);
+    if ((*env)->ExceptionCheck(env)) {
+        if (ckMechanism.pParameter != NULL_PTR) {
+            free(ckMechanism.pParameter);
+        }
+        free(ckpKeyHandles);
+        return NULL;
+    }
+
+    jAttributeArrayToCKAttributeArray(env, jPrivateKeyTemplate, &ckpPrivateKeyAttributes, &ckPrivateKeyAttributesLength);
+    if ((*env)->ExceptionCheck(env)) {
+        if (ckMechanism.pParameter != NULL_PTR) {
+            free(ckMechanism.pParameter);
+        }
+        free(ckpKeyHandles);
+        freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
+        return NULL;
+    }
+
+    /*
+     * Workaround for NSS bug 1012786:
+     *
+     * Key generation may fail with CKR_FUNCTION_FAILED error
+     * if there is insufficient entropy to generate a random key.
+     *
+     * PKCS11 spec says the following about CKR_FUNCTION_FAILED error
+     * (see section 11.1.1):
+     *
+     *      ... In any event, although the function call failed, the situation
+     *      is not necessarily totally hopeless, as it is likely to be
+     *      when CKR_GENERAL_ERROR is returned. Depending on what the root cause of
+     *      the error actually was, it is possible that an attempt
+     *      to make the exact same function call again would succeed.
+     *
+     * Call C_GenerateKeyPair() several times if CKR_FUNCTION_FAILED occurs.
+     */
+    for (attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {
+        rv = (*ckpFunctions->C_GenerateKeyPair)(ckSessionHandle, &ckMechanism,
+                        ckpPublicKeyAttributes, ckPublicKeyAttributesLength,
+                        ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength,
+                        ckpPublicKeyHandle, ckpPrivateKeyHandle);
+        if (rv == CKR_FUNCTION_FAILED) {
+            printDebug("C_1GenerateKeyPair(): C_GenerateKeyPair() failed \
+                    with CKR_FUNCTION_FAILED error, try again\n");
+        } else {
+            break;
+        }
+    }
+
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jKeyHandles = ckULongArrayToJLongArray(env, ckpKeyHandles, 2);
+    }
+
+    if(ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+    free(ckpKeyHandles);
+    freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
+    freeCKAttributeArray(ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength);
+
+    return jKeyHandles ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_WRAPKEY
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_WrapKey
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;JJ)[B
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @param   jlong jWrappingKeyHandle    CK_OBJECT_HANDLE hWrappingKey
+ * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ * @return  jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
+ *                                      CK_ULONG_PTR pulWrappedKeyLen
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1WrapKey
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jWrappingKeyHandle, jlong jKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckWrappingKeyHandle;
+    CK_OBJECT_HANDLE ckKeyHandle;
+    jbyteArray jWrappedKey = NULL;
+    CK_RV rv;
+    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
+    CK_BYTE_PTR ckpWrappedKey = BUF;
+    CK_ULONG ckWrappedKeyLength = MAX_STACK_BUFFER_LEN;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return NULL; }
+
+    ckWrappingKeyHandle = jLongToCKULong(jWrappingKeyHandle);
+    ckKeyHandle = jLongToCKULong(jKeyHandle);
+
+    rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
+    if (rv == CKR_BUFFER_TOO_SMALL) {
+        ckpWrappedKey = (CK_BYTE_PTR) malloc(ckWrappedKeyLength);
+        if (ckpWrappedKey == NULL) {
+            if (ckMechanism.pParameter != NULL_PTR) {
+                free(ckMechanism.pParameter);
+            }
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+
+        rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
+    }
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jWrappedKey = ckByteArrayToJByteArray(env, ckpWrappedKey, ckWrappedKeyLength);
+    }
+
+    if (ckpWrappedKey != BUF) { free(ckpWrappedKey); }
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+    return jWrappedKey ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_UNWRAPKEY
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_UnwrapKey
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[B[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @param   jlong jUnwrappingKeyHandle  CK_OBJECT_HANDLE hUnwrappingKey
+ * @param   jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
+ *                                      CK_ULONG_PTR pulWrappedKeyLen
+ * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
+ *                                      CK_ULONG ulCount
+ * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
+ */
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1UnwrapKey
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jUnwrappingKeyHandle,
+     jbyteArray jWrappedKey, jobjectArray jTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckUnwrappingKeyHandle;
+    CK_BYTE_PTR ckpWrappedKey = NULL_PTR;
+    CK_ULONG ckWrappedKeyLength;
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
+    CK_ULONG ckAttributesLength;
+    CK_OBJECT_HANDLE ckKeyHandle = 0;
+    jlong jKeyHandle = 0L;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return 0L; }
+
+    ckUnwrappingKeyHandle = jLongToCKULong(jUnwrappingKeyHandle);
+    jByteArrayToCKByteArray(env, jWrappedKey, &ckpWrappedKey, &ckWrappedKeyLength);
+    if ((*env)->ExceptionCheck(env)) {
+        if (ckMechanism.pParameter != NULL_PTR) {
+            free(ckMechanism.pParameter);
+        }
+        return 0L;
+    }
+
+    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
+    if ((*env)->ExceptionCheck(env)) {
+        if (ckMechanism.pParameter != NULL_PTR) {
+            free(ckMechanism.pParameter);
+        }
+        free(ckpWrappedKey);
+        return 0L;
+    }
+
+
+    rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism, ckUnwrappingKeyHandle,
+                 ckpWrappedKey, ckWrappedKeyLength,
+                 ckpAttributes, ckAttributesLength, &ckKeyHandle);
+
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jKeyHandle = ckLongToJLong(ckKeyHandle);
+
+#if 0
+        /* cheack, if we must give a initialization vector back to Java */
+        if (ckMechanism.mechanism == CKM_KEY_WRAP_SET_OAEP) {
+            /* we must copy back the unwrapped key info to the jMechanism object */
+            copyBackSetUnwrappedKey(env, &ckMechanism, jMechanism);
+        }
+#endif
+    }
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+    free(ckpWrappedKey);
+
+    return jKeyHandle ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_DERIVEKEY
+
+void freeMasterKeyDeriveParams(CK_MECHANISM_PTR ckMechanism) {
+    CK_SSL3_MASTER_KEY_DERIVE_PARAMS *params = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
+    if (params == NULL) {
+        return;
+    }
+
+    if (params->RandomInfo.pClientRandom != NULL) {
+        free(params->RandomInfo.pClientRandom);
+    }
+    if (params->RandomInfo.pServerRandom != NULL) {
+        free(params->RandomInfo.pServerRandom);
+    }
+    if (params->pVersion != NULL) {
+        free(params->pVersion);
+    }
+}
+
+void freeEcdh1DeriveParams(CK_MECHANISM_PTR ckMechanism) {
+    CK_ECDH1_DERIVE_PARAMS *params = (CK_ECDH1_DERIVE_PARAMS *) ckMechanism->pParameter;
+    if (params == NULL) {
+        return;
+    }
+
+    if (params->pSharedData != NULL) {
+        free(params->pSharedData);
+    }
+    if (params->pPublicData != NULL) {
+        free(params->pPublicData);
+    }
+}
+
+/*
+ * Copy back the PRF output to Java.
+ */
+void copyBackTLSPrfParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
+{
+    jclass jMechanismClass, jTLSPrfParamsClass;
+    CK_TLS_PRF_PARAMS *ckTLSPrfParams;
+    jobject jTLSPrfParams;
+    jfieldID fieldID;
+    CK_MECHANISM_TYPE ckMechanismType;
+    jlong jMechanismType;
+    CK_BYTE_PTR output;
+    jobject jOutput;
+    jint jLength;
+    jbyte* jBytes;
+    int i;
+
+    /* get mechanism */
+    jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
+    if (jMechanismClass == NULL) { return; }
+    fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
+    if (fieldID == NULL) { return; }
+    jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
+    ckMechanismType = jLongToCKULong(jMechanismType);
+    if (ckMechanismType != ckMechanism->mechanism) {
+        /* we do not have maching types, this should not occur */
+        return;
+    }
+
+    /* get the native CK_TLS_PRF_PARAMS */
+    ckTLSPrfParams = (CK_TLS_PRF_PARAMS *) ckMechanism->pParameter;
+    if (ckTLSPrfParams != NULL_PTR) {
+        /* get the Java CK_TLS_PRF_PARAMS object (pParameter) */
+        fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
+        if (fieldID == NULL) { return; }
+        jTLSPrfParams = (*env)->GetObjectField(env, jMechanism, fieldID);
+
+        /* copy back the client IV */
+        jTLSPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
+        if (jTLSPrfParamsClass == NULL) { return; }
+        fieldID = (*env)->GetFieldID(env, jTLSPrfParamsClass, "pOutput", "[B");
+        if (fieldID == NULL) { return; }
+        jOutput = (*env)->GetObjectField(env, jTLSPrfParams, fieldID);
+        output = ckTLSPrfParams->pOutput;
+
+        // Note: we assume that the token returned exactly as many bytes as we
+        // requested. Anything else would not make sense.
+        if (jOutput != NULL) {
+            jLength = (*env)->GetArrayLength(env, jOutput);
+            jBytes = (*env)->GetByteArrayElements(env, jOutput, NULL);
+            if (jBytes == NULL) { return; }
+
+            /* copy the bytes to the Java buffer */
+            for (i=0; i < jLength; i++) {
+                jBytes[i] = ckByteToJByte(output[i]);
+            }
+            /* copy back the Java buffer to the object */
+            (*env)->ReleaseByteArrayElements(env, jOutput, jBytes, 0);
+        }
+
+        // free malloc'd data
+        free(ckTLSPrfParams->pSeed);
+        free(ckTLSPrfParams->pLabel);
+        free(ckTLSPrfParams->pulOutputLen);
+        free(ckTLSPrfParams->pOutput);
+    }
+}
+
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DeriveKey
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @param   jlong jBaseKeyHandle        CK_OBJECT_HANDLE hBaseKey
+ * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
+ *                                      CK_ULONG ulCount
+ * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
+ */
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DeriveKey
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jBaseKeyHandle, jobjectArray jTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckBaseKeyHandle;
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
+    CK_ULONG ckAttributesLength;
+    CK_OBJECT_HANDLE ckKeyHandle = 0;
+    jlong jKeyHandle = 0L;
+    CK_RV rv;
+    CK_OBJECT_HANDLE_PTR phKey = &ckKeyHandle;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return 0L; }
+
+    ckBaseKeyHandle = jLongToCKULong(jBaseKeyHandle);
+    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
+    if ((*env)->ExceptionCheck(env)) {
+        if (ckMechanism.pParameter != NULL_PTR) {
+            free(ckMechanism.pParameter);
+        }
+        return 0L;
+    }
+
+    switch (ckMechanism.mechanism) {
+    case CKM_SSL3_KEY_AND_MAC_DERIVE:
+    case CKM_TLS_KEY_AND_MAC_DERIVE:
+    case CKM_TLS_PRF:
+        // these mechanism do not return a key handle via phKey
+        // set to NULL in case pedantic implementations check for it
+        phKey = NULL;
+        break;
+    default:
+        // empty
+        break;
+    }
+
+    rv = (*ckpFunctions->C_DeriveKey)(ckSessionHandle, &ckMechanism, ckBaseKeyHandle,
+                 ckpAttributes, ckAttributesLength, phKey);
+
+    jKeyHandle = ckLongToJLong(ckKeyHandle);
+
+    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+
+    switch (ckMechanism.mechanism) {
+    case CKM_SSL3_MASTER_KEY_DERIVE:
+    case CKM_TLS_MASTER_KEY_DERIVE:
+        /* we must copy back the client version */
+        copyBackClientVersion(env, &ckMechanism, jMechanism);
+        freeMasterKeyDeriveParams(&ckMechanism);
+        break;
+    case CKM_SSL3_MASTER_KEY_DERIVE_DH:
+    case CKM_TLS_MASTER_KEY_DERIVE_DH:
+        freeMasterKeyDeriveParams(&ckMechanism);
+        break;
+    case CKM_SSL3_KEY_AND_MAC_DERIVE:
+    case CKM_TLS_KEY_AND_MAC_DERIVE:
+        /* we must copy back the unwrapped key info to the jMechanism object */
+        copyBackSSLKeyMatParams(env, &ckMechanism, jMechanism);
+        break;
+    case CKM_TLS_PRF:
+        copyBackTLSPrfParams(env, &ckMechanism, jMechanism);
+        break;
+    case CKM_ECDH1_DERIVE:
+        freeEcdh1DeriveParams(&ckMechanism);
+        break;
+    default:
+        // empty
+        break;
+    }
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
+
+    return jKeyHandle ;
+}
+
+/*
+ * Copy back the client version information from the native
+ * structure to the Java object. This is only used for the
+ * CKM_SSL3_MASTER_KEY_DERIVE mechanism when used for deriving a key.
+ *
+ */
+void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
+{
+  jclass jMechanismClass, jSSL3MasterKeyDeriveParamsClass, jVersionClass;
+  CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams;
+  CK_VERSION *ckVersion;
+  jfieldID fieldID;
+  CK_MECHANISM_TYPE ckMechanismType;
+  jlong jMechanismType;
+  jobject jSSL3MasterKeyDeriveParams;
+  jobject jVersion;
+
+  /* get mechanism */
+  jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
+  if (jMechanismClass == NULL) { return; }
+  fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
+  if (fieldID == NULL) { return; }
+  jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
+  ckMechanismType = jLongToCKULong(jMechanismType);
+  if (ckMechanismType != ckMechanism->mechanism) {
+    /* we do not have maching types, this should not occur */
+    return;
+  }
+
+  /* get the native CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
+  ckSSL3MasterKeyDeriveParams = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
+  if (ckSSL3MasterKeyDeriveParams != NULL_PTR) {
+    /* get the native CK_VERSION */
+    ckVersion = ckSSL3MasterKeyDeriveParams->pVersion;
+    if (ckVersion != NULL_PTR) {
+      /* get the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS (pParameter) */
+      fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
+      if (fieldID == NULL) { return; }
+
+      jSSL3MasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID);
+
+      /* get the Java CK_VERSION */
+      jSSL3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
+      if (jSSL3MasterKeyDeriveParamsClass == NULL) { return; }
+      fieldID = (*env)->GetFieldID(env, jSSL3MasterKeyDeriveParamsClass, "pVersion", "L"CLASS_VERSION";");
+      if (fieldID == NULL) { return; }
+      jVersion = (*env)->GetObjectField(env, jSSL3MasterKeyDeriveParams, fieldID);
+
+      /* now copy back the version from the native structure to the Java structure */
+
+      /* copy back the major version */
+      jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
+      if (jVersionClass == NULL) { return; }
+      fieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
+      if (fieldID == NULL) { return; }
+      (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->major));
+
+      /* copy back the minor version */
+      fieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
+      if (fieldID == NULL) { return; }
+      (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->minor));
+    }
+  }
+}
+
+
+/*
+ * Copy back the derived keys and initialization vectors from the native
+ * structure to the Java object. This is only used for the
+ * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key.
+ *
+ */
+void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
+{
+  jclass jMechanismClass, jSSL3KeyMatParamsClass, jSSL3KeyMatOutClass;
+  CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam;
+  CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut;
+  jfieldID fieldID;
+  CK_MECHANISM_TYPE ckMechanismType;
+  jlong jMechanismType;
+  CK_BYTE_PTR iv;
+  jobject jSSL3KeyMatParam;
+  jobject jSSL3KeyMatOut;
+  jobject jIV;
+  jint jLength;
+  jbyte* jBytes;
+  int i;
+
+  /* get mechanism */
+  jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
+  if (jMechanismClass == NULL) { return; }
+  fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
+  if (fieldID == NULL) { return; }
+  jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
+  ckMechanismType = jLongToCKULong(jMechanismType);
+  if (ckMechanismType != ckMechanism->mechanism) {
+    /* we do not have maching types, this should not occur */
+    return;
+  }
+
+  /* get the native CK_SSL3_KEY_MAT_PARAMS */
+  ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter;
+  if (ckSSL3KeyMatParam != NULL_PTR) {
+    // free malloc'd data
+    if (ckSSL3KeyMatParam->RandomInfo.pClientRandom != NULL) {
+        free(ckSSL3KeyMatParam->RandomInfo.pClientRandom);
+    }
+    if (ckSSL3KeyMatParam->RandomInfo.pServerRandom != NULL) {
+        free(ckSSL3KeyMatParam->RandomInfo.pServerRandom);
+    }
+
+    /* get the native CK_SSL3_KEY_MAT_OUT */
+    ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial;
+    if (ckSSL3KeyMatOut != NULL_PTR) {
+      /* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */
+      fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
+      if (fieldID == NULL) { return; }
+      jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID);
+
+      /* get the Java CK_SSL3_KEY_MAT_OUT */
+      jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
+      if (jSSL3KeyMatParamsClass == NULL) { return; }
+      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";");
+      if (fieldID == NULL) { return; }
+      jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID);
+
+      /* now copy back all the key handles and the initialization vectors */
+      /* copy back client MAC secret handle */
+      jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
+      if (jSSL3KeyMatOutClass == NULL) { return; }
+      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J");
+      if (fieldID == NULL) { return; }
+      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret));
+
+      /* copy back server MAC secret handle */
+      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J");
+      if (fieldID == NULL) { return; }
+      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret));
+
+      /* copy back client secret key handle */
+      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J");
+      if (fieldID == NULL) { return; }
+      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey));
+
+      /* copy back server secret key handle */
+      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J");
+      if (fieldID == NULL) { return; }
+      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey));
+
+      /* copy back the client IV */
+      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B");
+      if (fieldID == NULL) { return; }
+      jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
+      iv = ckSSL3KeyMatOut->pIVClient;
+
+      if (jIV != NULL) {
+        jLength = (*env)->GetArrayLength(env, jIV);
+        jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
+        if (jBytes == NULL) { return; }
+        /* copy the bytes to the Java buffer */
+        for (i=0; i < jLength; i++) {
+          jBytes[i] = ckByteToJByte(iv[i]);
+        }
+        /* copy back the Java buffer to the object */
+        (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
+      }
+      // free malloc'd data
+      free(ckSSL3KeyMatOut->pIVClient);
+
+      /* copy back the server IV */
+      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B");
+      if (fieldID == NULL) { return; }
+      jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
+      iv = ckSSL3KeyMatOut->pIVServer;
+
+      if (jIV != NULL) {
+        jLength = (*env)->GetArrayLength(env, jIV);
+        jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
+        if (jBytes == NULL) { return; }
+        /* copy the bytes to the Java buffer */
+        for (i=0; i < jLength; i++) {
+          jBytes[i] = ckByteToJByte(iv[i]);
+        }
+        /* copy back the Java buffer to the object */
+        (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
+      }
+      // free malloc'd data
+      free(ckSSL3KeyMatOut->pIVServer);
+      free(ckSSL3KeyMatOut);
+    }
+  }
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,552 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+/* The initArgs that enable the application to do custom mutex-handling */
+#ifndef NO_CALLBACKS
+jobject jInitArgsObject;
+CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs;
+#endif /* NO_CALLBACKS */
+
+/* ************************************************************************** */
+/* Now come the functions for mutex handling and notification callbacks       */
+/* ************************************************************************** */
+
+/*
+ * converts the InitArgs object to a CK_C_INITIALIZE_ARGS structure and sets the functions
+ * that will call the right Java mutex functions
+ *
+ * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
+ * @param pInitArgs - the InitArgs object with the Java mutex functions to call
+ * @return - the pointer to the CK_C_INITIALIZE_ARGS structure with the functions that will call
+ *           the corresponding Java functions
+ */
+CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject jInitArgs)
+{
+    CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
+    jclass jInitArgsClass;
+    jfieldID fieldID;
+    jlong jFlags;
+    jobject jReserved;
+    CK_ULONG ckReservedLength;
+#ifndef NO_CALLBACKS
+    jobject jMutexHandler;
+#endif /* NO_CALLBACKS */
+
+    if(jInitArgs == NULL) {
+        return NULL_PTR;
+    }
+
+    /* convert the Java InitArgs object to a pointer to a CK_C_INITIALIZE_ARGS structure */
+    ckpInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS));
+    if (ckpInitArgs == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL_PTR;
+    }
+    ckpInitArgs->flags = (CK_FLAGS)0;
+    ckpInitArgs->pReserved = (CK_VOID_PTR)NULL;
+
+    /* Set the mutex functions that will call the Java mutex functions, but
+     * only set it, if the field is not null.
+     */
+    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
+    if (jInitArgsClass == NULL) {
+        free(ckpInitArgs);
+        return NULL;
+    }
+
+#ifdef NO_CALLBACKS
+    ckpInitArgs->CreateMutex = NULL_PTR;
+    ckpInitArgs->DestroyMutex = NULL_PTR;
+    ckpInitArgs->LockMutex = NULL_PTR;
+    ckpInitArgs->UnlockMutex = NULL_PTR;
+#else
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;");
+    if (fieldID == NULL) {
+        free(ckpInitArgs);
+        return NULL;
+    }
+    jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
+    ckpInitArgs->CreateMutex = (jMutexHandler != NULL) ? &callJCreateMutex : NULL_PTR;
+
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;");
+    if (fieldID == NULL) {
+        free(ckpInitArgs);
+        return NULL;
+    }
+    jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
+    ckpInitArgs->DestroyMutex = (jMutexHandler != NULL) ? &callJDestroyMutex : NULL_PTR;
+
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;");
+    if (fieldID == NULL) {
+        free(ckpInitArgs);
+        return NULL;
+    }
+    jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
+    ckpInitArgs->LockMutex = (jMutexHandler != NULL) ? &callJLockMutex : NULL_PTR;
+
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;");
+    if (fieldID == NULL) {
+        free(ckpInitArgs);
+        return NULL;
+    }
+    jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
+    ckpInitArgs->UnlockMutex = (jMutexHandler != NULL) ? &callJUnlockMutex : NULL_PTR;
+
+    if ((ckpInitArgs->CreateMutex != NULL_PTR)
+            || (ckpInitArgs->DestroyMutex != NULL_PTR)
+            || (ckpInitArgs->LockMutex != NULL_PTR)
+            || (ckpInitArgs->UnlockMutex != NULL_PTR)) {
+        /* we only need to keep a global copy, if we need callbacks */
+        /* set the global object jInitArgs so that the right Java mutex functions will be called */
+        jInitArgsObject = (*env)->NewGlobalRef(env, jInitArgs);
+        ckpGlobalInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS));
+        if (ckpGlobalInitArgs == NULL) {
+            free(ckpInitArgs);
+            throwOutOfMemoryError(env, 0);
+            return NULL_PTR;
+        }
+
+        memcpy(ckpGlobalInitArgs, ckpInitArgs, sizeof(CK_C_INITIALIZE_ARGS));
+    }
+#endif /* NO_CALLBACKS */
+
+    /* convert and set the flags field */
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "flags", "J");
+    if (fieldID == NULL) {
+        free(ckpInitArgs);
+        return NULL;
+    }
+    jFlags = (*env)->GetLongField(env, jInitArgs, fieldID);
+    ckpInitArgs->flags = jLongToCKULong(jFlags);
+
+    /* pReserved should be NULL_PTR in this version */
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "pReserved", "Ljava/lang/Object;");
+    if (fieldID == NULL) {
+        free(ckpInitArgs);
+        return NULL;
+    }
+    jReserved = (*env)->GetObjectField(env, jInitArgs, fieldID);
+
+    /* we try to convert the reserved parameter also */
+    jObjectToPrimitiveCKObjectPtrPtr(env, jReserved, &(ckpInitArgs->pReserved), &ckReservedLength);
+
+    return ckpInitArgs ;
+}
+
+#ifndef NO_CALLBACKS
+
+/*
+ * is the function that gets called by PKCS#11 to create a mutex and calls the Java
+ * CreateMutex function
+ *
+ * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
+ * @param ppMutex - the new created mutex
+ * @return - should return CKR_OK if the mutex creation was ok
+ */
+CK_RV callJCreateMutex(CK_VOID_PTR_PTR ppMutex)
+{
+    extern JavaVM *jvm;
+    JNIEnv *env;
+    jint returnValue;
+    jthrowable pkcs11Exception;
+    jclass pkcs11ExceptionClass;
+    jlong errorCode;
+    CK_RV rv = CKR_OK;
+    int wasAttached = 1;
+    jclass jCreateMutexClass;
+    jclass jInitArgsClass;
+    jmethodID methodID;
+    jfieldID fieldID;
+    jobject jCreateMutex;
+    jobject jMutex;
+
+
+    /* Get the currently running Java VM */
+    if (jvm == NULL) { return rv ;} /* there is no VM running */
+
+    /* Determine, if current thread is already attached */
+    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
+    if (returnValue == JNI_EDETACHED) {
+        /* thread detached, so attach it */
+        wasAttached = 0;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else if (returnValue == JNI_EVERSION) {
+        /* this version of JNI is not supported, so just try to attach */
+        /* we assume it was attached to ensure that this thread is not detached
+         * afterwards even though it should not
+         */
+        wasAttached = 1;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else {
+        /* attached */
+        wasAttached = 1;
+    }
+
+    jCreateMutexClass = (*env)->FindClass(env, CLASS_CREATEMUTEX);
+    if (jCreateMutexClass == NULL) { return rv; }
+    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
+    if (jInitArgsClass == NULL) { return rv; }
+
+    /* get the CreateMutex object out of the jInitArgs object */
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;");
+    if (fieldID == NULL) { return rv; }
+    jCreateMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
+    assert(jCreateMutex != 0);
+
+    /* call the CK_CREATEMUTEX function of the CreateMutex object */
+    /* and get the new Java mutex object */
+    methodID = (*env)->GetMethodID(env, jCreateMutexClass, "CK_CREATEMUTEX", "()Ljava/lang/Object;");
+    if (methodID == NULL) { return rv; }
+    jMutex = (*env)->CallObjectMethod(env, jCreateMutex, methodID);
+
+    /* set a global reference on the Java mutex */
+    jMutex = (*env)->NewGlobalRef(env, jMutex);
+    /* convert the Java mutex to a CK mutex */
+    *ppMutex = jObjectToCKVoidPtr(jMutex);
+
+
+    /* check, if callback threw an exception */
+    pkcs11Exception = (*env)->ExceptionOccurred(env);
+
+    if (pkcs11Exception != NULL) {
+        /* TBD: clear the pending exception with ExceptionClear? */
+        /* The was an exception thrown, now we get the error-code from it */
+        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
+        if (pkcs11ExceptionClass == NULL) { return rv; }
+        methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
+        if (methodID == NULL) { return rv; }
+
+        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
+        rv = jLongToCKULong(errorCode);
+    }
+
+    /* if we attached this thread to the VM just for callback, we detach it now */
+    if (wasAttached) {
+        returnValue = (*jvm)->DetachCurrentThread(jvm);
+    }
+
+    return rv ;
+}
+
+/*
+ * is the function that gets called by PKCS#11 to destroy a mutex and calls the Java
+ * DestroyMutex function
+ *
+ * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
+ * @param pMutex - the mutex to destroy
+ * @return - should return CKR_OK if the mutex was destroyed
+ */
+CK_RV callJDestroyMutex(CK_VOID_PTR pMutex)
+{
+    extern JavaVM *jvm;
+    JNIEnv *env;
+    jint returnValue;
+    jthrowable pkcs11Exception;
+    jclass pkcs11ExceptionClass;
+    jlong errorCode;
+    CK_RV rv = CKR_OK;
+    int wasAttached = 1;
+    jclass jDestroyMutexClass;
+    jclass jInitArgsClass;
+    jmethodID methodID;
+    jfieldID fieldID;
+    jobject jDestroyMutex;
+    jobject jMutex;
+
+
+    /* Get the currently running Java VM */
+    if (jvm == NULL) { return rv ; } /* there is no VM running */
+
+    /* Determine, if current thread is already attached */
+    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
+    if (returnValue == JNI_EDETACHED) {
+        /* thread detached, so attach it */
+        wasAttached = 0;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else if (returnValue == JNI_EVERSION) {
+        /* this version of JNI is not supported, so just try to attach */
+        /* we assume it was attached to ensure that this thread is not detached
+         * afterwards even though it should not
+         */
+        wasAttached = 1;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else {
+        /* attached */
+        wasAttached = 1;
+    }
+
+    jDestroyMutexClass = (*env)->FindClass(env, CLASS_DESTROYMUTEX);
+    if (jDestroyMutexClass == NULL) { return rv; }
+    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
+    if (jInitArgsClass == NULL) { return rv; }
+
+    /* convert the CK mutex to a Java mutex */
+    jMutex = ckVoidPtrToJObject(pMutex);
+
+    /* get the DestroyMutex object out of the jInitArgs object */
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;");
+    if (fieldID == NULL) { return rv; }
+    jDestroyMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
+    assert(jDestroyMutex != 0);
+
+    /* call the CK_DESTROYMUTEX method of the DestroyMutex object */
+    methodID = (*env)->GetMethodID(env, jDestroyMutexClass, "CK_DESTROYMUTEX", "(Ljava/lang/Object;)V");
+    if (methodID == NULL) { return rv; }
+    (*env)->CallVoidMethod(env, jDestroyMutex, methodID, jMutex);
+
+    /* delete the global reference on the Java mutex */
+    (*env)->DeleteGlobalRef(env, jMutex);
+
+
+    /* check, if callback threw an exception */
+    pkcs11Exception = (*env)->ExceptionOccurred(env);
+
+    if (pkcs11Exception != NULL) {
+        /* TBD: clear the pending exception with ExceptionClear? */
+        /* The was an exception thrown, now we get the error-code from it */
+        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
+        if (pkcs11ExceptionClass == NULL) { return rv; }
+        methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
+        if (methodID == NULL) { return rv; }
+        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
+        rv = jLongToCKULong(errorCode);
+    }
+
+    /* if we attached this thread to the VM just for callback, we detach it now */
+    if (wasAttached) {
+        returnValue = (*jvm)->DetachCurrentThread(jvm);
+    }
+
+    return rv ;
+}
+
+/*
+ * is the function that gets called by PKCS#11 to lock a mutex and calls the Java
+ * LockMutex function
+ *
+ * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
+ * @param pMutex - the mutex to lock
+ * @return - should return CKR_OK if the mutex was not locked already
+ */
+CK_RV callJLockMutex(CK_VOID_PTR pMutex)
+{
+    extern JavaVM *jvm;
+    JNIEnv *env;
+    jint returnValue;
+    jthrowable pkcs11Exception;
+    jclass pkcs11ExceptionClass;
+    jlong errorCode;
+    CK_RV rv = CKR_OK;
+    int wasAttached = 1;
+    jclass jLockMutexClass;
+    jclass jInitArgsClass;
+    jmethodID methodID;
+    jfieldID fieldID;
+    jobject jLockMutex;
+    jobject jMutex;
+
+
+    /* Get the currently running Java VM */
+    if (jvm == NULL) { return rv ; } /* there is no VM running */
+
+    /* Determine, if current thread is already attached */
+    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
+    if (returnValue == JNI_EDETACHED) {
+        /* thread detached, so attach it */
+        wasAttached = 0;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else if (returnValue == JNI_EVERSION) {
+        /* this version of JNI is not supported, so just try to attach */
+        /* we assume it was attached to ensure that this thread is not detached
+         * afterwards even though it should not
+         */
+        wasAttached = 1;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else {
+        /* attached */
+        wasAttached = 1;
+    }
+
+    jLockMutexClass = (*env)->FindClass(env, CLASS_LOCKMUTEX);
+    if (jLockMutexClass == NULL) { return rv; }
+    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
+    if (jInitArgsClass == NULL) { return rv; }
+
+    /* convert the CK mutex to a Java mutex */
+    jMutex = ckVoidPtrToJObject(pMutex);
+
+    /* get the LockMutex object out of the jInitArgs object */
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;");
+    if (fieldID == NULL) { return rv; }
+    jLockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
+    assert(jLockMutex != 0);
+
+    /* call the CK_LOCKMUTEX method of the LockMutex object */
+    methodID = (*env)->GetMethodID(env, jLockMutexClass, "CK_LOCKMUTEX", "(Ljava/lang/Object;)V");
+    if (methodID == NULL) { return rv; }
+    (*env)->CallVoidMethod(env, jLockMutex, methodID, jMutex);
+
+    /* check, if callback threw an exception */
+    pkcs11Exception = (*env)->ExceptionOccurred(env);
+
+    if (pkcs11Exception != NULL) {
+        /* TBD: clear the pending exception with ExceptionClear? */
+        /* The was an exception thrown, now we get the error-code from it */
+        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
+        if (pkcs11ExceptionClass == NULL) { return rv; }
+        methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
+        if (methodID == NULL) { return rv; }
+        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
+        rv = jLongToCKULong(errorCode);
+    }
+
+    /* if we attached this thread to the VM just for callback, we detach it now */
+    if (wasAttached) {
+        returnValue = (*jvm)->DetachCurrentThread(jvm);
+    }
+
+    return rv ;
+}
+
+/*
+ * is the function that gets called by PKCS#11 to unlock a mutex and calls the Java
+ * UnlockMutex function
+ *
+ * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
+ * @param pMutex - the mutex to unlock
+ * @return - should return CKR_OK if the mutex was not unlocked already
+ */
+CK_RV callJUnlockMutex(CK_VOID_PTR pMutex)
+{
+    extern JavaVM *jvm;
+    JNIEnv *env;
+    jint returnValue;
+    jthrowable pkcs11Exception;
+    jclass pkcs11ExceptionClass;
+    jlong errorCode;
+    CK_RV rv = CKR_OK;
+    int wasAttached = 1;
+    jclass jUnlockMutexClass;
+    jclass jInitArgsClass;
+    jmethodID methodID;
+    jfieldID fieldID;
+    jobject jUnlockMutex;
+    jobject jMutex;
+
+
+    /* Get the currently running Java VM */
+    if (jvm == NULL) { return rv ; } /* there is no VM running */
+
+    /* Determine, if current thread is already attached */
+    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
+    if (returnValue == JNI_EDETACHED) {
+        /* thread detached, so attach it */
+        wasAttached = 0;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else if (returnValue == JNI_EVERSION) {
+        /* this version of JNI is not supported, so just try to attach */
+        /* we assume it was attached to ensure that this thread is not detached
+         * afterwards even though it should not
+         */
+        wasAttached = 1;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else {
+        /* attached */
+        wasAttached = 1;
+    }
+
+    jUnlockMutexClass = (*env)->FindClass(env, CLASS_UNLOCKMUTEX);
+    if (jUnlockMutexClass == NULL) { return rv; }
+    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
+    if (jInitArgsClass == NULL) { return rv; }
+
+    /* convert the CK-type mutex to a Java mutex */
+    jMutex = ckVoidPtrToJObject(pMutex);
+
+    /* get the UnlockMutex object out of the jInitArgs object */
+    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;");
+    if (fieldID == NULL) { return rv; }
+    jUnlockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
+    assert(jUnlockMutex != 0);
+
+    /* call the CK_UNLOCKMUTEX method of the UnLockMutex object */
+    methodID = (*env)->GetMethodID(env, jUnlockMutexClass, "CK_UNLOCKMUTEX", "(Ljava/lang/Object;)V");
+    if (methodID == NULL) { return rv; }
+    (*env)->CallVoidMethod(env, jUnlockMutex, methodID, jMutex);
+
+    /* check, if callback threw an exception */
+    pkcs11Exception = (*env)->ExceptionOccurred(env);
+
+    if (pkcs11Exception != NULL) {
+        /* TBD: clear the pending exception with ExceptionClear? */
+        /* The was an exception thrown, now we get the error-code from it */
+        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
+        if (pkcs11ExceptionClass == NULL) { return rv; }
+        methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
+        if (methodID == NULL) { return rv; }
+        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
+        rv = jLongToCKULong(errorCode);
+    }
+
+    /* if we attached this thread to the VM just for callback, we detach it now */
+    if (wasAttached) {
+        returnValue = (*jvm)->DetachCurrentThread(jvm);
+    }
+
+    return rv ;
+}
+
+#endif /* NO_CALLBACKS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+#ifdef P11_ENABLE_C_CREATEOBJECT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_CreateObject
+ * Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
+ *                                      CK_ULONG ulCount
+ * @return  jlong jObjectHandle         CK_OBJECT_HANDLE_PTR phObject
+ */
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CreateObject
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_OBJECT_HANDLE ckObjectHandle;
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
+    CK_ULONG ckAttributesLength;
+    jlong jObjectHandle = 0L;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
+    if ((*env)->ExceptionCheck(env)) { return 0L; }
+
+    rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle, ckpAttributes, ckAttributesLength, &ckObjectHandle);
+
+    jObjectHandle = ckULongToJLong(ckObjectHandle);
+    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
+
+    return jObjectHandle ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_COPYOBJECT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_CopyObject
+ * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
+ * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
+ *                                      CK_ULONG ulCount
+ * @return  jlong jNewObjectHandle      CK_OBJECT_HANDLE_PTR phNewObject
+ */
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CopyObject
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_OBJECT_HANDLE ckObjectHandle;
+    CK_OBJECT_HANDLE ckNewObjectHandle;
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
+    CK_ULONG ckAttributesLength;
+    jlong jNewObjectHandle = 0L;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckObjectHandle = jLongToCKULong(jObjectHandle);
+    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
+    if ((*env)->ExceptionCheck(env)) { return 0L; }
+
+    rv = (*ckpFunctions->C_CopyObject)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength, &ckNewObjectHandle);
+
+    jNewObjectHandle = ckULongToJLong(ckNewObjectHandle);
+    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+
+    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
+
+    return jNewObjectHandle ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_DESTROYOBJECT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_DestroyObject
+ * Signature: (JJ)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DestroyObject
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_OBJECT_HANDLE ckObjectHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckObjectHandle = jLongToCKULong(jObjectHandle);
+
+    rv = (*ckpFunctions->C_DestroyObject)(ckSessionHandle, ckObjectHandle);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETOBJECTSIZE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetObjectSize
+ * Signature: (JJ)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
+ * @return  jlong jObjectSize           CK_ULONG_PTR pulSize
+ */
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetObjectSize
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_OBJECT_HANDLE ckObjectHandle;
+    CK_ULONG ckObjectSize;
+    jlong jObjectSize = 0L;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckObjectHandle = jLongToCKULong(jObjectHandle);
+
+    rv = (*ckpFunctions->C_GetObjectSize)(ckSessionHandle, ckObjectHandle, &ckObjectSize);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
+
+    jObjectSize = ckULongToJLong(ckObjectSize);
+
+    return jObjectSize ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETATTRIBUTEVALUE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetAttributeValue
+ * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
+ * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
+ *                                      CK_ULONG ulCount
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetAttributeValue
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_OBJECT_HANDLE ckObjectHandle;
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
+    CK_ULONG ckAttributesLength;
+    CK_ULONG ckBufferLength;
+    CK_ULONG i;
+    jobject jAttribute;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    TRACE0("DEBUG: C_GetAttributeValue");
+    TRACE1(", hSession=%u", jSessionHandle);
+    TRACE1(", hObject=%u", jObjectHandle);
+    TRACE1(", pTemplate=%p", jTemplate);
+    TRACE0(" ... ");
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckObjectHandle = jLongToCKULong(jObjectHandle);
+    TRACE1("jAttributeArrayToCKAttributeArray now with jTemplate = %d", jTemplate);
+    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    TRACE2("DEBUG: jAttributeArrayToCKAttributeArray finished with ckpAttribute = %d, Length = %d\n", ckpAttributes, ckAttributesLength);
+
+    /* first set all pValue to NULL, to get the needed buffer length */
+    for(i = 0; i < ckAttributesLength; i++) {
+        if (ckpAttributes[i].pValue != NULL_PTR) {
+            free(ckpAttributes[i].pValue);
+            ckpAttributes[i].pValue = NULL_PTR;
+        }
+    }
+
+    rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+        free(ckpAttributes);
+        return ;
+    }
+
+    /* now, the ulValueLength field of each attribute should hold the exact buffer length needed
+     * allocate the needed buffers accordingly
+     */
+    for (i = 0; i < ckAttributesLength; i++) {
+        ckBufferLength = sizeof(CK_BYTE) * ckpAttributes[i].ulValueLen;
+        ckpAttributes[i].pValue = (void *) malloc(ckBufferLength);
+        if (ckpAttributes[i].pValue == NULL) {
+            freeCKAttributeArray(ckpAttributes, i);
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+        ckpAttributes[i].ulValueLen = ckBufferLength;
+    }
+
+    /* now get the attributes with all values */
+    rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
+
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        /* copy back the values to the Java attributes */
+        for (i = 0; i < ckAttributesLength; i++) {
+            jAttribute = ckAttributePtrToJAttribute(env, &(ckpAttributes[i]));
+            if (jAttribute == NULL) {
+                freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+                return;
+            }
+            (*env)->SetObjectArrayElement(env, jTemplate, i, jAttribute);
+            if ((*env)->ExceptionCheck(env)) {
+                freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+                return;
+            }
+        }
+    }
+    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+    TRACE0("FINISHED\n");
+}
+#endif
+
+#ifdef P11_ENABLE_C_SETATTRIBUTEVALUE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SetAttributeValue
+ * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
+ * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
+ *                                      CK_ULONG ulCount
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetAttributeValue
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_OBJECT_HANDLE ckObjectHandle;
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
+    CK_ULONG ckAttributesLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckObjectHandle = jLongToCKULong(jObjectHandle);
+    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    rv = (*ckpFunctions->C_SetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
+
+    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+
+    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_FINDOBJECTSINIT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_FindObjectsInit
+ * Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
+ *                                      CK_ULONG ulCount
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsInit
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
+    CK_ULONG ckAttributesLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    TRACE0("DEBUG: C_FindObjectsInit");
+    TRACE1(", hSession=%u", jSessionHandle);
+    TRACE1(", pTemplate=%p", jTemplate);
+    TRACE0(" ... ");
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    rv = (*ckpFunctions->C_FindObjectsInit)(ckSessionHandle, ckpAttributes, ckAttributesLength);
+
+    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
+    TRACE0("FINISHED\n");
+
+    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_FINDOBJECTS
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_FindObjects
+ * Signature: (JJ)[J
+ * Parametermapping:                        *PKCS11*
+ * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
+ * @param   jlong jMaxObjectCount           CK_ULONG ulMaxObjectCount
+ * @return  jlongArray jObjectHandleArray   CK_OBJECT_HANDLE_PTR phObject
+ *                                          CK_ULONG_PTR pulObjectCount
+ */
+JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjects
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jMaxObjectCount)
+{
+    CK_RV rv;
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_ULONG ckMaxObjectLength;
+    CK_OBJECT_HANDLE_PTR ckpObjectHandleArray;
+    CK_ULONG ckActualObjectCount;
+    jlongArray jObjectHandleArray = NULL;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckMaxObjectLength = jLongToCKULong(jMaxObjectCount);
+    ckpObjectHandleArray = (CK_OBJECT_HANDLE_PTR) malloc(sizeof(CK_OBJECT_HANDLE) * ckMaxObjectLength);
+    if (ckpObjectHandleArray == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    rv = (*ckpFunctions->C_FindObjects)(ckSessionHandle, ckpObjectHandleArray, ckMaxObjectLength, &ckActualObjectCount);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jObjectHandleArray = ckULongArrayToJLongArray(env, ckpObjectHandleArray, ckActualObjectCount);
+    }
+
+    free(ckpObjectHandleArray);
+
+    return jObjectHandleArray ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_FINDOBJECTSFINAL
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_FindObjectsFinal
+ * Signature: (J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsFinal
+    (JNIEnv *env, jobject obj, jlong jSessionHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    rv = (*ckpFunctions->C_FindObjectsFinal)(ckSessionHandle);
+    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,634 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+/* The list of notify callback handles that are currently active and waiting
+ * for callbacks from their sessions.
+ */
+#ifndef NO_CALLBACKS
+NotifyListNode *notifyListHead = NULL;
+jobject notifyListLock = NULL;
+#endif /* NO_CALLBACKS */
+
+#ifdef P11_ENABLE_C_OPENSESSION
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_OpenSession
+ * Signature: (JJLjava/lang/Object;Lsun/security/pkcs11/wrapper/CK_NOTIFY;)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @param   jlong jFlags                CK_FLAGS flags
+ * @param   jobject jApplication        CK_VOID_PTR pApplication
+ * @param   jobject jNotify             CK_NOTIFY Notify
+ * @return  jlong jSessionHandle        CK_SESSION_HANDLE_PTR phSession
+ */
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1OpenSession
+    (JNIEnv *env, jobject obj, jlong jSlotID, jlong jFlags, jobject jApplication, jobject jNotify)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_SLOT_ID ckSlotID;
+    CK_FLAGS ckFlags;
+    CK_VOID_PTR ckpApplication;
+    CK_NOTIFY ckNotify;
+    jlong jSessionHandle;
+    CK_RV rv;
+#ifndef NO_CALLBACKS
+    NotifyEncapsulation *notifyEncapsulation = NULL;
+#endif /* NO_CALLBACKS */
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+    ckFlags = jLongToCKULong(jFlags);
+
+#ifndef NO_CALLBACKS
+    if (jNotify != NULL) {
+        notifyEncapsulation = (NotifyEncapsulation *) malloc(sizeof(NotifyEncapsulation));
+        if (notifyEncapsulation == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return 0L;
+        }
+        notifyEncapsulation->jApplicationData = (jApplication != NULL)
+                ? (*env)->NewGlobalRef(env, jApplication)
+                : NULL;
+        notifyEncapsulation->jNotifyObject = (*env)->NewGlobalRef(env, jNotify);
+        ckpApplication = notifyEncapsulation;
+        ckNotify = (CK_NOTIFY) &notifyCallback;
+    } else {
+        ckpApplication = NULL_PTR;
+        ckNotify = NULL_PTR;
+    }
+#else
+        ckpApplication = NULL_PTR;
+        ckNotify = NULL_PTR;
+#endif /* NO_CALLBACKS */
+
+    TRACE0("DEBUG: C_OpenSession");
+    TRACE1(", slotID=%u", ckSlotID);
+    TRACE1(", flags=%x", ckFlags);
+    TRACE0(" ... ");
+
+    rv = (*ckpFunctions->C_OpenSession)(ckSlotID, ckFlags, ckpApplication, ckNotify, &ckSessionHandle);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+#ifndef NO_CALLBACKS
+        if (notifyEncapsulation != NULL) {
+            if (notifyEncapsulation->jApplicationData != NULL) {
+                (*env)->DeleteGlobalRef(env, jApplication);
+            }
+            (*env)->DeleteGlobalRef(env, jNotify);
+            free(notifyEncapsulation);
+        }
+#endif /* NO_CALLBACKS */
+        return 0L;
+    }
+
+    TRACE0("got session");
+    TRACE1(", SessionHandle=%u", ckSessionHandle);
+    TRACE0(" ... ");
+
+    jSessionHandle = ckULongToJLong(ckSessionHandle);
+
+#ifndef NO_CALLBACKS
+    if (notifyEncapsulation != NULL) {
+        /* store the notifyEncapsulation to enable later cleanup */
+        putNotifyEntry(env, ckSessionHandle, notifyEncapsulation);
+    }
+#endif /* NO_CALLBACKS */
+
+    TRACE0("FINISHED\n");
+
+    return jSessionHandle ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_CLOSESESSION
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_CloseSession
+ * Signature: (J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseSession
+    (JNIEnv *env, jobject obj, jlong jSessionHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+#ifndef NO_CALLBACKS
+    NotifyEncapsulation *notifyEncapsulation;
+    jobject jApplicationData;
+#endif /* NO_CALLBACKS */
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    rv = (*ckpFunctions->C_CloseSession)(ckSessionHandle);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+
+#ifndef NO_CALLBACKS
+    notifyEncapsulation = removeNotifyEntry(env, ckSessionHandle);
+
+    if (notifyEncapsulation != NULL) {
+        /* there was a notify object used with this session, now dump the
+         * encapsulation object
+         */
+        (*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject);
+        jApplicationData = notifyEncapsulation->jApplicationData;
+        if (jApplicationData != NULL) {
+            (*env)->DeleteGlobalRef(env, jApplicationData);
+        }
+        free(notifyEncapsulation);
+    }
+#endif /* NO_CALLBACKS */
+
+}
+#endif
+
+#ifdef P11_ENABLE_C_CLOSEALLSESSIONS
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_CloseAllSessions
+ * Signature: (J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseAllSessions
+    (JNIEnv *env, jobject obj, jlong jSlotID)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_RV rv;
+#ifndef NO_CALLBACKS
+    NotifyEncapsulation *notifyEncapsulation;
+    jobject jApplicationData;
+#endif /* NO_CALLBACKS */
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+
+    rv = (*ckpFunctions->C_CloseAllSessions)(ckSlotID);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+
+#ifndef NO_CALLBACKS
+    /* Remove all notify callback helper objects. */
+    while ((notifyEncapsulation = removeFirstNotifyEntry(env)) != NULL) {
+        /* there was a notify object used with this session, now dump the
+         * encapsulation object
+         */
+        (*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject);
+        jApplicationData = notifyEncapsulation->jApplicationData;
+        if (jApplicationData != NULL) {
+            (*env)->DeleteGlobalRef(env, jApplicationData);
+        }
+        free(notifyEncapsulation);
+    }
+#endif /* NO_CALLBACKS */
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETSESSIONINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetSessionInfo
+ * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SESSION_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @return  jobject jSessionInfo        CK_SESSION_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionInfo
+    (JNIEnv *env, jobject obj, jlong jSessionHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_SESSION_INFO ckSessionInfo;
+    jobject jSessionInfo=NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    rv = (*ckpFunctions->C_GetSessionInfo)(ckSessionHandle, &ckSessionInfo);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jSessionInfo = ckSessionInfoPtrToJSessionInfo(env, &ckSessionInfo);
+    }
+    return jSessionInfo ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETOPERATIONSTATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetOperationState
+ * Signature: (J)[B
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @return  jbyteArray jState           CK_BYTE_PTR pOperationState
+ *                                      CK_ULONG_PTR pulOperationStateLen
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState
+    (JNIEnv *env, jobject obj, jlong jSessionHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpState;
+    CK_ULONG ckStateLength;
+    jbyteArray jState = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, NULL_PTR, &ckStateLength);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    ckpState = (CK_BYTE_PTR) malloc(ckStateLength);
+    if (ckpState == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, ckpState, &ckStateLength);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jState = ckByteArrayToJByteArray(env, ckpState, ckStateLength);
+    }
+    free(ckpState);
+
+    return jState ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_SETOPERATIONSTATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SetOperationState
+ * Signature: (J[BJJ)V
+ * Parametermapping:                        *PKCS11*
+ * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jOperationState      CK_BYTE_PTR pOperationState
+ *                                          CK_ULONG ulOperationStateLen
+ * @param   jlong jEncryptionKeyHandle      CK_OBJECT_HANDLE hEncryptionKey
+ * @param   jlong jAuthenticationKeyHandle  CK_OBJECT_HANDLE hAuthenticationKey
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jOperationState, jlong jEncryptionKeyHandle, jlong jAuthenticationKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpState = NULL_PTR;
+    CK_ULONG ckStateLength;
+    CK_OBJECT_HANDLE ckEncryptionKeyHandle;
+    CK_OBJECT_HANDLE ckAuthenticationKeyHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jOperationState, &ckpState, &ckStateLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    ckEncryptionKeyHandle = jLongToCKULong(jEncryptionKeyHandle);
+    ckAuthenticationKeyHandle = jLongToCKULong(jAuthenticationKeyHandle);
+
+    rv = (*ckpFunctions->C_SetOperationState)(ckSessionHandle, ckpState, ckStateLength, ckEncryptionKeyHandle, ckAuthenticationKeyHandle);
+
+    free(ckpState);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_LOGIN
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Login
+ * Signature: (JJ[C)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jlong jUserType             CK_USER_TYPE userType
+ * @param   jcharArray jPin             CK_CHAR_PTR pPin
+ *                                      CK_ULONG ulPinLen
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, jcharArray jPin)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_USER_TYPE ckUserType;
+    CK_CHAR_PTR ckpPinArray = NULL_PTR;
+    CK_ULONG ckPinLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    ckUserType = jLongToCKULong(jUserType);
+    jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray, ckPinLength);
+
+    free(ckpPinArray);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_LOGOUT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Logout
+ * Signature: (J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout
+    (JNIEnv *env, jobject obj, jlong jSessionHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    rv = (*ckpFunctions->C_Logout)(ckSessionHandle);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+/* ************************************************************************** */
+/* Functions for keeping track of notify callbacks                            */
+/* ************************************************************************** */
+
+#ifndef NO_CALLBACKS
+
+/*
+ * Add the given notify encapsulation object to the list of active notify
+ * objects.
+ * If notifyEncapsulation is NULL, this function does nothing.
+ */
+void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation *notifyEncapsulation) {
+    NotifyListNode *currentNode, *newNode;
+
+    if (notifyEncapsulation == NULL) {
+        return;
+    }
+
+    newNode = (NotifyListNode *) malloc(sizeof(NotifyListNode));
+    if (newNode == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    newNode->hSession = hSession;
+    newNode->notifyEncapsulation = notifyEncapsulation;
+    newNode->next = NULL;
+
+    (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
+
+    if (notifyListHead == NULL) {
+        /* this is the first entry */
+        notifyListHead = newNode;
+    } else {
+        /* go to the last entry; i.e. the first node which's 'next' is NULL.
+         */
+        currentNode = notifyListHead;
+        while (currentNode->next != NULL) {
+            currentNode = currentNode->next;
+        }
+        currentNode->next = newNode;
+    }
+
+    (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
+}
+
+/*
+ * Removes the active notifyEncapsulation object used with the given session and
+ * returns it. If there is no notifyEncapsulation active for this session, this
+ * function returns NULL.
+ */
+NotifyEncapsulation * removeNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession) {
+    NotifyEncapsulation *notifyEncapsulation;
+    NotifyListNode *currentNode, *previousNode;
+
+    (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
+
+    if (notifyListHead == NULL) {
+        /* this is the first entry */
+        notifyEncapsulation = NULL;
+    } else {
+        /* Find the node with the wanted session handle. Also stop, when we reach
+         * the last entry; i.e. the first node which's 'next' is NULL.
+         */
+        currentNode = notifyListHead;
+        previousNode = NULL;
+
+        while ((currentNode->hSession != hSession) && (currentNode->next != NULL)) {
+            previousNode = currentNode;
+            currentNode = currentNode->next;
+        }
+
+        if (currentNode->hSession == hSession) {
+            /* We found a entry for the wanted session, now remove it. */
+            if (previousNode == NULL) {
+                /* it's the first node */
+                notifyListHead = currentNode->next;
+            } else {
+                previousNode->next = currentNode->next;
+            }
+            notifyEncapsulation = currentNode->notifyEncapsulation;
+            free(currentNode);
+        } else {
+            /* We did not find a entry for this session */
+            notifyEncapsulation = NULL;
+        }
+    }
+
+    (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
+
+    return notifyEncapsulation ;
+}
+
+/*
+
+ * Removes the first notifyEncapsulation object. If there is no notifyEncapsulation,
+ * this function returns NULL.
+ */
+NotifyEncapsulation * removeFirstNotifyEntry(JNIEnv *env) {
+    NotifyEncapsulation *notifyEncapsulation;
+    NotifyListNode *currentNode;
+
+    (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
+
+    if (notifyListHead == NULL) {
+        /* this is the first entry */
+        notifyEncapsulation = NULL;
+    } else {
+        /* Remove the first entry. */
+        currentNode = notifyListHead;
+        notifyListHead = notifyListHead->next;
+        notifyEncapsulation = currentNode->notifyEncapsulation;
+        free(currentNode);
+    }
+
+    (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
+
+    return notifyEncapsulation ;
+}
+
+#endif /* NO_CALLBACKS */
+
+#ifndef NO_CALLBACKS
+
+/*
+ * The function handling notify callbacks. It casts the pApplication parameter
+ * back to a NotifyEncapsulation structure and retrieves the Notify object and
+ * the application data from it.
+ *
+ * @param hSession The session, this callback is comming from.
+ * @param event The type of event that occurred.
+ * @param pApplication The application data as passed in upon OpenSession. In
+                       this wrapper we always pass in a NotifyEncapsulation
+                       object, which holds necessary information for delegating
+                       the callback to the Java VM.
+ * @return
+ */
+CK_RV notifyCallback(
+    CK_SESSION_HANDLE hSession,     /* the session's handle */
+    CK_NOTIFICATION   event,
+    CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
+)
+{
+    NotifyEncapsulation *notifyEncapsulation;
+    extern JavaVM *jvm;
+    JNIEnv *env;
+    jint returnValue;
+    jlong jSessionHandle;
+    jlong jEvent;
+    jclass ckNotifyClass;
+    jmethodID jmethod;
+    jthrowable pkcs11Exception;
+    jclass pkcs11ExceptionClass;
+    jlong errorCode;
+    CK_RV rv = CKR_OK;
+    int wasAttached = 1;
+
+    if (pApplication == NULL) { return rv ; } /* This should not occur in this wrapper. */
+
+    notifyEncapsulation = (NotifyEncapsulation *) pApplication;
+
+    /* Get the currently running Java VM */
+    if (jvm == NULL) { return rv ; } /* there is no VM running */
+
+    /* Determine, if current thread is already attached */
+    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
+    if (returnValue == JNI_EDETACHED) {
+        /* thread detached, so attach it */
+        wasAttached = 0;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else if (returnValue == JNI_EVERSION) {
+        /* this version of JNI is not supported, so just try to attach */
+        /* we assume it was attached to ensure that this thread is not detached
+         * afterwards even though it should not
+         */
+        wasAttached = 1;
+        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
+    } else {
+        /* attached */
+        wasAttached = 1;
+    }
+
+    jSessionHandle = ckULongToJLong(hSession);
+    jEvent = ckULongToJLong(event);
+
+    ckNotifyClass = (*env)->FindClass(env, CLASS_NOTIFY);
+    if (ckNotifyClass == NULL) { return rv; }
+    jmethod = (*env)->GetMethodID(env, ckNotifyClass, "CK_NOTIFY", "(JJLjava/lang/Object;)V");
+    if (jmethod == NULL) { return rv; }
+
+    (*env)->CallVoidMethod(env, notifyEncapsulation->jNotifyObject, jmethod,
+                         jSessionHandle, jEvent, notifyEncapsulation->jApplicationData);
+
+    /* check, if callback threw an exception */
+    pkcs11Exception = (*env)->ExceptionOccurred(env);
+
+    if (pkcs11Exception != NULL) {
+        /* TBD: clear the pending exception with ExceptionClear? */
+        /* The was an exception thrown, now we get the error-code from it */
+        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
+        if (pkcs11ExceptionClass == NULL) { return rv; }
+
+        jmethod = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
+        if (jmethod == NULL) { return rv; }
+
+        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, jmethod);
+        rv = jLongToCKULong(errorCode);
+    }
+
+    /* if we attached this thread to the VM just for callback, we detach it now */
+    if (wasAttached) {
+        returnValue = (*jvm)->DetachCurrentThread(jvm);
+    }
+
+    return rv ;
+}
+
+#endif /* NO_CALLBACKS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,674 @@
+/*
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "jlong.h"
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+#ifdef P11_ENABLE_C_SIGNINIT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SignInit
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignInit
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckKeyHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return; }
+    ckKeyHandle = jLongToCKULong(jKeyHandle);
+
+    rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_SIGN
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Sign
+ * Signature: (J[B)[B
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jData            CK_BYTE_PTR pData
+ *                                      CK_ULONG ulDataLen
+ * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
+ *                                      CK_ULONG_PTR pulSignatureLen
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Sign
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpData = NULL_PTR;
+    CK_BYTE_PTR ckpSignature;
+    CK_ULONG ckDataLength;
+    CK_ULONG ckSignatureLength = 0;
+    jbyteArray jSignature = NULL;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
+    if ((*env)->ExceptionCheck(env)) { return NULL; }
+
+    /* START standard code */
+
+    /* first determine the length of the signature */
+    rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckSignatureLength);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+        free(ckpData);
+        return NULL;
+    }
+
+    ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
+    if (ckpSignature == NULL) {
+        free(ckpData);
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+
+    /* now get the signature */
+    rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
+ /* END standard code */
+
+
+    /* START workaround code for operation abort bug in pkcs#11 of Datakey and iButton */
+/*
+    ckpSignature = (CK_BYTE_PTR) malloc(256 * sizeof(CK_BYTE));
+    if (ckpSignature == NULL) {
+        free(ckpData);
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
+
+    if (rv == CKR_BUFFER_TOO_SMALL) {
+        free(ckpSignature);
+        ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
+        if (ckpSignature == NULL) {
+            free(ckpData);
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
+    }
+ */
+    /* END workaround code */
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength);
+    }
+    free(ckpData);
+    free(ckpSignature);
+
+    return jSignature ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_SIGNUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SignUpdate
+ * Signature: (J[BII)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jPart            CK_BYTE_PTR pPart
+ *                                      CK_ULONG ulPartLen
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignUpdate
+  (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE_PTR bufP;
+    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
+    jsize bufLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (directIn != 0) {
+        rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, (CK_BYTE_PTR) jlong_to_ptr(directIn), jInLen);
+        ckAssertReturnValueOK(env, rv);
+        return;
+    }
+
+    if (jInLen <= MAX_STACK_BUFFER_LEN) {
+        bufLen = MAX_STACK_BUFFER_LEN;
+        bufP = BUF;
+    } else {
+        bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
+        bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
+        if (bufP == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+    }
+
+    while (jInLen > 0) {
+        jsize chunkLen = min(bufLen, jInLen);
+        (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
+        if ((*env)->ExceptionCheck(env)) {
+            if (bufP != BUF) { free(bufP); }
+            return;
+        }
+        rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, bufP, chunkLen);
+        if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+            if (bufP != BUF) {
+                free(bufP);
+            }
+            return;
+        }
+        jInOfs += chunkLen;
+        jInLen -= chunkLen;
+    }
+
+    if (bufP != BUF) { free(bufP); }
+}
+#endif
+
+#ifdef P11_ENABLE_C_SIGNFINAL
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SignFinal
+ * Signature: (J)[B
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
+ *                                      CK_ULONG_PTR pulSignatureLen
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignFinal
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jint jExpectedLength)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    jbyteArray jSignature = NULL;
+    CK_RV rv;
+    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
+    CK_BYTE_PTR bufP = BUF;
+    CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if ((jExpectedLength > 0) && ((CK_ULONG)jExpectedLength < ckSignatureLength)) {
+        ckSignatureLength = jExpectedLength;
+    }
+
+    rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
+    if (rv == CKR_BUFFER_TOO_SMALL) {
+        bufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
+        if (bufP == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
+    }
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength);
+    }
+
+    if (bufP != BUF) { free(bufP); }
+
+    return jSignature;
+}
+#endif
+
+#ifdef P11_ENABLE_C_SIGNRECOVERINIT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SignRecoverInit
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecoverInit
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckKeyHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    ckKeyHandle = jLongToCKULong(jKeyHandle);
+
+    rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+
+    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_SIGNRECOVER
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SignRecover
+ * Signature: (J[BII[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jData            CK_BYTE_PTR pData
+ *                                      CK_ULONG ulDataLen
+ * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
+ *                                      CK_ULONG_PTR pulSignatureLen
+ */
+JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecover
+  (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
+    CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
+    CK_BYTE_PTR inBufP;
+    CK_BYTE_PTR outBufP = OUTBUF;
+    CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (jInLen <= MAX_STACK_BUFFER_LEN) {
+        inBufP = INBUF;
+    } else {
+        inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
+        if (inBufP == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return 0;
+        }
+    }
+
+    (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
+    if ((*env)->ExceptionCheck(env)) {
+        if (inBufP != INBUF) { free(inBufP); }
+        return 0;
+    }
+    rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
+    /* re-alloc larger buffer if it fits into our Java buffer */
+    if ((rv == CKR_BUFFER_TOO_SMALL) && (ckSignatureLength <= jIntToCKULong(jOutLen))) {
+        outBufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
+        if (outBufP == NULL) {
+            if (inBufP != INBUF) {
+                free(inBufP);
+            }
+            throwOutOfMemoryError(env, 0);
+            return 0;
+        }
+        rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
+    }
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckSignatureLength, (jbyte *)outBufP);
+    }
+
+    if (inBufP != INBUF) { free(inBufP); }
+    if (outBufP != OUTBUF) { free(outBufP); }
+
+    return ckSignatureLength;
+}
+#endif
+
+#ifdef P11_ENABLE_C_VERIFYINIT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_VerifyInit
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyInit
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckKeyHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    ckKeyHandle = jLongToCKULong(jKeyHandle);
+
+    rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
+
+    if(ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_VERIFY
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Verify
+ * Signature: (J[B[B)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jData            CK_BYTE_PTR pData
+ *                                      CK_ULONG ulDataLen
+ * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
+ *                                      CK_ULONG_PTR pulSignatureLen
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Verify
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData, jbyteArray jSignature)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpData = NULL_PTR;
+    CK_BYTE_PTR ckpSignature = NULL_PTR;
+    CK_ULONG ckDataLength;
+    CK_ULONG ckSignatureLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
+    if ((*env)->ExceptionCheck(env)) {
+        free(ckpData);
+        return;
+    }
+
+    /* verify the signature */
+    rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength);
+
+    free(ckpData);
+    free(ckpSignature);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_VERIFYUPDATE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_VerifyUpdate
+ * Signature: (J[BII)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jPart            CK_BYTE_PTR pPart
+ *                                      CK_ULONG ulPartLen
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyUpdate
+  (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE_PTR bufP;
+    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
+    jsize bufLen;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (directIn != 0) {
+        rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen);
+        ckAssertReturnValueOK(env, rv);
+        return;
+    }
+
+    if (jInLen <= MAX_STACK_BUFFER_LEN) {
+        bufLen = MAX_STACK_BUFFER_LEN;
+        bufP = BUF;
+    } else {
+        bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
+        bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
+        if (bufP == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+    }
+
+    while (jInLen > 0) {
+        jsize chunkLen = min(bufLen, jInLen);
+        (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
+        if ((*env)->ExceptionCheck(env)) {
+            if (bufP != BUF) { free(bufP); }
+            return;
+        }
+
+        rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, bufP, chunkLen);
+        if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+            if (bufP != BUF) { free(bufP); }
+            return;
+        }
+        jInOfs += chunkLen;
+        jInLen -= chunkLen;
+    }
+
+    if (bufP != BUF) { free(bufP); }
+}
+#endif
+
+#ifdef P11_ENABLE_C_VERIFYFINAL
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_VerifyFinal
+ * Signature: (J[B)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
+ *                                      CK_ULONG ulSignatureLen
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyFinal
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_BYTE_PTR ckpSignature = NULL_PTR;
+    CK_ULONG ckSignatureLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    /* verify the signature */
+    rv = (*ckpFunctions->C_VerifyFinal)(ckSessionHandle, ckpSignature, ckSignatureLength);
+
+    free(ckpSignature);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_VERIFYRECOVERINIT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_VerifyRecoverInit
+ * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
+ * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecoverInit
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_MECHANISM ckMechanism;
+    CK_OBJECT_HANDLE ckKeyHandle;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    if ((*env)->ExceptionCheck(env)) { return; }
+
+    ckKeyHandle = jLongToCKULong(jKeyHandle);
+
+    rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
+
+    if (ckMechanism.pParameter != NULL_PTR) {
+        free(ckMechanism.pParameter);
+    }
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_VERIFYRECOVER
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_VerifyRecover
+ * Signature: (J[BII[BII)I
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
+ *                                      CK_ULONG ulSignatureLen
+ * @return  jbyteArray jData            CK_BYTE_PTR pData
+ *                                      CK_ULONG_PTR pulDataLen
+ */
+JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover
+  (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_RV rv;
+    CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
+    CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
+    CK_BYTE_PTR inBufP;
+    CK_BYTE_PTR outBufP = OUTBUF;
+    CK_ULONG ckDataLength = MAX_STACK_BUFFER_LEN;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+
+    if (jInLen <= MAX_STACK_BUFFER_LEN) {
+        inBufP = INBUF;
+    } else {
+        inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
+        if (inBufP == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return 0;
+        }
+    }
+
+    (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
+    if ((*env)->ExceptionCheck(env)) {
+        if (inBufP != INBUF) { free(inBufP); }
+        return 0;
+    }
+
+    rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
+
+    /* re-alloc larger buffer if it fits into our Java buffer */
+    if ((rv == CKR_BUFFER_TOO_SMALL) && (ckDataLength <= jIntToCKULong(jOutLen))) {
+        outBufP = (CK_BYTE_PTR) malloc(ckDataLength);
+        if (outBufP == NULL) {
+            if (inBufP != INBUF) { free(inBufP); }
+            throwOutOfMemoryError(env, 0);
+            return 0;
+        }
+        rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
+    }
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDataLength, (jbyte *)outBufP);
+    }
+
+    if (inBufP != INBUF) { free(inBufP); }
+    if (outBufP != OUTBUF) { free(outBufP); }
+
+    return ckDataLength;
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,1157 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/* declare file private functions */
+
+ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
+int isModulePresent(JNIEnv *env, jobject pkcs11Implementation);
+void removeAllModuleEntries(JNIEnv *env);
+
+
+/* ************************************************************************** */
+/* Functions for keeping track of currently active and loaded modules         */
+/* ************************************************************************** */
+
+
+/*
+ * Create a new object for locking.
+ */
+jobject createLockObject(JNIEnv *env) {
+    jclass jObjectClass;
+    jobject jLockObject;
+    jmethodID jConstructor;
+
+    jObjectClass = (*env)->FindClass(env, "java/lang/Object");
+    if (jObjectClass == NULL) { return NULL; }
+    jConstructor = (*env)->GetMethodID(env, jObjectClass, "<init>", "()V");
+    if (jConstructor == NULL) { return NULL; }
+    jLockObject = (*env)->NewObject(env, jObjectClass, jConstructor);
+    if (jLockObject == NULL) { return NULL; }
+    jLockObject = (*env)->NewGlobalRef(env, jLockObject);
+
+    return jLockObject ;
+}
+
+/*
+ * Create a new object for locking.
+ */
+void destroyLockObject(JNIEnv *env, jobject jLockObject) {
+    if (jLockObject != NULL) {
+        (*env)->DeleteGlobalRef(env, jLockObject);
+    }
+}
+
+/*
+ * Add the given pkcs11Implementation object to the list of present modules.
+ * Attach the given data to the entry. If the given pkcs11Implementation is
+ * already in the lsit, just override its old module data with the new one.
+ * None of the arguments can be NULL. If one of the arguments is NULL, this
+ * function does nothing.
+ */
+void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData) {
+    if (pkcs11Implementation == NULL_PTR) {
+        return ;
+    }
+    if (moduleData == NULL) {
+        return ;
+    }
+    (*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, ptr_to_jlong(moduleData));
+}
+
+
+/*
+ * Get the module data of the entry for the given pkcs11Implementation. Returns
+ * NULL, if the pkcs11Implementation is not in the list.
+ */
+ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
+    jlong jData;
+    if (pkcs11Implementation == NULL) {
+        return NULL;
+    }
+    jData = (*env)->GetLongField(env, pkcs11Implementation, pNativeDataID);
+    return (ModuleData*)jlong_to_ptr(jData);
+}
+
+CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation) {
+    ModuleData *moduleData;
+    CK_FUNCTION_LIST_PTR ckpFunctions;
+
+    moduleData = getModuleEntry(env, pkcs11Implementation);
+    if (moduleData == NULL) {
+        throwDisconnectedRuntimeException(env);
+        return NULL;
+    }
+    ckpFunctions = moduleData->ckFunctionListPtr;
+    return ckpFunctions;
+}
+
+
+/*
+ * Returns 1, if the given pkcs11Implementation is in the list.
+ * 0, otherwise.
+ */
+int isModulePresent(JNIEnv *env, jobject pkcs11Implementation) {
+    int present;
+
+    ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
+
+    present = (moduleData != NULL) ? 1 : 0;
+
+    return present ;
+}
+
+
+/*
+ * Removes the entry for the given pkcs11Implementation from the list. Returns
+ * the module's data, after the node was removed. If this function returns NULL
+ * the pkcs11Implementation was not in the list.
+ */
+ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
+    ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
+    if (moduleData == NULL) {
+        return NULL;
+    }
+    (*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, 0);
+    return moduleData;
+}
+
+/*
+ * Removes all present entries from the list of modules and frees all
+ * associated resources. This function is used for clean-up.
+ */
+void removeAllModuleEntries(JNIEnv *env) {
+    /* XXX empty */
+}
+
+/* ************************************************************************** */
+/* Below there follow the helper functions to support conversions between     */
+/* Java and Cryptoki types                                                    */
+/* ************************************************************************** */
+
+/*
+ * function to convert a PKCS#11 return value into a PKCS#11Exception
+ *
+ * This function generates a PKCS#11Exception with the returnValue as the errorcode
+ * if the returnValue is not CKR_OK. The functin returns 0, if the returnValue is
+ * CKR_OK. Otherwise, it returns the returnValue as a jLong.
+ *
+ * @param env - used to call JNI funktions and to get the Exception class
+ * @param returnValue - of the PKCS#11 function
+ */
+jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue)
+{
+    jclass jPKCS11ExceptionClass;
+    jmethodID jConstructor;
+    jthrowable jPKCS11Exception;
+    jlong jErrorCode = 0L;
+
+    if (returnValue != CKR_OK) {
+        jErrorCode = ckULongToJLong(returnValue);
+        jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
+        if (jPKCS11ExceptionClass != NULL) {
+            jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass, "<init>", "(J)V");
+            if (jConstructor != NULL) {
+                jPKCS11Exception = (jthrowable) (*env)->NewObject(env, jPKCS11ExceptionClass, jConstructor, jErrorCode);
+                if (jPKCS11Exception != NULL) {
+                    (*env)->Throw(env, jPKCS11Exception);
+                }
+            }
+        }
+        (*env)->DeleteLocalRef(env, jPKCS11ExceptionClass);
+    }
+    return jErrorCode ;
+}
+
+
+/*
+ * Throws a Java Exception by name
+ */
+void throwByName(JNIEnv *env, const char *name, const char *msg)
+{
+    jclass cls = (*env)->FindClass(env, name);
+
+    if (cls != 0) /* Otherwise an exception has already been thrown */
+        (*env)->ThrowNew(env, cls, msg);
+}
+
+/*
+ * Throws java.lang.OutOfMemoryError
+ */
+void throwOutOfMemoryError(JNIEnv *env, const char *msg)
+{
+    throwByName(env, "java/lang/OutOfMemoryError", msg);
+}
+
+/*
+ * Throws java.lang.NullPointerException
+ */
+void throwNullPointerException(JNIEnv *env, const char *msg)
+{
+    throwByName(env, "java/lang/NullPointerException", msg);
+}
+
+/*
+ * Throws java.io.IOException
+ */
+void throwIOException(JNIEnv *env, const char *msg)
+{
+    throwByName(env, "java/io/IOException", msg);
+}
+
+/*
+ * This function simply throws a PKCS#11RuntimeException with the given
+ * string as its message.
+ *
+ * @param env Used to call JNI funktions and to get the Exception class.
+ * @param jmessage The message string of the Exception object.
+ */
+void throwPKCS11RuntimeException(JNIEnv *env, const char *message)
+{
+    throwByName(env, CLASS_PKCS11RUNTIMEEXCEPTION, message);
+}
+
+/*
+ * This function simply throws a PKCS#11RuntimeException. The message says that
+ * the object is not connected to the module.
+ *
+ * @param env Used to call JNI funktions and to get the Exception class.
+ */
+void throwDisconnectedRuntimeException(JNIEnv *env)
+{
+    throwPKCS11RuntimeException(env, "This object is not connected to a module.");
+}
+
+/* This function frees the specified CK_ATTRIBUTE array.
+ *
+ * @param attrPtr pointer to the to-be-freed CK_ATTRIBUTE array.
+ * @param len the length of the array
+ */
+void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len)
+{
+    int i;
+
+    for (i=0; i<len; i++) {
+        if (attrPtr[i].pValue != NULL_PTR) {
+            free(attrPtr[i].pValue);
+        }
+    }
+    free(attrPtr);
+}
+
+/*
+ * the following functions convert Java arrays to PKCS#11 array pointers and
+ * their array length and vice versa
+ *
+ * void j<Type>ArrayToCK<Type>Array(JNIEnv *env,
+ *                                  const j<Type>Array jArray,
+ *                                  CK_<Type>_PTR *ckpArray,
+ *                                  CK_ULONG_PTR ckLength);
+ *
+ * j<Type>Array ck<Type>ArrayToJ<Type>Array(JNIEnv *env,
+ *                                          const CK_<Type>_PTR ckpArray,
+ *                                          CK_ULONG ckLength);
+ *
+ * PKCS#11 arrays consist always of a pointer to the beginning of the array and
+ * the array length whereas Java arrays carry their array length.
+ *
+ * The Functions to convert a Java array to a PKCS#11 array are void functions.
+ * Their arguments are the Java array object to convert, the reference to the
+ * array pointer, where the new PKCS#11 array should be stored and the reference
+ * to the array length where the PKCS#11 array length should be stored. These two
+ * references must not be NULL_PTR.
+ *
+ * The functions first obtain the array length of the Java array and then allocate
+ * the memory for the PKCS#11 array and set the array length. Then each element
+ * gets converted depending on their type. After use the allocated memory of the
+ * PKCS#11 array has to be explicitly freed.
+ *
+ * The Functions to convert a PKCS#11 array to a Java array get the PKCS#11 array
+ * pointer and the array length and they return the new Java array object. The
+ * Java array does not need to get freed after use.
+ */
+
+/*
+ * converts a jbooleanArray to a CK_BBOOL array. The allocated memory has to be freed after use!
+ *
+ * @param env - used to call JNI funktions to get the array informtaion
+ * @param jArray - the Java array to convert
+ * @param ckpArray - the reference, where the pointer to the new CK_BBOOL array will be stored
+ * @param ckpLength - the reference, where the array length will be stored
+ */
+void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckpLength)
+{
+    jboolean* jpTemp;
+    CK_ULONG i;
+
+    if(jArray == NULL) {
+        *ckpArray = NULL_PTR;
+        *ckpLength = 0L;
+        return;
+    }
+    *ckpLength = (*env)->GetArrayLength(env, jArray);
+    jpTemp = (jboolean*) malloc((*ckpLength) * sizeof(jboolean));
+    if (jpTemp == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    (*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
+    if ((*env)->ExceptionCheck(env)) {
+        free(jpTemp);
+        return;
+    }
+
+    *ckpArray = (CK_BBOOL*) malloc ((*ckpLength) * sizeof(CK_BBOOL));
+    if (*ckpArray == NULL) {
+        free(jpTemp);
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    for (i=0; i<(*ckpLength); i++) {
+        (*ckpArray)[i] = jBooleanToCKBBool(jpTemp[i]);
+    }
+    free(jpTemp);
+}
+
+/*
+ * converts a jbyteArray to a CK_BYTE array. The allocated memory has to be freed after use!
+ *
+ * @param env - used to call JNI funktions to get the array informtaion
+ * @param jArray - the Java array to convert
+ * @param ckpArray - the reference, where the pointer to the new CK_BYTE array will be stored
+ * @param ckpLength - the reference, where the array length will be stored
+ */
+void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
+{
+    jbyte* jpTemp;
+    CK_ULONG i;
+
+    if(jArray == NULL) {
+        *ckpArray = NULL_PTR;
+        *ckpLength = 0L;
+        return;
+    }
+    *ckpLength = (*env)->GetArrayLength(env, jArray);
+    jpTemp = (jbyte*) malloc((*ckpLength) * sizeof(jbyte));
+    if (jpTemp == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    (*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
+    if ((*env)->ExceptionCheck(env)) {
+        free(jpTemp);
+        return;
+    }
+
+    /* if CK_BYTE is the same size as jbyte, we save an additional copy */
+    if (sizeof(CK_BYTE) == sizeof(jbyte)) {
+        *ckpArray = (CK_BYTE_PTR) jpTemp;
+    } else {
+        *ckpArray = (CK_BYTE_PTR) malloc ((*ckpLength) * sizeof(CK_BYTE));
+        if (*ckpArray == NULL) {
+            free(jpTemp);
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+        for (i=0; i<(*ckpLength); i++) {
+            (*ckpArray)[i] = jByteToCKByte(jpTemp[i]);
+        }
+        free(jpTemp);
+    }
+}
+
+/*
+ * converts a jlongArray to a CK_ULONG array. The allocated memory has to be freed after use!
+ *
+ * @param env - used to call JNI funktions to get the array informtaion
+ * @param jArray - the Java array to convert
+ * @param ckpArray - the reference, where the pointer to the new CK_ULONG array will be stored
+ * @param ckpLength - the reference, where the array length will be stored
+ */
+void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckpLength)
+{
+    jlong* jTemp;
+    CK_ULONG i;
+
+    if(jArray == NULL) {
+        *ckpArray = NULL_PTR;
+        *ckpLength = 0L;
+        return;
+    }
+    *ckpLength = (*env)->GetArrayLength(env, jArray);
+    jTemp = (jlong*) malloc((*ckpLength) * sizeof(jlong));
+    if (jTemp == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    (*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jTemp);
+    if ((*env)->ExceptionCheck(env)) {
+        free(jTemp);
+        return;
+    }
+
+    *ckpArray = (CK_ULONG_PTR) malloc (*ckpLength * sizeof(CK_ULONG));
+    if (*ckpArray == NULL) {
+        free(jTemp);
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    for (i=0; i<(*ckpLength); i++) {
+        (*ckpArray)[i] = jLongToCKULong(jTemp[i]);
+    }
+    free(jTemp);
+}
+
+/*
+ * converts a jcharArray to a CK_CHAR array. The allocated memory has to be freed after use!
+ *
+ * @param env - used to call JNI funktions to get the array informtaion
+ * @param jArray - the Java array to convert
+ * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
+ * @param ckpLength - the reference, where the array length will be stored
+ */
+void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
+{
+    jchar* jpTemp;
+    CK_ULONG i;
+
+    if(jArray == NULL) {
+        *ckpArray = NULL_PTR;
+        *ckpLength = 0L;
+        return;
+    }
+    *ckpLength = (*env)->GetArrayLength(env, jArray);
+    jpTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
+    if (jpTemp == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
+    if ((*env)->ExceptionCheck(env)) {
+        free(jpTemp);
+        return;
+    }
+
+    *ckpArray = (CK_CHAR_PTR) malloc (*ckpLength * sizeof(CK_CHAR));
+    if (*ckpArray == NULL) {
+        free(jpTemp);
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    for (i=0; i<(*ckpLength); i++) {
+        (*ckpArray)[i] = jCharToCKChar(jpTemp[i]);
+    }
+    free(jpTemp);
+}
+
+/*
+ * converts a jcharArray to a CK_UTF8CHAR array. The allocated memory has to be freed after use!
+ *
+ * @param env - used to call JNI funktions to get the array informtaion
+ * @param jArray - the Java array to convert
+ * @param ckpArray - the reference, where the pointer to the new CK_UTF8CHAR array will be stored
+ * @param ckpLength - the reference, where the array length will be stored
+ */
+void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
+{
+    jchar* jTemp;
+    CK_ULONG i;
+
+    if(jArray == NULL) {
+        *ckpArray = NULL_PTR;
+        *ckpLength = 0L;
+        return;
+    }
+    *ckpLength = (*env)->GetArrayLength(env, jArray);
+    jTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
+    if (jTemp == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jTemp);
+    if ((*env)->ExceptionCheck(env)) {
+        free(jTemp);
+        return;
+    }
+
+    *ckpArray = (CK_UTF8CHAR_PTR) malloc (*ckpLength * sizeof(CK_UTF8CHAR));
+    if (*ckpArray == NULL) {
+        free(jTemp);
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    for (i=0; i<(*ckpLength); i++) {
+        (*ckpArray)[i] = jCharToCKUTF8Char(jTemp[i]);
+    }
+    free(jTemp);
+}
+
+/*
+ * converts a jstring to a CK_CHAR array. The allocated memory has to be freed after use!
+ *
+ * @param env - used to call JNI funktions to get the array informtaion
+ * @param jArray - the Java array to convert
+ * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
+ * @param ckpLength - the reference, where the array length will be stored
+ */
+void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
+{
+    const char* pCharArray;
+    jboolean isCopy;
+
+    if(jArray == NULL) {
+        *ckpArray = NULL_PTR;
+        *ckpLength = 0L;
+        return;
+    }
+
+    pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
+    if (pCharArray == NULL) { return; }
+
+    *ckpLength = (CK_ULONG) strlen(pCharArray);
+    *ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
+    if (*ckpArray == NULL) {
+        (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    strcpy((char*)*ckpArray, pCharArray);
+    (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
+}
+
+/*
+ * converts a jobjectArray with Java Attributes to a CK_ATTRIBUTE array. The allocated memory
+ * has to be freed after use!
+ *
+ * @param env - used to call JNI funktions to get the array informtaion
+ * @param jArray - the Java Attribute array (template) to convert
+ * @param ckpArray - the reference, where the pointer to the new CK_ATTRIBUTE array will be
+ *                   stored
+ * @param ckpLength - the reference, where the array length will be stored
+ */
+void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
+{
+    CK_ULONG i;
+    jlong jLength;
+    jobject jAttribute;
+
+    TRACE0("\nDEBUG: jAttributeArrayToCKAttributeArray");
+    if (jArray == NULL) {
+        *ckpArray = NULL_PTR;
+        *ckpLength = 0L;
+        return;
+    }
+    jLength = (*env)->GetArrayLength(env, jArray);
+    *ckpLength = jLongToCKULong(jLength);
+    *ckpArray = (CK_ATTRIBUTE_PTR) malloc(*ckpLength * sizeof(CK_ATTRIBUTE));
+    if (*ckpArray == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    TRACE1(", converting %d attributes", jLength);
+    for (i=0; i<(*ckpLength); i++) {
+        TRACE1(", getting %d. attribute", i);
+        jAttribute = (*env)->GetObjectArrayElement(env, jArray, i);
+        if ((*env)->ExceptionCheck(env)) {
+            freeCKAttributeArray(*ckpArray, i);
+            return;
+        }
+        TRACE1(", jAttribute = %d", jAttribute);
+        TRACE1(", converting %d. attribute", i);
+        (*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute);
+        if ((*env)->ExceptionCheck(env)) {
+            freeCKAttributeArray(*ckpArray, i);
+            return;
+        }
+    }
+    TRACE0("FINISHED\n");
+}
+
+/*
+ * converts a CK_BYTE array and its length to a jbyteArray.
+ *
+ * @param env - used to call JNI funktions to create the new Java array
+ * @param ckpArray - the pointer to the CK_BYTE array to convert
+ * @param ckpLength - the length of the array to convert
+ * @return - the new Java byte array or NULL if error occurred
+ */
+jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength)
+{
+    CK_ULONG i;
+    jbyte* jpTemp;
+    jbyteArray jArray;
+
+    /* if CK_BYTE is the same size as jbyte, we save an additional copy */
+    if (sizeof(CK_BYTE) == sizeof(jbyte)) {
+        jpTemp = (jbyte*) ckpArray;
+    } else {
+        jpTemp = (jbyte*) malloc((ckLength) * sizeof(jbyte));
+        if (jpTemp == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        for (i=0; i<ckLength; i++) {
+            jpTemp[i] = ckByteToJByte(ckpArray[i]);
+        }
+    }
+
+    jArray = (*env)->NewByteArray(env, ckULongToJSize(ckLength));
+    if (jArray != NULL) {
+        (*env)->SetByteArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
+    }
+
+    if (sizeof(CK_BYTE) != sizeof(jbyte)) { free(jpTemp); }
+
+    return jArray ;
+}
+
+/*
+ * converts a CK_ULONG array and its length to a jlongArray.
+ *
+ * @param env - used to call JNI funktions to create the new Java array
+ * @param ckpArray - the pointer to the CK_ULONG array to convert
+ * @param ckpLength - the length of the array to convert
+ * @return - the new Java long array
+ */
+jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength)
+{
+    CK_ULONG i;
+    jlong* jpTemp;
+    jlongArray jArray;
+
+    jpTemp = (jlong*) malloc((ckLength) * sizeof(jlong));
+    if (jpTemp == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    for (i=0; i<ckLength; i++) {
+        jpTemp[i] = ckLongToJLong(ckpArray[i]);
+    }
+    jArray = (*env)->NewLongArray(env, ckULongToJSize(ckLength));
+    if (jArray != NULL) {
+        (*env)->SetLongArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
+    }
+    free(jpTemp);
+
+    return jArray ;
+}
+
+/*
+ * converts a CK_CHAR array and its length to a jcharArray.
+ *
+ * @param env - used to call JNI funktions to create the new Java array
+ * @param ckpArray - the pointer to the CK_CHAR array to convert
+ * @param ckpLength - the length of the array to convert
+ * @return - the new Java char array
+ */
+jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG ckLength)
+{
+    CK_ULONG i;
+    jchar* jpTemp;
+    jcharArray jArray;
+
+    jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
+    if (jpTemp == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    for (i=0; i<ckLength; i++) {
+        jpTemp[i] = ckCharToJChar(ckpArray[i]);
+    }
+    jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
+    if (jArray != NULL) {
+        (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
+    }
+    free(jpTemp);
+
+    return jArray ;
+}
+
+/*
+ * converts a CK_UTF8CHAR array and its length to a jcharArray.
+ *
+ * @param env - used to call JNI funktions to create the new Java array
+ * @param ckpArray - the pointer to the CK_UTF8CHAR array to convert
+ * @param ckpLength - the length of the array to convert
+ * @return - the new Java char array
+ */
+jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength)
+{
+    CK_ULONG i;
+    jchar* jpTemp;
+    jcharArray jArray;
+
+    jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
+    if (jpTemp == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    for (i=0; i<ckLength; i++) {
+        jpTemp[i] = ckUTF8CharToJChar(ckpArray[i]);
+    }
+    jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
+    if (jArray != NULL) {
+        (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
+    }
+    free(jpTemp);
+
+    return jArray ;
+}
+
+/*
+ * the following functions convert Java objects to PKCS#11 pointers and the
+ * length in bytes and vice versa
+ *
+ * CK_<Type>_PTR j<Object>ToCK<Type>Ptr(JNIEnv *env, jobject jObject);
+ *
+ * jobject ck<Type>PtrToJ<Object>(JNIEnv *env, const CK_<Type>_PTR ckpValue);
+ *
+ * The functions that convert a Java object to a PKCS#11 pointer first allocate
+ * the memory for the PKCS#11 pointer. Then they set each element corresponding
+ * to the fields in the Java object to convert. After use the allocated memory of
+ * the PKCS#11 pointer has to be explicitly freed.
+ *
+ * The functions to convert a PKCS#11 pointer to a Java object create a new Java
+ * object first and than they set all fields in the object depending on the values
+ * of the type or structure where the PKCS#11 pointer points to.
+ */
+
+/*
+ * converts a CK_BBOOL pointer to a Java boolean Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpValue - the pointer to the CK_BBOOL value
+ * @return - the new Java boolean object with the boolean value
+ */
+jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL *ckpValue)
+{
+    jclass jValueObjectClass;
+    jmethodID jConstructor;
+    jobject jValueObject;
+    jboolean jValue;
+
+    jValueObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
+    if (jValueObjectClass == NULL) { return NULL; }
+    jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(Z)V");
+    if (jConstructor == NULL) { return NULL; }
+    jValue = ckBBoolToJBoolean(*ckpValue);
+    jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
+
+    return jValueObject ;
+}
+
+/*
+ * converts a CK_ULONG pointer to a Java long Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpValue - the pointer to the CK_ULONG value
+ * @return - the new Java long object with the long value
+ */
+jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue)
+{
+    jclass jValueObjectClass;
+    jmethodID jConstructor;
+    jobject jValueObject;
+    jlong jValue;
+
+    jValueObjectClass = (*env)->FindClass(env, "java/lang/Long");
+    if (jValueObjectClass == NULL) { return NULL; }
+    jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V");
+    if (jConstructor == NULL) { return NULL; }
+    jValue = ckULongToJLong(*ckpValue);
+    jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
+
+    return jValueObject ;
+}
+
+/*
+ * converts a Java boolean object into a pointer to a CK_BBOOL value. The memory has to be
+ * freed after use!
+ *
+ * @param env - used to call JNI funktions to get the value out of the Java object
+ * @param jObject - the "java/lang/Boolean" object to convert
+ * @return - the pointer to the new CK_BBOOL value
+ */
+CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject)
+{
+    jclass jObjectClass;
+    jmethodID jValueMethod;
+    jboolean jValue;
+    CK_BBOOL *ckpValue;
+
+    jObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
+    if (jObjectClass == NULL) { return NULL; }
+    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "booleanValue", "()Z");
+    if (jValueMethod == NULL) { return NULL; }
+    jValue = (*env)->CallBooleanMethod(env, jObject, jValueMethod);
+    ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL));
+    if (ckpValue == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    *ckpValue = jBooleanToCKBBool(jValue);
+
+    return ckpValue ;
+}
+
+/*
+ * converts a Java byte object into a pointer to a CK_BYTE value. The memory has to be
+ * freed after use!
+ *
+ * @param env - used to call JNI funktions to get the value out of the Java object
+ * @param jObject - the "java/lang/Byte" object to convert
+ * @return - the pointer to the new CK_BYTE value
+ */
+CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject)
+{
+    jclass jObjectClass;
+    jmethodID jValueMethod;
+    jbyte jValue;
+    CK_BYTE_PTR ckpValue;
+
+    jObjectClass = (*env)->FindClass(env, "java/lang/Byte");
+    if (jObjectClass == NULL) { return NULL; }
+    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "byteValue", "()B");
+    if (jValueMethod == NULL) { return NULL; }
+    jValue = (*env)->CallByteMethod(env, jObject, jValueMethod);
+    ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE));
+    if (ckpValue == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    *ckpValue = jByteToCKByte(jValue);
+    return ckpValue ;
+}
+
+/*
+ * converts a Java integer object into a pointer to a CK_ULONG value. The memory has to be
+ * freed after use!
+ *
+ * @param env - used to call JNI funktions to get the value out of the Java object
+ * @param jObject - the "java/lang/Integer" object to convert
+ * @return - the pointer to the new CK_ULONG value
+ */
+CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject)
+{
+    jclass jObjectClass;
+    jmethodID jValueMethod;
+    jint jValue;
+    CK_ULONG *ckpValue;
+
+    jObjectClass = (*env)->FindClass(env, "java/lang/Integer");
+    if (jObjectClass == NULL) { return NULL; }
+    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "intValue", "()I");
+    if (jValueMethod == NULL) { return NULL; }
+    jValue = (*env)->CallIntMethod(env, jObject, jValueMethod);
+    ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
+    if (ckpValue == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    *ckpValue = jLongToCKLong(jValue);
+    return ckpValue ;
+}
+
+/*
+ * converts a Java long object into a pointer to a CK_ULONG value. The memory has to be
+ * freed after use!
+ *
+ * @param env - used to call JNI funktions to get the value out of the Java object
+ * @param jObject - the "java/lang/Long" object to convert
+ * @return - the pointer to the new CK_ULONG value
+ */
+CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject)
+{
+    jclass jObjectClass;
+    jmethodID jValueMethod;
+    jlong jValue;
+    CK_ULONG *ckpValue;
+
+    jObjectClass = (*env)->FindClass(env, "java/lang/Long");
+    if (jObjectClass == NULL) { return NULL; }
+    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J");
+    if (jValueMethod == NULL) { return NULL; }
+    jValue = (*env)->CallLongMethod(env, jObject, jValueMethod);
+    ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
+    if (ckpValue == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    *ckpValue = jLongToCKULong(jValue);
+
+    return ckpValue ;
+}
+
+/*
+ * converts a Java char object into a pointer to a CK_CHAR value. The memory has to be
+ * freed after use!
+ *
+ * @param env - used to call JNI funktions to get the value out of the Java object
+ * @param jObject - the "java/lang/Char" object to convert
+ * @return - the pointer to the new CK_CHAR value
+ */
+CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject)
+{
+    jclass jObjectClass;
+    jmethodID jValueMethod;
+    jchar jValue;
+    CK_CHAR_PTR ckpValue;
+
+    jObjectClass = (*env)->FindClass(env, "java/lang/Char");
+    if (jObjectClass == NULL) { return NULL; }
+    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "charValue", "()C");
+    if (jValueMethod == NULL) { return NULL; }
+    jValue = (*env)->CallCharMethod(env, jObject, jValueMethod);
+    ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR));
+    if (ckpValue == NULL) {
+        throwOutOfMemoryError(env, 0);
+        return NULL;
+    }
+    *ckpValue = jCharToCKChar(jValue);
+
+    return ckpValue ;
+}
+
+/*
+ * converts a Java object into a pointer to CK-type or a CK-structure with the length in Bytes.
+ * The memory of *ckpObjectPtr to be freed after use! This function is only used by
+ * jAttributeToCKAttribute by now.
+ *
+ * @param env - used to call JNI funktions to get the Java classes and objects
+ * @param jObject - the Java object to convert
+ * @param ckpObjectPtr - the reference of the new pointer to the new CK-value or CK-structure
+ * @param ckpLength - the reference of the length in bytes of the new CK-value or CK-structure
+ */
+void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *ckpLength)
+{
+    jclass jLongClass, jBooleanClass, jByteArrayClass, jCharArrayClass;
+    jclass jByteClass, jDateClass, jCharacterClass, jIntegerClass;
+    jclass jBooleanArrayClass, jIntArrayClass, jLongArrayClass;
+    jclass jStringClass;
+    jclass jObjectClass, jClassClass;
+    CK_VOID_PTR ckpVoid = *ckpObjectPtr;
+    jmethodID jMethod;
+    jobject jClassObject;
+    jstring jClassNameString;
+    char *classNameString, *exceptionMsgPrefix, *exceptionMsg;
+
+    TRACE0("\nDEBUG: jObjectToPrimitiveCKObjectPtrPtr");
+    if (jObject == NULL) {
+        *ckpObjectPtr = NULL;
+        *ckpLength = 0;
+        return;
+    }
+
+    jLongClass = (*env)->FindClass(env, "java/lang/Long");
+    if (jLongClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jLongClass)) {
+        *ckpObjectPtr = jLongObjectToCKULongPtr(env, jObject);
+        *ckpLength = sizeof(CK_ULONG);
+        TRACE1("<converted long value %X>", *((CK_ULONG *) *ckpObjectPtr));
+        return;
+    }
+
+    jBooleanClass = (*env)->FindClass(env, "java/lang/Boolean");
+    if (jBooleanClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) {
+        *ckpObjectPtr = jBooleanObjectToCKBBoolPtr(env, jObject);
+        *ckpLength = sizeof(CK_BBOOL);
+        TRACE0(" <converted boolean value ");
+        TRACE0((*((CK_BBOOL *) *ckpObjectPtr) == TRUE) ? "TRUE>" : "FALSE>");
+        return;
+    }
+
+    jByteArrayClass = (*env)->FindClass(env, "[B");
+    if (jByteArrayClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) {
+        jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*)ckpObjectPtr, ckpLength);
+        return;
+    }
+
+    jCharArrayClass = (*env)->FindClass(env, "[C");
+    if (jCharArrayClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) {
+        jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength);
+        return;
+    }
+
+    jByteClass = (*env)->FindClass(env, "java/lang/Byte");
+    if (jByteClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jByteClass)) {
+        *ckpObjectPtr = jByteObjectToCKBytePtr(env, jObject);
+        *ckpLength = sizeof(CK_BYTE);
+        TRACE1("<converted byte value %X>", *((CK_BYTE *) *ckpObjectPtr));
+        return;
+    }
+
+    jDateClass = (*env)->FindClass(env, CLASS_DATE);
+    if (jDateClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jDateClass)) {
+        *ckpObjectPtr = jDateObjectPtrToCKDatePtr(env, jObject);
+        *ckpLength = sizeof(CK_DATE);
+        TRACE3("<converted date value %.4s-%.2s-%.2s>", (*((CK_DATE *) *ckpObjectPtr)).year, (*((CK_DATE *) *ckpObjectPtr)).month, (*((CK_DATE *) *ckpObjectPtr)).day);
+        return;
+    }
+
+    jCharacterClass = (*env)->FindClass(env, "java/lang/Character");
+    if (jCharacterClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) {
+        *ckpObjectPtr = jCharObjectToCKCharPtr(env, jObject);
+        *ckpLength = sizeof(CK_UTF8CHAR);
+        TRACE1("<converted char value %c>", *((CK_CHAR *) *ckpObjectPtr));
+        return;
+    }
+
+    jIntegerClass = (*env)->FindClass(env, "java/lang/Integer");
+    if (jIntegerClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) {
+        *ckpObjectPtr = jIntegerObjectToCKULongPtr(env, jObject);
+        *ckpLength = sizeof(CK_ULONG);
+        TRACE1("<converted integer value %X>", *((CK_ULONG *) *ckpObjectPtr));
+        return;
+    }
+
+    jBooleanArrayClass = (*env)->FindClass(env, "[Z");
+    if (jBooleanArrayClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) {
+        jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**)ckpObjectPtr, ckpLength);
+        return;
+    }
+
+    jIntArrayClass = (*env)->FindClass(env, "[I");
+    if (jIntArrayClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) {
+        jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength);
+        return;
+    }
+
+    jLongArrayClass = (*env)->FindClass(env, "[J");
+    if (jLongArrayClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) {
+        jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength);
+        return;
+    }
+
+    jStringClass = (*env)->FindClass(env, "java/lang/String");
+    if (jStringClass == NULL) { return; }
+    if ((*env)->IsInstanceOf(env, jObject, jStringClass)) {
+        jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength);
+        return;
+    }
+
+    /* type of jObject unknown, throw PKCS11RuntimeException */
+    jObjectClass = (*env)->FindClass(env, "java/lang/Object");
+    if (jObjectClass == NULL) { return; }
+    jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;");
+    if (jMethod == NULL) { return; }
+    jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod);
+    assert(jClassObject != 0);
+    jClassClass = (*env)->FindClass(env, "java/lang/Class");
+    if (jClassClass == NULL) { return; }
+    jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;");
+    if (jMethod == NULL) { return; }
+    jClassNameString = (jstring)
+        (*env)->CallObjectMethod(env, jClassObject, jMethod);
+    assert(jClassNameString != 0);
+    classNameString = (char*)
+        (*env)->GetStringUTFChars(env, jClassNameString, NULL);
+    if (classNameString == NULL) { return; }
+    exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: ";
+    exceptionMsg = (char *)
+        malloc((strlen(exceptionMsgPrefix) + strlen(classNameString) + 1));
+    if (exceptionMsg == NULL) {
+        (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    strcpy(exceptionMsg, exceptionMsgPrefix);
+    strcat(exceptionMsg, classNameString);
+    (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
+    throwPKCS11RuntimeException(env, exceptionMsg);
+    free(exceptionMsg);
+    *ckpObjectPtr = NULL;
+    *ckpLength = 0;
+
+    TRACE0("FINISHED\n");
+}
+
+#ifdef P11_MEMORYDEBUG
+
+#undef malloc
+#undef free
+
+void *p11malloc(size_t c, char *file, int line) {
+    void *p = malloc(c);
+    printf("malloc\t%08x\t%d\t%s:%d\n", p, c, file, line); fflush(stdout);
+    return p;
+}
+
+void p11free(void *p, char *file, int line) {
+    printf("free\t%08x\t\t%s:%d\n", p, file, line); fflush(stdout);
+    free(p);
+}
+
+#endif
+
+// prints a message to stdout if debug output is enabled
+void printDebug(const char *format, ...) {
+    if (debug == JNI_TRUE) {
+        va_list args;
+        fprintf(stdout, "sunpkcs11: ");
+        va_start(args, format);
+        vfprintf(stdout, format, args);
+        va_end(args);
+        fflush(stdout);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs-11v2-20a3.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,124 @@
+/* pkcs-11v2-20a3.h include file for the PKCS #11 Version 2.20 Amendment 3
+   document. */
+
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki) Version 2.20 Amendment 3" in all material mentioning or
+ * referencing this software.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* This file is preferably included after inclusion of pkcs11.h */
+
+#ifndef _PKCS_11V2_20A3_H_
+#define _PKCS_11V2_20A3_H_ 1
+
+/* Are the definitions of this file already included in pkcs11t.h ? */
+#ifndef CKK_CAMELLIA
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Key types */
+
+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
+#define CKK_CAMELLIA                   0x00000025
+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
+#define CKK_ARIA                       0x00000026
+
+
+/* Mask-generating functions */
+
+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
+#define CKG_MGF1_SHA224                0x00000005
+
+
+/* Mechanism Identifiers */
+
+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224                     0x00000255
+#define CKM_SHA224_HMAC                0x00000256
+#define CKM_SHA224_HMAC_GENERAL        0x00000257
+
+/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224_KEY_DERIVATION      0x00000396
+
+/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224_RSA_PKCS            0x00000046
+#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
+
+/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_AES_CTR                    0x00001086
+
+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_CAMELLIA_KEY_GEN           0x00000550
+#define CKM_CAMELLIA_ECB               0x00000551
+#define CKM_CAMELLIA_CBC               0x00000552
+#define CKM_CAMELLIA_MAC               0x00000553
+#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
+#define CKM_CAMELLIA_CBC_PAD           0x00000555
+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
+#define CKM_CAMELLIA_CTR               0x00000558
+
+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_ARIA_KEY_GEN               0x00000560
+#define CKM_ARIA_ECB                   0x00000561
+#define CKM_ARIA_CBC                   0x00000562
+#define CKM_ARIA_MAC                   0x00000563
+#define CKM_ARIA_MAC_GENERAL           0x00000564
+#define CKM_ARIA_CBC_PAD               0x00000565
+#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
+#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
+
+
+/* Mechanism parameters */
+
+/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_AES_CTR_PARAMS {
+    CK_ULONG ulCounterBits;
+    CK_BYTE cb[16];
+} CK_AES_CTR_PARAMS;
+
+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
+
+/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_CAMELLIA_CTR_PARAMS {
+    CK_ULONG ulCounterBits;
+    CK_BYTE cb[16];
+} CK_CAMELLIA_CTR_PARAMS;
+
+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
+
+/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
+    CK_BYTE      iv[16];
+    CK_BYTE_PTR  pData;
+    CK_ULONG     length;
+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
+    CK_BYTE      iv[16];
+    CK_BYTE_PTR  pData;
+    CK_ULONG     length;
+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,299 @@
+/* pkcs11.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+#ifndef _PKCS11_H_
+#define _PKCS11_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Before including this file (pkcs11.h) (or pkcs11t.h by
+ * itself), 6 platform-specific macros must be defined.  These
+ * macros are described below, and typical definitions for them
+ * are also given.  Be advised that these definitions can depend
+ * on both the platform and the compiler used (and possibly also
+ * on whether a Cryptoki library is linked statically or
+ * dynamically).
+ *
+ * In addition to defining these 6 macros, the packing convention
+ * for Cryptoki structures should be set.  The Cryptoki
+ * convention on packing is that structures should be 1-byte
+ * aligned.
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, this might be done by using the following
+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(push, cryptoki, 1)
+ *
+ * and using the following preprocessor directive after including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(pop, cryptoki)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, this might be done by using
+ * the following preprocessor directive before including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(1)
+ *
+ * In a UNIX environment, you're on your own for this.  You might
+ * not need to do (or be able to do!) anything.
+ *
+ *
+ * Now for the macros:
+ *
+ *
+ * 1. CK_PTR: The indirection string for making a pointer to an
+ * object.  It can be used like this:
+ *
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, it might be defined by:
+ *
+ * #define CK_PTR far *
+ *
+ * In a typical UNIX environment, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ *
+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
+ * an exportable Cryptoki library function definition out of a
+ * return type and a function name.  It should be used in the
+ * following fashion to define the exposed Cryptoki functions in
+ * a Cryptoki library:
+ *
+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
+ *   CK_VOID_PTR pReserved
+ * )
+ * {
+ *   ...
+ * }
+ *
+ * If you're using Microsoft Developer Studio 5.0 to define a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ *   returnType __declspec(dllexport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to define a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ *   returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ *   returnType name
+ *
+ *
+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
+ * an importable Cryptoki library function declaration out of a
+ * return type and a function name.  It should be used in the
+ * following fashion:
+ *
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
+ *   CK_VOID_PTR pReserved
+ * );
+ *
+ * If you're using Microsoft Developer Studio 5.0 to declare a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ *   returnType __declspec(dllimport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to declare a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ *   returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ *   returnType name
+ *
+ *
+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
+ * which makes a Cryptoki API function pointer declaration or
+ * function pointer type declaration out of a return type and a
+ * function name.  It should be used in the following fashion:
+ *
+ * // Define funcPtr to be a pointer to a Cryptoki API function
+ * // taking arguments args and returning CK_RV.
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
+ *
+ * or
+ *
+ * // Define funcPtrType to be the type of a pointer to a
+ * // Cryptoki API function taking arguments args and returning
+ * // CK_RV, and then define funcPtr to be a variable of type
+ * // funcPtrType.
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
+ * funcPtrType funcPtr;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to access
+ * functions in a Win32 Cryptoki .dll, in might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ *   returnType __declspec(dllimport) (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to access functions in a Win16 Cryptoki .dll, it might
+ * be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ *   returnType __export _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ *   returnType (* name)
+ *
+ *
+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
+ * a function pointer type for an application callback out of
+ * a return type for the callback and a name for the callback.
+ * It should be used in the following fashion:
+ *
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
+ *
+ * to declare a function pointer, myCallback, to a callback
+ * which takes arguments args and returns a CK_RV.  It can also
+ * be used like this:
+ *
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
+ * myCallbackType myCallback;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to do Win32
+ * Cryptoki development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ *   returnType (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to do Win16 development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ *   returnType _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ *   returnType (* name)
+ *
+ *
+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
+ *
+ * In any ANSI/ISO C environment (and in many others as well),
+ * this should best be defined by
+ *
+ * #ifndef NULL_PTR
+ * #define NULL_PTR 0
+ * #endif
+ */
+
+
+/* All the various Cryptoki types and #define'd values are in the
+ * file pkcs11t.h. */
+#include "pkcs11t.h"
+
+#define __PASTE(x,y)      x##y
+
+
+/* ==============================================================
+ * Define the "extern" form of all the entry points.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST  1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+  extern CK_DECLARE_FUNCTION(CK_RV, name)
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define the typedef form of all the entry points.  That is, for
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
+ * a pointer to that kind of function.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST  1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define structed vector of entry points.  A CK_FUNCTION_LIST
+ * contains a CK_VERSION indicating a library's Cryptoki version
+ * and then a whole slew of function pointers to the routines in
+ * the library.  This type was declared, but not defined, in
+ * pkcs11t.h.
+ * ==============================================================
+ */
+
+#define CK_PKCS11_FUNCTION_INFO(name) \
+  __PASTE(CK_,name) name;
+
+struct CK_FUNCTION_LIST {
+
+  CK_VERSION    version;  /* Cryptoki version */
+
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+};
+
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+#undef __PASTE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,912 @@
+/* pkcs11f.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* This header file contains pretty much everything about all the */
+/* Cryptoki function prototypes.  Because this information is */
+/* used for more than just declaring function prototypes, the */
+/* order of the functions appearing herein is important, and */
+/* should not be altered. */
+
+/* General-purpose */
+
+/* C_Initialize initializes the Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Initialize)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
+                            * cast to CK_C_INITIALIZE_ARGS_PTR
+                            * and dereferenced */
+);
+#endif
+
+
+/* C_Finalize indicates that an application is done with the
+ * Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Finalize)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
+);
+#endif
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_INFO_PTR   pInfo  /* location that receives information */
+);
+#endif
+
+
+/* C_GetFunctionList returns the function list. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
+                                            * function list */
+);
+#endif
+
+
+
+/* Slot and token management */
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
+  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
+  CK_ULONG_PTR   pulCount       /* receives number of slots */
+);
+#endif
+
+
+/* C_GetSlotInfo obtains information about a particular slot in
+ * the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID       slotID,  /* the ID of the slot */
+  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
+);
+#endif
+
+
+/* C_GetTokenInfo obtains information about a particular token
+ * in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID        slotID,  /* ID of the token's slot */
+  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
+);
+#endif
+
+
+/* C_GetMechanismList obtains a list of mechanism types
+ * supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID            slotID,          /* ID of token's slot */
+  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
+  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
+);
+#endif
+
+
+/* C_GetMechanismInfo obtains information about a particular
+ * mechanism possibly supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID            slotID,  /* ID of the token's slot */
+  CK_MECHANISM_TYPE     type,    /* type of mechanism */
+  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
+);
+#endif
+
+
+/* C_InitToken initializes a token. */
+CK_PKCS11_FUNCTION_INFO(C_InitToken)
+#ifdef CK_NEED_ARG_LIST
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+(
+  CK_SLOT_ID      slotID,    /* ID of the token's slot */
+  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
+  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
+  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
+);
+#endif
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
+  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
+);
+#endif
+
+
+/* C_SetPIN modifies the PIN of the user who is logged in. */
+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
+  CK_ULONG          ulOldLen,  /* length of the old PIN */
+  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
+  CK_ULONG          ulNewLen   /* length of the new PIN */
+);
+#endif
+
+
+
+/* Session management */
+
+/* C_OpenSession opens a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID            slotID,        /* the slot's ID */
+  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
+  CK_VOID_PTR           pApplication,  /* passed to callback */
+  CK_NOTIFY             Notify,        /* callback function */
+  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
+);
+#endif
+
+
+/* C_CloseSession closes a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID     slotID  /* the token's slot */
+);
+#endif
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE   hSession,  /* the session's handle */
+  CK_SESSION_INFO_PTR pInfo      /* receives session info */
+);
+#endif
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session. */
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,             /* session's handle */
+  CK_BYTE_PTR       pOperationState,      /* gets state */
+  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
+);
+#endif
+
+
+/* C_SetOperationState restores the state of the cryptographic
+ * operation in a session. */
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR      pOperationState,      /* holds state */
+  CK_ULONG         ulOperationStateLen,  /* holds state length */
+  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
+  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
+);
+#endif
+
+
+/* C_Login logs a user into a token. */
+CK_PKCS11_FUNCTION_INFO(C_Login)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_USER_TYPE      userType,  /* the user type */
+  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
+  CK_ULONG          ulPinLen   /* the length of the PIN */
+);
+#endif
+
+
+/* C_Logout logs a user out from a token. */
+CK_PKCS11_FUNCTION_INFO(C_Logout)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+
+/* Object management */
+
+/* C_CreateObject creates a new object. */
+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
+  CK_ULONG          ulCount,     /* attributes in template */
+  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
+);
+#endif
+
+
+/* C_CopyObject copies an object, creating a new object for the
+ * copy. */
+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
+  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
+  CK_ULONG             ulCount,     /* attributes in template */
+  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
+);
+#endif
+
+
+/* C_DestroyObject destroys an object. */
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_OBJECT_HANDLE  hObject    /* the object's handle */
+);
+#endif
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
+  CK_ULONG_PTR      pulSize    /* receives size of object */
+);
+#endif
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+ * attributes. */
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
+  CK_ULONG          ulCount     /* attributes in template */
+);
+#endif
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+ * attributes */
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
+  CK_ULONG          ulCount     /* attributes in template */
+);
+#endif
+
+
+/* C_FindObjectsInit initializes a search for token and session
+ * objects that match a template. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
+  CK_ULONG          ulCount     /* attrs in search template */
+);
+#endif
+
+
+/* C_FindObjects continues a search for token and session
+ * objects that match a template, obtaining additional object
+ * handles. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE    hSession,          /* session's handle */
+ CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
+ CK_ULONG             ulMaxObjectCount,  /* max handles to get */
+ CK_ULONG_PTR         pulObjectCount     /* actual # returned */
+);
+#endif
+
+
+/* C_FindObjectsFinal finishes a search for token and session
+ * objects. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+
+/* Encryption and decryption */
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
+  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
+);
+#endif
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pData,               /* the plaintext data */
+  CK_ULONG          ulDataLen,           /* bytes of plaintext */
+  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
+  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptUpdate continues a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,           /* session's handle */
+  CK_BYTE_PTR       pPart,              /* the plaintext data */
+  CK_ULONG          ulPartLen,          /* plaintext data len */
+  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
+  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptFinal finishes a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,                /* session handle */
+  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
+  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
+);
+#endif
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
+  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
+);
+#endif
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,           /* session's handle */
+  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
+  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
+  CK_BYTE_PTR       pData,              /* gets plaintext */
+  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
+);
+#endif
+
+
+/* C_DecryptUpdate continues a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
+  CK_ULONG          ulEncryptedPartLen,  /* input length */
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
+  CK_ULONG_PTR      pulPartLen           /* p-text size */
+);
+#endif
+
+
+/* C_DecryptFinal finishes a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
+  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
+  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
+);
+#endif
+
+
+
+/* Message digesting */
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
+);
+#endif
+
+
+/* C_Digest digests data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Digest)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
+  CK_BYTE_PTR       pData,        /* data to be digested */
+  CK_ULONG          ulDataLen,    /* bytes of data to digest */
+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
+  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
+);
+#endif
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_BYTE_PTR       pPart,     /* data to be digested */
+  CK_ULONG          ulPartLen  /* bytes of data to be digested */
+);
+#endif
+
+
+/* C_DigestKey continues a multi-part message-digesting
+ * operation, by digesting the value of a secret key as part of
+ * the data already digested. */
+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
+);
+#endif
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
+  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
+);
+#endif
+
+
+
+/* Signing and MACing */
+
+/* C_SignInit initializes a signature (private key encryption)
+ * operation, where the signature is (will be) an appendix to
+ * the data, and plaintext cannot be recovered from the
+ *signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
+  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
+);
+#endif
+
+
+/* C_Sign signs (encrypts with private key) data in a single
+ * part, where the signature is (will be) an appendix to the
+ * data, and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Sign)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_BYTE_PTR       pData,           /* the data to sign */
+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
+);
+#endif
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_BYTE_PTR       pPart,     /* the data to sign */
+  CK_ULONG          ulPartLen  /* count of bytes to sign */
+);
+#endif
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * returning the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
+);
+#endif
+
+
+/* C_SignRecoverInit initializes a signature operation, where
+ * the data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
+  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
+);
+#endif
+
+
+/* C_SignRecover signs data in a single operation, where the
+ * data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_BYTE_PTR       pData,           /* the data to sign */
+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
+);
+#endif
+
+
+
+/* Verifying signatures and MACs */
+
+/* C_VerifyInit initializes a verification operation, where the
+ * signature is an appendix to the data, and plaintext cannot
+ *  cannot be recovered from the signature (e.g. DSA). */
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
+  CK_OBJECT_HANDLE  hKey         /* verification key */
+);
+#endif
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data, and plaintext
+ * cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Verify)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
+  CK_BYTE_PTR       pData,          /* signed data */
+  CK_ULONG          ulDataLen,      /* length of signed data */
+  CK_BYTE_PTR       pSignature,     /* signature */
+  CK_ULONG          ulSignatureLen  /* signature length*/
+);
+#endif
+
+
+/* C_VerifyUpdate continues a multiple-part verification
+ * operation, where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_BYTE_PTR       pPart,     /* signed data */
+  CK_ULONG          ulPartLen  /* length of signed data */
+);
+#endif
+
+
+/* C_VerifyFinal finishes a multiple-part verification
+ * operation, checking the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
+  CK_BYTE_PTR       pSignature,     /* signature to verify */
+  CK_ULONG          ulSignatureLen  /* signature length */
+);
+#endif
+
+
+/* C_VerifyRecoverInit initializes a signature verification
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
+  CK_OBJECT_HANDLE  hKey         /* verification key */
+);
+#endif
+
+
+/* C_VerifyRecover verifies a signature in a single-part
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_BYTE_PTR       pSignature,      /* signature to verify */
+  CK_ULONG          ulSignatureLen,  /* signature length */
+  CK_BYTE_PTR       pData,           /* gets signed data */
+  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
+);
+#endif
+
+
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting
+ * and encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pPart,               /* the plaintext data */
+  CK_ULONG          ulPartLen,           /* plaintext length */
+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
+  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
+);
+#endif
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pPart,               /* the plaintext data */
+  CK_ULONG          ulPartLen,           /* plaintext length */
+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
+  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
+);
+#endif
+
+
+
+/* Key management */
+
+/* C_GenerateKey generates a secret key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
+  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
+  CK_ULONG             ulCount,     /* # of attrs in template */
+  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
+);
+#endif
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,                    /* session
+                                                     * handle */
+  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
+                                                     * mech. */
+  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
+                                                     * for pub.
+                                                     * key */
+  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
+                                                     * attrs. */
+  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
+                                                     * for priv.
+                                                     * key */
+  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
+                                                     * attrs. */
+  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
+                                                     * key
+                                                     * handle */
+  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
+                                                     * priv. key
+                                                     * handle */
+);
+#endif
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
+  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
+  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
+  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
+  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
+);
+#endif
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+ * key object. */
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,          /* session's handle */
+  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
+  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
+  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
+  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
+  CK_ULONG             ulAttributeCount,  /* template length */
+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
+);
+#endif
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,          /* session's handle */
+  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
+  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
+  CK_ULONG             ulAttributeCount,  /* template length */
+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
+);
+#endif
+
+
+
+/* Random number generation */
+
+/* C_SeedRandom mixes additional seed material into the token's
+ * random number generator. */
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_BYTE_PTR       pSeed,     /* the seed material */
+  CK_ULONG          ulSeedLen  /* length of seed material */
+);
+#endif
+
+
+/* C_GenerateRandom generates random data. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_BYTE_PTR       RandomData,  /* receives the random data */
+  CK_ULONG          ulRandomLen  /* # of bytes to generate */
+);
+#endif
+
+
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus is a legacy function; it obtains an
+ * updated status of a function running in parallel with an
+ * application. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+/* C_CancelFunction is a legacy function; it cancels a function
+ * running in parallel. */
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+
+/* Functions added in for Cryptoki Version 2.01 or later */
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur. */
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_FLAGS flags,        /* blocking/nonblocking flag */
+  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
+  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
+);
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,1685 @@
+/* pkcs11t.h include file for PKCS #11. */
+/* $Revision: 1.6 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* See top of pkcs11.h for information about the macros that
+ * must be defined and the structure-packing conventions that
+ * must be set before including this file. */
+
+#ifndef _PKCS11T_H_
+#define _PKCS11T_H_ 1
+
+#define CK_TRUE 1
+#define CK_FALSE 0
+
+#ifndef CK_DISABLE_TRUE_FALSE
+#ifndef FALSE
+#define FALSE CK_FALSE
+#endif
+
+#ifndef TRUE
+#define TRUE CK_TRUE
+#endif
+#endif
+
+/* an unsigned 8-bit value */
+typedef unsigned char     CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE           CK_CHAR;
+
+/* an 8-bit UTF-8 character */
+typedef CK_BYTE           CK_UTF8CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE           CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+/* CK_LONG is new for v2.0 */
+typedef long int          CK_LONG;
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef CK_ULONG          CK_FLAGS;
+
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE    0
+
+
+typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
+typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
+typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
+typedef void        CK_PTR   CK_VOID_PTR;
+
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
+
+
+/* The following value is always invalid if used as a session */
+/* handle or object handle */
+#define CK_INVALID_HANDLE 0
+
+
+typedef struct CK_VERSION {
+  CK_BYTE       major;  /* integer portion of version number */
+  CK_BYTE       minor;  /* 1/100ths portion of version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
+
+
+typedef struct CK_INFO {
+  /* manufacturerID and libraryDecription have been changed from
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
+  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
+  CK_FLAGS      flags;               /* must be zero */
+
+  /* libraryDescription and libraryVersion are new for v2.0 */
+  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
+  CK_VERSION    libraryVersion;          /* version of library */
+} CK_INFO;
+
+typedef CK_INFO CK_PTR    CK_INFO_PTR;
+
+
+/* CK_NOTIFICATION enumerates the types of notifications that
+ * Cryptoki provides to an application */
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER       0
+
+
+typedef CK_ULONG          CK_SLOT_ID;
+
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot */
+typedef struct CK_SLOT_INFO {
+  /* slotDescription and manufacturerID have been changed from
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
+  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
+  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
+  CK_FLAGS      flags;
+
+  /* hardwareVersion and firmwareVersion are new for v2.0 */
+  CK_VERSION    hardwareVersion;  /* version of hardware */
+  CK_VERSION    firmwareVersion;  /* version of firmware */
+} CK_SLOT_INFO;
+
+/* flags: bit flags that provide capabilities of the slot
+ *      Bit Flag              Mask        Meaning
+ */
+#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
+#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
+#define CKF_HW_SLOT           0x00000004  /* hardware slot */
+
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token */
+typedef struct CK_TOKEN_INFO {
+  /* label, manufacturerID, and model have been changed from
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
+  CK_UTF8CHAR   label[32];           /* blank padded */
+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
+  CK_UTF8CHAR   model[16];           /* blank padded */
+  CK_CHAR       serialNumber[16];    /* blank padded */
+  CK_FLAGS      flags;               /* see below */
+
+  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
+   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
+   * changed from CK_USHORT to CK_ULONG for v2.0 */
+  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
+  CK_ULONG      ulSessionCount;        /* sess. now open */
+  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
+  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
+  CK_ULONG      ulMaxPinLen;           /* in bytes */
+  CK_ULONG      ulMinPinLen;           /* in bytes */
+  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
+  CK_ULONG      ulFreePublicMemory;    /* in bytes */
+  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
+  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
+
+  /* hardwareVersion, firmwareVersion, and time are new for
+   * v2.0 */
+  CK_VERSION    hardwareVersion;       /* version of hardware */
+  CK_VERSION    firmwareVersion;       /* version of firmware */
+  CK_CHAR       utcTime[16];           /* time */
+} CK_TOKEN_INFO;
+
+/* The flags parameter is defined as follows:
+ *      Bit Flag                    Mask        Meaning
+ */
+#define CKF_RNG                     0x00000001  /* has random #
+                                                 * generator */
+#define CKF_WRITE_PROTECTED         0x00000002  /* token is
+                                                 * write-
+                                                 * protected */
+#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
+                                                 * login */
+#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
+                                                 * PIN is set */
+
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
+ * that means that *every* time the state of cryptographic
+ * operations of a session is successfully saved, all keys
+ * needed to continue those operations are stored in the state */
+#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
+
+/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
+ * that the token has some sort of clock.  The time on that
+ * clock is returned in the token info structure */
+#define CKF_CLOCK_ON_TOKEN          0x00000040
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
+ * set, that means that there is some way for the user to login
+ * without sending a PIN through the Cryptoki library itself */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
+
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
+ * that means that a single session with the token can perform
+ * dual simultaneous cryptographic operations (digest and
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
+ * and sign) */
+#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
+
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized. */
+#define CKF_TOKEN_INITIALIZED       0x00000400
+
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
+ * true, the token supports secondary authentication for
+ * private key objects. This flag is deprecated in v2.11 and
+   onwards. */
+#define CKF_SECONDARY_AUTHENTICATION  0x00000800
+
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect user login PIN has been entered at least once
+ * since the last successful authentication. */
+#define CKF_USER_PIN_COUNT_LOW       0x00010000
+
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect user PIN will it to become locked. */
+#define CKF_USER_PIN_FINAL_TRY       0x00020000
+
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
+ * user PIN has been locked. User login to the token is not
+ * possible. */
+#define CKF_USER_PIN_LOCKED          0x00040000
+
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
+
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
+ * the last successful authentication. */
+#define CKF_SO_PIN_COUNT_LOW         0x00100000
+
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect SO PIN will it to become locked. */
+#define CKF_SO_PIN_FINAL_TRY         0x00200000
+
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED            0x00400000
+
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
+
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
+ * identifies a session */
+typedef CK_ULONG          CK_SESSION_HANDLE;
+
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+
+
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO    0
+/* Normal user */
+#define CKU_USER  1
+/* Context specific (added in v2.20) */
+#define CKU_CONTEXT_SPECIFIC   2
+
+/* CK_STATE enumerates the session states */
+/* CK_STATE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_STATE;
+#define CKS_RO_PUBLIC_SESSION  0
+#define CKS_RO_USER_FUNCTIONS  1
+#define CKS_RW_PUBLIC_SESSION  2
+#define CKS_RW_USER_FUNCTIONS  3
+#define CKS_RW_SO_FUNCTIONS    4
+
+
+/* CK_SESSION_INFO provides information about a session */
+typedef struct CK_SESSION_INFO {
+  CK_SLOT_ID    slotID;
+  CK_STATE      state;
+  CK_FLAGS      flags;          /* see below */
+
+  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
+   * v2.0 */
+  CK_ULONG      ulDeviceError;  /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table:
+ *      Bit Flag                Mask        Meaning
+ */
+#define CKF_RW_SESSION          0x00000002  /* session is r/w */
+#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
+
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
+ * object  */
+typedef CK_ULONG          CK_OBJECT_HANDLE;
+
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
+ * types) of objects that Cryptoki recognizes.  It is defined
+ * as follows: */
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+/* CKO_HW_FEATURE is new for v2.10 */
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+/* CKO_MECHANISM is new for v2.20 */
+#define CKO_DATA              0x00000000
+#define CKO_CERTIFICATE       0x00000001
+#define CKO_PUBLIC_KEY        0x00000002
+#define CKO_PRIVATE_KEY       0x00000003
+#define CKO_SECRET_KEY        0x00000004
+#define CKO_HW_FEATURE        0x00000005
+#define CKO_DOMAIN_PARAMETERS 0x00000006
+#define CKO_MECHANISM         0x00000007
+#define CKO_VENDOR_DEFINED    0x80000000
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
+ * value that identifies the hardware feature type of an object
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
+typedef CK_ULONG          CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined */
+/* CKH_USER_INTERFACE is new for v2.20 */
+#define CKH_MONOTONIC_COUNTER  0x00000001
+#define CKH_CLOCK           0x00000002
+#define CKH_USER_INTERFACE  0x00000003
+#define CKH_VENDOR_DEFINED  0x80000000
+
+/* CK_KEY_TYPE is a value that identifies a key type */
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG          CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA             0x00000000
+#define CKK_DSA             0x00000001
+#define CKK_DH              0x00000002
+
+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
+#define CKK_ECDSA           0x00000003
+#define CKK_EC              0x00000003
+#define CKK_X9_42_DH        0x00000004
+#define CKK_KEA             0x00000005
+
+#define CKK_GENERIC_SECRET  0x00000010
+#define CKK_RC2             0x00000011
+#define CKK_RC4             0x00000012
+#define CKK_DES             0x00000013
+#define CKK_DES2            0x00000014
+#define CKK_DES3            0x00000015
+
+/* all these key types are new for v2.0 */
+#define CKK_CAST            0x00000016
+#define CKK_CAST3           0x00000017
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
+#define CKK_CAST5           0x00000018
+#define CKK_CAST128         0x00000018
+#define CKK_RC5             0x00000019
+#define CKK_IDEA            0x0000001A
+#define CKK_SKIPJACK        0x0000001B
+#define CKK_BATON           0x0000001C
+#define CKK_JUNIPER         0x0000001D
+#define CKK_CDMF            0x0000001E
+#define CKK_AES             0x0000001F
+
+/* BlowFish and TwoFish are new for v2.20 */
+#define CKK_BLOWFISH        0x00000020
+#define CKK_TWOFISH         0x00000021
+
+#define CKK_VENDOR_DEFINED  0x80000000
+
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
+ * type */
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG          CK_CERTIFICATE_TYPE;
+
+/* The following certificate types are defined: */
+/* CKC_X_509_ATTR_CERT is new for v2.10 */
+/* CKC_WTLS is new for v2.20 */
+#define CKC_X_509           0x00000000
+#define CKC_X_509_ATTR_CERT 0x00000001
+#define CKC_WTLS            0x00000002
+#define CKC_VENDOR_DEFINED  0x80000000
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+ * type */
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
+
+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
+   consists of an array of values. */
+#define CKF_ARRAY_ATTRIBUTE    0x40000000
+
+/* The following attribute types are defined: */
+#define CKA_CLASS              0x00000000
+#define CKA_TOKEN              0x00000001
+#define CKA_PRIVATE            0x00000002
+#define CKA_LABEL              0x00000003
+#define CKA_APPLICATION        0x00000010
+#define CKA_VALUE              0x00000011
+
+/* CKA_OBJECT_ID is new for v2.10 */
+#define CKA_OBJECT_ID          0x00000012
+
+#define CKA_CERTIFICATE_TYPE   0x00000080
+#define CKA_ISSUER             0x00000081
+#define CKA_SERIAL_NUMBER      0x00000082
+
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
+ * for v2.10 */
+#define CKA_AC_ISSUER          0x00000083
+#define CKA_OWNER              0x00000084
+#define CKA_ATTR_TYPES         0x00000085
+
+/* CKA_TRUSTED is new for v2.11 */
+#define CKA_TRUSTED            0x00000086
+
+/* CKA_CERTIFICATE_CATEGORY ...
+ * CKA_CHECK_VALUE are new for v2.20 */
+#define CKA_CERTIFICATE_CATEGORY        0x00000087
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
+#define CKA_URL                         0x00000089
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
+#define CKA_CHECK_VALUE                 0x00000090
+
+#define CKA_KEY_TYPE           0x00000100
+#define CKA_SUBJECT            0x00000101
+#define CKA_ID                 0x00000102
+#define CKA_SENSITIVE          0x00000103
+#define CKA_ENCRYPT            0x00000104
+#define CKA_DECRYPT            0x00000105
+#define CKA_WRAP               0x00000106
+#define CKA_UNWRAP             0x00000107
+#define CKA_SIGN               0x00000108
+#define CKA_SIGN_RECOVER       0x00000109
+#define CKA_VERIFY             0x0000010A
+#define CKA_VERIFY_RECOVER     0x0000010B
+#define CKA_DERIVE             0x0000010C
+#define CKA_START_DATE         0x00000110
+#define CKA_END_DATE           0x00000111
+#define CKA_MODULUS            0x00000120
+#define CKA_MODULUS_BITS       0x00000121
+#define CKA_PUBLIC_EXPONENT    0x00000122
+#define CKA_PRIVATE_EXPONENT   0x00000123
+#define CKA_PRIME_1            0x00000124
+#define CKA_PRIME_2            0x00000125
+#define CKA_EXPONENT_1         0x00000126
+#define CKA_EXPONENT_2         0x00000127
+#define CKA_COEFFICIENT        0x00000128
+#define CKA_PRIME              0x00000130
+#define CKA_SUBPRIME           0x00000131
+#define CKA_BASE               0x00000132
+
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+#define CKA_PRIME_BITS         0x00000133
+#define CKA_SUBPRIME_BITS      0x00000134
+#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
+/* (To retain backwards-compatibility) */
+
+#define CKA_VALUE_BITS         0x00000160
+#define CKA_VALUE_LEN          0x00000161
+
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+ * and CKA_EC_POINT are new for v2.0 */
+#define CKA_EXTRACTABLE        0x00000162
+#define CKA_LOCAL              0x00000163
+#define CKA_NEVER_EXTRACTABLE  0x00000164
+#define CKA_ALWAYS_SENSITIVE   0x00000165
+
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+#define CKA_KEY_GEN_MECHANISM  0x00000166
+
+#define CKA_MODIFIABLE         0x00000170
+
+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
+ * CKA_EC_PARAMS is preferred. */
+#define CKA_ECDSA_PARAMS       0x00000180
+#define CKA_EC_PARAMS          0x00000180
+
+#define CKA_EC_POINT           0x00000181
+
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
+ * are new for v2.10. Deprecated in v2.11 and onwards. */
+#define CKA_SECONDARY_AUTH     0x00000200
+#define CKA_AUTH_PIN_FLAGS     0x00000201
+
+/* CKA_ALWAYS_AUTHENTICATE ...
+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
+#define CKA_ALWAYS_AUTHENTICATE  0x00000202
+
+#define CKA_WRAP_WITH_TRUSTED    0x00000210
+#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
+#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
+
+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+ * are new for v2.10 */
+#define CKA_HW_FEATURE_TYPE    0x00000300
+#define CKA_RESET_ON_INIT      0x00000301
+#define CKA_HAS_RESET          0x00000302
+
+/* The following attributes are new for v2.20 */
+#define CKA_PIXEL_X                     0x00000400
+#define CKA_PIXEL_Y                     0x00000401
+#define CKA_RESOLUTION                  0x00000402
+#define CKA_CHAR_ROWS                   0x00000403
+#define CKA_CHAR_COLUMNS                0x00000404
+#define CKA_COLOR                       0x00000405
+#define CKA_BITS_PER_PIXEL              0x00000406
+#define CKA_CHAR_SETS                   0x00000480
+#define CKA_ENCODING_METHODS            0x00000481
+#define CKA_MIME_TYPES                  0x00000482
+#define CKA_MECHANISM_TYPE              0x00000500
+#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
+#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
+#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
+#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
+
+#define CKA_VENDOR_DEFINED     0x80000000
+
+
+/* CK_ATTRIBUTE is a structure that includes the type, length
+ * and value of an attribute */
+typedef struct CK_ATTRIBUTE {
+  CK_ATTRIBUTE_TYPE type;
+  CK_VOID_PTR       pValue;
+
+  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
+  CK_ULONG          ulValueLen;  /* in bytes */
+} CK_ATTRIBUTE;
+
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+
+/* CK_DATE is a structure that defines a date */
+typedef struct CK_DATE{
+  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
+  CK_CHAR       month[2];  /* the month ("01" - "12") */
+  CK_CHAR       day[2];    /* the day   ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
+ * type */
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
+#define CKM_RSA_PKCS                   0x00000001
+#define CKM_RSA_9796                   0x00000002
+#define CKM_RSA_X_509                  0x00000003
+
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
+ * are new for v2.0.  They are mechanisms which hash and sign */
+#define CKM_MD2_RSA_PKCS               0x00000004
+#define CKM_MD5_RSA_PKCS               0x00000005
+#define CKM_SHA1_RSA_PKCS              0x00000006
+
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
+#define CKM_RIPEMD128_RSA_PKCS         0x00000007
+#define CKM_RIPEMD160_RSA_PKCS         0x00000008
+#define CKM_RSA_PKCS_OAEP              0x00000009
+
+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
+#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
+#define CKM_RSA_X9_31                  0x0000000B
+#define CKM_SHA1_RSA_X9_31             0x0000000C
+#define CKM_RSA_PKCS_PSS               0x0000000D
+#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
+
+#define CKM_DSA_KEY_PAIR_GEN           0x00000010
+#define CKM_DSA                        0x00000011
+#define CKM_DSA_SHA1                   0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
+#define CKM_DH_PKCS_DERIVE             0x00000021
+
+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
+ * v2.11 */
+#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
+#define CKM_X9_42_DH_DERIVE            0x00000031
+#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
+#define CKM_X9_42_MQV_DERIVE           0x00000033
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256_RSA_PKCS            0x00000040
+#define CKM_SHA384_RSA_PKCS            0x00000041
+#define CKM_SHA512_RSA_PKCS            0x00000042
+#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
+#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
+#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
+
+#define CKM_RC2_KEY_GEN                0x00000100
+#define CKM_RC2_ECB                    0x00000101
+#define CKM_RC2_CBC                    0x00000102
+#define CKM_RC2_MAC                    0x00000103
+
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
+#define CKM_RC2_MAC_GENERAL            0x00000104
+#define CKM_RC2_CBC_PAD                0x00000105
+
+#define CKM_RC4_KEY_GEN                0x00000110
+#define CKM_RC4                        0x00000111
+#define CKM_DES_KEY_GEN                0x00000120
+#define CKM_DES_ECB                    0x00000121
+#define CKM_DES_CBC                    0x00000122
+#define CKM_DES_MAC                    0x00000123
+
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
+#define CKM_DES_MAC_GENERAL            0x00000124
+#define CKM_DES_CBC_PAD                0x00000125
+
+#define CKM_DES2_KEY_GEN               0x00000130
+#define CKM_DES3_KEY_GEN               0x00000131
+#define CKM_DES3_ECB                   0x00000132
+#define CKM_DES3_CBC                   0x00000133
+#define CKM_DES3_MAC                   0x00000134
+
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
+#define CKM_DES3_MAC_GENERAL           0x00000135
+#define CKM_DES3_CBC_PAD               0x00000136
+#define CKM_CDMF_KEY_GEN               0x00000140
+#define CKM_CDMF_ECB                   0x00000141
+#define CKM_CDMF_CBC                   0x00000142
+#define CKM_CDMF_MAC                   0x00000143
+#define CKM_CDMF_MAC_GENERAL           0x00000144
+#define CKM_CDMF_CBC_PAD               0x00000145
+
+/* the following four DES mechanisms are new for v2.20 */
+#define CKM_DES_OFB64                  0x00000150
+#define CKM_DES_OFB8                   0x00000151
+#define CKM_DES_CFB64                  0x00000152
+#define CKM_DES_CFB8                   0x00000153
+
+#define CKM_MD2                        0x00000200
+
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD2_HMAC                   0x00000201
+#define CKM_MD2_HMAC_GENERAL           0x00000202
+
+#define CKM_MD5                        0x00000210
+
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD5_HMAC                   0x00000211
+#define CKM_MD5_HMAC_GENERAL           0x00000212
+
+#define CKM_SHA_1                      0x00000220
+
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
+#define CKM_SHA_1_HMAC                 0x00000221
+#define CKM_SHA_1_HMAC_GENERAL         0x00000222
+
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
+#define CKM_RIPEMD128                  0x00000230
+#define CKM_RIPEMD128_HMAC             0x00000231
+#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
+#define CKM_RIPEMD160                  0x00000240
+#define CKM_RIPEMD160_HMAC             0x00000241
+#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256                     0x00000250
+#define CKM_SHA256_HMAC                0x00000251
+#define CKM_SHA256_HMAC_GENERAL        0x00000252
+#define CKM_SHA384                     0x00000260
+#define CKM_SHA384_HMAC                0x00000261
+#define CKM_SHA384_HMAC_GENERAL        0x00000262
+#define CKM_SHA512                     0x00000270
+#define CKM_SHA512_HMAC                0x00000271
+#define CKM_SHA512_HMAC_GENERAL        0x00000272
+
+/* All of the following mechanisms are new for v2.0 */
+/* Note that CAST128 and CAST5 are the same algorithm */
+#define CKM_CAST_KEY_GEN               0x00000300
+#define CKM_CAST_ECB                   0x00000301
+#define CKM_CAST_CBC                   0x00000302
+#define CKM_CAST_MAC                   0x00000303
+#define CKM_CAST_MAC_GENERAL           0x00000304
+#define CKM_CAST_CBC_PAD               0x00000305
+#define CKM_CAST3_KEY_GEN              0x00000310
+#define CKM_CAST3_ECB                  0x00000311
+#define CKM_CAST3_CBC                  0x00000312
+#define CKM_CAST3_MAC                  0x00000313
+#define CKM_CAST3_MAC_GENERAL          0x00000314
+#define CKM_CAST3_CBC_PAD              0x00000315
+#define CKM_CAST5_KEY_GEN              0x00000320
+#define CKM_CAST128_KEY_GEN            0x00000320
+#define CKM_CAST5_ECB                  0x00000321
+#define CKM_CAST128_ECB                0x00000321
+#define CKM_CAST5_CBC                  0x00000322
+#define CKM_CAST128_CBC                0x00000322
+#define CKM_CAST5_MAC                  0x00000323
+#define CKM_CAST128_MAC                0x00000323
+#define CKM_CAST5_MAC_GENERAL          0x00000324
+#define CKM_CAST128_MAC_GENERAL        0x00000324
+#define CKM_CAST5_CBC_PAD              0x00000325
+#define CKM_CAST128_CBC_PAD            0x00000325
+#define CKM_RC5_KEY_GEN                0x00000330
+#define CKM_RC5_ECB                    0x00000331
+#define CKM_RC5_CBC                    0x00000332
+#define CKM_RC5_MAC                    0x00000333
+#define CKM_RC5_MAC_GENERAL            0x00000334
+#define CKM_RC5_CBC_PAD                0x00000335
+#define CKM_IDEA_KEY_GEN               0x00000340
+#define CKM_IDEA_ECB                   0x00000341
+#define CKM_IDEA_CBC                   0x00000342
+#define CKM_IDEA_MAC                   0x00000343
+#define CKM_IDEA_MAC_GENERAL           0x00000344
+#define CKM_IDEA_CBC_PAD               0x00000345
+#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
+#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
+#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
+#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
+#define CKM_XOR_BASE_AND_DATA          0x00000364
+#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
+#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
+#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
+#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
+
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
+#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
+#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
+#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
+#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
+
+/* CKM_TLS_PRF is new for v2.20 */
+#define CKM_TLS_PRF                    0x00000378
+
+#define CKM_SSL3_MD5_MAC               0x00000380
+#define CKM_SSL3_SHA1_MAC              0x00000381
+#define CKM_MD5_KEY_DERIVATION         0x00000390
+#define CKM_MD2_KEY_DERIVATION         0x00000391
+#define CKM_SHA1_KEY_DERIVATION        0x00000392
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256_KEY_DERIVATION      0x00000393
+#define CKM_SHA384_KEY_DERIVATION      0x00000394
+#define CKM_SHA512_KEY_DERIVATION      0x00000395
+
+#define CKM_PBE_MD2_DES_CBC            0x000003A0
+#define CKM_PBE_MD5_DES_CBC            0x000003A1
+#define CKM_PBE_MD5_CAST_CBC           0x000003A2
+#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
+#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
+#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
+#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
+#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
+#define CKM_PBE_SHA1_RC4_128           0x000003A6
+#define CKM_PBE_SHA1_RC4_40            0x000003A7
+#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
+#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
+#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
+#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
+
+/* CKM_PKCS5_PBKD2 is new for v2.10 */
+#define CKM_PKCS5_PBKD2                0x000003B0
+
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
+
+/* WTLS mechanisms are new for v2.20 */
+#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
+#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
+#define CKM_WTLS_PRF                        0x000003D3
+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
+
+#define CKM_KEY_WRAP_LYNKS             0x00000400
+#define CKM_KEY_WRAP_SET_OAEP          0x00000401
+
+/* CKM_CMS_SIG is new for v2.20 */
+#define CKM_CMS_SIG                    0x00000500
+
+/* Fortezza mechanisms */
+#define CKM_SKIPJACK_KEY_GEN           0x00001000
+#define CKM_SKIPJACK_ECB64             0x00001001
+#define CKM_SKIPJACK_CBC64             0x00001002
+#define CKM_SKIPJACK_OFB64             0x00001003
+#define CKM_SKIPJACK_CFB64             0x00001004
+#define CKM_SKIPJACK_CFB32             0x00001005
+#define CKM_SKIPJACK_CFB16             0x00001006
+#define CKM_SKIPJACK_CFB8              0x00001007
+#define CKM_SKIPJACK_WRAP              0x00001008
+#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
+#define CKM_SKIPJACK_RELAYX            0x0000100a
+#define CKM_KEA_KEY_PAIR_GEN           0x00001010
+#define CKM_KEA_KEY_DERIVE             0x00001011
+#define CKM_FORTEZZA_TIMESTAMP         0x00001020
+#define CKM_BATON_KEY_GEN              0x00001030
+#define CKM_BATON_ECB128               0x00001031
+#define CKM_BATON_ECB96                0x00001032
+#define CKM_BATON_CBC128               0x00001033
+#define CKM_BATON_COUNTER              0x00001034
+#define CKM_BATON_SHUFFLE              0x00001035
+#define CKM_BATON_WRAP                 0x00001036
+
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
+ * CKM_EC_KEY_PAIR_GEN is preferred */
+#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
+#define CKM_EC_KEY_PAIR_GEN            0x00001040
+
+#define CKM_ECDSA                      0x00001041
+#define CKM_ECDSA_SHA1                 0x00001042
+
+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
+ * are new for v2.11 */
+#define CKM_ECDH1_DERIVE               0x00001050
+#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
+#define CKM_ECMQV_DERIVE               0x00001052
+
+#define CKM_JUNIPER_KEY_GEN            0x00001060
+#define CKM_JUNIPER_ECB128             0x00001061
+#define CKM_JUNIPER_CBC128             0x00001062
+#define CKM_JUNIPER_COUNTER            0x00001063
+#define CKM_JUNIPER_SHUFFLE            0x00001064
+#define CKM_JUNIPER_WRAP               0x00001065
+#define CKM_FASTHASH                   0x00001070
+
+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
+ * new for v2.11 */
+#define CKM_AES_KEY_GEN                0x00001080
+#define CKM_AES_ECB                    0x00001081
+#define CKM_AES_CBC                    0x00001082
+#define CKM_AES_MAC                    0x00001083
+#define CKM_AES_MAC_GENERAL            0x00001084
+#define CKM_AES_CBC_PAD                0x00001085
+
+/* BlowFish and TwoFish are new for v2.20 */
+#define CKM_BLOWFISH_KEY_GEN           0x00001090
+#define CKM_BLOWFISH_CBC               0x00001091
+#define CKM_TWOFISH_KEY_GEN            0x00001092
+#define CKM_TWOFISH_CBC                0x00001093
+
+
+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
+#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
+#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
+#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
+#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
+#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
+#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
+
+#define CKM_DSA_PARAMETER_GEN          0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
+#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
+
+#define CKM_VENDOR_DEFINED             0x80000000
+
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular
+ * mechanism  */
+typedef struct CK_MECHANISM {
+  CK_MECHANISM_TYPE mechanism;
+  CK_VOID_PTR       pParameter;
+
+  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
+   * v2.0 */
+  CK_ULONG          ulParameterLen;  /* in bytes */
+} CK_MECHANISM;
+
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* CK_MECHANISM_INFO provides information about a particular
+ * mechanism */
+typedef struct CK_MECHANISM_INFO {
+    CK_ULONG    ulMinKeySize;
+    CK_ULONG    ulMaxKeySize;
+    CK_FLAGS    flags;
+} CK_MECHANISM_INFO;
+
+/* The flags are defined as follows:
+ *      Bit Flag               Mask        Meaning */
+#define CKF_HW                 0x00000001  /* performed by HW */
+
+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
+ * and CKF_DERIVE are new for v2.0.  They specify whether or not
+ * a mechanism can be used for a particular task */
+#define CKF_ENCRYPT            0x00000100
+#define CKF_DECRYPT            0x00000200
+#define CKF_DIGEST             0x00000400
+#define CKF_SIGN               0x00000800
+#define CKF_SIGN_RECOVER       0x00001000
+#define CKF_VERIFY             0x00002000
+#define CKF_VERIFY_RECOVER     0x00004000
+#define CKF_GENERATE           0x00008000
+#define CKF_GENERATE_KEY_PAIR  0x00010000
+#define CKF_WRAP               0x00020000
+#define CKF_UNWRAP             0x00040000
+#define CKF_DERIVE             0x00080000
+
+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
+ * describe a token's EC capabilities not available in mechanism
+ * information. */
+#define CKF_EC_F_P             0x00100000
+#define CKF_EC_F_2M            0x00200000
+#define CKF_EC_ECPARAMETERS    0x00400000
+#define CKF_EC_NAMEDCURVE      0x00800000
+#define CKF_EC_UNCOMPRESS      0x01000000
+#define CKF_EC_COMPRESS        0x02000000
+
+#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
+
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+
+/* CK_RV is a value that identifies the return value of a
+ * Cryptoki function */
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG          CK_RV;
+
+#define CKR_OK                                0x00000000
+#define CKR_CANCEL                            0x00000001
+#define CKR_HOST_MEMORY                       0x00000002
+#define CKR_SLOT_ID_INVALID                   0x00000003
+
+/* CKR_FLAGS_INVALID was removed for v2.0 */
+
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
+#define CKR_GENERAL_ERROR                     0x00000005
+#define CKR_FUNCTION_FAILED                   0x00000006
+
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
+ * and CKR_CANT_LOCK are new for v2.01 */
+#define CKR_ARGUMENTS_BAD                     0x00000007
+#define CKR_NO_EVENT                          0x00000008
+#define CKR_NEED_TO_CREATE_THREADS            0x00000009
+#define CKR_CANT_LOCK                         0x0000000A
+
+#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
+#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
+#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
+#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
+#define CKR_DATA_INVALID                      0x00000020
+#define CKR_DATA_LEN_RANGE                    0x00000021
+#define CKR_DEVICE_ERROR                      0x00000030
+#define CKR_DEVICE_MEMORY                     0x00000031
+#define CKR_DEVICE_REMOVED                    0x00000032
+#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
+#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
+#define CKR_FUNCTION_CANCELED                 0x00000050
+#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
+
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
+#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
+
+#define CKR_KEY_HANDLE_INVALID                0x00000060
+
+/* CKR_KEY_SENSITIVE was removed for v2.0 */
+
+#define CKR_KEY_SIZE_RANGE                    0x00000062
+#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
+
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
+ * v2.0 */
+#define CKR_KEY_NOT_NEEDED                    0x00000064
+#define CKR_KEY_CHANGED                       0x00000065
+#define CKR_KEY_NEEDED                        0x00000066
+#define CKR_KEY_INDIGESTIBLE                  0x00000067
+#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
+#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
+#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
+
+#define CKR_MECHANISM_INVALID                 0x00000070
+#define CKR_MECHANISM_PARAM_INVALID           0x00000071
+
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
+ * were removed for v2.0 */
+#define CKR_OBJECT_HANDLE_INVALID             0x00000082
+#define CKR_OPERATION_ACTIVE                  0x00000090
+#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
+#define CKR_PIN_INCORRECT                     0x000000A0
+#define CKR_PIN_INVALID                       0x000000A1
+#define CKR_PIN_LEN_RANGE                     0x000000A2
+
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
+#define CKR_PIN_EXPIRED                       0x000000A3
+#define CKR_PIN_LOCKED                        0x000000A4
+
+#define CKR_SESSION_CLOSED                    0x000000B0
+#define CKR_SESSION_COUNT                     0x000000B1
+#define CKR_SESSION_HANDLE_INVALID            0x000000B3
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
+#define CKR_SESSION_READ_ONLY                 0x000000B5
+#define CKR_SESSION_EXISTS                    0x000000B6
+
+/* CKR_SESSION_READ_ONLY_EXISTS and
+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
+#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
+#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
+
+#define CKR_SIGNATURE_INVALID                 0x000000C0
+#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
+#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
+#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
+#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
+#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
+#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
+#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
+#define CKR_USER_NOT_LOGGED_IN                0x00000101
+#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
+#define CKR_USER_TYPE_INVALID                 0x00000103
+
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
+ * are new to v2.01 */
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
+#define CKR_USER_TOO_MANY_TYPES               0x00000105
+
+#define CKR_WRAPPED_KEY_INVALID               0x00000110
+#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
+#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
+#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
+#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
+
+/* These are new to v2.0 */
+#define CKR_RANDOM_NO_RNG                     0x00000121
+
+/* These are new to v2.11 */
+#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
+
+/* These are new to v2.0 */
+#define CKR_BUFFER_TOO_SMALL                  0x00000150
+#define CKR_SAVED_STATE_INVALID               0x00000160
+#define CKR_INFORMATION_SENSITIVE             0x00000170
+#define CKR_STATE_UNSAVEABLE                  0x00000180
+
+/* These are new to v2.01 */
+#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
+#define CKR_MUTEX_BAD                         0x000001A0
+#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
+
+/* This is new to v2.20 */
+#define CKR_FUNCTION_REJECTED                 0x00000200
+
+#define CKR_VENDOR_DEFINED                    0x80000000
+
+
+/* CK_NOTIFY is an application callback that processes events */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
+  CK_NOTIFICATION   event,
+  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
+);
+
+
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+ * version and pointers of appropriate types to all the
+ * Cryptoki functions */
+/* CK_FUNCTION_LIST is new for v2.0 */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+
+/* CK_CREATEMUTEX is an application callback for creating a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
+  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
+  CK_VOID_PTR pMutex  /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
+  CK_VOID_PTR pMutex  /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
+ * mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
+  CK_VOID_PTR pMutex  /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
+ * C_Initialize */
+typedef struct CK_C_INITIALIZE_ARGS {
+  CK_CREATEMUTEX CreateMutex;
+  CK_DESTROYMUTEX DestroyMutex;
+  CK_LOCKMUTEX LockMutex;
+  CK_UNLOCKMUTEX UnlockMutex;
+  CK_FLAGS flags;
+  CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS;
+
+/* flags: bit flags that provide capabilities of the slot
+ *      Bit Flag                           Mask       Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
+#define CKF_OS_LOCKING_OK                  0x00000002
+
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK     1
+
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
+ * scheme. */
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
+
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
+ * are new for v2.20 */
+#define CKG_MGF1_SHA1         0x00000001
+#define CKG_MGF1_SHA256       0x00000002
+#define CKG_MGF1_SHA384       0x00000003
+#define CKG_MGF1_SHA512       0x00000004
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
+ * of the encoding parameter when formatting a message block
+ * for the PKCS #1 OAEP encryption scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED    0x00000001
+
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism. */
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+        CK_MECHANISM_TYPE hashAlg;
+        CK_RSA_PKCS_MGF_TYPE mgf;
+        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+        CK_VOID_PTR pSourceData;
+        CK_ULONG ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
+
+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_PSS mechanism(s). */
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+        CK_MECHANISM_TYPE    hashAlg;
+        CK_RSA_PKCS_MGF_TYPE mgf;
+        CK_ULONG             sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
+
+/* CK_EC_KDF_TYPE is new for v2.11. */
+typedef CK_ULONG CK_EC_KDF_TYPE;
+
+/* The following EC Key Derivation Functions are defined */
+#define CKD_NULL                 0x00000001
+#define CKD_SHA1_KDF             0x00000002
+
+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
+ * where each party contributes one key pair.
+ */
+typedef struct CK_ECDH1_DERIVE_PARAMS {
+  CK_EC_KDF_TYPE kdf;
+  CK_ULONG ulSharedDataLen;
+  CK_BYTE_PTR pSharedData;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+} CK_ECDH1_DERIVE_PARAMS;
+
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
+
+
+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
+typedef struct CK_ECDH2_DERIVE_PARAMS {
+  CK_EC_KDF_TYPE kdf;
+  CK_ULONG ulSharedDataLen;
+  CK_BYTE_PTR pSharedData;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+  CK_ULONG ulPrivateDataLen;
+  CK_OBJECT_HANDLE hPrivateData;
+  CK_ULONG ulPublicDataLen2;
+  CK_BYTE_PTR pPublicData2;
+} CK_ECDH2_DERIVE_PARAMS;
+
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_ECMQV_DERIVE_PARAMS {
+  CK_EC_KDF_TYPE kdf;
+  CK_ULONG ulSharedDataLen;
+  CK_BYTE_PTR pSharedData;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+  CK_ULONG ulPrivateDataLen;
+  CK_OBJECT_HANDLE hPrivateData;
+  CK_ULONG ulPublicDataLen2;
+  CK_BYTE_PTR pPublicData2;
+  CK_OBJECT_HANDLE publicKey;
+} CK_ECMQV_DERIVE_PARAMS;
+
+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
+
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
+
+/* The following X9.42 DH key derivation functions are defined
+   (besides CKD_NULL already defined : */
+#define CKD_SHA1_KDF_ASN1        0x00000003
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
+
+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
+ * contributes one key pair */
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
+  CK_X9_42_DH_KDF_TYPE kdf;
+  CK_ULONG ulOtherInfoLen;
+  CK_BYTE_PTR pOtherInfo;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+} CK_X9_42_DH1_DERIVE_PARAMS;
+
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
+
+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
+ * mechanisms, where each party contributes two key pairs */
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
+  CK_X9_42_DH_KDF_TYPE kdf;
+  CK_ULONG ulOtherInfoLen;
+  CK_BYTE_PTR pOtherInfo;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+  CK_ULONG ulPrivateDataLen;
+  CK_OBJECT_HANDLE hPrivateData;
+  CK_ULONG ulPublicDataLen2;
+  CK_BYTE_PTR pPublicData2;
+} CK_X9_42_DH2_DERIVE_PARAMS;
+
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
+  CK_X9_42_DH_KDF_TYPE kdf;
+  CK_ULONG ulOtherInfoLen;
+  CK_BYTE_PTR pOtherInfo;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+  CK_ULONG ulPrivateDataLen;
+  CK_OBJECT_HANDLE hPrivateData;
+  CK_ULONG ulPublicDataLen2;
+  CK_BYTE_PTR pPublicData2;
+  CK_OBJECT_HANDLE publicKey;
+} CK_X9_42_MQV_DERIVE_PARAMS;
+
+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
+ * CKM_KEA_DERIVE mechanism */
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
+typedef struct CK_KEA_DERIVE_PARAMS {
+  CK_BBOOL      isSender;
+  CK_ULONG      ulRandomLen;
+  CK_BYTE_PTR   pRandomA;
+  CK_BYTE_PTR   pRandomB;
+  CK_ULONG      ulPublicDataLen;
+  CK_BYTE_PTR   pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+ * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
+ * holds the effective keysize */
+typedef CK_ULONG          CK_RC2_PARAMS;
+
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+ * mechanism */
+typedef struct CK_RC2_CBC_PARAMS {
+  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
+   * v2.0 */
+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
+
+  CK_BYTE       iv[8];            /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC2_MAC_GENERAL mechanism */
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
+  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
+  CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+ * CKM_RC5_MAC mechanisms */
+/* CK_RC5_PARAMS is new for v2.0 */
+typedef struct CK_RC5_PARAMS {
+  CK_ULONG      ulWordsize;  /* wordsize in bits */
+  CK_ULONG      ulRounds;    /* number of rounds */
+} CK_RC5_PARAMS;
+
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+ * mechanism */
+/* CK_RC5_CBC_PARAMS is new for v2.0 */
+typedef struct CK_RC5_CBC_PARAMS {
+  CK_ULONG      ulWordsize;  /* wordsize in bits */
+  CK_ULONG      ulRounds;    /* number of rounds */
+  CK_BYTE_PTR   pIv;         /* pointer to IV */
+  CK_ULONG      ulIvLen;     /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC5_MAC_GENERAL mechanism */
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+  CK_ULONG      ulWordsize;   /* wordsize in bits */
+  CK_ULONG      ulRounds;     /* number of rounds */
+  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
+  CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
+ * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
+ * the MAC */
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
+  CK_BYTE      iv[8];
+  CK_BYTE_PTR  pData;
+  CK_ULONG     length;
+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
+  CK_BYTE      iv[16];
+  CK_BYTE_PTR  pData;
+  CK_ULONG     length;
+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+  CK_ULONG      ulPasswordLen;
+  CK_BYTE_PTR   pPassword;
+  CK_ULONG      ulPublicDataLen;
+  CK_BYTE_PTR   pPublicData;
+  CK_ULONG      ulPAndGLen;
+  CK_ULONG      ulQLen;
+  CK_ULONG      ulRandomLen;
+  CK_BYTE_PTR   pRandomA;
+  CK_BYTE_PTR   pPrimeP;
+  CK_BYTE_PTR   pBaseG;
+  CK_BYTE_PTR   pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+  CK_SKIPJACK_PRIVATE_WRAP_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism */
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+  CK_ULONG      ulOldWrappedXLen;
+  CK_BYTE_PTR   pOldWrappedX;
+  CK_ULONG      ulOldPasswordLen;
+  CK_BYTE_PTR   pOldPassword;
+  CK_ULONG      ulOldPublicDataLen;
+  CK_BYTE_PTR   pOldPublicData;
+  CK_ULONG      ulOldRandomLen;
+  CK_BYTE_PTR   pOldRandomA;
+  CK_ULONG      ulNewPasswordLen;
+  CK_BYTE_PTR   pNewPassword;
+  CK_ULONG      ulNewPublicDataLen;
+  CK_BYTE_PTR   pNewPublicData;
+  CK_ULONG      ulNewRandomLen;
+  CK_BYTE_PTR   pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
+  CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+
+typedef struct CK_PBE_PARAMS {
+  CK_BYTE_PTR      pInitVector;
+  CK_UTF8CHAR_PTR  pPassword;
+  CK_ULONG         ulPasswordLen;
+  CK_BYTE_PTR      pSalt;
+  CK_ULONG         ulSaltLen;
+  CK_ULONG         ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+ * CKM_KEY_WRAP_SET_OAEP mechanism */
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+  CK_BYTE       bBC;     /* block contents byte */
+  CK_BYTE_PTR   pX;      /* extra data */
+  CK_ULONG      ulXLen;  /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
+  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_RANDOM_DATA {
+  CK_BYTE_PTR  pClientRandom;
+  CK_ULONG     ulClientRandomLen;
+  CK_BYTE_PTR  pServerRandom;
+  CK_ULONG     ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+  CK_SSL3_RANDOM_DATA RandomInfo;
+  CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+  CK_OBJECT_HANDLE hClientMacSecret;
+  CK_OBJECT_HANDLE hServerMacSecret;
+  CK_OBJECT_HANDLE hClientKey;
+  CK_OBJECT_HANDLE hServerKey;
+  CK_BYTE_PTR      pIVClient;
+  CK_BYTE_PTR      pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+  CK_ULONG                ulMacSizeInBits;
+  CK_ULONG                ulKeySizeInBits;
+  CK_ULONG                ulIVSizeInBits;
+  CK_BBOOL                bIsExport;
+  CK_SSL3_RANDOM_DATA     RandomInfo;
+  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
+typedef struct CK_TLS_PRF_PARAMS {
+  CK_BYTE_PTR  pSeed;
+  CK_ULONG     ulSeedLen;
+  CK_BYTE_PTR  pLabel;
+  CK_ULONG     ulLabelLen;
+  CK_BYTE_PTR  pOutput;
+  CK_ULONG_PTR pulOutputLen;
+} CK_TLS_PRF_PARAMS;
+
+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
+
+/* WTLS is new for version 2.20 */
+typedef struct CK_WTLS_RANDOM_DATA {
+  CK_BYTE_PTR pClientRandom;
+  CK_ULONG    ulClientRandomLen;
+  CK_BYTE_PTR pServerRandom;
+  CK_ULONG    ulServerRandomLen;
+} CK_WTLS_RANDOM_DATA;
+
+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
+
+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
+  CK_MECHANISM_TYPE   DigestMechanism;
+  CK_WTLS_RANDOM_DATA RandomInfo;
+  CK_BYTE_PTR         pVersion;
+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
+
+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_WTLS_PRF_PARAMS {
+  CK_MECHANISM_TYPE DigestMechanism;
+  CK_BYTE_PTR       pSeed;
+  CK_ULONG          ulSeedLen;
+  CK_BYTE_PTR       pLabel;
+  CK_ULONG          ulLabelLen;
+  CK_BYTE_PTR       pOutput;
+  CK_ULONG_PTR      pulOutputLen;
+} CK_WTLS_PRF_PARAMS;
+
+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_OUT {
+  CK_OBJECT_HANDLE hMacSecret;
+  CK_OBJECT_HANDLE hKey;
+  CK_BYTE_PTR      pIV;
+} CK_WTLS_KEY_MAT_OUT;
+
+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_PARAMS {
+  CK_MECHANISM_TYPE       DigestMechanism;
+  CK_ULONG                ulMacSizeInBits;
+  CK_ULONG                ulKeySizeInBits;
+  CK_ULONG                ulIVSizeInBits;
+  CK_ULONG                ulSequenceNumber;
+  CK_BBOOL                bIsExport;
+  CK_WTLS_RANDOM_DATA     RandomInfo;
+  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_WTLS_KEY_MAT_PARAMS;
+
+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
+
+/* CMS is new for version 2.20 */
+typedef struct CK_CMS_SIG_PARAMS {
+  CK_OBJECT_HANDLE      certificateHandle;
+  CK_MECHANISM_PTR      pSigningMechanism;
+  CK_MECHANISM_PTR      pDigestMechanism;
+  CK_UTF8CHAR_PTR       pContentType;
+  CK_BYTE_PTR           pRequestedAttributes;
+  CK_ULONG              ulRequestedAttributesLen;
+  CK_BYTE_PTR           pRequiredAttributes;
+  CK_ULONG              ulRequiredAttributesLen;
+} CK_CMS_SIG_PARAMS;
+
+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
+
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+  CK_BYTE_PTR pData;
+  CK_ULONG    ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
+  CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
+/* The CK_EXTRACT_PARAMS is used for the
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
+ * of the base key should be used as the first bit of the
+ * derived key */
+/* CK_EXTRACT_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
+ * key bits using PKCS #5 PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+/* The following PRFs are defined in PKCS #5 v2.0. */
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
+
+
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
+ * PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED        0x00000001
+
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
+        CK_VOID_PTR                                pSaltSourceData;
+        CK_ULONG                                   ulSaltSourceDataLen;
+        CK_ULONG                                   iterations;
+        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+        CK_VOID_PTR                                pPrfData;
+        CK_ULONG                                   ulPrfDataLen;
+        CK_UTF8CHAR_PTR                            pPassword;
+        CK_ULONG_PTR                               ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+/*
+ * pkcs11wrapper.h
+ * 18.05.2001
+ *
+ * declaration of all functions used by pkcs11wrapper.c
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
+ */
+
+#ifndef _PKCS11WRAPPER_H
+#define _PKCS11WRAPPER_H 1
+
+/* disable asserts in product mode */
+#ifndef DEBUG
+  #ifndef NDEBUG
+    #define NDEBUG
+  #endif
+#endif
+
+/* extra PKCS#11 constants not in the standard include files */
+
+#define CKA_NETSCAPE_BASE                       (0x80000000 + 0x4E534350)
+#define CKA_NETSCAPE_TRUST_BASE                 (CKA_NETSCAPE_BASE + 0x2000)
+
+#define CKA_NETSCAPE_TRUST_SERVER_AUTH          (CKA_NETSCAPE_TRUST_BASE + 8)
+#define CKA_NETSCAPE_TRUST_CLIENT_AUTH          (CKA_NETSCAPE_TRUST_BASE + 9)
+#define CKA_NETSCAPE_TRUST_CODE_SIGNING (CKA_NETSCAPE_TRUST_BASE + 10)
+#define CKA_NETSCAPE_TRUST_EMAIL_PROTECTION     (CKA_NETSCAPE_TRUST_BASE + 11)
+
+/*
+
+ Define the PKCS#11 functions to include and exclude. Reduces the size
+ of the binary somewhat.
+
+ This list needs to be kept in sync with the mapfile and PKCS11.java
+
+*/
+
+#define P11_ENABLE_C_INITIALIZE
+#define P11_ENABLE_C_FINALIZE
+#define P11_ENABLE_C_GETINFO
+#define P11_ENABLE_C_GETSLOTLIST
+#define P11_ENABLE_C_GETSLOTINFO
+#define P11_ENABLE_C_GETTOKENINFO
+#define P11_ENABLE_C_GETMECHANISMLIST
+#define P11_ENABLE_C_GETMECHANISMINFO
+#undef  P11_ENABLE_C_INITTOKEN
+#undef  P11_ENABLE_C_INITPIN
+#undef  P11_ENABLE_C_SETPIN
+#define P11_ENABLE_C_OPENSESSION
+#define P11_ENABLE_C_CLOSESESSION
+#undef  P11_ENABLE_C_CLOSEALLSESSIONS
+#define P11_ENABLE_C_GETSESSIONINFO
+#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
+#define P11_ENABLE_C_COPYOBJECT
+#define P11_ENABLE_C_DESTROYOBJECT
+#undef  P11_ENABLE_C_GETOBJECTSIZE
+#define P11_ENABLE_C_GETATTRIBUTEVALUE
+#define P11_ENABLE_C_SETATTRIBUTEVALUE
+#define P11_ENABLE_C_FINDOBJECTSINIT
+#define P11_ENABLE_C_FINDOBJECTS
+#define P11_ENABLE_C_FINDOBJECTSFINAL
+#define P11_ENABLE_C_ENCRYPTINIT
+#define P11_ENABLE_C_ENCRYPT
+#define P11_ENABLE_C_ENCRYPTUPDATE
+#define P11_ENABLE_C_ENCRYPTFINAL
+#define P11_ENABLE_C_DECRYPTINIT
+#define P11_ENABLE_C_DECRYPT
+#define P11_ENABLE_C_DECRYPTUPDATE
+#define P11_ENABLE_C_DECRYPTFINAL
+#define P11_ENABLE_C_DIGESTINIT
+#define P11_ENABLE_C_DIGEST
+#define P11_ENABLE_C_DIGESTUPDATE
+#define P11_ENABLE_C_DIGESTKEY
+#define P11_ENABLE_C_DIGESTFINAL
+#define P11_ENABLE_C_SIGNINIT
+#define P11_ENABLE_C_SIGN
+#define P11_ENABLE_C_SIGNUPDATE
+#define P11_ENABLE_C_SIGNFINAL
+#define P11_ENABLE_C_SIGNRECOVERINIT
+#define P11_ENABLE_C_SIGNRECOVER
+#define P11_ENABLE_C_VERIFYINIT
+#define P11_ENABLE_C_VERIFY
+#define P11_ENABLE_C_VERIFYUPDATE
+#define P11_ENABLE_C_VERIFYFINAL
+#define P11_ENABLE_C_VERIFYRECOVERINIT
+#define P11_ENABLE_C_VERIFYRECOVER
+#undef  P11_ENABLE_C_DIGESTENCRYPTUPDATE
+#undef  P11_ENABLE_C_DECRYPTDIGESTUPDATE
+#undef  P11_ENABLE_C_SIGNENCRYPTUPDATE
+#undef  P11_ENABLE_C_DECRYPTVERIFYUPDATE
+#define P11_ENABLE_C_GENERATEKEY
+#define P11_ENABLE_C_GENERATEKEYPAIR
+#define P11_ENABLE_C_WRAPKEY
+#define P11_ENABLE_C_UNWRAPKEY
+#define P11_ENABLE_C_DERIVEKEY
+#define P11_ENABLE_C_SEEDRANDOM
+#define P11_ENABLE_C_GENERATERANDOM
+#undef  P11_ENABLE_C_GETFUNCTIONSTATUS
+#undef  P11_ENABLE_C_CANCELFUNCTION
+#undef  P11_ENABLE_C_WAITFORSLOTEVENT
+
+/* include the platform dependent part of the header */
+#include "p11_md.h"
+
+#include "pkcs11.h"
+#include "pkcs-11v2-20a3.h"
+#include <jni.h>
+#include <jni_util.h>
+#include <stdarg.h>
+
+#define MAX_STACK_BUFFER_LEN (4 * 1024)
+#define MAX_HEAP_BUFFER_LEN (64 * 1024)
+
+#define MAX_DIGEST_LEN (64)
+
+#ifndef min
+#define min(a, b)       (((a) < (b)) ? (a) : (b))
+#endif
+
+#define ckBBoolToJBoolean(x) ((x == TRUE) ? JNI_TRUE : JNI_FALSE);
+#define jBooleanToCKBBool(x) ((x == JNI_TRUE) ? TRUE : FALSE);
+
+#define ckByteToJByte(x) ((jbyte) x)
+#define jByteToCKByte(x) ((CK_BYTE) x)
+
+#define ckLongToJLong(x) ((jlong) x)
+#define jLongToCKLong(x) ((CK_LONG) x)
+
+#define ckULongToJLong(x) ((jlong) x)
+#define jLongToCKULong(x) ((CK_ULONG) x)
+
+// For CK_UNAVAILABLE_INFORMATION, always return -1 to avoid 32/64 bit problems.
+#define ckULongSpecialToJLong(x) (((x) == CK_UNAVAILABLE_INFORMATION) \
+    ? (jlong)-1 : ((jlong) x))
+
+#define ckCharToJChar(x) ((jchar) x)
+#define jCharToCKChar(x) ((CK_CHAR) x)
+
+#define ckUTF8CharToJChar(x) ((jchar) x)
+#define jCharToCKUTF8Char(x) ((CK_UTF8CHAR) x)
+
+#define ckFlageToJLong(x) ((jlong) x)
+
+#define ckVoidPtrToJObject(x) ((jobject) x)
+#define jObjectToCKVoidPtr(x) ((CK_VOID_PTR) x)
+
+#define jIntToCKLong(x)         ((CK_LONG) x)
+#define jIntToCKULong(x)        ((CK_ULONG) x)
+#define ckLongToJInt(x)         ((jint) x)
+#define ckULongToJInt(x)        ((jint) x)
+#define ckULongToJSize(x)       ((jsize) x)
+#define unsignedIntToCKULong(x) ((CK_ULONG) x)
+
+#ifdef P11_DEBUG
+#define TRACE0(s) { printf(s); fflush(stdout); }
+#define TRACE1(s, p1) { printf(s, p1); fflush(stdout); }
+#define TRACE2(s, p1, p2) { printf(s, p1, p2); fflush(stdout); }
+#define TRACE3(s, p1, p2, p3) { printf(s, p1, p2, p3); fflush(stdout); }
+#else
+#define TRACE0(s)
+#define TRACE1(s, p1)
+#define TRACE2(s, p1, p2)
+#define TRACE3(s, p1, p2, p3)
+#define TRACE_INTEND
+#define TRACE_UNINTEND
+#endif
+
+/* debug output */
+extern jboolean debug;
+void printDebug(const char *format, ...);
+
+#define CK_ASSERT_OK 0L
+
+#define CLASS_INFO "sun/security/pkcs11/wrapper/CK_INFO"
+#define CLASS_VERSION "sun/security/pkcs11/wrapper/CK_VERSION"
+#define CLASS_SLOT_INFO "sun/security/pkcs11/wrapper/CK_SLOT_INFO"
+#define CLASS_TOKEN_INFO "sun/security/pkcs11/wrapper/CK_TOKEN_INFO"
+#define CLASS_MECHANISM "sun/security/pkcs11/wrapper/CK_MECHANISM"
+#define CLASS_MECHANISM_INFO "sun/security/pkcs11/wrapper/CK_MECHANISM_INFO"
+#define CLASS_SESSION_INFO "sun/security/pkcs11/wrapper/CK_SESSION_INFO"
+#define CLASS_ATTRIBUTE "sun/security/pkcs11/wrapper/CK_ATTRIBUTE"
+#define CLASS_DATE "sun/security/pkcs11/wrapper/CK_DATE"
+#define CLASS_PKCS11EXCEPTION "sun/security/pkcs11/wrapper/PKCS11Exception"
+#define CLASS_PKCS11RUNTIMEEXCEPTION "sun/security/pkcs11/wrapper/PKCS11RuntimeException"
+#define CLASS_FILE_NOT_FOUND_EXCEPTION "java/io/FileNotFoundException"
+#define CLASS_C_INITIALIZE_ARGS "sun/security/pkcs11/wrapper/CK_C_INITIALIZE_ARGS"
+#define CLASS_CREATEMUTEX "sun/security/pkcs11/wrapper/CK_CREATEMUTEX"
+#define CLASS_DESTROYMUTEX "sun/security/pkcs11/wrapper/CK_DESTROYMUTEX"
+#define CLASS_LOCKMUTEX "sun/security/pkcs11/wrapper/CK_LOCKMUTEX"
+#define CLASS_UNLOCKMUTEX "sun/security/pkcs11/wrapper/CK_UNLOCKMUTEX"
+#define CLASS_NOTIFY "sun/security/pkcs11/wrapper/CK_NOTIFY"
+
+
+/* mechanism parameter classes */
+
+#define CLASS_RSA_PKCS_OAEP_PARAMS "sun/security/pkcs11/wrapper/CK_RSA_PKCS_OAEP_PARAMS"
+#define CLASS_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_MAC_GENERAL_PARAMS"
+#define CLASS_PBE_PARAMS "sun/security/pkcs11/wrapper/CK_PBE_PARAMS"
+#define PBE_INIT_VECTOR_SIZE 8
+#define CLASS_PKCS5_PBKD2_PARAMS "sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS"
+#define CLASS_EXTRACT_PARAMS "sun/security/pkcs11/wrapper/CK_EXTRACT_PARAMS"
+
+#define CLASS_RSA_PKCS_PSS_PARAMS "sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS"
+#define CLASS_ECDH1_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS"
+#define CLASS_ECDH2_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_ECDH2_DERIVE_PARAMS"
+#define CLASS_X9_42_DH1_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS"
+#define CLASS_X9_42_DH2_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_X9_42_DH2_DERIVE_PARAMS"
+
+/*
+#define CLASS_KEA_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_KEA_DERIVE_PARAMS"
+#define CLASS_RC2_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_PARAMS"
+#define CLASS_RC2_CBC_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_CBC_PARAMS"
+#define CLASS_RC2_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_MAC_GENERAL_PARAMS"
+#define CLASS_RC5_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_PARAMS"
+#define CLASS_RC5_CBC_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_CBC_PARAMS"
+#define CLASS_RC5_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_MAC_GENERAL_PARAMS"
+#define CLASS_SKIPJACK_PRIVATE_WRAP_PARAMS "sun/security/pkcs11/wrapper/CK_SKIPJACK_PRIVATE_WRAP_PARAMS"
+#define CLASS_SKIPJACK_RELAYX_PARAMS "sun/security/pkcs11/wrapper/CK_SKIPJACK_RELAYX_PARAMS"
+#define CLASS_KEY_WRAP_SET_OAEP_PARAMS "sun/security/pkcs11/wrapper/CK_KEY_WRAP_SET_OAEP_PARAMS"
+#define CLASS_KEY_DERIVATION_STRING_DATA "sun/security/pkcs11/wrapper/CK_KEY_DERIVATION_STRING_DATA"
+*/
+
+#define CLASS_SSL3_RANDOM_DATA "sun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA"
+// CLASS_SSL3_RANDOM_DATA is used by CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS
+#define CLASS_SSL3_KEY_MAT_OUT "sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT"
+// CLASS_SSL3_KEY_MAT_OUT is used by CLASS_SSL3_KEY_MAT_PARAMS
+#define CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_SSL3_MASTER_KEY_DERIVE_PARAMS"
+#define CLASS_SSL3_KEY_MAT_PARAMS "sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_PARAMS"
+#define CLASS_TLS_PRF_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS"
+#define CLASS_AES_CTR_PARAMS "sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS"
+
+/* function to convert a PKCS#11 return value other than CK_OK into a Java Exception
+ * or to throw a PKCS11RuntimeException
+ */
+
+jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue);
+void throwOutOfMemoryError(JNIEnv *env, const char *message);
+void throwNullPointerException(JNIEnv *env, const char *message);
+void throwIOException(JNIEnv *env, const char *message);
+void throwPKCS11RuntimeException(JNIEnv *env, const char *message);
+void throwDisconnectedRuntimeException(JNIEnv *env);
+
+/* function to free CK_ATTRIBUTE array
+ */
+void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len);
+
+/* funktions to convert Java arrays to a CK-type array and the array length */
+
+void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckLength);
+void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckLength);
+void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckLength);
+void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckLength);
+void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckLength);
+void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength);
+void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jAArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength);
+/*void jObjectArrayToCKVoidPtrArray(JNIEnv *env, const jobjectArray jArray, CK_VOID_PTR_PTR ckpArray, CK_ULONG_PTR ckpLength); */
+
+
+/* funktions to convert a CK-type array and the array length to a Java array */
+
+jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength);
+jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength);
+jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG length);
+jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength);
+
+
+/* funktions to convert a CK-type structure or a pointer to a CK-value to a Java object */
+
+jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL* ckpValue);
+jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue);
+jobject ckDatePtrToJDateObject(JNIEnv *env, const CK_DATE *ckpValue);
+jobject ckVersionPtrToJVersion(JNIEnv *env, const CK_VERSION_PTR ckpVersion);
+jobject ckSessionInfoPtrToJSessionInfo(JNIEnv *env, const CK_SESSION_INFO_PTR ckpSessionInfo);
+jobject ckAttributePtrToJAttribute(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute);
+
+
+/* funktion to convert the CK-value used by the CK_ATTRIBUTE structure to a Java object */
+
+jobject ckAttributeValueToJObject(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute);
+
+
+/* funktions to convert a Java object to a CK-type structure or a pointer to a CK-value */
+
+CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject);
+CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject);
+CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject);
+CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject);
+CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject);
+CK_VERSION_PTR jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion);
+CK_DATE * jDateObjectPtrToCKDatePtr(JNIEnv *env, jobject jDate);
+CK_ATTRIBUTE jAttributeToCKAttribute(JNIEnv *env, jobject jAttribute);
+/*CK_MECHANISM jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism);*/
+void jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism, CK_MECHANISM_PTR ckMechanismPtr);
+
+
+/* funktions to convert Java objects used by the Mechanism and Attribute class to a CK-type structure */
+
+void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *pLength);
+void jMechanismParameterToCKMechanismParameter(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength);
+
+
+/* functions to convert a specific Java mechanism parameter object to a CK-mechanism parameter structure */
+
+CK_RSA_PKCS_OAEP_PARAMS jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobject jParam);
+CK_KEA_DERIVE_PARAMS jKeaDeriveParamToCKKeaDeriveParam(JNIEnv *env, jobject jParam);
+CK_RC2_CBC_PARAMS jRc2CbcParamToCKRc2CbcParam(JNIEnv *env, jobject jParam);
+CK_RC2_MAC_GENERAL_PARAMS jRc2MacGeneralParamToCKRc2MacGeneralParam(JNIEnv *env, jobject jParam);
+CK_RC5_PARAMS jRc5ParamToCKRc5Param(JNIEnv *env, jobject jParam);
+CK_RC5_CBC_PARAMS jRc5CbcParamToCKRc5CbcParam(JNIEnv *env, jobject jParam);
+CK_RC5_MAC_GENERAL_PARAMS jRc5MacGeneralParamToCKRc5MacGeneralParam(JNIEnv *env, jobject jParam);
+CK_SKIPJACK_PRIVATE_WRAP_PARAMS jSkipjackPrivateWrapParamToCKSkipjackPrivateWrapParam(JNIEnv *env, jobject jParam);
+CK_SKIPJACK_RELAYX_PARAMS jSkipjackRelayxParamToCKSkipjackRelayxParam(JNIEnv *env, jobject jParam);
+CK_PBE_PARAMS jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam);
+void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
+CK_PKCS5_PBKD2_PARAMS jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject jParam);
+CK_KEY_WRAP_SET_OAEP_PARAMS jKeyWrapSetOaepParamToCKKeyWrapSetOaepParam(JNIEnv *env, jobject jParam);
+void copyBackSetUnwrappedKey(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
+CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam);
+void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
+CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam);
+void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
+CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam);
+CK_RSA_PKCS_PSS_PARAMS jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam);
+CK_ECDH1_DERIVE_PARAMS jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam);
+CK_ECDH2_DERIVE_PARAMS jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv *env, jobject jParam);
+CK_X9_42_DH1_DERIVE_PARAMS jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env, jobject jParam);
+CK_X9_42_DH2_DERIVE_PARAMS jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env, jobject jParam);
+
+
+/* functions to convert the InitArgs object for calling the right Java mutex functions */
+
+CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject pInitArgs);
+
+#ifndef NO_CALLBACKS /* if the library should not make callbacks; e.g. no javai.lib or jvm.lib available */
+CK_RV callJCreateMutex(CK_VOID_PTR_PTR ppMutex);
+CK_RV callJDestroyMutex(CK_VOID_PTR pMutex);
+CK_RV callJLockMutex(CK_VOID_PTR pMutex);
+CK_RV callJUnlockMutex(CK_VOID_PTR pMutex);
+#endif /* NO_CALLBACKS */
+
+void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData);
+ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
+CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation);
+
+/* A structure to encapsulate the required data for a Notify callback */
+struct NotifyEncapsulation {
+
+    /* The object that implements the CK_NOTIFY interface and which should be
+     * notified.
+     */
+    jobject jNotifyObject;
+
+    /* The data object to pass back to the Notify object upon callback. */
+    jobject jApplicationData;
+};
+typedef struct NotifyEncapsulation NotifyEncapsulation;
+
+/* The function for handling notify callbacks. */
+CK_RV notifyCallback(
+    CK_SESSION_HANDLE hSession,     /* the session's handle */
+    CK_NOTIFICATION   event,
+    CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
+);
+
+
+/* A node of the list of notify callbacks. To be able to free the resources after use. */
+struct NotifyListNode {
+
+    /* The handle of the session this notify object is attached to*/
+    CK_SESSION_HANDLE hSession;
+
+    /* Reference to the Notify encapsulation object that was passed to C_OpenSession. */
+    NotifyEncapsulation *notifyEncapsulation;
+
+    /* Pointer to the next node in the list. */
+    struct NotifyListNode *next;
+
+};
+typedef struct NotifyListNode NotifyListNode;
+
+void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation *notifyEncapsulation);
+NotifyEncapsulation * removeNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession);
+NotifyEncapsulation * removeFirstNotifyEntry(JNIEnv *env);
+
+jobject createLockObject(JNIEnv *env);
+void destroyLockObject(JNIEnv *env, jobject jLockObject);
+
+extern jfieldID pNativeDataID;
+extern jfieldID mech_mechanismID;
+extern jfieldID mech_pParameterID;
+
+extern jclass jByteArrayClass;
+extern jclass jLongClass;
+
+#ifndef NO_CALLBACKS
+extern NotifyListNode *notifyListHead;
+extern jobject notifyListLock;
+
+extern jobject jInitArgsObject;
+extern CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs;
+#endif /* NO_CALLBACKS */
+
+#ifdef P11_MEMORYDEBUG
+#include <stdlib.h>
+
+/* Simple malloc/free dumper */
+void *p11malloc(size_t c, char *file, int line);
+void p11free(void *p, char *file, int line);
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+    #define THIS_FILE __FILE__
+#endif
+
+#define malloc(c)       (p11malloc((c), THIS_FILE, __LINE__))
+#define free(c)         (p11free((c), THIS_FILE, __LINE__))
+
+#endif
+
+#endif /* _PKCS11WRAPPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/solaris/conf/security/sunpkcs11-solaris.cfg	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,23 @@
+#
+# Configuration file to allow the SunPKCS11 provider to utilize
+# the Solaris Cryptographic Framework, if it is available
+#
+
+name = Solaris
+
+description = SunPKCS11 accessing Solaris Cryptographic Framework
+
+library = /usr/lib/$ISA/libpkcs11.so
+
+handleStartupErrors = ignoreAll
+
+# Use the X9.63 encoding for EC points (do not wrap in an ASN.1 OctetString).
+useEcX963Encoding = true
+
+attributes = compatibility
+
+disabledMechanisms = {
+  CKM_DSA_KEY_PAIR_GEN
+  SecureRandom
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2005, 2016, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <dlfcn.h>
+
+#include <jni_util.h>
+
+#include "j2secmod.h"
+#include "pkcs11wrapper.h"
+
+void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
+    void *hModule = (void*)jlong_to_ptr(jHandle);
+    void *fAddress = dlsym(hModule, functionName);
+    if (fAddress == NULL) {
+        char errorMessage[256];
+        snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName);
+        throwNullPointerException(env, errorMessage);
+        return NULL;
+    }
+    return fAddress;
+}
+
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
+  (JNIEnv *env, jclass thisClass, jstring jLibName)
+{
+    void *hModule;
+    const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
+    if (libName == NULL) {
+        return 0L;
+    }
+
+    // look up existing handle only, do not load
+#if defined(AIX)
+    hModule = dlopen(libName, RTLD_LAZY);
+#else
+    hModule = dlopen(libName, RTLD_NOLOAD);
+#endif
+    dprintf2("-handle for %s: %u\n", libName, hModule);
+    (*env)->ReleaseStringUTFChars(env, jLibName, libName);
+    return ptr_to_jlong(hModule);
+}
+
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary
+  (JNIEnv *env, jclass thisClass, jstring jLibName)
+{
+    void *hModule;
+    const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
+    if (libName == NULL) {
+       return 0L;
+    }
+
+    dprintf1("-lib %s\n", libName);
+    hModule = dlopen(libName, RTLD_LAZY);
+    (*env)->ReleaseStringUTFChars(env, jLibName, libName);
+    dprintf2("-handle: %u (0X%X)\n", hModule, hModule);
+
+    if (hModule == NULL) {
+        throwIOException(env, dlerror());
+        return 0;
+    }
+
+    return ptr_to_jlong(hModule);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+// in nss.h:
+// extern PRBool NSS_VersionCheck(const char *importedVersion);
+// extern SECStatus NSS_Initialize(const char *configdir,
+//     const char *certPrefix, const char *keyPrefix,
+//     const char *secmodName, PRUint32 flags);
+
+typedef int (*FPTR_VersionCheck)(const char *importedVersion);
+typedef int (*FPTR_Initialize)(const char *configdir,
+        const char *certPrefix, const char *keyPrefix,
+        const char *secmodName, unsigned int flags);
+
+// in secmod.h
+//extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent,
+//                                                      PRBool recurse);
+//char **SECMOD_GetModuleSpecList(SECMODModule *module);
+//extern SECMODModuleList *SECMOD_GetDBModuleList(void);
+
+typedef void *(*FPTR_LoadModule)(char *moduleSpec, void *parent, int recurse);
+typedef char **(*FPTR_GetModuleSpecList)(void *module);
+typedef void *(*FPTR_GetDBModuleList)(void);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+/*
+ * pkcs11wrapper.c
+ * 18.05.2001
+ *
+ * This module contains the native functions of the Java to PKCS#11 interface
+ * which are platform dependent. This includes loading a dynamic link libary,
+ * retrieving the function list and unloading the dynamic link library.
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <dlfcn.h>
+
+#include <jni.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    connect
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
+    (JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList)
+{
+    void *hModule;
+    char *error;
+    CK_C_GetFunctionList C_GetFunctionList=NULL;
+    CK_RV rv;
+    ModuleData *moduleData;
+    jobject globalPKCS11ImplementationReference;
+    char *systemErrorMessage;
+    char *exceptionMessage;
+    const char *getFunctionListStr;
+
+    const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0);
+    if (libraryNameStr == NULL) {
+        return;
+    }
+    TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
+
+
+    /*
+     * Load the PKCS #11 DLL
+     */
+    dlerror(); /* clear any old error message not fetched */
+#ifdef DEBUG
+    hModule = dlopen(libraryNameStr, RTLD_NOW);
+#else
+    hModule = dlopen(libraryNameStr, RTLD_LAZY);
+#endif /* DEBUG */
+
+    if (hModule == NULL) {
+        systemErrorMessage = dlerror();
+        exceptionMessage = (char *) malloc(sizeof(char) * (strlen(systemErrorMessage) + strlen(libraryNameStr) + 1));
+        if (exceptionMessage == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return;
+        }
+        strcpy(exceptionMessage, systemErrorMessage);
+        strcat(exceptionMessage, libraryNameStr);
+        throwIOException(env, exceptionMessage);
+        (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
+        free(exceptionMessage);
+        return;
+    }
+
+    /*
+     * Get function pointer to C_GetFunctionList
+     */
+    dlerror(); /* clear any old error message not fetched */
+    // with the old JAR file jGetFunctionList is null, temporarily check for that
+    if (jGetFunctionList != NULL) {
+        getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
+        if (getFunctionListStr == NULL) {
+            return;
+        }
+        C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr);
+        (*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
+    }
+    if (C_GetFunctionList == NULL) {
+        throwIOException(env, "ERROR: C_GetFunctionList == NULL");
+        return;
+    } else if ( (systemErrorMessage = dlerror()) != NULL ){
+        throwIOException(env, systemErrorMessage);
+        return;
+    }
+
+    /*
+     * Get function pointers to all PKCS #11 functions
+     */
+    moduleData = (ModuleData *) malloc(sizeof(ModuleData));
+    if (moduleData == NULL) {
+        dlclose(hModule);
+        throwOutOfMemoryError(env, 0);
+        return;
+    }
+    moduleData->hModule = hModule;
+    moduleData->applicationMutexHandler = NULL;
+    rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
+    globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
+    putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
+
+    (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
+    TRACE0("FINISHED\n");
+
+    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    disconnect
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_disconnect
+    (JNIEnv *env, jobject obj)
+{
+    ModuleData *moduleData;
+    TRACE0("DEBUG: disconnecting module...");
+    moduleData = removeModuleEntry(env, obj);
+
+    if (moduleData != NULL) {
+        dlclose(moduleData->hModule);
+    }
+
+    free(moduleData);
+    TRACE0("FINISHED\n");
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,90 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+/*
+ * pkcs11wrapper.h
+ * 18.05.2001
+ *
+ * declaration of all functions used by pkcs11wrapper.c
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+
+/* defines for UNIX platforms *************************************************/
+
+#ifndef _P11_MD_H
+#define _P11_MD_H 1
+
+#define CK_PTR *
+#define CK_DEFINE_FUNCTION(returnType, name) returnType name
+#define CK_DECLARE_FUNCTION(returnType, name) returnType name
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif
+
+#include "pkcs11.h"
+
+#include "jni.h"
+
+/* A data structure to hold required information about a PKCS#11 module. */
+struct ModuleData {
+
+    /* the module (DLL or shared library) handle */
+    void *hModule;
+
+    /* The pointer to the PKCS#11 functions of this module. */
+    CK_FUNCTION_LIST_PTR ckFunctionListPtr;
+
+    /* Reference to the object to use for mutex handling. NULL, if not used. */
+    jobject applicationMutexHandler;
+
+};
+typedef struct ModuleData ModuleData;
+
+#endif  /* _P11_MD_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2005, 2011, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <jni_util.h>
+
+#include "j2secmod.h"
+
+extern void throwNullPointerException(JNIEnv *env, const char *message);
+extern void throwIOException(JNIEnv *env, const char *message);
+
+void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
+    HINSTANCE hModule = (HINSTANCE)jHandle;
+    void *fAddress = GetProcAddress(hModule, functionName);
+    if (fAddress == NULL) {
+        char errorMessage[256];
+        _snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName);
+        throwNullPointerException(env, errorMessage);
+        return NULL;
+    }
+    return fAddress;
+}
+
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
+  (JNIEnv *env, jclass thisClass, jstring jLibName)
+{
+    const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
+    HMODULE hModule = GetModuleHandle(libName);
+    dprintf2("-handle for %s: %d\n", libName, hModule);
+    (*env)->ReleaseStringUTFChars(env, jLibName, libName);
+    return (jlong)hModule;
+}
+
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary
+  (JNIEnv *env, jclass thisClass, jstring jName)
+{
+    HINSTANCE hModule;
+    LPVOID lpMsgBuf;
+
+    const char *libName = (*env)->GetStringUTFChars(env, jName, NULL);
+    dprintf1("-lib %s\n", libName);
+
+    hModule = LoadLibrary(libName);
+    (*env)->ReleaseStringUTFChars(env, jName, libName);
+
+    if (hModule == NULL) {
+        FormatMessage(
+            FORMAT_MESSAGE_ALLOCATE_BUFFER |
+            FORMAT_MESSAGE_FROM_SYSTEM |
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+            NULL,
+            GetLastError(),
+            0, /* Default language */
+            (LPTSTR) &lpMsgBuf,
+            0,
+            NULL
+        );
+        dprintf1("-error: %s\n", lpMsgBuf);
+        throwIOException(env, (char*)lpMsgBuf);
+        LocalFree(lpMsgBuf);
+        return 0;
+    }
+    dprintf2("-handle: %d (0X%X)\n", hModule, hModule);
+    return (jlong)hModule;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2005, 2013, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+#include <windows.h>
+
+// in nss.h:
+// extern PRBool NSS_VersionCheck(const char *importedVersion);
+// extern SECStatus NSS_Initialize(const char *configdir,
+//      const char *certPrefix, const char *keyPrefix,
+//      const char *secmodName, PRUint32 flags);
+
+typedef int __declspec(dllimport) (*FPTR_VersionCheck)(const char *importedVersion);
+typedef int __declspec(dllimport) (*FPTR_Initialize)(const char *configdir,
+        const char *certPrefix, const char *keyPrefix,
+        const char *secmodName, unsigned int flags);
+
+// in secmod.h
+//extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent,
+//                                                      PRBool recurse);
+//char **SECMOD_GetModuleSpecList(SECMODModule *module);
+//extern SECMODModuleList *SECMOD_GetDBModuleList(void);
+
+typedef void __declspec(dllimport) *(*FPTR_LoadModule)(char *moduleSpec, void *parent, int recurse);
+typedef char __declspec(dllimport) **(*FPTR_GetModuleSpecList)(void *module);
+typedef void __declspec(dllimport) *(*FPTR_GetDBModuleList)(void);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+/*
+ * pkcs11wrapper.c
+ * 18.05.2001
+ *
+ * This module contains the native functions of the Java to PKCS#11 interface
+ * which are platform dependent. This includes loading a dynamic link libary,
+ * retrieving the function list and unloading the dynamic link library.
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <windows.h>
+
+#include <jni.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    connect
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
+    (JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList)
+{
+    HINSTANCE hModule;
+    CK_C_GetFunctionList C_GetFunctionList;
+    CK_RV rv;
+    ModuleData *moduleData;
+    jobject globalPKCS11ImplementationReference;
+    LPVOID lpMsgBuf;
+    char *exceptionMessage;
+    const char *getFunctionListStr;
+
+    const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0);
+    TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
+
+
+  /*
+   * Load the PKCS #11 DLL
+   */
+    hModule = LoadLibrary(libraryNameStr);
+    if (hModule == NULL) {
+        FormatMessage(
+            FORMAT_MESSAGE_ALLOCATE_BUFFER |
+            FORMAT_MESSAGE_FROM_SYSTEM |
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+            NULL,
+            GetLastError(),
+            0, /* Default language */
+            (LPTSTR) &lpMsgBuf,
+            0,
+            NULL
+        );
+        exceptionMessage = (char *) malloc(sizeof(char) * (strlen((LPTSTR) lpMsgBuf) + strlen(libraryNameStr) + 1));
+        strcpy(exceptionMessage, (LPTSTR) lpMsgBuf);
+        strcat(exceptionMessage, libraryNameStr);
+        throwIOException(env, (LPTSTR) exceptionMessage);
+        /* Free the buffer. */
+        free(exceptionMessage);
+        LocalFree(lpMsgBuf);
+        return;
+    }
+
+    /*
+     * Get function pointer to C_GetFunctionList
+     */
+    getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
+    C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule, getFunctionListStr);
+    (*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
+    if (C_GetFunctionList == NULL) {
+        FormatMessage(
+            FORMAT_MESSAGE_ALLOCATE_BUFFER |
+            FORMAT_MESSAGE_FROM_SYSTEM |
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+            NULL,
+            GetLastError(),
+            0, /* Default language */
+            (LPTSTR) &lpMsgBuf,
+            0,
+            NULL
+        );
+        throwIOException(env, (LPTSTR) lpMsgBuf);
+        /* Free the buffer. */
+        LocalFree( lpMsgBuf );
+        return;
+    }
+
+    /*
+     * Get function pointers to all PKCS #11 functions
+     */
+    moduleData = (ModuleData *) malloc(sizeof(ModuleData));
+    moduleData->hModule = hModule;
+    moduleData->applicationMutexHandler = NULL;
+    rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
+    globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
+    putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
+
+    (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
+    TRACE0("FINISHED\n");
+
+    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    disconnect
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_disconnect
+    (JNIEnv *env, jobject obj)
+{
+    ModuleData *moduleData;
+    TRACE0("DEBUG: disconnecting module...");
+    moduleData = removeModuleEntry(env, obj);
+
+    if (moduleData != NULL) {
+        FreeLibrary(moduleData->hModule);
+    }
+
+    free(moduleData);
+    TRACE0("FINISHED\n");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h	Mon Jan 23 11:49:01 2017 -0800
@@ -0,0 +1,98 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+/*
+ * platoform.h
+ * 10.12.2001
+ *
+ * declaration of all platform dependent functions used by pkcs11wrapper.c
+ *
+ * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
+ */
+
+/* defines for WIN32 platform *************************************************/
+
+#include <windows.h>
+
+/* statement according to PKCS11 docu */
+#pragma pack(push, cryptoki, 1)
+
+/* definitions according to PKCS#11 docu for Win32 environment */
+#define CK_PTR *
+#define CK_DEFINE_FUNCTION(returnType, name) returnType __declspec(dllexport) name
+#define CK_DECLARE_FUNCTION(returnType, name) returnType __declspec(dllimport) name
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType __declspec(dllimport) (* name)
+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif /* NULL_PTR */
+
+/* to avoid clash with Win32 #define */
+#ifdef CreateMutex
+#undef CreateMutex
+#endif /* CreateMutex */
+
+#include "pkcs11.h"
+
+/* statement according to PKCS11 docu */
+#pragma pack(pop, cryptoki)
+
+#include "jni.h"
+
+/* A data structure to hold required information about a PKCS#11 module. */
+struct ModuleData {
+
+    HINSTANCE hModule;
+
+    /* The pointer to the PKCS#11 functions of this module. */
+    CK_FUNCTION_LIST_PTR ckFunctionListPtr;
+
+    /* Reference to the object to use for mutex handling. NULL, if not used. */
+    jobject applicationMutexHandler;
+
+};
+typedef struct ModuleData ModuleData;
--- a/jdk/src/jdk.crypto.token/share/classes/module-info.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2014, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-module jdk.crypto.token {
-    // Depends on SunEC provider for EC related functionality
-    requires jdk.crypto.ec;
-    provides java.security.Provider with sun.security.pkcs11.SunPKCS11;
-}
-
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/Config.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1008 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.io.*;
-import static java.io.StreamTokenizer.*;
-import java.math.BigInteger;
-import java.util.*;
-
-import java.security.*;
-
-import sun.security.util.PropertyExpander;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-import static sun.security.pkcs11.wrapper.CK_ATTRIBUTE.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-
-/**
- * Configuration container and file parsing.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class Config {
-
-    static final int ERR_HALT       = 1;
-    static final int ERR_IGNORE_ALL = 2;
-    static final int ERR_IGNORE_LIB = 3;
-
-    // same as allowSingleThreadedModules but controlled via a system property
-    // and applied to all providers. if set to false, no SunPKCS11 instances
-    // will accept single threaded modules regardless of the setting in their
-    // config files.
-    private static final boolean staticAllowSingleThreadedModules;
-    private static final String osName;
-    private static final String osArch;
-
-    static {
-        List<String> props = AccessController.doPrivileged(
-            new PrivilegedAction<>() {
-                @Override
-                public List<String> run() {
-                    return List.of(
-                        System.getProperty(
-                            "sun.security.pkcs11.allowSingleThreadedModules",
-                            "true"),
-                        System.getProperty("os.name"),
-                        System.getProperty("os.arch"));
-                }
-            }
-        );
-        if ("false".equalsIgnoreCase(props.get(0))) {
-            staticAllowSingleThreadedModules = false;
-        } else {
-            staticAllowSingleThreadedModules = true;
-        }
-        osName = props.get(1);
-        osArch = props.get(2);
-    }
-
-    private final static boolean DEBUG = false;
-
-    private static void debug(Object o) {
-        if (DEBUG) {
-            System.out.println(o);
-        }
-    }
-
-    // file name containing this configuration
-    private String filename;
-
-    // Reader and StringTokenizer used during parsing
-    private Reader reader;
-
-    private StreamTokenizer st;
-
-    private Set<String> parsedKeywords;
-
-    // name suffix of the provider
-    private String name;
-
-    // name of the PKCS#11 library
-    private String library;
-
-    // description to pass to the provider class
-    private String description;
-
-    // slotID of the slot to use
-    private int slotID = -1;
-
-    // slot to use, specified as index in the slotlist
-    private int slotListIndex = -1;
-
-    // set of enabled mechanisms (or null to use default)
-    private Set<Long> enabledMechanisms;
-
-    // set of disabled mechanisms
-    private Set<Long> disabledMechanisms;
-
-    // whether to print debug info during startup
-    private boolean showInfo = false;
-
-    // template manager, initialized from parsed attributes
-    private TemplateManager templateManager;
-
-    // how to handle error during startup, one of ERR_
-    private int handleStartupErrors = ERR_HALT;
-
-    // flag indicating whether the P11KeyStore should
-    // be more tolerant of input parameters
-    private boolean keyStoreCompatibilityMode = true;
-
-    // flag indicating whether we need to explicitly cancel operations
-    // see Token
-    private boolean explicitCancel = true;
-
-    // how often to test for token insertion, if no token is present
-    private int insertionCheckInterval = 2000;
-
-    // flag inidicating whether to omit the call to C_Initialize()
-    // should be used only if we are running within a process that
-    // has already called it (e.g. Plugin inside of Mozilla/NSS)
-    private boolean omitInitialize = false;
-
-    // whether to allow modules that only support single threaded access.
-    // they cannot be used safely from multiple PKCS#11 consumers in the
-    // same process, for example NSS and SunPKCS11
-    private boolean allowSingleThreadedModules = true;
-
-    // name of the C function that returns the PKCS#11 functionlist
-    // This option primarily exists for the deprecated
-    // Secmod.Module.getProvider() method.
-    private String functionList = "C_GetFunctionList";
-
-    // whether to use NSS secmod mode. Implicitly set if nssLibraryDirectory,
-    // nssSecmodDirectory, or nssModule is specified.
-    private boolean nssUseSecmod;
-
-    // location of the NSS library files (libnss3.so, etc.)
-    private String nssLibraryDirectory;
-
-    // location of secmod.db
-    private String nssSecmodDirectory;
-
-    // which NSS module to use
-    private String nssModule;
-
-    private Secmod.DbMode nssDbMode = Secmod.DbMode.READ_WRITE;
-
-    // Whether the P11KeyStore should specify the CKA_NETSCAPE_DB attribute
-    // when creating private keys. Only valid if nssUseSecmod is true.
-    private boolean nssNetscapeDbWorkaround = true;
-
-    // Special init argument string for the NSS softtoken.
-    // This is used when using the NSS softtoken directly without secmod mode.
-    private String nssArgs;
-
-    // whether to use NSS trust attributes for the KeyStore of this provider
-    // this option is for internal use by the SunPKCS11 code only and
-    // works only for NSS providers created via the Secmod API
-    private boolean nssUseSecmodTrust = false;
-
-    // Flag to indicate whether the X9.63 encoding for EC points shall be used
-    // (true) or whether that encoding shall be wrapped in an ASN.1 OctetString
-    // (false).
-    private boolean useEcX963Encoding = false;
-
-    // Flag to indicate whether NSS should favour performance (false) or
-    // memory footprint (true).
-    private boolean nssOptimizeSpace = false;
-
-    Config(String fn) throws IOException {
-        this.filename = fn;
-        if (filename.startsWith("--")) {
-            // inline config
-            String config = filename.substring(2).replace("\\n", "\n");
-            reader = new StringReader(config);
-        } else {
-            reader = new BufferedReader(new InputStreamReader
-                (new FileInputStream(expand(filename))));
-        }
-        parsedKeywords = new HashSet<String>();
-        st = new StreamTokenizer(reader);
-        setupTokenizer();
-        parse();
-    }
-
-    String getFileName() {
-        return filename;
-    }
-
-    String getName() {
-        return name;
-    }
-
-    String getLibrary() {
-        return library;
-    }
-
-    String getDescription() {
-        if (description != null) {
-            return description;
-        }
-        return "SunPKCS11-" + name + " using library " + library;
-    }
-
-    int getSlotID() {
-        return slotID;
-    }
-
-    int getSlotListIndex() {
-        if ((slotID == -1) && (slotListIndex == -1)) {
-            // if neither is set, default to first slot
-            return 0;
-        } else {
-            return slotListIndex;
-        }
-    }
-
-    boolean getShowInfo() {
-        return (SunPKCS11.debug != null) || showInfo;
-    }
-
-    TemplateManager getTemplateManager() {
-        if (templateManager == null) {
-            templateManager = new TemplateManager();
-        }
-        return templateManager;
-    }
-
-    boolean isEnabled(long m) {
-        if (enabledMechanisms != null) {
-            return enabledMechanisms.contains(Long.valueOf(m));
-        }
-        if (disabledMechanisms != null) {
-            return !disabledMechanisms.contains(Long.valueOf(m));
-        }
-        return true;
-    }
-
-    int getHandleStartupErrors() {
-        return handleStartupErrors;
-    }
-
-    boolean getKeyStoreCompatibilityMode() {
-        return keyStoreCompatibilityMode;
-    }
-
-    boolean getExplicitCancel() {
-        return explicitCancel;
-    }
-
-    int getInsertionCheckInterval() {
-        return insertionCheckInterval;
-    }
-
-    boolean getOmitInitialize() {
-        return omitInitialize;
-    }
-
-    boolean getAllowSingleThreadedModules() {
-        return staticAllowSingleThreadedModules && allowSingleThreadedModules;
-    }
-
-    String getFunctionList() {
-        return functionList;
-    }
-
-    boolean getNssUseSecmod() {
-        return nssUseSecmod;
-    }
-
-    String getNssLibraryDirectory() {
-        return nssLibraryDirectory;
-    }
-
-    String getNssSecmodDirectory() {
-        return nssSecmodDirectory;
-    }
-
-    String getNssModule() {
-        return nssModule;
-    }
-
-    Secmod.DbMode getNssDbMode() {
-        return nssDbMode;
-    }
-
-    public boolean getNssNetscapeDbWorkaround() {
-        return nssUseSecmod && nssNetscapeDbWorkaround;
-    }
-
-    String getNssArgs() {
-        return nssArgs;
-    }
-
-    boolean getNssUseSecmodTrust() {
-        return nssUseSecmodTrust;
-    }
-
-    boolean getUseEcX963Encoding() {
-        return useEcX963Encoding;
-    }
-
-    boolean getNssOptimizeSpace() {
-        return nssOptimizeSpace;
-    }
-
-    private static String expand(final String s) throws IOException {
-        try {
-            return PropertyExpander.expand(s);
-        } catch (Exception e) {
-            throw new RuntimeException(e.getMessage());
-        }
-    }
-
-    private void setupTokenizer() {
-        st.resetSyntax();
-        st.wordChars('a', 'z');
-        st.wordChars('A', 'Z');
-        st.wordChars('0', '9');
-        st.wordChars(':', ':');
-        st.wordChars('.', '.');
-        st.wordChars('_', '_');
-        st.wordChars('-', '-');
-        st.wordChars('/', '/');
-        st.wordChars('\\', '\\');
-        st.wordChars('$', '$');
-        st.wordChars('{', '{'); // need {} for property subst
-        st.wordChars('}', '}');
-        st.wordChars('*', '*');
-        st.wordChars('+', '+');
-        st.wordChars('~', '~');
-        // XXX check ASCII table and add all other characters except special
-
-        // special: #="(),
-        st.whitespaceChars(0, ' ');
-        st.commentChar('#');
-        st.eolIsSignificant(true);
-        st.quoteChar('\"');
-    }
-
-    private ConfigurationException excToken(String msg) {
-        return new ConfigurationException(msg + " " + st);
-    }
-
-    private ConfigurationException excLine(String msg) {
-        return new ConfigurationException(msg + ", line " + st.lineno());
-    }
-
-    private void parse() throws IOException {
-        while (true) {
-            int token = nextToken();
-            if (token == TT_EOF) {
-                break;
-            }
-            if (token == TT_EOL) {
-                continue;
-            }
-            if (token != TT_WORD) {
-                throw excToken("Unexpected token:");
-            }
-            String word = st.sval;
-            if (word.equals("name")) {
-                name = parseStringEntry(word);
-            } else if (word.equals("library")) {
-                library = parseLibrary(word);
-            } else if (word.equals("description")) {
-                parseDescription(word);
-            } else if (word.equals("slot")) {
-                parseSlotID(word);
-            } else if (word.equals("slotListIndex")) {
-                parseSlotListIndex(word);
-            } else if (word.equals("enabledMechanisms")) {
-                parseEnabledMechanisms(word);
-            } else if (word.equals("disabledMechanisms")) {
-                parseDisabledMechanisms(word);
-            } else if (word.equals("attributes")) {
-                parseAttributes(word);
-            } else if (word.equals("handleStartupErrors")) {
-                parseHandleStartupErrors(word);
-            } else if (word.endsWith("insertionCheckInterval")) {
-                insertionCheckInterval = parseIntegerEntry(word);
-                if (insertionCheckInterval < 100) {
-                    throw excLine(word + " must be at least 100 ms");
-                }
-            } else if (word.equals("showInfo")) {
-                showInfo = parseBooleanEntry(word);
-            } else if (word.equals("keyStoreCompatibilityMode")) {
-                keyStoreCompatibilityMode = parseBooleanEntry(word);
-            } else if (word.equals("explicitCancel")) {
-                explicitCancel = parseBooleanEntry(word);
-            } else if (word.equals("omitInitialize")) {
-                omitInitialize = parseBooleanEntry(word);
-            } else if (word.equals("allowSingleThreadedModules")) {
-                allowSingleThreadedModules = parseBooleanEntry(word);
-            } else if (word.equals("functionList")) {
-                functionList = parseStringEntry(word);
-            } else if (word.equals("nssUseSecmod")) {
-                nssUseSecmod = parseBooleanEntry(word);
-            } else if (word.equals("nssLibraryDirectory")) {
-                nssLibraryDirectory = parseLibrary(word);
-                nssUseSecmod = true;
-            } else if (word.equals("nssSecmodDirectory")) {
-                nssSecmodDirectory = expand(parseStringEntry(word));
-                nssUseSecmod = true;
-            } else if (word.equals("nssModule")) {
-                nssModule = parseStringEntry(word);
-                nssUseSecmod = true;
-            } else if (word.equals("nssDbMode")) {
-                String mode = parseStringEntry(word);
-                if (mode.equals("readWrite")) {
-                    nssDbMode = Secmod.DbMode.READ_WRITE;
-                } else if (mode.equals("readOnly")) {
-                    nssDbMode = Secmod.DbMode.READ_ONLY;
-                } else if (mode.equals("noDb")) {
-                    nssDbMode = Secmod.DbMode.NO_DB;
-                } else {
-                    throw excToken("nssDbMode must be one of readWrite, readOnly, and noDb:");
-                }
-                nssUseSecmod = true;
-            } else if (word.equals("nssNetscapeDbWorkaround")) {
-                nssNetscapeDbWorkaround = parseBooleanEntry(word);
-                nssUseSecmod = true;
-            } else if (word.equals("nssArgs")) {
-                parseNSSArgs(word);
-            } else if (word.equals("nssUseSecmodTrust")) {
-                nssUseSecmodTrust = parseBooleanEntry(word);
-            } else if (word.equals("useEcX963Encoding")) {
-                useEcX963Encoding = parseBooleanEntry(word);
-            } else if (word.equals("nssOptimizeSpace")) {
-                nssOptimizeSpace = parseBooleanEntry(word);
-            } else {
-                throw new ConfigurationException
-                        ("Unknown keyword '" + word + "', line " + st.lineno());
-            }
-            parsedKeywords.add(word);
-        }
-        reader.close();
-        reader = null;
-        st = null;
-        parsedKeywords = null;
-        if (name == null) {
-            throw new ConfigurationException("name must be specified");
-        }
-        if (nssUseSecmod == false) {
-            if (library == null) {
-                throw new ConfigurationException("library must be specified");
-            }
-        } else {
-            if (library != null) {
-                throw new ConfigurationException
-                    ("library must not be specified in NSS mode");
-            }
-            if ((slotID != -1) || (slotListIndex != -1)) {
-                throw new ConfigurationException
-                    ("slot and slotListIndex must not be specified in NSS mode");
-            }
-            if (nssArgs != null) {
-                throw new ConfigurationException
-                    ("nssArgs must not be specified in NSS mode");
-            }
-            if (nssUseSecmodTrust != false) {
-                throw new ConfigurationException("nssUseSecmodTrust is an "
-                    + "internal option and must not be specified in NSS mode");
-            }
-        }
-    }
-
-    //
-    // Parsing helper methods
-    //
-
-    private int nextToken() throws IOException {
-        int token = st.nextToken();
-        debug(st);
-        return token;
-    }
-
-    private void parseEquals() throws IOException {
-        int token = nextToken();
-        if (token != '=') {
-            throw excToken("Expected '=', read");
-        }
-    }
-
-    private void parseOpenBraces() throws IOException {
-        while (true) {
-            int token = nextToken();
-            if (token == TT_EOL) {
-                continue;
-            }
-            if ((token == TT_WORD) && st.sval.equals("{")) {
-                return;
-            }
-            throw excToken("Expected '{', read");
-        }
-    }
-
-    private boolean isCloseBraces(int token) {
-        return (token == TT_WORD) && st.sval.equals("}");
-    }
-
-    private String parseWord() throws IOException {
-        int token = nextToken();
-        if (token != TT_WORD) {
-            throw excToken("Unexpected value:");
-        }
-        return st.sval;
-    }
-
-    private String parseStringEntry(String keyword) throws IOException {
-        checkDup(keyword);
-        parseEquals();
-
-        int token = nextToken();
-        if (token != TT_WORD && token != '\"') {
-            // not a word token nor a string enclosed by double quotes
-            throw excToken("Unexpected value:");
-        }
-        String value = st.sval;
-
-        debug(keyword + ": " + value);
-        return value;
-    }
-
-    private boolean parseBooleanEntry(String keyword) throws IOException {
-        checkDup(keyword);
-        parseEquals();
-        boolean value = parseBoolean();
-        debug(keyword + ": " + value);
-        return value;
-    }
-
-    private int parseIntegerEntry(String keyword) throws IOException {
-        checkDup(keyword);
-        parseEquals();
-        int value = decodeNumber(parseWord());
-        debug(keyword + ": " + value);
-        return value;
-    }
-
-    private boolean parseBoolean() throws IOException {
-        String val = parseWord();
-        switch (val) {
-            case "true":
-                return true;
-            case "false":
-                return false;
-            default:
-                throw excToken("Expected boolean value, read:");
-        }
-    }
-
-    private String parseLine() throws IOException {
-        // allow quoted string as part of line
-        String s = null;
-        while (true) {
-            int token = nextToken();
-            if ((token == TT_EOL) || (token == TT_EOF)) {
-                break;
-            }
-            if (token != TT_WORD && token != '\"') {
-                throw excToken("Unexpected value");
-            }
-            if (s == null) {
-                s = st.sval;
-            } else {
-                s = s + " " + st.sval;
-            }
-        }
-        if (s == null) {
-            throw excToken("Unexpected empty line");
-        }
-        return s;
-    }
-
-    private int decodeNumber(String str) throws IOException {
-        try {
-            if (str.startsWith("0x") || str.startsWith("0X")) {
-                return Integer.parseInt(str.substring(2), 16);
-            } else {
-                return Integer.parseInt(str);
-            }
-        } catch (NumberFormatException e) {
-            throw excToken("Expected number, read");
-        }
-    }
-
-    private static boolean isNumber(String s) {
-        if (s.length() == 0) {
-            return false;
-        }
-        char ch = s.charAt(0);
-        return ((ch >= '0') && (ch <= '9'));
-    }
-
-    private void parseComma() throws IOException {
-        int token = nextToken();
-        if (token != ',') {
-            throw excToken("Expected ',', read");
-        }
-    }
-
-    private static boolean isByteArray(String val) {
-        return val.startsWith("0h");
-    }
-
-    private byte[] decodeByteArray(String str) throws IOException {
-        if (str.startsWith("0h") == false) {
-            throw excToken("Expected byte array value, read");
-        }
-        str = str.substring(2);
-        // XXX proper hex parsing
-        try {
-            return new BigInteger(str, 16).toByteArray();
-        } catch (NumberFormatException e) {
-            throw excToken("Expected byte array value, read");
-        }
-    }
-
-    private void checkDup(String keyword) throws IOException {
-        if (parsedKeywords.contains(keyword)) {
-            throw excLine(keyword + " must only be specified once");
-        }
-    }
-
-    //
-    // individual entry parsing methods
-    //
-
-    private String parseLibrary(String keyword) throws IOException {
-        checkDup(keyword);
-        parseEquals();
-        String lib = parseLine();
-        lib = expand(lib);
-        int i = lib.indexOf("/$ISA/");
-        if (i != -1) {
-            // replace "/$ISA/" with "/sparcv9/" on 64-bit Solaris SPARC
-            // and with "/amd64/" on Solaris AMD64.
-            // On all other platforms, just turn it into a "/"
-            String prefix = lib.substring(0, i);
-            String suffix = lib.substring(i + 5);
-            if (osName.equals("SunOS") && osArch.equals("sparcv9")) {
-                lib = prefix + "/sparcv9" + suffix;
-            } else if (osName.equals("SunOS") && osArch.equals("amd64")) {
-                lib = prefix + "/amd64" + suffix;
-            } else {
-                lib = prefix + suffix;
-            }
-        }
-        debug(keyword + ": " + lib);
-
-        // Check to see if full path is specified to prevent the DLL
-        // preloading attack
-        if (!(new File(lib)).isAbsolute()) {
-            throw new ConfigurationException(
-                "Absolute path required for library value: " + lib);
-        }
-        return lib;
-    }
-
-    private void parseDescription(String keyword) throws IOException {
-        checkDup(keyword);
-        parseEquals();
-        description = parseLine();
-        debug("description: " + description);
-    }
-
-    private void parseSlotID(String keyword) throws IOException {
-        if (slotID >= 0) {
-            throw excLine("Duplicate slot definition");
-        }
-        if (slotListIndex >= 0) {
-            throw excLine
-                ("Only one of slot and slotListIndex must be specified");
-        }
-        parseEquals();
-        String slotString = parseWord();
-        slotID = decodeNumber(slotString);
-        debug("slot: " + slotID);
-    }
-
-    private void parseSlotListIndex(String keyword) throws IOException {
-        if (slotListIndex >= 0) {
-            throw excLine("Duplicate slotListIndex definition");
-        }
-        if (slotID >= 0) {
-            throw excLine
-                ("Only one of slot and slotListIndex must be specified");
-        }
-        parseEquals();
-        String slotString = parseWord();
-        slotListIndex = decodeNumber(slotString);
-        debug("slotListIndex: " + slotListIndex);
-    }
-
-    private void parseEnabledMechanisms(String keyword) throws IOException {
-        enabledMechanisms = parseMechanisms(keyword);
-    }
-
-    private void parseDisabledMechanisms(String keyword) throws IOException {
-        disabledMechanisms = parseMechanisms(keyword);
-    }
-
-    private Set<Long> parseMechanisms(String keyword) throws IOException {
-        checkDup(keyword);
-        Set<Long> mechs = new HashSet<Long>();
-        parseEquals();
-        parseOpenBraces();
-        while (true) {
-            int token = nextToken();
-            if (isCloseBraces(token)) {
-                break;
-            }
-            if (token == TT_EOL) {
-                continue;
-            }
-            if (token != TT_WORD) {
-                throw excToken("Expected mechanism, read");
-            }
-            long mech = parseMechanism(st.sval);
-            mechs.add(Long.valueOf(mech));
-        }
-        if (DEBUG) {
-            System.out.print("mechanisms: [");
-            for (Long mech : mechs) {
-                System.out.print(Functions.getMechanismName(mech));
-                System.out.print(", ");
-            }
-            System.out.println("]");
-        }
-        return mechs;
-    }
-
-    private long parseMechanism(String mech) throws IOException {
-        if (isNumber(mech)) {
-            return decodeNumber(mech);
-        } else {
-            try {
-                return Functions.getMechanismId(mech);
-            } catch (IllegalArgumentException e) {
-                throw excLine("Unknown mechanism: " + mech);
-            }
-        }
-    }
-
-    private void parseAttributes(String keyword) throws IOException {
-        if (templateManager == null) {
-            templateManager = new TemplateManager();
-        }
-        int token = nextToken();
-        if (token == '=') {
-            String s = parseWord();
-            if (s.equals("compatibility") == false) {
-                throw excLine("Expected 'compatibility', read " + s);
-            }
-            setCompatibilityAttributes();
-            return;
-        }
-        if (token != '(') {
-            throw excToken("Expected '(' or '=', read");
-        }
-        String op = parseOperation();
-        parseComma();
-        long objectClass = parseObjectClass();
-        parseComma();
-        long keyAlg = parseKeyAlgorithm();
-        token = nextToken();
-        if (token != ')') {
-            throw excToken("Expected ')', read");
-        }
-        parseEquals();
-        parseOpenBraces();
-        List<CK_ATTRIBUTE> attributes = new ArrayList<CK_ATTRIBUTE>();
-        while (true) {
-            token = nextToken();
-            if (isCloseBraces(token)) {
-                break;
-            }
-            if (token == TT_EOL) {
-                continue;
-            }
-            if (token != TT_WORD) {
-                throw excToken("Expected mechanism, read");
-            }
-            String attributeName = st.sval;
-            long attributeId = decodeAttributeName(attributeName);
-            parseEquals();
-            String attributeValue = parseWord();
-            attributes.add(decodeAttributeValue(attributeId, attributeValue));
-        }
-        templateManager.addTemplate
-                (op, objectClass, keyAlg, attributes.toArray(CK_A0));
-    }
-
-    private void setCompatibilityAttributes() {
-        // all secret keys
-        templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, PCKK_ANY,
-        new CK_ATTRIBUTE[] {
-            TOKEN_FALSE,
-            SENSITIVE_FALSE,
-            EXTRACTABLE_TRUE,
-            ENCRYPT_TRUE,
-            DECRYPT_TRUE,
-            WRAP_TRUE,
-            UNWRAP_TRUE,
-        });
-
-        // generic secret keys are special
-        // They are used as MAC keys plus for the SSL/TLS (pre)master secrets
-        templateManager.addTemplate(O_ANY, CKO_SECRET_KEY, CKK_GENERIC_SECRET,
-        new CK_ATTRIBUTE[] {
-            SIGN_TRUE,
-            VERIFY_TRUE,
-            ENCRYPT_NULL,
-            DECRYPT_NULL,
-            WRAP_NULL,
-            UNWRAP_NULL,
-            DERIVE_TRUE,
-        });
-
-        // all private and public keys
-        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, PCKK_ANY,
-        new CK_ATTRIBUTE[] {
-            TOKEN_FALSE,
-            SENSITIVE_FALSE,
-            EXTRACTABLE_TRUE,
-        });
-        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, PCKK_ANY,
-        new CK_ATTRIBUTE[] {
-            TOKEN_FALSE,
-        });
-
-        // additional attributes for RSA private keys
-        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_RSA,
-        new CK_ATTRIBUTE[] {
-            DECRYPT_TRUE,
-            SIGN_TRUE,
-            SIGN_RECOVER_TRUE,
-            UNWRAP_TRUE,
-        });
-        // additional attributes for RSA public keys
-        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_RSA,
-        new CK_ATTRIBUTE[] {
-            ENCRYPT_TRUE,
-            VERIFY_TRUE,
-            VERIFY_RECOVER_TRUE,
-            WRAP_TRUE,
-        });
-
-        // additional attributes for DSA private keys
-        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DSA,
-        new CK_ATTRIBUTE[] {
-            SIGN_TRUE,
-        });
-        // additional attributes for DSA public keys
-        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_DSA,
-        new CK_ATTRIBUTE[] {
-            VERIFY_TRUE,
-        });
-
-        // additional attributes for DH private keys
-        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_DH,
-        new CK_ATTRIBUTE[] {
-            DERIVE_TRUE,
-        });
-
-        // additional attributes for EC private keys
-        templateManager.addTemplate(O_ANY, CKO_PRIVATE_KEY, CKK_EC,
-        new CK_ATTRIBUTE[] {
-            SIGN_TRUE,
-            DERIVE_TRUE,
-        });
-        // additional attributes for EC public keys
-        templateManager.addTemplate(O_ANY, CKO_PUBLIC_KEY, CKK_EC,
-        new CK_ATTRIBUTE[] {
-            VERIFY_TRUE,
-        });
-    }
-
-    private final static CK_ATTRIBUTE[] CK_A0 = new CK_ATTRIBUTE[0];
-
-    private String parseOperation() throws IOException {
-        String op = parseWord();
-        switch (op) {
-            case "*":
-                return TemplateManager.O_ANY;
-            case "generate":
-                return TemplateManager.O_GENERATE;
-            case "import":
-                return TemplateManager.O_IMPORT;
-            default:
-                throw excLine("Unknown operation " + op);
-        }
-    }
-
-    private long parseObjectClass() throws IOException {
-        String name = parseWord();
-        try {
-            return Functions.getObjectClassId(name);
-        } catch (IllegalArgumentException e) {
-            throw excLine("Unknown object class " + name);
-        }
-    }
-
-    private long parseKeyAlgorithm() throws IOException {
-        String name = parseWord();
-        if (isNumber(name)) {
-            return decodeNumber(name);
-        } else {
-            try {
-                return Functions.getKeyId(name);
-            } catch (IllegalArgumentException e) {
-                throw excLine("Unknown key algorithm " + name);
-            }
-        }
-    }
-
-    private long decodeAttributeName(String name) throws IOException {
-        if (isNumber(name)) {
-            return decodeNumber(name);
-        } else {
-            try {
-                return Functions.getAttributeId(name);
-            } catch (IllegalArgumentException e) {
-                throw excLine("Unknown attribute name " + name);
-            }
-        }
-    }
-
-    private CK_ATTRIBUTE decodeAttributeValue(long id, String value)
-            throws IOException {
-        if (value.equals("null")) {
-            return new CK_ATTRIBUTE(id);
-        } else if (value.equals("true")) {
-            return new CK_ATTRIBUTE(id, true);
-        } else if (value.equals("false")) {
-            return new CK_ATTRIBUTE(id, false);
-        } else if (isByteArray(value)) {
-            return new CK_ATTRIBUTE(id, decodeByteArray(value));
-        } else if (isNumber(value)) {
-            return new CK_ATTRIBUTE(id, Integer.valueOf(decodeNumber(value)));
-        } else {
-            throw excLine("Unknown attribute value " + value);
-        }
-    }
-
-    private void parseNSSArgs(String keyword) throws IOException {
-        checkDup(keyword);
-        parseEquals();
-        int token = nextToken();
-        if (token != '"') {
-            throw excToken("Expected quoted string");
-        }
-        nssArgs = expand(st.sval);
-        debug("nssArgs: " + nssArgs);
-    }
-
-    private void parseHandleStartupErrors(String keyword) throws IOException {
-        checkDup(keyword);
-        parseEquals();
-        String val = parseWord();
-        if (val.equals("ignoreAll")) {
-            handleStartupErrors = ERR_IGNORE_ALL;
-        } else if (val.equals("ignoreMissingLibrary")) {
-            handleStartupErrors = ERR_IGNORE_LIB;
-        } else if (val.equals("halt")) {
-            handleStartupErrors = ERR_HALT;
-        } else {
-            throw excToken("Invalid value for handleStartupErrors:");
-        }
-        debug("handleStartupErrors: " + handleStartupErrors);
-    }
-
-}
-
-class ConfigurationException extends IOException {
-    private static final long serialVersionUID = 254492758807673194L;
-    ConfigurationException(String msg) {
-        super(msg);
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/KeyCache.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.util.*;
-import java.lang.ref.*;
-
-import java.security.Key;
-
-import sun.security.util.Cache;
-
-/**
- * Key to P11Key translation cache. The PKCS#11 token can only perform
- * operations on keys stored on the token (permanently or temporarily). That
- * means that in order to allow the PKCS#11 provider to use keys from other
- * providers, we need to transparently convert them to P11Keys. The engines
- * do that using (Secret)KeyFactories, which in turn use this class as a
- * cache.
- *
- * There are two KeyCache instances per provider, one for secret keys and
- * one for public and private keys.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class KeyCache {
-
-    private final Cache<IdentityWrapper, P11Key> strongCache;
-
-    private WeakReference<Map<Key,P11Key>> cacheReference;
-
-    KeyCache() {
-        strongCache = Cache.newHardMemoryCache(16);
-    }
-
-    private static final class IdentityWrapper {
-        final Object obj;
-        IdentityWrapper(Object obj) {
-            this.obj = obj;
-        }
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o instanceof IdentityWrapper == false) {
-                return false;
-            }
-            IdentityWrapper other = (IdentityWrapper)o;
-            return this.obj == other.obj;
-        }
-        public int hashCode() {
-            return System.identityHashCode(obj);
-        }
-    }
-
-    synchronized P11Key get(Key key) {
-        P11Key p11Key = strongCache.get(new IdentityWrapper(key));
-        if (p11Key != null) {
-            return p11Key;
-        }
-        Map<Key,P11Key> map =
-                (cacheReference == null) ? null : cacheReference.get();
-        if (map == null) {
-            return null;
-        }
-        return map.get(key);
-    }
-
-    synchronized void put(Key key, P11Key p11Key) {
-        strongCache.put(new IdentityWrapper(key), p11Key);
-        Map<Key,P11Key> map =
-                (cacheReference == null) ? null : cacheReference.get();
-        if (map == null) {
-            map = new IdentityHashMap<>();
-            cacheReference = new WeakReference<>(map);
-        }
-        map.put(key, p11Key);
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Cipher.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,929 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-package sun.security.pkcs11;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Locale;
-
-import java.security.*;
-import java.security.spec.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import sun.nio.ch.DirectBuffer;
-import sun.security.jca.JCAUtil;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * Cipher implementation class. This class currently supports
- * DES, DESede, AES, ARCFOUR, and Blowfish.
- *
- * This class is designed to support ECB, CBC, CTR with NoPadding
- * and ECB, CBC with PKCS5Padding. It will use its own padding impl
- * if the native mechanism does not support padding.
- *
- * Note that PKCS#11 currently only supports ECB, CBC, and CTR.
- * There are no provisions for other modes such as CFB, OFB, and PCBC.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11Cipher extends CipherSpi {
-
-    // mode constant for ECB mode
-    private final static int MODE_ECB = 3;
-    // mode constant for CBC mode
-    private final static int MODE_CBC = 4;
-    // mode constant for CTR mode
-    private final static int MODE_CTR = 5;
-
-    // padding constant for NoPadding
-    private final static int PAD_NONE = 5;
-    // padding constant for PKCS5Padding
-    private final static int PAD_PKCS5 = 6;
-
-    private static interface Padding {
-        // ENC: format the specified buffer with padding bytes and return the
-        // actual padding length
-        int setPaddingBytes(byte[] paddingBuffer, int padLen);
-
-        // DEC: return the length of trailing padding bytes given the specified
-        // padded data
-        int unpad(byte[] paddedData, int len)
-                throws BadPaddingException, IllegalBlockSizeException;
-    }
-
-    private static class PKCS5Padding implements Padding {
-
-        private final int blockSize;
-
-        PKCS5Padding(int blockSize)
-                throws NoSuchPaddingException {
-            if (blockSize == 0) {
-                throw new NoSuchPaddingException
-                        ("PKCS#5 padding not supported with stream ciphers");
-            }
-            this.blockSize = blockSize;
-        }
-
-        public int setPaddingBytes(byte[] paddingBuffer, int padLen) {
-            Arrays.fill(paddingBuffer, 0, padLen, (byte) (padLen & 0x007f));
-            return padLen;
-        }
-
-        public int unpad(byte[] paddedData, int len)
-                throws BadPaddingException, IllegalBlockSizeException {
-            if ((len < 1) || (len % blockSize != 0)) {
-                throw new IllegalBlockSizeException
-                    ("Input length must be multiples of " + blockSize);
-            }
-            byte padValue = paddedData[len - 1];
-            if (padValue < 1 || padValue > blockSize) {
-                throw new BadPaddingException("Invalid pad value!");
-            }
-            // sanity check padding bytes
-            int padStartIndex = len - padValue;
-            for (int i = padStartIndex; i < len; i++) {
-                if (paddedData[i] != padValue) {
-                    throw new BadPaddingException("Invalid pad bytes!");
-                }
-            }
-            return padValue;
-        }
-    }
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // name of the key algorithm, e.g. DES instead of algorithm DES/CBC/...
-    private final String keyAlgorithm;
-
-    // mechanism id
-    private final long mechanism;
-
-    // associated session, if any
-    private Session session;
-
-    // key, if init() was called
-    private P11Key p11Key;
-
-    // flag indicating whether an operation is initialized
-    private boolean initialized;
-
-    // falg indicating encrypt or decrypt mode
-    private boolean encrypt;
-
-    // mode, one of MODE_* above (MODE_ECB for stream ciphers)
-    private int blockMode;
-
-    // block size, 0 for stream ciphers
-    private final int blockSize;
-
-    // padding type, on of PAD_* above (PAD_NONE for stream ciphers)
-    private int paddingType;
-
-    // when the padding is requested but unsupported by the native mechanism,
-    // we use the following to do padding and necessary data buffering.
-    // padding object which generate padding and unpad the decrypted data
-    private Padding paddingObj;
-    // buffer for holding back the block which contains padding bytes
-    private byte[] padBuffer;
-    private int padBufferLen;
-
-    // original IV, if in MODE_CBC or MODE_CTR
-    private byte[] iv;
-
-    // number of bytes buffered internally by the native mechanism and padBuffer
-    // if we do the padding
-    private int bytesBuffered;
-
-    // length of key size in bytes; currently only used by AES given its oid
-    // specification mandates a fixed size of the key
-    private int fixedKeySize = -1;
-
-    P11Cipher(Token token, String algorithm, long mechanism)
-            throws PKCS11Exception, NoSuchAlgorithmException {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-
-        String[] algoParts = algorithm.split("/");
-
-        if (algoParts[0].startsWith("AES")) {
-            blockSize = 16;
-            int index = algoParts[0].indexOf('_');
-            if (index != -1) {
-                // should be well-formed since we specify what we support
-                fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1))/8;
-            }
-            keyAlgorithm = "AES";
-        } else {
-            keyAlgorithm = algoParts[0];
-            if (keyAlgorithm.equals("RC4") ||
-                    keyAlgorithm.equals("ARCFOUR")) {
-                blockSize = 0;
-            } else { // DES, DESede, Blowfish
-                blockSize = 8;
-            }
-        }
-        this.blockMode =
-            (algoParts.length > 1 ? parseMode(algoParts[1]) : MODE_ECB);
-        String defPadding = (blockSize == 0 ? "NoPadding" : "PKCS5Padding");
-        String paddingStr =
-                (algoParts.length > 2 ? algoParts[2] : defPadding);
-        try {
-            engineSetPadding(paddingStr);
-        } catch (NoSuchPaddingException nspe) {
-            // should not happen
-            throw new ProviderException(nspe);
-        }
-    }
-
-    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
-        // Disallow change of mode for now since currently it's explicitly
-        // defined in transformation strings
-        throw new NoSuchAlgorithmException("Unsupported mode " + mode);
-    }
-
-    private int parseMode(String mode) throws NoSuchAlgorithmException {
-        mode = mode.toUpperCase(Locale.ENGLISH);
-        int result;
-        if (mode.equals("ECB")) {
-            result = MODE_ECB;
-        } else if (mode.equals("CBC")) {
-            if (blockSize == 0) {
-                throw new NoSuchAlgorithmException
-                        ("CBC mode not supported with stream ciphers");
-            }
-            result = MODE_CBC;
-        } else if (mode.equals("CTR")) {
-            result = MODE_CTR;
-        } else {
-            throw new NoSuchAlgorithmException("Unsupported mode " + mode);
-        }
-        return result;
-    }
-
-    // see JCE spec
-    protected void engineSetPadding(String padding)
-            throws NoSuchPaddingException {
-        paddingObj = null;
-        padBuffer = null;
-        padding = padding.toUpperCase(Locale.ENGLISH);
-        if (padding.equals("NOPADDING")) {
-            paddingType = PAD_NONE;
-        } else if (padding.equals("PKCS5PADDING")) {
-            if (this.blockMode == MODE_CTR) {
-                throw new NoSuchPaddingException
-                    ("PKCS#5 padding not supported with CTR mode");
-            }
-            paddingType = PAD_PKCS5;
-            if (mechanism != CKM_DES_CBC_PAD && mechanism != CKM_DES3_CBC_PAD &&
-                    mechanism != CKM_AES_CBC_PAD) {
-                // no native padding support; use our own padding impl
-                paddingObj = new PKCS5Padding(blockSize);
-                padBuffer = new byte[blockSize];
-            }
-        } else {
-            throw new NoSuchPaddingException("Unsupported padding " + padding);
-        }
-    }
-
-    // see JCE spec
-    protected int engineGetBlockSize() {
-        return blockSize;
-    }
-
-    // see JCE spec
-    protected int engineGetOutputSize(int inputLen) {
-        return doFinalLength(inputLen);
-    }
-
-    // see JCE spec
-    protected byte[] engineGetIV() {
-        return (iv == null) ? null : iv.clone();
-    }
-
-    // see JCE spec
-    protected AlgorithmParameters engineGetParameters() {
-        if (iv == null) {
-            return null;
-        }
-        IvParameterSpec ivSpec = new IvParameterSpec(iv);
-        try {
-            AlgorithmParameters params =
-                    AlgorithmParameters.getInstance(keyAlgorithm,
-                    P11Util.getSunJceProvider());
-            params.init(ivSpec);
-            return params;
-        } catch (GeneralSecurityException e) {
-            // NoSuchAlgorithmException, NoSuchProviderException
-            // InvalidParameterSpecException
-            throw new ProviderException("Could not encode parameters", e);
-        }
-    }
-
-    // see JCE spec
-    protected void engineInit(int opmode, Key key, SecureRandom random)
-            throws InvalidKeyException {
-        try {
-            implInit(opmode, key, null, random);
-        } catch (InvalidAlgorithmParameterException e) {
-            throw new InvalidKeyException("init() failed", e);
-        }
-    }
-
-    // see JCE spec
-    protected void engineInit(int opmode, Key key,
-            AlgorithmParameterSpec params, SecureRandom random)
-            throws InvalidKeyException, InvalidAlgorithmParameterException {
-        byte[] ivValue;
-        if (params != null) {
-            if (params instanceof IvParameterSpec == false) {
-                throw new InvalidAlgorithmParameterException
-                        ("Only IvParameterSpec supported");
-            }
-            IvParameterSpec ivSpec = (IvParameterSpec) params;
-            ivValue = ivSpec.getIV();
-        } else {
-            ivValue = null;
-        }
-        implInit(opmode, key, ivValue, random);
-    }
-
-    // see JCE spec
-    protected void engineInit(int opmode, Key key, AlgorithmParameters params,
-            SecureRandom random)
-            throws InvalidKeyException, InvalidAlgorithmParameterException {
-        byte[] ivValue;
-        if (params != null) {
-            try {
-                IvParameterSpec ivSpec =
-                        params.getParameterSpec(IvParameterSpec.class);
-                ivValue = ivSpec.getIV();
-            } catch (InvalidParameterSpecException e) {
-                throw new InvalidAlgorithmParameterException
-                        ("Could not decode IV", e);
-            }
-        } else {
-            ivValue = null;
-        }
-        implInit(opmode, key, ivValue, random);
-    }
-
-    // actual init() implementation
-    private void implInit(int opmode, Key key, byte[] iv,
-            SecureRandom random)
-            throws InvalidKeyException, InvalidAlgorithmParameterException {
-        reset(true);
-        if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
-            throw new InvalidKeyException("Key size is invalid");
-        }
-        switch (opmode) {
-            case Cipher.ENCRYPT_MODE:
-                encrypt = true;
-                break;
-            case Cipher.DECRYPT_MODE:
-                encrypt = false;
-                break;
-            default:
-                throw new InvalidAlgorithmParameterException
-                        ("Unsupported mode: " + opmode);
-        }
-        if (blockMode == MODE_ECB) { // ECB or stream cipher
-            if (iv != null) {
-                if (blockSize == 0) {
-                    throw new InvalidAlgorithmParameterException
-                            ("IV not used with stream ciphers");
-                } else {
-                    throw new InvalidAlgorithmParameterException
-                            ("IV not used in ECB mode");
-                }
-            }
-        } else { // MODE_CBC or MODE_CTR
-            if (iv == null) {
-                if (encrypt == false) {
-                    String exMsg =
-                        (blockMode == MODE_CBC ?
-                         "IV must be specified for decryption in CBC mode" :
-                         "IV must be specified for decryption in CTR mode");
-                    throw new InvalidAlgorithmParameterException(exMsg);
-                }
-                // generate random IV
-                if (random == null) {
-                    random = JCAUtil.getSecureRandom();
-                }
-                iv = new byte[blockSize];
-                random.nextBytes(iv);
-            } else {
-                if (iv.length != blockSize) {
-                    throw new InvalidAlgorithmParameterException
-                            ("IV length must match block size");
-                }
-            }
-        }
-        this.iv = iv;
-        p11Key = P11SecretKeyFactory.convertKey(token, key, keyAlgorithm);
-        try {
-            initialize();
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not initialize cipher", e);
-        }
-    }
-
-    private void cancelOperation() {
-        if (initialized == false) {
-            return;
-        }
-
-        if ((session == null) || (token.explicitCancel == false)) {
-            return;
-        }
-        try {
-            if (session.hasObjects() == false) {
-                session = token.killSession(session);
-                return;
-            } else {
-                // cancel operation by finishing it
-                int bufLen = doFinalLength(0);
-                byte[] buffer = new byte[bufLen];
-                if (encrypt) {
-                    token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen);
-                } else {
-                    token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
-                }
-            }
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("Cancel failed", e);
-        }
-    }
-
-    private void ensureInitialized() throws PKCS11Exception {
-        if (initialized == false) {
-            initialize();
-        }
-    }
-
-    private void initialize() throws PKCS11Exception {
-        if (session == null) {
-            session = token.getOpSession();
-        }
-        CK_MECHANISM mechParams = (blockMode == MODE_CTR?
-            new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) :
-            new CK_MECHANISM(mechanism, iv));
-
-        try {
-            if (encrypt) {
-                token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID);
-            } else {
-                token.p11.C_DecryptInit(session.id(), mechParams, p11Key.keyID);
-            }
-        } catch (PKCS11Exception ex) {
-            // release session when initialization failed
-            session = token.releaseSession(session);
-            throw ex;
-        }
-        bytesBuffered = 0;
-        padBufferLen = 0;
-        initialized = true;
-    }
-
-    // if update(inLen) is called, how big does the output buffer have to be?
-    private int updateLength(int inLen) {
-        if (inLen <= 0) {
-            return 0;
-        }
-
-        int result = inLen + bytesBuffered;
-        if (blockSize != 0 && blockMode != MODE_CTR) {
-            // minus the number of bytes in the last incomplete block.
-            result -= (result & (blockSize - 1));
-        }
-        return result;
-    }
-
-    // if doFinal(inLen) is called, how big does the output buffer have to be?
-    private int doFinalLength(int inLen) {
-        if (inLen < 0) {
-            return 0;
-        }
-
-        int result = inLen + bytesBuffered;
-        if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
-            // add the number of bytes to make the last block complete.
-            result += (blockSize - (result & (blockSize - 1)));
-        }
-        return result;
-    }
-
-    // reset the states to the pre-initialized values
-    private void reset(boolean doCancel) {
-        if (doCancel) cancelOperation();
-
-        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 {
-            byte[] out = new byte[updateLength(inLen)];
-            int n = engineUpdate(in, inOfs, inLen, out, 0);
-            return P11Util.convert(out, 0, n);
-        } catch (ShortBufferException e) {
-            // convert since the output length is calculated by updateLength()
-            throw new ProviderException(e);
-        }
-    }
-
-    // see JCE spec
-    protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
-            int outOfs) throws ShortBufferException {
-        int outLen = out.length - outOfs;
-        return implUpdate(in, inOfs, inLen, out, outOfs, outLen);
-    }
-
-    // see JCE spec
-    @Override
-    protected int engineUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
-            throws ShortBufferException {
-        return implUpdate(inBuffer, outBuffer);
-    }
-
-    // see JCE spec
-    protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
-            throws IllegalBlockSizeException, BadPaddingException {
-        try {
-            byte[] out = new byte[doFinalLength(inLen)];
-            int n = engineDoFinal(in, inOfs, inLen, out, 0);
-            return P11Util.convert(out, 0, n);
-        } catch (ShortBufferException e) {
-            // convert since the output length is calculated by doFinalLength()
-            throw new ProviderException(e);
-        }
-    }
-
-    // see JCE spec
-    protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
-            int outOfs) throws ShortBufferException, IllegalBlockSizeException,
-            BadPaddingException {
-        int n = 0;
-        if ((inLen != 0) && (in != null)) {
-            n = engineUpdate(in, inOfs, inLen, out, outOfs);
-            outOfs += n;
-        }
-        n += implDoFinal(out, outOfs, out.length - outOfs);
-        return n;
-    }
-
-    // see JCE spec
-    @Override
-    protected int engineDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
-            throws ShortBufferException, IllegalBlockSizeException,
-            BadPaddingException {
-        int n = engineUpdate(inBuffer, outBuffer);
-        n += implDoFinal(outBuffer);
-        return n;
-    }
-
-    private int implUpdate(byte[] in, int inOfs, int inLen,
-            byte[] out, int outOfs, int outLen) throws ShortBufferException {
-        if (outLen < updateLength(inLen)) {
-            throw new ShortBufferException();
-        }
-        try {
-            ensureInitialized();
-            int k = 0;
-            if (encrypt) {
-                k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen,
-                        0, out, outOfs, outLen);
-            } else {
-                int newPadBufferLen = 0;
-                if (paddingObj != null) {
-                    if (padBufferLen != 0) {
-                        // NSS throws up when called with data not in multiple
-                        // of blocks. Try to work around this by holding the
-                        // extra data in padBuffer.
-                        if (padBufferLen != padBuffer.length) {
-                            int bufCapacity = padBuffer.length - padBufferLen;
-                            if (inLen > bufCapacity) {
-                                bufferInputBytes(in, inOfs, bufCapacity);
-                                inOfs += bufCapacity;
-                                inLen -= bufCapacity;
-                            } else {
-                                bufferInputBytes(in, inOfs, inLen);
-                                return 0;
-                            }
-                        }
-                        k = token.p11.C_DecryptUpdate(session.id(),
-                                0, padBuffer, 0, padBufferLen,
-                                0, out, outOfs, outLen);
-                        padBufferLen = 0;
-                    }
-                    newPadBufferLen = inLen & (blockSize - 1);
-                    if (newPadBufferLen == 0) {
-                        newPadBufferLen = padBuffer.length;
-                    }
-                    inLen -= newPadBufferLen;
-                }
-                if (inLen > 0) {
-                    k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
-                            inLen, 0, out, (outOfs + k), (outLen - k));
-                }
-                // update 'padBuffer' if using our own padding impl.
-                if (paddingObj != null) {
-                    bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
-                }
-            }
-            bytesBuffered += (inLen - k);
-            return k;
-        } catch (PKCS11Exception e) {
-            if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
-                throw (ShortBufferException)
-                        (new ShortBufferException().initCause(e));
-            }
-            reset(false);
-            throw new ProviderException("update() failed", e);
-        }
-    }
-
-    private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
-            throws ShortBufferException {
-        int inLen = inBuffer.remaining();
-        if (inLen <= 0) {
-            return 0;
-        }
-
-        int outLen = outBuffer.remaining();
-        if (outLen < updateLength(inLen)) {
-            throw new ShortBufferException();
-        }
-        int origPos = inBuffer.position();
-        try {
-            ensureInitialized();
-
-            long inAddr = 0;
-            int inOfs = 0;
-            byte[] inArray = null;
-
-            if (inBuffer instanceof DirectBuffer) {
-                inAddr = ((DirectBuffer) inBuffer).address();
-                inOfs = origPos;
-            } else if (inBuffer.hasArray()) {
-                inArray = inBuffer.array();
-                inOfs = (origPos + inBuffer.arrayOffset());
-            }
-
-            long outAddr = 0;
-            int outOfs = 0;
-            byte[] outArray = null;
-            if (outBuffer instanceof DirectBuffer) {
-                outAddr = ((DirectBuffer) outBuffer).address();
-                outOfs = outBuffer.position();
-            } else {
-                if (outBuffer.hasArray()) {
-                    outArray = outBuffer.array();
-                    outOfs = (outBuffer.position() + outBuffer.arrayOffset());
-                } else {
-                    outArray = new byte[outLen];
-                }
-            }
-
-            int k = 0;
-            if (encrypt) {
-                if (inAddr == 0 && inArray == null) {
-                    inArray = new byte[inLen];
-                    inBuffer.get(inArray);
-                } else {
-                    inBuffer.position(origPos + inLen);
-                }
-                k = token.p11.C_EncryptUpdate(session.id(),
-                        inAddr, inArray, inOfs, inLen,
-                        outAddr, outArray, outOfs, outLen);
-            } else {
-                int newPadBufferLen = 0;
-                if (paddingObj != null) {
-                    if (padBufferLen != 0) {
-                        // NSS throws up when called with data not in multiple
-                        // of blocks. Try to work around this by holding the
-                        // extra data in padBuffer.
-                        if (padBufferLen != padBuffer.length) {
-                            int bufCapacity = padBuffer.length - padBufferLen;
-                            if (inLen > bufCapacity) {
-                                bufferInputBytes(inBuffer, bufCapacity);
-                                inOfs += bufCapacity;
-                                inLen -= bufCapacity;
-                            } else {
-                                bufferInputBytes(inBuffer, inLen);
-                                return 0;
-                            }
-                        }
-                        k = token.p11.C_DecryptUpdate(session.id(), 0,
-                                padBuffer, 0, padBufferLen, outAddr, outArray,
-                                outOfs, outLen);
-                        padBufferLen = 0;
-                    }
-                    newPadBufferLen = inLen & (blockSize - 1);
-                    if (newPadBufferLen == 0) {
-                        newPadBufferLen = padBuffer.length;
-                    }
-                    inLen -= newPadBufferLen;
-                }
-                if (inLen > 0) {
-                    if (inAddr == 0 && inArray == null) {
-                        inArray = new byte[inLen];
-                        inBuffer.get(inArray);
-                    } else {
-                        inBuffer.position(inBuffer.position() + inLen);
-                    }
-                    k += token.p11.C_DecryptUpdate(session.id(), inAddr,
-                            inArray, inOfs, inLen, outAddr, outArray,
-                            (outOfs + k), (outLen - k));
-                }
-                // update 'padBuffer' if using our own padding impl.
-                if (paddingObj != null && newPadBufferLen != 0) {
-                    bufferInputBytes(inBuffer, newPadBufferLen);
-                }
-            }
-            bytesBuffered += (inLen - k);
-            if (!(outBuffer instanceof DirectBuffer) &&
-                    !outBuffer.hasArray()) {
-                outBuffer.put(outArray, outOfs, k);
-            } else {
-                outBuffer.position(outBuffer.position() + k);
-            }
-            return k;
-        } catch (PKCS11Exception e) {
-            // Reset input buffer to its original position for
-            inBuffer.position(origPos);
-            if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
-                throw (ShortBufferException)
-                        (new ShortBufferException().initCause(e));
-            }
-            reset(false);
-            throw new ProviderException("update() failed", e);
-        }
-    }
-
-    private int implDoFinal(byte[] out, int outOfs, int outLen)
-            throws ShortBufferException, IllegalBlockSizeException,
-            BadPaddingException {
-        int requiredOutLen = doFinalLength(0);
-        if (outLen < requiredOutLen) {
-            throw new ShortBufferException();
-        }
-        boolean doCancel = true;
-        try {
-            ensureInitialized();
-            int k = 0;
-            if (encrypt) {
-                if (paddingObj != null) {
-                    int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
-                            requiredOutLen - bytesBuffered);
-                    k = token.p11.C_EncryptUpdate(session.id(),
-                            0, padBuffer, 0, actualPadLen,
-                            0, out, outOfs, outLen);
-                }
-                k += token.p11.C_EncryptFinal(session.id(),
-                        0, out, (outOfs + k), (outLen - k));
-                doCancel = false;
-            } else {
-                // Special handling to match SunJCE provider behavior
-                if (bytesBuffered == 0 && padBufferLen == 0) {
-                    return 0;
-                }
-                if (paddingObj != null) {
-                    if (padBufferLen != 0) {
-                        k = token.p11.C_DecryptUpdate(session.id(), 0,
-                                padBuffer, 0, padBufferLen, 0, padBuffer, 0,
-                                padBuffer.length);
-                    }
-                    k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
-                            padBuffer.length - k);
-                    doCancel = false;
-
-                    int actualPadLen = paddingObj.unpad(padBuffer, k);
-                    k -= actualPadLen;
-                    System.arraycopy(padBuffer, 0, out, outOfs, k);
-                } else {
-                    k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
-                            outLen);
-                    doCancel = false;
-                }
-            }
-            return k;
-        } catch (PKCS11Exception e) {
-            doCancel = false;
-            handleException(e);
-            throw new ProviderException("doFinal() failed", e);
-        } finally {
-            reset(doCancel);
-        }
-    }
-
-    private int implDoFinal(ByteBuffer outBuffer)
-            throws ShortBufferException, IllegalBlockSizeException,
-            BadPaddingException {
-        int outLen = outBuffer.remaining();
-        int requiredOutLen = doFinalLength(0);
-        if (outLen < requiredOutLen) {
-            throw new ShortBufferException();
-        }
-
-        boolean doCancel = true;
-        try {
-            ensureInitialized();
-
-            long outAddr = 0;
-            byte[] outArray = null;
-            int outOfs = 0;
-            if (outBuffer instanceof DirectBuffer) {
-                outAddr = ((DirectBuffer) outBuffer).address();
-                outOfs = outBuffer.position();
-            } else {
-                if (outBuffer.hasArray()) {
-                    outArray = outBuffer.array();
-                    outOfs = outBuffer.position() + outBuffer.arrayOffset();
-                } else {
-                    outArray = new byte[outLen];
-                }
-            }
-
-            int k = 0;
-
-            if (encrypt) {
-                if (paddingObj != null) {
-                    int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
-                            requiredOutLen - bytesBuffered);
-                    k = token.p11.C_EncryptUpdate(session.id(),
-                            0, padBuffer, 0, actualPadLen,
-                            outAddr, outArray, outOfs, outLen);
-                }
-                k += token.p11.C_EncryptFinal(session.id(),
-                        outAddr, outArray, (outOfs + k), (outLen - k));
-                doCancel = false;
-            } else {
-                // Special handling to match SunJCE provider behavior
-                if (bytesBuffered == 0 && padBufferLen == 0) {
-                    return 0;
-                }
-
-                if (paddingObj != null) {
-                    if (padBufferLen != 0) {
-                        k = token.p11.C_DecryptUpdate(session.id(),
-                                0, padBuffer, 0, padBufferLen,
-                                0, padBuffer, 0, padBuffer.length);
-                        padBufferLen = 0;
-                    }
-                    k += token.p11.C_DecryptFinal(session.id(),
-                            0, padBuffer, k, padBuffer.length - k);
-                    doCancel = false;
-
-                    int actualPadLen = paddingObj.unpad(padBuffer, k);
-                    k -= actualPadLen;
-                    outArray = padBuffer;
-                    outOfs = 0;
-                } else {
-                    k = token.p11.C_DecryptFinal(session.id(),
-                            outAddr, outArray, outOfs, outLen);
-                    doCancel = false;
-                }
-            }
-            if ((!encrypt && paddingObj != null) ||
-                    (!(outBuffer instanceof DirectBuffer) &&
-                    !outBuffer.hasArray())) {
-                outBuffer.put(outArray, outOfs, k);
-            } else {
-                outBuffer.position(outBuffer.position() + k);
-            }
-            return k;
-        } catch (PKCS11Exception e) {
-            doCancel = false;
-            handleException(e);
-            throw new ProviderException("doFinal() failed", e);
-        } finally {
-            reset(doCancel);
-        }
-    }
-
-    private void handleException(PKCS11Exception e)
-            throws ShortBufferException, IllegalBlockSizeException {
-        long errorCode = e.getErrorCode();
-        if (errorCode == CKR_BUFFER_TOO_SMALL) {
-            throw (ShortBufferException)
-                    (new ShortBufferException().initCause(e));
-        } else if (errorCode == CKR_DATA_LEN_RANGE ||
-                   errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
-            throw (IllegalBlockSizeException)
-                    (new IllegalBlockSizeException(e.toString()).initCause(e));
-        }
-    }
-
-    // see JCE spec
-    protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
-            InvalidKeyException {
-        // XXX key wrapping
-        throw new UnsupportedOperationException("engineWrap()");
-    }
-
-    // see JCE spec
-    protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
-            int wrappedKeyType)
-            throws InvalidKeyException, NoSuchAlgorithmException {
-        // XXX key unwrapping
-        throw new UnsupportedOperationException("engineUnwrap()");
-    }
-
-    // see JCE spec
-    @Override
-    protected int engineGetKeySize(Key key) throws InvalidKeyException {
-        int n = P11SecretKeyFactory.convertKey
-                (token, key, keyAlgorithm).length();
-        return n;
-    }
-
-    private final void bufferInputBytes(byte[] in, int inOfs, int len) {
-        System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
-        padBufferLen += len;
-        bytesBuffered += len;
-    }
-
-    private final void bufferInputBytes(ByteBuffer inBuffer, int len) {
-        inBuffer.get(padBuffer, padBufferLen, len);
-        padBufferLen += len;
-        bytesBuffered += len;
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11DHKeyFactory.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.math.BigInteger;
-
-import java.security.*;
-import java.security.spec.*;
-
-import javax.crypto.interfaces.*;
-import javax.crypto.spec.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * DH KeyFactory implementation.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11DHKeyFactory extends P11KeyFactory {
-
-    P11DHKeyFactory(Token token, String algorithm) {
-        super(token, algorithm);
-    }
-
-    PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
-        try {
-            if (key instanceof DHPublicKey) {
-                DHPublicKey dhKey = (DHPublicKey)key;
-                DHParameterSpec params = dhKey.getParams();
-                return generatePublic(
-                    dhKey.getY(),
-                    params.getP(),
-                    params.getG()
-                );
-            } else if ("X.509".equals(key.getFormat())) {
-                // let SunJCE provider parse for us, then recurse
-                try {
-                    KeyFactory factory = implGetSoftwareFactory();
-                    key = (PublicKey)factory.translateKey(key);
-                    return implTranslatePublicKey(key);
-                } catch (GeneralSecurityException e) {
-                    throw new InvalidKeyException("Could not translate key", e);
-                }
-            } else {
-                throw new InvalidKeyException("PublicKey must be instance "
-                        + "of DHPublicKey or have X.509 encoding");
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create DH public key", e);
-        }
-    }
-
-    PrivateKey implTranslatePrivateKey(PrivateKey key)
-            throws InvalidKeyException {
-        try {
-            if (key instanceof DHPrivateKey) {
-                DHPrivateKey dhKey = (DHPrivateKey)key;
-                DHParameterSpec params = dhKey.getParams();
-                return generatePrivate(
-                    dhKey.getX(),
-                    params.getP(),
-                    params.getG()
-                );
-            } else if ("PKCS#8".equals(key.getFormat())) {
-                // let SunJCE provider parse for us, then recurse
-                try {
-                    KeyFactory factory = implGetSoftwareFactory();
-                    key = (PrivateKey)factory.translateKey(key);
-                    return implTranslatePrivateKey(key);
-                } catch (GeneralSecurityException e) {
-                    throw new InvalidKeyException("Could not translate key", e);
-                }
-            } else {
-                throw new InvalidKeyException("PrivateKey must be instance "
-                        + "of DHPrivateKey or have PKCS#8 encoding");
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create DH private key", e);
-        }
-    }
-
-    // see JCA spec
-    protected PublicKey engineGeneratePublic(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec instanceof X509EncodedKeySpec) {
-            try {
-                KeyFactory factory = implGetSoftwareFactory();
-                PublicKey key = factory.generatePublic(keySpec);
-                return implTranslatePublicKey(key);
-            } catch (GeneralSecurityException e) {
-                throw new InvalidKeySpecException
-                        ("Could not create DH public key", e);
-            }
-        }
-        if (keySpec instanceof DHPublicKeySpec == false) {
-            throw new InvalidKeySpecException("Only DHPublicKeySpec and "
-                + "X509EncodedKeySpec supported for DH public keys");
-        }
-        try {
-            DHPublicKeySpec ds = (DHPublicKeySpec)keySpec;
-            return generatePublic(
-                ds.getY(),
-                ds.getP(),
-                ds.getG()
-            );
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeySpecException
-                ("Could not create DH public key", e);
-        }
-    }
-
-    // see JCA spec
-    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec instanceof PKCS8EncodedKeySpec) {
-            try {
-                KeyFactory factory = implGetSoftwareFactory();
-                PrivateKey key = factory.generatePrivate(keySpec);
-                return implTranslatePrivateKey(key);
-            } catch (GeneralSecurityException e) {
-                throw new InvalidKeySpecException
-                        ("Could not create DH private key", e);
-            }
-        }
-        if (keySpec instanceof DHPrivateKeySpec == false) {
-            throw new InvalidKeySpecException("Only DHPrivateKeySpec and "
-                + "PKCS8EncodedKeySpec supported for DH private keys");
-        }
-        try {
-            DHPrivateKeySpec ds = (DHPrivateKeySpec)keySpec;
-            return generatePrivate(
-                ds.getX(),
-                ds.getP(),
-                ds.getG()
-            );
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeySpecException
-                ("Could not create DH private key", e);
-        }
-    }
-
-    private PublicKey generatePublic(BigInteger y, BigInteger p, BigInteger g)
-            throws PKCS11Exception {
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DH),
-            new CK_ATTRIBUTE(CKA_VALUE, y),
-            new CK_ATTRIBUTE(CKA_PRIME, p),
-            new CK_ATTRIBUTE(CKA_BASE, g),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PUBLIC_KEY, CKK_DH, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.publicKey
-                (session, keyID, "DH", p.bitLength(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private PrivateKey generatePrivate(BigInteger x, BigInteger p,
-            BigInteger g) throws PKCS11Exception {
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DH),
-            new CK_ATTRIBUTE(CKA_VALUE, x),
-            new CK_ATTRIBUTE(CKA_PRIME, p),
-            new CK_ATTRIBUTE(CKA_BASE, g),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PRIVATE_KEY, CKK_DH, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.privateKey
-                (session, keyID, "DH", p.bitLength(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
-        if (DHPublicKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_PRIME),
-                new CK_ATTRIBUTE(CKA_BASE),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            KeySpec spec = new DHPublicKeySpec(
-                attributes[0].getBigInteger(),
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger()
-            );
-            return keySpec.cast(spec);
-        } else { // X.509 handled in superclass
-            throw new InvalidKeySpecException("Only DHPublicKeySpec and "
-                + "X509EncodedKeySpec supported for DH public keys");
-        }
-    }
-
-    <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
-        if (DHPrivateKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_PRIME),
-                new CK_ATTRIBUTE(CKA_BASE),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            KeySpec spec = new DHPrivateKeySpec(
-                attributes[0].getBigInteger(),
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger()
-            );
-            return keySpec.cast(spec);
-        } else { // PKCS#8 handled in superclass
-            throw new InvalidKeySpecException("Only DHPrivateKeySpec "
-                + "and PKCS8EncodedKeySpec supported for DH private keys");
-        }
-    }
-
-    KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
-        return KeyFactory.getInstance("DH", P11Util.getSunJceProvider());
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11DSAKeyFactory.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.math.BigInteger;
-
-import java.security.*;
-import java.security.interfaces.*;
-import java.security.spec.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * DSA KeyFactory implementation.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11DSAKeyFactory extends P11KeyFactory {
-
-    P11DSAKeyFactory(Token token, String algorithm) {
-        super(token, algorithm);
-    }
-
-    PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
-        try {
-            if (key instanceof DSAPublicKey) {
-                DSAPublicKey dsaKey = (DSAPublicKey)key;
-                DSAParams params = dsaKey.getParams();
-                return generatePublic(
-                    dsaKey.getY(),
-                    params.getP(),
-                    params.getQ(),
-                    params.getG()
-                );
-            } else if ("X.509".equals(key.getFormat())) {
-                // let Sun provider parse for us, then recurse
-                byte[] encoded = key.getEncoded();
-                key = new sun.security.provider.DSAPublicKey(encoded);
-                return implTranslatePublicKey(key);
-            } else {
-                throw new InvalidKeyException("PublicKey must be instance "
-                        + "of DSAPublicKey or have X.509 encoding");
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create DSA public key", e);
-        }
-    }
-
-    PrivateKey implTranslatePrivateKey(PrivateKey key)
-            throws InvalidKeyException {
-        try {
-            if (key instanceof DSAPrivateKey) {
-                DSAPrivateKey dsaKey = (DSAPrivateKey)key;
-                DSAParams params = dsaKey.getParams();
-                return generatePrivate(
-                    dsaKey.getX(),
-                    params.getP(),
-                    params.getQ(),
-                    params.getG()
-                );
-            } else if ("PKCS#8".equals(key.getFormat())) {
-                // let Sun provider parse for us, then recurse
-                byte[] encoded = key.getEncoded();
-                key = new sun.security.provider.DSAPrivateKey(encoded);
-                return implTranslatePrivateKey(key);
-            } else {
-                throw new InvalidKeyException("PrivateKey must be instance "
-                        + "of DSAPrivateKey or have PKCS#8 encoding");
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create DSA private key", e);
-        }
-    }
-
-    // see JCA spec
-    protected PublicKey engineGeneratePublic(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec instanceof X509EncodedKeySpec) {
-            try {
-                byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
-                PublicKey key = new sun.security.provider.DSAPublicKey(encoded);
-                return implTranslatePublicKey(key);
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeySpecException
-                        ("Could not create DSA public key", e);
-            }
-        }
-        if (keySpec instanceof DSAPublicKeySpec == false) {
-            throw new InvalidKeySpecException("Only DSAPublicKeySpec and "
-                + "X509EncodedKeySpec supported for DSA public keys");
-        }
-        try {
-            DSAPublicKeySpec ds = (DSAPublicKeySpec)keySpec;
-            return generatePublic(
-                ds.getY(),
-                ds.getP(),
-                ds.getQ(),
-                ds.getG()
-            );
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeySpecException
-                ("Could not create DSA public key", e);
-        }
-    }
-
-    // see JCA spec
-    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec instanceof PKCS8EncodedKeySpec) {
-            try {
-                byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
-                PrivateKey key = new sun.security.provider.DSAPrivateKey(encoded);
-                return implTranslatePrivateKey(key);
-            } catch (GeneralSecurityException e) {
-                throw new InvalidKeySpecException
-                        ("Could not create DSA private key", e);
-            }
-        }
-        if (keySpec instanceof DSAPrivateKeySpec == false) {
-            throw new InvalidKeySpecException("Only DSAPrivateKeySpec and "
-                + "PKCS8EncodedKeySpec supported for DSA private keys");
-        }
-        try {
-            DSAPrivateKeySpec ds = (DSAPrivateKeySpec)keySpec;
-            return generatePrivate(
-                ds.getX(),
-                ds.getP(),
-                ds.getQ(),
-                ds.getG()
-            );
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeySpecException
-                ("Could not create DSA private key", e);
-        }
-    }
-
-    private PublicKey generatePublic(BigInteger y, BigInteger p, BigInteger q,
-            BigInteger g) throws PKCS11Exception {
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
-            new CK_ATTRIBUTE(CKA_VALUE, y),
-            new CK_ATTRIBUTE(CKA_PRIME, p),
-            new CK_ATTRIBUTE(CKA_SUBPRIME, q),
-            new CK_ATTRIBUTE(CKA_BASE, g),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PUBLIC_KEY, CKK_DSA, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.publicKey
-                (session, keyID, "DSA", p.bitLength(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private PrivateKey generatePrivate(BigInteger x, BigInteger p,
-            BigInteger q, BigInteger g) throws PKCS11Exception {
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
-            new CK_ATTRIBUTE(CKA_VALUE, x),
-            new CK_ATTRIBUTE(CKA_PRIME, p),
-            new CK_ATTRIBUTE(CKA_SUBPRIME, q),
-            new CK_ATTRIBUTE(CKA_BASE, g),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PRIVATE_KEY, CKK_DSA, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.privateKey
-                (session, keyID, "DSA", p.bitLength(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
-        if (DSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_PRIME),
-                new CK_ATTRIBUTE(CKA_SUBPRIME),
-                new CK_ATTRIBUTE(CKA_BASE),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            KeySpec spec = new DSAPublicKeySpec(
-                attributes[0].getBigInteger(),
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger(),
-                attributes[3].getBigInteger()
-            );
-            return keySpec.cast(spec);
-        } else { // X.509 handled in superclass
-            throw new InvalidKeySpecException("Only DSAPublicKeySpec and "
-                + "X509EncodedKeySpec supported for DSA public keys");
-        }
-    }
-
-    <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
-        if (DSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_PRIME),
-                new CK_ATTRIBUTE(CKA_SUBPRIME),
-                new CK_ATTRIBUTE(CKA_BASE),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            KeySpec spec = new DSAPrivateKeySpec(
-                attributes[0].getBigInteger(),
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger(),
-                attributes[3].getBigInteger()
-            );
-            return keySpec.cast(spec);
-        } else { // PKCS#8 handled in superclass
-            throw new InvalidKeySpecException("Only DSAPrivateKeySpec "
-                + "and PKCS8EncodedKeySpec supported for DSA private keys");
-        }
-    }
-
-    KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
-        return KeyFactory.getInstance("DSA", P11Util.getSunProvider());
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Digest.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,325 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.util.*;
-import java.nio.ByteBuffer;
-
-import java.security.*;
-
-import javax.crypto.SecretKey;
-
-import sun.nio.ch.DirectBuffer;
-
-import sun.security.util.MessageDigestSpi2;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * MessageDigest implementation class. This class currently supports
- * MD2, MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512.
- *
- * Note that many digest operations are on fairly small amounts of data
- * (less than 100 bytes total). For example, the 2nd hashing in HMAC or
- * the PRF in TLS. In order to speed those up, we use some buffering to
- * minimize number of the Java->native transitions.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11Digest extends MessageDigestSpi implements Cloneable,
-    MessageDigestSpi2 {
-
-    /* fields initialized, no session acquired */
-    private final static int S_BLANK    = 1;
-
-    /* data in buffer, session acquired, but digest not initialized */
-    private final static int S_BUFFERED = 2;
-
-    /* session initialized for digesting */
-    private final static int S_INIT     = 3;
-
-    private final static int BUFFER_SIZE = 96;
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id object
-    private final CK_MECHANISM mechanism;
-
-    // length of the digest in bytes
-    private final int digestLength;
-
-    // associated session, if any
-    private Session session;
-
-    // current state, one of S_* above
-    private int state;
-
-    // buffer to reduce number of JNI calls
-    private byte[] buffer;
-
-    // offset into the buffer
-    private int bufOfs;
-
-    P11Digest(Token token, String algorithm, long mechanism) {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = new CK_MECHANISM(mechanism);
-        switch ((int)mechanism) {
-        case (int)CKM_MD2:
-        case (int)CKM_MD5:
-            digestLength = 16;
-            break;
-        case (int)CKM_SHA_1:
-            digestLength = 20;
-            break;
-        case (int)CKM_SHA224:
-            digestLength = 28;
-            break;
-        case (int)CKM_SHA256:
-            digestLength = 32;
-            break;
-        case (int)CKM_SHA384:
-            digestLength = 48;
-            break;
-        case (int)CKM_SHA512:
-            digestLength = 64;
-            break;
-        default:
-            throw new ProviderException("Unknown mechanism: " + mechanism);
-        }
-        buffer = new byte[BUFFER_SIZE];
-        state = S_BLANK;
-    }
-
-    // see JCA spec
-    protected int engineGetDigestLength() {
-        return digestLength;
-    }
-
-    private void fetchSession() {
-        token.ensureValid();
-        if (state == S_BLANK) {
-            try {
-                session = token.getOpSession();
-                state = S_BUFFERED;
-            } catch (PKCS11Exception e) {
-                throw new ProviderException("No more session available", e);
-            }
-        }
-    }
-
-    // see JCA spec
-    protected void engineReset() {
-        token.ensureValid();
-
-        if (session != null) {
-            if (state == S_INIT && token.explicitCancel == true) {
-                session = token.killSession(session);
-            } else {
-                session = token.releaseSession(session);
-            }
-        }
-        state = S_BLANK;
-        bufOfs = 0;
-    }
-
-    // see JCA spec
-    protected byte[] engineDigest() {
-        try {
-            byte[] digest = new byte[digestLength];
-            int n = engineDigest(digest, 0, digestLength);
-            return digest;
-        } catch (DigestException e) {
-            throw new ProviderException("internal error", e);
-        }
-    }
-
-    // see JCA spec
-    protected int engineDigest(byte[] digest, int ofs, int len)
-            throws DigestException {
-        if (len < 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(), mechanism, buffer, 0,
-                        bufOfs, digest, ofs, len);
-                bufOfs = 0;
-            } else {
-                if (bufOfs != 0) {
-                    token.p11.C_DigestUpdate(session.id(), 0, buffer, 0,
-                            bufOfs);
-                    bufOfs = 0;
-                }
-                n = token.p11.C_DigestFinal(session.id(), digest, ofs, len);
-            }
-            if (n != digestLength) {
-                throw new ProviderException("internal digest length error");
-            }
-            return n;
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("digest() failed", e);
-        } finally {
-            engineReset();
-        }
-    }
-
-    // see JCA spec
-    protected void engineUpdate(byte in) {
-        byte[] temp = { in };
-        engineUpdate(temp, 0, 1);
-    }
-
-    // see JCA spec
-    protected void engineUpdate(byte[] in, int ofs, int len) {
-        if (len <= 0) {
-            return;
-        }
-
-        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);
-        }
-    }
-
-    // Called by SunJSSE via reflection during the SSL 3.0 handshake if
-    // the master secret is sensitive.
-    // Note: Change to protected after this method is moved from
-    // sun.security.util.MessageSpi2 interface to
-    // java.security.MessageDigestSpi class
-    public void engineUpdate(SecretKey key) throws InvalidKeyException {
-        // 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.
-        if (key instanceof P11Key == false) {
-            throw new InvalidKeyException("Not a P11Key: " + key);
-        }
-        P11Key p11Key = (P11Key)key;
-        if (p11Key.token != token) {
-            throw new InvalidKeyException("Not a P11Key of this provider: " +
-                    key);
-        }
-
-        fetchSession();
-        try {
-            if (state == S_BUFFERED) {
-                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) {
-        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(), mechanism);
-                state = S_INIT;
-            }
-            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);
-        }
-    }
-
-    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));
-        }
-        return copy;
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11ECDHKeyAgreement.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,214 +0,0 @@
-/*
- * Copyright (c) 2006, 2007, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.security.*;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * KeyAgreement implementation for ECDH.
- *
- * @author  Andreas Sterbenz
- * @since   1.6
- */
-final class P11ECDHKeyAgreement extends KeyAgreementSpi {
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id
-    private final long mechanism;
-
-    // private key, if initialized
-    private P11Key privateKey;
-
-    // encoded public point, non-null between doPhase() and generateSecret() only
-    private byte[] publicValue;
-
-    // length of the secret to be derived
-    private int secretLen;
-
-    P11ECDHKeyAgreement(Token token, String algorithm, long mechanism) {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-    }
-
-    // see JCE spec
-    protected void engineInit(Key key, SecureRandom random)
-            throws InvalidKeyException {
-        if (key instanceof PrivateKey == false) {
-            throw new InvalidKeyException
-                        ("Key must be instance of PrivateKey");
-        }
-        privateKey = P11KeyFactory.convertKey(token, key, "EC");
-        publicValue = null;
-    }
-
-    // see JCE spec
-    protected void engineInit(Key key, AlgorithmParameterSpec params,
-            SecureRandom random) throws InvalidKeyException,
-            InvalidAlgorithmParameterException {
-        if (params != null) {
-            throw new InvalidAlgorithmParameterException
-                        ("Parameters not supported");
-        }
-        engineInit(key, random);
-    }
-
-    // see JCE spec
-    protected Key engineDoPhase(Key key, boolean lastPhase)
-            throws InvalidKeyException, IllegalStateException {
-        if (privateKey == null) {
-            throw new IllegalStateException("Not initialized");
-        }
-        if (publicValue != null) {
-            throw new IllegalStateException("Phase already executed");
-        }
-        if (lastPhase == false) {
-            throw new IllegalStateException
-                ("Only two party agreement supported, lastPhase must be true");
-        }
-        if (key instanceof ECPublicKey == false) {
-            throw new InvalidKeyException
-                ("Key must be a PublicKey with algorithm EC");
-        }
-        ECPublicKey ecKey = (ECPublicKey)key;
-        int keyLenBits = ecKey.getParams().getCurve().getField().getFieldSize();
-        secretLen = (keyLenBits + 7) >> 3;
-        publicValue = P11ECKeyFactory.getEncodedPublicValue(ecKey);
-        return null;
-    }
-
-    // see JCE spec
-    protected byte[] engineGenerateSecret() throws IllegalStateException {
-        if ((privateKey == null) || (publicValue == null)) {
-            throw new IllegalStateException("Not initialized correctly");
-        }
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
-            };
-            CK_ECDH1_DERIVE_PARAMS ckParams =
-                    new CK_ECDH1_DERIVE_PARAMS(CKD_NULL, null, publicValue);
-            attributes = token.getAttributes
-                (O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
-            long keyID = token.p11.C_DeriveKey(session.id(),
-                new CK_MECHANISM(mechanism, ckParams), privateKey.keyID,
-                attributes);
-            attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE)
-            };
-            token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
-            byte[] secret = attributes[0].getByteArray();
-            token.p11.C_DestroyObject(session.id(), keyID);
-            return secret;
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("Could not derive key", e);
-        } finally {
-            publicValue = null;
-            token.releaseSession(session);
-        }
-    }
-
-    // see JCE spec
-    protected int engineGenerateSecret(byte[] sharedSecret, int
-            offset) throws IllegalStateException, ShortBufferException {
-        if (offset + secretLen > sharedSecret.length) {
-            throw new ShortBufferException("Need " + secretLen
-                + " bytes, only " + (sharedSecret.length - offset) + " available");
-        }
-        byte[] secret = engineGenerateSecret();
-        System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
-        return secret.length;
-    }
-
-    // see JCE spec
-    protected SecretKey engineGenerateSecret(String algorithm)
-            throws IllegalStateException, NoSuchAlgorithmException,
-            InvalidKeyException {
-        if (algorithm == null) {
-            throw new NoSuchAlgorithmException("Algorithm must not be null");
-        }
-        if (algorithm.equals("TlsPremasterSecret") == false) {
-            throw new NoSuchAlgorithmException
-                ("Only supported for algorithm TlsPremasterSecret");
-        }
-        return nativeGenerateSecret(algorithm);
-    }
-
-    private SecretKey nativeGenerateSecret(String algorithm)
-            throws IllegalStateException, NoSuchAlgorithmException,
-            InvalidKeyException {
-        if ((privateKey == null) || (publicValue == null)) {
-            throw new IllegalStateException("Not initialized correctly");
-        }
-        long keyType = CKK_GENERIC_SECRET;
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
-            };
-            CK_ECDH1_DERIVE_PARAMS ckParams =
-                    new CK_ECDH1_DERIVE_PARAMS(CKD_NULL, null, publicValue);
-            attributes = token.getAttributes
-                (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
-            long keyID = token.p11.C_DeriveKey(session.id(),
-                new CK_MECHANISM(mechanism, ckParams), privateKey.keyID,
-                attributes);
-            CK_ATTRIBUTE[] lenAttributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE_LEN),
-            };
-            token.p11.C_GetAttributeValue(session.id(), keyID, lenAttributes);
-            int keyLen = (int)lenAttributes[0].getLong();
-            SecretKey key = P11Key.secretKey
-                        (session, keyID, algorithm, keyLen << 3, attributes);
-            return key;
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not derive key", e);
-        } finally {
-            publicValue = null;
-            token.releaseSession(session);
-        }
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11ECKeyFactory.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 2006, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.io.IOException;
-import java.math.BigInteger;
-
-import java.security.*;
-import java.security.interfaces.*;
-import java.security.spec.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-import sun.security.util.DerValue;
-import sun.security.util.ECUtil;
-
-/**
- * EC KeyFactory implementation.
- *
- * @author  Andreas Sterbenz
- * @since   1.6
- */
-final class P11ECKeyFactory extends P11KeyFactory {
-    private static Provider sunECprovider;
-
-    private static Provider getSunECProvider() {
-        if (sunECprovider == null) {
-            sunECprovider = Security.getProvider("SunEC");
-            if (sunECprovider == null) {
-                throw new RuntimeException("Cannot load SunEC provider");
-            }
-        }
-
-        return sunECprovider;
-    }
-
-    P11ECKeyFactory(Token token, String algorithm) {
-        super(token, algorithm);
-    }
-
-    static ECParameterSpec getECParameterSpec(String name) {
-        return ECUtil.getECParameterSpec(getSunECProvider(), name);
-    }
-
-    static ECParameterSpec getECParameterSpec(int keySize) {
-        return ECUtil.getECParameterSpec(getSunECProvider(), keySize);
-    }
-
-    // Check that spec is a known supported curve and convert it to our
-    // ECParameterSpec subclass. If not possible, return null.
-    static ECParameterSpec getECParameterSpec(ECParameterSpec spec) {
-        return ECUtil.getECParameterSpec(getSunECProvider(), spec);
-    }
-
-    static ECParameterSpec decodeParameters(byte[] params) throws IOException {
-        return ECUtil.getECParameterSpec(getSunECProvider(), params);
-    }
-
-    static byte[] encodeParameters(ECParameterSpec params) {
-        return ECUtil.encodeECParameterSpec(getSunECProvider(), params);
-    }
-
-    static ECPoint decodePoint(byte[] encoded, EllipticCurve curve) throws IOException {
-        return ECUtil.decodePoint(encoded, curve);
-    }
-
-    // Used by ECDH KeyAgreement
-    static byte[] getEncodedPublicValue(PublicKey key) throws InvalidKeyException {
-        if (key instanceof ECPublicKey) {
-            ECPublicKey ecKey = (ECPublicKey)key;
-            ECPoint w = ecKey.getW();
-            ECParameterSpec params = ecKey.getParams();
-            return ECUtil.encodePoint(w, params.getCurve());
-        } else {
-            // should never occur
-            throw new InvalidKeyException
-                ("Key class not yet supported: " + key.getClass().getName());
-        }
-    }
-
-    PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
-        try {
-            if (key instanceof ECPublicKey) {
-                ECPublicKey ecKey = (ECPublicKey)key;
-                return generatePublic(
-                    ecKey.getW(),
-                    ecKey.getParams()
-                );
-            } else if ("X.509".equals(key.getFormat())) {
-                // let Sun provider parse for us, then recurse
-                byte[] encoded = key.getEncoded();
-
-                try {
-                    key = ECUtil.decodeX509ECPublicKey(encoded);
-                } catch (InvalidKeySpecException ikse) {
-                    throw new InvalidKeyException(ikse);
-                }
-
-                return implTranslatePublicKey(key);
-            } else {
-                throw new InvalidKeyException("PublicKey must be instance "
-                        + "of ECPublicKey or have X.509 encoding");
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create EC public key", e);
-        }
-    }
-
-    PrivateKey implTranslatePrivateKey(PrivateKey key)
-            throws InvalidKeyException {
-        try {
-            if (key instanceof ECPrivateKey) {
-                ECPrivateKey ecKey = (ECPrivateKey)key;
-                return generatePrivate(
-                    ecKey.getS(),
-                    ecKey.getParams()
-                );
-            } else if ("PKCS#8".equals(key.getFormat())) {
-                // let Sun provider parse for us, then recurse
-                byte[] encoded = key.getEncoded();
-
-                try {
-                    key = ECUtil.decodePKCS8ECPrivateKey(encoded);
-                } catch (InvalidKeySpecException ikse) {
-                    throw new InvalidKeyException(ikse);
-                }
-
-                return implTranslatePrivateKey(key);
-            } else {
-                throw new InvalidKeyException("PrivateKey must be instance "
-                        + "of ECPrivateKey or have PKCS#8 encoding");
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create EC private key", e);
-        }
-    }
-
-    // see JCA spec
-    protected PublicKey engineGeneratePublic(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec instanceof X509EncodedKeySpec) {
-            try {
-                byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
-                PublicKey key = ECUtil.decodeX509ECPublicKey(encoded);
-                return implTranslatePublicKey(key);
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeySpecException
-                        ("Could not create EC public key", e);
-            }
-        }
-        if (keySpec instanceof ECPublicKeySpec == false) {
-            throw new InvalidKeySpecException("Only ECPublicKeySpec and "
-                + "X509EncodedKeySpec supported for EC public keys");
-        }
-        try {
-            ECPublicKeySpec ec = (ECPublicKeySpec)keySpec;
-            return generatePublic(
-                ec.getW(),
-                ec.getParams()
-            );
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeySpecException
-                ("Could not create EC public key", e);
-        }
-    }
-
-    // see JCA spec
-    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec instanceof PKCS8EncodedKeySpec) {
-            try {
-                byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
-                PrivateKey key = ECUtil.decodePKCS8ECPrivateKey(encoded);
-                return implTranslatePrivateKey(key);
-            } catch (GeneralSecurityException e) {
-                throw new InvalidKeySpecException
-                        ("Could not create EC private key", e);
-            }
-        }
-        if (keySpec instanceof ECPrivateKeySpec == false) {
-            throw new InvalidKeySpecException("Only ECPrivateKeySpec and "
-                + "PKCS8EncodedKeySpec supported for EC private keys");
-        }
-        try {
-            ECPrivateKeySpec ec = (ECPrivateKeySpec)keySpec;
-            return generatePrivate(
-                ec.getS(),
-                ec.getParams()
-            );
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeySpecException
-                ("Could not create EC private key", e);
-        }
-    }
-
-    private PublicKey generatePublic(ECPoint point, ECParameterSpec params)
-            throws PKCS11Exception {
-        byte[] encodedParams =
-            ECUtil.encodeECParameterSpec(getSunECProvider(), params);
-        byte[] encodedPoint =
-            ECUtil.encodePoint(point, params.getCurve());
-
-        // Check whether the X9.63 encoding of an EC point shall be wrapped
-        // in an ASN.1 OCTET STRING
-        if (!token.config.getUseEcX963Encoding()) {
-            try {
-                encodedPoint =
-                    new DerValue(DerValue.tag_OctetString, encodedPoint)
-                        .toByteArray();
-            } catch (IOException e) {
-                throw new
-                    IllegalArgumentException("Could not DER encode point", e);
-            }
-        }
-
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
-            new CK_ATTRIBUTE(CKA_EC_POINT, encodedPoint),
-            new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PUBLIC_KEY, CKK_EC, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.publicKey
-                (session, keyID, "EC", params.getCurve().getField().getFieldSize(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private PrivateKey generatePrivate(BigInteger s, ECParameterSpec params)
-            throws PKCS11Exception {
-        byte[] encodedParams =
-            ECUtil.encodeECParameterSpec(getSunECProvider(), params);
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
-            new CK_ATTRIBUTE(CKA_VALUE, s),
-            new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PRIVATE_KEY, CKK_EC, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.privateKey
-                (session, keyID, "EC", params.getCurve().getField().getFieldSize(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
-        if (ECPublicKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_EC_POINT),
-                new CK_ATTRIBUTE(CKA_EC_PARAMS),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            try {
-                ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
-                ECPoint point = decodePoint(attributes[0].getByteArray(), params.getCurve());
-                return keySpec.cast(new ECPublicKeySpec(point, params));
-            } catch (IOException e) {
-                throw new InvalidKeySpecException("Could not parse key", e);
-            }
-        } else { // X.509 handled in superclass
-            throw new InvalidKeySpecException("Only ECPublicKeySpec and "
-                + "X509EncodedKeySpec supported for EC public keys");
-        }
-    }
-
-    <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
-        if (ECPrivateKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_EC_PARAMS),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            try {
-                ECParameterSpec params = decodeParameters(attributes[1].getByteArray());
-                return keySpec.cast(
-                    new ECPrivateKeySpec(attributes[0].getBigInteger(), params));
-            } catch (IOException e) {
-                throw new InvalidKeySpecException("Could not parse key", e);
-            }
-        } else { // PKCS#8 handled in superclass
-            throw new InvalidKeySpecException("Only ECPrivateKeySpec "
-                + "and PKCS8EncodedKeySpec supported for EC private keys");
-        }
-    }
-
-    KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
-        return KeyFactory.getInstance("EC", getSunECProvider());
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Key.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1188 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.io.*;
-import java.lang.ref.*;
-import java.math.BigInteger;
-import java.util.*;
-
-import java.security.*;
-import java.security.interfaces.*;
-import java.security.spec.*;
-
-import javax.crypto.*;
-import javax.crypto.interfaces.*;
-import javax.crypto.spec.*;
-
-import sun.security.rsa.RSAPublicKeyImpl;
-
-import sun.security.internal.interfaces.TlsMasterSecret;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-import sun.security.util.Debug;
-import sun.security.util.DerValue;
-import sun.security.util.Length;
-import sun.security.util.ECUtil;
-
-/**
- * Key implementation classes.
- *
- * In PKCS#11, the components of private and secret keys may or may not
- * be accessible. If they are, we use the algorithm specific key classes
- * (e.g. DSAPrivateKey) for compatibility with existing applications.
- * If the components are not accessible, we use a generic class that
- * only implements PrivateKey (or SecretKey). Whether the components of a
- * key are extractable is automatically determined when the key object is
- * created.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-abstract class P11Key implements Key, Length {
-
-    private static final long serialVersionUID = -2575874101938349339L;
-
-    private final static String PUBLIC = "public";
-    private final static String PRIVATE = "private";
-    private final static String SECRET = "secret";
-
-    // type of key, one of (PUBLIC, PRIVATE, SECRET)
-    final String type;
-
-    // token instance
-    final Token token;
-
-    // algorithm name, returned by getAlgorithm(), etc.
-    final String algorithm;
-
-    // key id
-    final long keyID;
-
-    // effective key length of the key, e.g. 56 for a DES key
-    final int keyLength;
-
-    // flags indicating whether the key is a token object, sensitive, extractable
-    final boolean tokenObject, sensitive, extractable;
-
-    // phantom reference notification clean up for session keys
-    private final SessionKeyRef sessionKeyRef;
-
-    P11Key(String type, Session session, long keyID, String algorithm,
-            int keyLength, CK_ATTRIBUTE[] attributes) {
-        this.type = type;
-        this.token = session.token;
-        this.keyID = keyID;
-        this.algorithm = algorithm;
-        this.keyLength = keyLength;
-        boolean tokenObject = false;
-        boolean sensitive = false;
-        boolean extractable = true;
-        int n = (attributes == null) ? 0 : attributes.length;
-        for (int i = 0; i < n; i++) {
-            CK_ATTRIBUTE attr = attributes[i];
-            if (attr.type == CKA_TOKEN) {
-                tokenObject = attr.getBoolean();
-            } else if (attr.type == CKA_SENSITIVE) {
-                sensitive = attr.getBoolean();
-            } else if (attr.type == CKA_EXTRACTABLE) {
-                extractable = attr.getBoolean();
-            }
-        }
-        this.tokenObject = tokenObject;
-        this.sensitive = sensitive;
-        this.extractable = extractable;
-        if (tokenObject == false) {
-            sessionKeyRef = new SessionKeyRef(this, keyID, session);
-        } else {
-            sessionKeyRef = null;
-        }
-    }
-
-    // see JCA spec
-    public final String getAlgorithm() {
-        token.ensureValid();
-        return algorithm;
-    }
-
-    // see JCA spec
-    public final byte[] getEncoded() {
-        byte[] b = getEncodedInternal();
-        return (b == null) ? null : b.clone();
-    }
-
-    abstract byte[] getEncodedInternal();
-
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        // equals() should never throw exceptions
-        if (token.isValid() == false) {
-            return false;
-        }
-        if (obj instanceof Key == false) {
-            return false;
-        }
-        String thisFormat = getFormat();
-        if (thisFormat == null) {
-            // no encoding, key only equal to itself
-            // XXX getEncoded() for unextractable keys will change that
-            return false;
-        }
-        Key other = (Key)obj;
-        if (thisFormat.equals(other.getFormat()) == false) {
-            return false;
-        }
-        byte[] thisEnc = this.getEncodedInternal();
-        byte[] otherEnc;
-        if (obj instanceof P11Key) {
-            otherEnc = ((P11Key)other).getEncodedInternal();
-        } else {
-            otherEnc = other.getEncoded();
-        }
-        return MessageDigest.isEqual(thisEnc, otherEnc);
-    }
-
-    public int hashCode() {
-        // hashCode() should never throw exceptions
-        if (token.isValid() == false) {
-            return 0;
-        }
-        byte[] b1 = getEncodedInternal();
-        if (b1 == null) {
-            return 0;
-        }
-        int r = b1.length;
-        for (int i = 0; i < b1.length; i++) {
-            r += (b1[i] & 0xff) * 37;
-        }
-        return r;
-    }
-
-    protected Object writeReplace() throws ObjectStreamException {
-        KeyRep.Type type;
-        String format = getFormat();
-        if (isPrivate() && "PKCS#8".equals(format)) {
-            type = KeyRep.Type.PRIVATE;
-        } else if (isPublic() && "X.509".equals(format)) {
-            type = KeyRep.Type.PUBLIC;
-        } else if (isSecret() && "RAW".equals(format)) {
-            type = KeyRep.Type.SECRET;
-        } else {
-            // XXX short term serialization for unextractable keys
-            throw new NotSerializableException
-                ("Cannot serialize sensitive and unextractable keys");
-        }
-        return new KeyRep(type, getAlgorithm(), format, getEncoded());
-    }
-
-    public String toString() {
-        token.ensureValid();
-        String s1 = token.provider.getName() + " " + algorithm + " " + type
-                + " key, " + keyLength + " bits";
-        s1 += " (id " + keyID + ", "
-                + (tokenObject ? "token" : "session") + " object";
-        if (isPublic()) {
-            s1 += ")";
-        } else {
-            s1 += ", " + (sensitive ? "" : "not ") + "sensitive";
-            s1 += ", " + (extractable ? "" : "un") + "extractable)";
-        }
-        return s1;
-    }
-
-    /**
-     * Return bit length of the key.
-     */
-    @Override
-    public int length() {
-        return keyLength;
-    }
-
-    boolean isPublic() {
-        return type == PUBLIC;
-    }
-
-    boolean isPrivate() {
-        return type == PRIVATE;
-    }
-
-    boolean isSecret() {
-        return type == SECRET;
-    }
-
-    void fetchAttributes(CK_ATTRIBUTE[] attributes) {
-        Session tempSession = null;
-        try {
-            tempSession = token.getOpSession();
-            token.p11.C_GetAttributeValue(tempSession.id(), keyID, attributes);
-        } catch (PKCS11Exception e) {
-            throw new ProviderException(e);
-        } finally {
-            token.releaseSession(tempSession);
-        }
-    }
-
-    private final static CK_ATTRIBUTE[] A0 = new CK_ATTRIBUTE[0];
-
-    private static CK_ATTRIBUTE[] getAttributes(Session session, long keyID,
-            CK_ATTRIBUTE[] knownAttributes, CK_ATTRIBUTE[] desiredAttributes) {
-        if (knownAttributes == null) {
-            knownAttributes = A0;
-        }
-        for (int i = 0; i < desiredAttributes.length; i++) {
-            // For each desired attribute, check to see if we have the value
-            // available already. If everything is here, we save a native call.
-            CK_ATTRIBUTE attr = desiredAttributes[i];
-            for (CK_ATTRIBUTE known : knownAttributes) {
-                if ((attr.type == known.type) && (known.pValue != null)) {
-                    attr.pValue = known.pValue;
-                    break; // break inner for loop
-                }
-            }
-            if (attr.pValue == null) {
-                // nothing found, need to call C_GetAttributeValue()
-                for (int j = 0; j < i; j++) {
-                    // clear values copied from knownAttributes
-                    desiredAttributes[j].pValue = null;
-                }
-                try {
-                    session.token.p11.C_GetAttributeValue
-                            (session.id(), keyID, desiredAttributes);
-                } catch (PKCS11Exception e) {
-                    throw new ProviderException(e);
-                }
-                break; // break loop, goto return
-            }
-        }
-        return desiredAttributes;
-    }
-
-    static SecretKey secretKey(Session session, long keyID, String algorithm,
-            int keyLength, CK_ATTRIBUTE[] attributes) {
-        attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_TOKEN),
-            new CK_ATTRIBUTE(CKA_SENSITIVE),
-            new CK_ATTRIBUTE(CKA_EXTRACTABLE),
-        });
-        return new P11SecretKey(session, keyID, algorithm, keyLength, attributes);
-    }
-
-    static SecretKey masterSecretKey(Session session, long keyID, String algorithm,
-            int keyLength, CK_ATTRIBUTE[] attributes, int major, int minor) {
-        attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_TOKEN),
-            new CK_ATTRIBUTE(CKA_SENSITIVE),
-            new CK_ATTRIBUTE(CKA_EXTRACTABLE),
-        });
-        return new P11TlsMasterSecretKey
-                (session, keyID, algorithm, keyLength, attributes, major, minor);
-    }
-
-    // we assume that all components of public keys are always accessible
-    static PublicKey publicKey(Session session, long keyID, String algorithm,
-            int keyLength, CK_ATTRIBUTE[] attributes) {
-        switch (algorithm) {
-            case "RSA":
-                return new P11RSAPublicKey
-                    (session, keyID, algorithm, keyLength, attributes);
-            case "DSA":
-                return new P11DSAPublicKey
-                    (session, keyID, algorithm, keyLength, attributes);
-            case "DH":
-                return new P11DHPublicKey
-                    (session, keyID, algorithm, keyLength, attributes);
-            case "EC":
-                return new P11ECPublicKey
-                    (session, keyID, algorithm, keyLength, attributes);
-            default:
-                throw new ProviderException
-                    ("Unknown public key algorithm " + algorithm);
-        }
-    }
-
-    static PrivateKey privateKey(Session session, long keyID, String algorithm,
-            int keyLength, CK_ATTRIBUTE[] attributes) {
-        attributes = getAttributes(session, keyID, attributes, new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_TOKEN),
-            new CK_ATTRIBUTE(CKA_SENSITIVE),
-            new CK_ATTRIBUTE(CKA_EXTRACTABLE),
-        });
-        if (attributes[1].getBoolean() || (attributes[2].getBoolean() == false)) {
-            return new P11PrivateKey
-                (session, keyID, algorithm, keyLength, attributes);
-        } else {
-            switch (algorithm) {
-                case "RSA":
-                    // In order to decide if this is RSA CRT key, we first query
-                    // and see if all extra CRT attributes are available.
-                    CK_ATTRIBUTE[] attrs2 = new CK_ATTRIBUTE[] {
-                        new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
-                        new CK_ATTRIBUTE(CKA_PRIME_1),
-                        new CK_ATTRIBUTE(CKA_PRIME_2),
-                        new CK_ATTRIBUTE(CKA_EXPONENT_1),
-                        new CK_ATTRIBUTE(CKA_EXPONENT_2),
-                        new CK_ATTRIBUTE(CKA_COEFFICIENT),
-                    };
-                    boolean crtKey;
-                    try {
-                        session.token.p11.C_GetAttributeValue
-                            (session.id(), keyID, attrs2);
-                        crtKey = ((attrs2[0].pValue instanceof byte[]) &&
-                                  (attrs2[1].pValue instanceof byte[]) &&
-                                  (attrs2[2].pValue instanceof byte[]) &&
-                                  (attrs2[3].pValue instanceof byte[]) &&
-                                  (attrs2[4].pValue instanceof byte[]) &&
-                                  (attrs2[5].pValue instanceof byte[])) ;
-                    } catch (PKCS11Exception e) {
-                        // ignore, assume not available
-                        crtKey = false;
-                    }
-                    if (crtKey) {
-                        return new P11RSAPrivateKey
-                                (session, keyID, algorithm, keyLength, attributes, attrs2);
-                    } else {
-                        return new P11RSAPrivateNonCRTKey
-                                (session, keyID, algorithm, keyLength, attributes);
-                    }
-                case "DSA":
-                    return new P11DSAPrivateKey
-                            (session, keyID, algorithm, keyLength, attributes);
-                case "DH":
-                    return new P11DHPrivateKey
-                            (session, keyID, algorithm, keyLength, attributes);
-                case "EC":
-                    return new P11ECPrivateKey
-                            (session, keyID, algorithm, keyLength, attributes);
-                default:
-                    throw new ProviderException
-                            ("Unknown private key algorithm " + algorithm);
-            }
-        }
-    }
-
-    // class for sensitive and unextractable private keys
-    private static final class P11PrivateKey extends P11Key
-                                                implements PrivateKey {
-        private static final long serialVersionUID = -2138581185214187615L;
-
-        P11PrivateKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
-        }
-        // XXX temporary encoding for serialization purposes
-        public String getFormat() {
-            token.ensureValid();
-            return null;
-        }
-        byte[] getEncodedInternal() {
-            token.ensureValid();
-            return null;
-        }
-    }
-
-    private static class P11SecretKey extends P11Key implements SecretKey {
-        private static final long serialVersionUID = -7828241727014329084L;
-        private volatile byte[] encoded;
-        P11SecretKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(SECRET, session, keyID, algorithm, keyLength, attributes);
-        }
-        public String getFormat() {
-            token.ensureValid();
-            if (sensitive || (extractable == false)) {
-                return null;
-            } else {
-                return "RAW";
-            }
-        }
-        byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (getFormat() == null) {
-                return null;
-            }
-            byte[] b = encoded;
-            if (b == null) {
-                synchronized (this) {
-                    b = encoded;
-                    if (b == null) {
-                        Session tempSession = null;
-                        try {
-                            tempSession = token.getOpSession();
-                            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                                new CK_ATTRIBUTE(CKA_VALUE),
-                            };
-                            token.p11.C_GetAttributeValue
-                                (tempSession.id(), keyID, attributes);
-                            b = attributes[0].getByteArray();
-                        } catch (PKCS11Exception e) {
-                            throw new ProviderException(e);
-                        } finally {
-                            token.releaseSession(tempSession);
-                        }
-                        encoded = b;
-                    }
-                }
-            }
-            return b;
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    private static class P11TlsMasterSecretKey extends P11SecretKey
-            implements TlsMasterSecret {
-        private static final long serialVersionUID = -1318560923770573441L;
-
-        private final int majorVersion, minorVersion;
-        P11TlsMasterSecretKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes, int major, int minor) {
-            super(session, keyID, algorithm, keyLength, attributes);
-            this.majorVersion = major;
-            this.minorVersion = minor;
-        }
-        public int getMajorVersion() {
-            return majorVersion;
-        }
-
-        public int getMinorVersion() {
-            return minorVersion;
-        }
-    }
-
-    // RSA CRT private key
-    private static final class P11RSAPrivateKey extends P11Key
-                implements RSAPrivateCrtKey {
-        private static final long serialVersionUID = 9215872438913515220L;
-
-        private BigInteger n, e, d, p, q, pe, qe, coeff;
-        private byte[] encoded;
-        P11RSAPrivateKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE[] crtAttrs) {
-            super(PRIVATE, session, keyID, algorithm, keyLength, attrs);
-
-            for (CK_ATTRIBUTE a : crtAttrs) {
-                if (a.type == CKA_PUBLIC_EXPONENT) {
-                    e = a.getBigInteger();
-                } else if (a.type == CKA_PRIME_1) {
-                    p = a.getBigInteger();
-                } else if (a.type == CKA_PRIME_2) {
-                    q = a.getBigInteger();
-                } else if (a.type == CKA_EXPONENT_1) {
-                    pe = a.getBigInteger();
-                } else if (a.type == CKA_EXPONENT_2) {
-                    qe = a.getBigInteger();
-                } else if (a.type == CKA_COEFFICIENT) {
-                    coeff = a.getBigInteger();
-                }
-            }
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (n != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_MODULUS),
-                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
-            };
-            fetchAttributes(attributes);
-            n = attributes[0].getBigInteger();
-            d = attributes[1].getBigInteger();
-        }
-
-        public String getFormat() {
-            token.ensureValid();
-            return "PKCS#8";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    // XXX make constructor in SunRsaSign provider public
-                    // and call it directly
-                    KeyFactory factory = KeyFactory.getInstance
-                        ("RSA", P11Util.getSunRsaSignProvider());
-                    Key newKey = factory.translateKey(this);
-                    encoded = newKey.getEncoded();
-                } catch (GeneralSecurityException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public BigInteger getModulus() {
-            fetchValues();
-            return n;
-        }
-        public BigInteger getPublicExponent() {
-            return e;
-        }
-        public BigInteger getPrivateExponent() {
-            fetchValues();
-            return d;
-        }
-        public BigInteger getPrimeP() {
-            return p;
-        }
-        public BigInteger getPrimeQ() {
-            return q;
-        }
-        public BigInteger getPrimeExponentP() {
-            return pe;
-        }
-        public BigInteger getPrimeExponentQ() {
-            return qe;
-        }
-        public BigInteger getCrtCoefficient() {
-            return coeff;
-        }
-    }
-
-    // RSA non-CRT private key
-    private static final class P11RSAPrivateNonCRTKey extends P11Key
-                implements RSAPrivateKey {
-        private static final long serialVersionUID = 1137764983777411481L;
-
-        private BigInteger n, d;
-        private byte[] encoded;
-        P11RSAPrivateNonCRTKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (n != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_MODULUS),
-                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
-            };
-            fetchAttributes(attributes);
-            n = attributes[0].getBigInteger();
-            d = attributes[1].getBigInteger();
-        }
-        public String getFormat() {
-            token.ensureValid();
-            return "PKCS#8";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    // XXX make constructor in SunRsaSign provider public
-                    // and call it directly
-                    KeyFactory factory = KeyFactory.getInstance
-                        ("RSA", P11Util.getSunRsaSignProvider());
-                    Key newKey = factory.translateKey(this);
-                    encoded = newKey.getEncoded();
-                } catch (GeneralSecurityException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public BigInteger getModulus() {
-            fetchValues();
-            return n;
-        }
-        public BigInteger getPrivateExponent() {
-            fetchValues();
-            return d;
-        }
-    }
-
-    private static final class P11RSAPublicKey extends P11Key
-                                                implements RSAPublicKey {
-        private static final long serialVersionUID = -826726289023854455L;
-
-        private BigInteger n, e;
-        private byte[] encoded;
-        P11RSAPublicKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PUBLIC, session, keyID, algorithm, keyLength, attributes);
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (n != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_MODULUS),
-                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
-            };
-            fetchAttributes(attributes);
-            n = attributes[0].getBigInteger();
-            e = attributes[1].getBigInteger();
-        }
-        public String getFormat() {
-            token.ensureValid();
-            return "X.509";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    encoded = new RSAPublicKeyImpl(n, e).getEncoded();
-                } catch (InvalidKeyException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public BigInteger getModulus() {
-            fetchValues();
-            return n;
-        }
-        public BigInteger getPublicExponent() {
-            fetchValues();
-            return e;
-        }
-        public String toString() {
-            fetchValues();
-            return super.toString() +  "\n  modulus: " + n
-                + "\n  public exponent: " + e;
-        }
-    }
-
-    private static final class P11DSAPublicKey extends P11Key
-                                                implements DSAPublicKey {
-        private static final long serialVersionUID = 5989753793316396637L;
-
-        private BigInteger y;
-        private DSAParams params;
-        private byte[] encoded;
-        P11DSAPublicKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PUBLIC, session, keyID, algorithm, keyLength, attributes);
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (y != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_PRIME),
-                new CK_ATTRIBUTE(CKA_SUBPRIME),
-                new CK_ATTRIBUTE(CKA_BASE),
-            };
-            fetchAttributes(attributes);
-            y = attributes[0].getBigInteger();
-            params = new DSAParameterSpec(
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger(),
-                attributes[3].getBigInteger()
-            );
-        }
-        public String getFormat() {
-            token.ensureValid();
-            return "X.509";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    Key key = new sun.security.provider.DSAPublicKey
-                            (y, params.getP(), params.getQ(), params.getG());
-                    encoded = key.getEncoded();
-                } catch (InvalidKeyException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public BigInteger getY() {
-            fetchValues();
-            return y;
-        }
-        public DSAParams getParams() {
-            fetchValues();
-            return params;
-        }
-        public String toString() {
-            fetchValues();
-            return super.toString() +  "\n  y: " + y + "\n  p: " + params.getP()
-                + "\n  q: " + params.getQ() + "\n  g: " + params.getG();
-        }
-    }
-
-    private static final class P11DSAPrivateKey extends P11Key
-                                                implements DSAPrivateKey {
-        private static final long serialVersionUID = 3119629997181999389L;
-
-        private BigInteger x;
-        private DSAParams params;
-        private byte[] encoded;
-        P11DSAPrivateKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (x != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_PRIME),
-                new CK_ATTRIBUTE(CKA_SUBPRIME),
-                new CK_ATTRIBUTE(CKA_BASE),
-            };
-            fetchAttributes(attributes);
-            x = attributes[0].getBigInteger();
-            params = new DSAParameterSpec(
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger(),
-                attributes[3].getBigInteger()
-            );
-        }
-        public String getFormat() {
-            token.ensureValid();
-            return "PKCS#8";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    Key key = new sun.security.provider.DSAPrivateKey
-                            (x, params.getP(), params.getQ(), params.getG());
-                    encoded = key.getEncoded();
-                } catch (InvalidKeyException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public BigInteger getX() {
-            fetchValues();
-            return x;
-        }
-        public DSAParams getParams() {
-            fetchValues();
-            return params;
-        }
-    }
-
-    private static final class P11DHPrivateKey extends P11Key
-                                                implements DHPrivateKey {
-        private static final long serialVersionUID = -1698576167364928838L;
-
-        private BigInteger x;
-        private DHParameterSpec params;
-        private byte[] encoded;
-        P11DHPrivateKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (x != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_PRIME),
-                new CK_ATTRIBUTE(CKA_BASE),
-            };
-            fetchAttributes(attributes);
-            x = attributes[0].getBigInteger();
-            params = new DHParameterSpec(
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger()
-            );
-        }
-        public String getFormat() {
-            token.ensureValid();
-            return "PKCS#8";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    DHPrivateKeySpec spec = new DHPrivateKeySpec
-                        (x, params.getP(), params.getG());
-                    KeyFactory kf = KeyFactory.getInstance
-                        ("DH", P11Util.getSunJceProvider());
-                    Key key = kf.generatePrivate(spec);
-                    encoded = key.getEncoded();
-                } catch (GeneralSecurityException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public BigInteger getX() {
-            fetchValues();
-            return x;
-        }
-        public DHParameterSpec getParams() {
-            fetchValues();
-            return params;
-        }
-        public int hashCode() {
-            if (token.isValid() == false) {
-                return 0;
-            }
-            fetchValues();
-            return Objects.hash(x, params.getP(), params.getG());
-        }
-        public boolean equals(Object obj) {
-            if (this == obj) return true;
-            // equals() should never throw exceptions
-            if (token.isValid() == false) {
-                return false;
-            }
-            if (!(obj instanceof DHPrivateKey)) {
-                return false;
-            }
-            fetchValues();
-            DHPrivateKey other = (DHPrivateKey) obj;
-            DHParameterSpec otherParams = other.getParams();
-            return ((this.x.compareTo(other.getX()) == 0) &&
-                    (this.params.getP().compareTo(otherParams.getP()) == 0) &&
-                    (this.params.getG().compareTo(otherParams.getG()) == 0));
-        }
-    }
-
-    private static final class P11DHPublicKey extends P11Key
-                                                implements DHPublicKey {
-        static final long serialVersionUID = -598383872153843657L;
-
-        private BigInteger y;
-        private DHParameterSpec params;
-        private byte[] encoded;
-        P11DHPublicKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PUBLIC, session, keyID, algorithm, keyLength, attributes);
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (y != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_PRIME),
-                new CK_ATTRIBUTE(CKA_BASE),
-            };
-            fetchAttributes(attributes);
-            y = attributes[0].getBigInteger();
-            params = new DHParameterSpec(
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger()
-            );
-        }
-        public String getFormat() {
-            token.ensureValid();
-            return "X.509";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    DHPublicKeySpec spec = new DHPublicKeySpec
-                        (y, params.getP(), params.getG());
-                    KeyFactory kf = KeyFactory.getInstance
-                        ("DH", P11Util.getSunJceProvider());
-                    Key key = kf.generatePublic(spec);
-                    encoded = key.getEncoded();
-                } catch (GeneralSecurityException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public BigInteger getY() {
-            fetchValues();
-            return y;
-        }
-        public DHParameterSpec getParams() {
-            fetchValues();
-            return params;
-        }
-        public String toString() {
-            fetchValues();
-            return super.toString() +  "\n  y: " + y + "\n  p: " + params.getP()
-                + "\n  g: " + params.getG();
-        }
-        public int hashCode() {
-            if (token.isValid() == false) {
-                return 0;
-            }
-            fetchValues();
-            return Objects.hash(y, params.getP(), params.getG());
-        }
-        public boolean equals(Object obj) {
-            if (this == obj) return true;
-            // equals() should never throw exceptions
-            if (token.isValid() == false) {
-                return false;
-            }
-            if (!(obj instanceof DHPublicKey)) {
-                return false;
-            }
-            fetchValues();
-            DHPublicKey other = (DHPublicKey) obj;
-            DHParameterSpec otherParams = other.getParams();
-            return ((this.y.compareTo(other.getY()) == 0) &&
-                    (this.params.getP().compareTo(otherParams.getP()) == 0) &&
-                    (this.params.getG().compareTo(otherParams.getG()) == 0));
-        }
-    }
-
-    private static final class P11ECPrivateKey extends P11Key
-                                                implements ECPrivateKey {
-        private static final long serialVersionUID = -7786054399510515515L;
-
-        private BigInteger s;
-        private ECParameterSpec params;
-        private byte[] encoded;
-        P11ECPrivateKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PRIVATE, session, keyID, algorithm, keyLength, attributes);
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (s != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE),
-                new CK_ATTRIBUTE(CKA_EC_PARAMS, params),
-            };
-            fetchAttributes(attributes);
-            s = attributes[0].getBigInteger();
-            try {
-                params = P11ECKeyFactory.decodeParameters
-                            (attributes[1].getByteArray());
-            } catch (Exception e) {
-                throw new RuntimeException("Could not parse key values", e);
-            }
-        }
-        public String getFormat() {
-            token.ensureValid();
-            return "PKCS#8";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    Key key = ECUtil.generateECPrivateKey(s, params);
-                    encoded = key.getEncoded();
-                } catch (InvalidKeySpecException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public BigInteger getS() {
-            fetchValues();
-            return s;
-        }
-        public ECParameterSpec getParams() {
-            fetchValues();
-            return params;
-        }
-    }
-
-    private static final class P11ECPublicKey extends P11Key
-                                                implements ECPublicKey {
-        private static final long serialVersionUID = -6371481375154806089L;
-
-        private ECPoint w;
-        private ECParameterSpec params;
-        private byte[] encoded;
-        P11ECPublicKey(Session session, long keyID, String algorithm,
-                int keyLength, CK_ATTRIBUTE[] attributes) {
-            super(PUBLIC, session, keyID, algorithm, keyLength, attributes);
-        }
-        private synchronized void fetchValues() {
-            token.ensureValid();
-            if (w != null) {
-                return;
-            }
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_EC_POINT),
-                new CK_ATTRIBUTE(CKA_EC_PARAMS),
-            };
-            fetchAttributes(attributes);
-
-            try {
-                params = P11ECKeyFactory.decodeParameters
-                            (attributes[1].getByteArray());
-                byte[] ecKey = attributes[0].getByteArray();
-
-                // Check whether the X9.63 encoding of an EC point is wrapped
-                // in an ASN.1 OCTET STRING
-                if (!token.config.getUseEcX963Encoding()) {
-                    DerValue wECPoint = new DerValue(ecKey);
-
-                    if (wECPoint.getTag() != DerValue.tag_OctetString) {
-                        throw new IOException("Could not DER decode EC point." +
-                            " Unexpected tag: " + wECPoint.getTag());
-                    }
-                    w = P11ECKeyFactory.decodePoint
-                        (wECPoint.getDataBytes(), params.getCurve());
-
-                } else {
-                    w = P11ECKeyFactory.decodePoint(ecKey, params.getCurve());
-                }
-
-            } catch (Exception e) {
-                throw new RuntimeException("Could not parse key values", e);
-            }
-        }
-        public String getFormat() {
-            token.ensureValid();
-            return "X.509";
-        }
-        synchronized byte[] getEncodedInternal() {
-            token.ensureValid();
-            if (encoded == null) {
-                fetchValues();
-                try {
-                    return ECUtil.x509EncodeECPublicKey(w, params);
-                } catch (InvalidKeySpecException e) {
-                    throw new ProviderException(e);
-                }
-            }
-            return encoded;
-        }
-        public ECPoint getW() {
-            fetchValues();
-            return w;
-        }
-        public ECParameterSpec getParams() {
-            fetchValues();
-            return params;
-        }
-        public String toString() {
-            fetchValues();
-            return super.toString()
-                + "\n  public x coord: " + w.getAffineX()
-                + "\n  public y coord: " + w.getAffineY()
-                + "\n  parameters: " + params;
-        }
-    }
-}
-
-/*
- * NOTE: Must use PhantomReference here and not WeakReference
- * otherwise the key maybe cleared before other objects which
- * still use these keys during finalization such as SSLSocket.
- */
-final class SessionKeyRef extends PhantomReference<P11Key>
-    implements Comparable<SessionKeyRef> {
-    private static ReferenceQueue<P11Key> refQueue =
-        new ReferenceQueue<P11Key>();
-    private static Set<SessionKeyRef> refList =
-        Collections.synchronizedSortedSet(new TreeSet<SessionKeyRef>());
-
-    static ReferenceQueue<P11Key> referenceQueue() {
-        return refQueue;
-    }
-
-    private static void drainRefQueueBounded() {
-        Session sess = null;
-        Token tkn = null;
-        while (true) {
-            SessionKeyRef next = (SessionKeyRef) refQueue.poll();
-            if (next == null) {
-                break;
-            }
-
-            // If the token is still valid, try to remove the object
-            if (next.session.token.isValid()) {
-                // If this key's token is the same as the previous key, the
-                // same session can be used for C_DestroyObject.
-                try {
-                    if (next.session.token != tkn || sess == null) {
-                        // Release session if not using previous token
-                        if (tkn != null && sess != null) {
-                            tkn.releaseSession(sess);
-                            sess = null;
-                        }
-
-                        tkn = next.session.token;
-                        sess = tkn.getOpSession();
-                    }
-                    next.disposeNative(sess);
-                } catch (PKCS11Exception e) {
-                    // ignore
-                }
-            }
-            // Regardless of native results, dispose of java references
-            next.dispose();
-        }
-
-        if (tkn != null && sess != null) {
-            tkn.releaseSession(sess);
-        }
-    }
-
-    // handle to the native key
-    private long keyID;
-    private Session session;
-
-    SessionKeyRef(P11Key key , long keyID, Session session) {
-        super(key, refQueue);
-        this.keyID = keyID;
-        this.session = session;
-        this.session.addObject();
-        refList.add(this);
-        drainRefQueueBounded();
-    }
-
-    private void disposeNative(Session s) throws PKCS11Exception {
-        session.token.p11.C_DestroyObject(s.id(), keyID);
-    }
-
-    private void dispose() {
-        refList.remove(this);
-        this.clear();
-        session.removeObject();
-    }
-
-    public int compareTo(SessionKeyRef other) {
-        if (this.keyID == other.keyID) {
-            return 0;
-        } else {
-            return (this.keyID < other.keyID) ? -1 : 1;
-        }
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyAgreement.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.math.BigInteger;
-
-import java.security.*;
-import java.security.spec.*;
-
-import javax.crypto.*;
-import javax.crypto.interfaces.*;
-import javax.crypto.spec.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-import sun.security.util.KeyUtil;
-
-/**
- * KeyAgreement implementation class. This class currently supports
- * DH.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11KeyAgreement extends KeyAgreementSpi {
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id
-    private final long mechanism;
-
-    // private key, if initialized
-    private P11Key privateKey;
-
-    // other sides public value ("y"), if doPhase() already called
-    private BigInteger publicValue;
-
-    // length of the secret to be derived
-    private int secretLen;
-
-    // KeyAgreement from SunJCE as fallback for > 2 party agreement
-    private KeyAgreement multiPartyAgreement;
-
-    P11KeyAgreement(Token token, String algorithm, long mechanism) {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-    }
-
-    // see JCE spec
-    protected void engineInit(Key key, SecureRandom random)
-            throws InvalidKeyException {
-        if (key instanceof PrivateKey == false) {
-            throw new InvalidKeyException
-                        ("Key must be instance of PrivateKey");
-        }
-        privateKey = P11KeyFactory.convertKey(token, key, algorithm);
-        publicValue = null;
-        multiPartyAgreement = null;
-    }
-
-    // see JCE spec
-    protected void engineInit(Key key, AlgorithmParameterSpec params,
-            SecureRandom random) throws InvalidKeyException,
-            InvalidAlgorithmParameterException {
-        if (params != null) {
-            throw new InvalidAlgorithmParameterException
-                        ("Parameters not supported");
-        }
-        engineInit(key, random);
-    }
-
-    // see JCE spec
-    protected Key engineDoPhase(Key key, boolean lastPhase)
-            throws InvalidKeyException, IllegalStateException {
-        if (privateKey == null) {
-            throw new IllegalStateException("Not initialized");
-        }
-        if (publicValue != null) {
-            throw new IllegalStateException("Phase already executed");
-        }
-        // PKCS#11 only allows key agreement between 2 parties
-        // JCE allows >= 2 parties. To support that case (for compatibility
-        // and to pass JCK), fall back to SunJCE in this case.
-        // NOTE that we initialize using the P11Key, which will fail if it
-        // is sensitive/unextractable. However, this is not an issue in the
-        // compatibility configuration, which is all we are targeting here.
-        if ((multiPartyAgreement != null) || (lastPhase == false)) {
-            if (multiPartyAgreement == null) {
-                try {
-                    multiPartyAgreement = KeyAgreement.getInstance
-                        ("DH", P11Util.getSunJceProvider());
-                    multiPartyAgreement.init(privateKey);
-                } catch (NoSuchAlgorithmException e) {
-                    throw new InvalidKeyException
-                        ("Could not initialize multi party agreement", e);
-                }
-            }
-            return multiPartyAgreement.doPhase(key, lastPhase);
-        }
-        if ((key instanceof PublicKey == false)
-                || (key.getAlgorithm().equals(algorithm) == false)) {
-            throw new InvalidKeyException
-                ("Key must be a PublicKey with algorithm DH");
-        }
-        BigInteger p, g, y;
-        if (key instanceof DHPublicKey) {
-            DHPublicKey dhKey = (DHPublicKey)key;
-
-            // validate the Diffie-Hellman public key
-            KeyUtil.validate(dhKey);
-
-            y = dhKey.getY();
-            DHParameterSpec params = dhKey.getParams();
-            p = params.getP();
-            g = params.getG();
-        } else {
-            // normally, DH PublicKeys will always implement DHPublicKey
-            // just in case not, attempt conversion
-            P11DHKeyFactory kf = new P11DHKeyFactory(token, "DH");
-            try {
-                DHPublicKeySpec spec = kf.engineGetKeySpec(
-                        key, DHPublicKeySpec.class);
-
-                // validate the Diffie-Hellman public key
-                KeyUtil.validate(spec);
-
-                y = spec.getY();
-                p = spec.getP();
-                g = spec.getG();
-            } catch (InvalidKeySpecException e) {
-                throw new InvalidKeyException("Could not obtain key values", e);
-            }
-        }
-        // if parameters of private key are accessible, verify that
-        // they match parameters of public key
-        // XXX p and g should always be readable, even if the key is sensitive
-        if (privateKey instanceof DHPrivateKey) {
-            DHPrivateKey dhKey = (DHPrivateKey)privateKey;
-            DHParameterSpec params = dhKey.getParams();
-            if ((p.equals(params.getP()) == false)
-                                || (g.equals(params.getG()) == false)) {
-                throw new InvalidKeyException
-                ("PublicKey DH parameters must match PrivateKey DH parameters");
-            }
-        }
-        publicValue = y;
-        // length of the secret is length of key
-        secretLen = (p.bitLength() + 7) >> 3;
-        return null;
-    }
-
-    // see JCE spec
-    protected byte[] engineGenerateSecret() throws IllegalStateException {
-        if (multiPartyAgreement != null) {
-            byte[] val = multiPartyAgreement.generateSecret();
-            multiPartyAgreement = null;
-            return val;
-        }
-        if ((privateKey == null) || (publicValue == null)) {
-            throw new IllegalStateException("Not initialized correctly");
-        }
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET),
-            };
-            attributes = token.getAttributes
-                (O_GENERATE, CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
-            long keyID = token.p11.C_DeriveKey(session.id(),
-                new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
-                attributes);
-            attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE)
-            };
-            token.p11.C_GetAttributeValue(session.id(), keyID, attributes);
-            byte[] secret = attributes[0].getByteArray();
-            token.p11.C_DestroyObject(session.id(), keyID);
-            // Some vendors, e.g. NSS, trim off the leading 0x00 byte(s) from
-            // the generated secret. Thus, we need to check the secret length
-            // and trim/pad it so the returned value has the same length as
-            // the modulus size
-            if (secret.length == secretLen) {
-                return secret;
-            } else {
-                if (secret.length > secretLen) {
-                    // Shouldn't happen; but check just in case
-                    throw new ProviderException("generated secret is out-of-range");
-                }
-                byte[] newSecret = new byte[secretLen];
-                System.arraycopy(secret, 0, newSecret, secretLen - secret.length,
-                    secret.length);
-                return newSecret;
-            }
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("Could not derive key", e);
-        } finally {
-            publicValue = null;
-            token.releaseSession(session);
-        }
-    }
-
-    // see JCE spec
-    protected int engineGenerateSecret(byte[] sharedSecret, int
-            offset) throws IllegalStateException, ShortBufferException {
-        if (multiPartyAgreement != null) {
-            int n = multiPartyAgreement.generateSecret(sharedSecret, offset);
-            multiPartyAgreement = null;
-            return n;
-        }
-        if (offset + secretLen > sharedSecret.length) {
-            throw new ShortBufferException("Need " + secretLen
-                + " bytes, only " + (sharedSecret.length - offset) + " available");
-        }
-        byte[] secret = engineGenerateSecret();
-        System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
-        return secret.length;
-    }
-
-    // see JCE spec
-    protected SecretKey engineGenerateSecret(String algorithm)
-            throws IllegalStateException, NoSuchAlgorithmException,
-            InvalidKeyException {
-        if (multiPartyAgreement != null) {
-            SecretKey key = multiPartyAgreement.generateSecret(algorithm);
-            multiPartyAgreement = null;
-            return key;
-        }
-        if (algorithm == null) {
-            throw new NoSuchAlgorithmException("Algorithm must not be null");
-        }
-        if (algorithm.equals("TlsPremasterSecret")) {
-            // For now, only perform native derivation for TlsPremasterSecret
-            // as that is required for FIPS compliance.
-            // For other algorithms, there are unresolved issues regarding
-            // how this should work in JCE plus a Solaris truncation bug.
-            // (bug not yet filed).
-            return nativeGenerateSecret(algorithm);
-        }
-        byte[] secret = engineGenerateSecret();
-        // Maintain compatibility for SunJCE:
-        // verify secret length is sensible for algorithm / truncate
-        // return generated key itself if possible
-        int keyLen;
-        if (algorithm.equalsIgnoreCase("DES")) {
-            keyLen = 8;
-        } else if (algorithm.equalsIgnoreCase("DESede")) {
-            keyLen = 24;
-        } else if (algorithm.equalsIgnoreCase("Blowfish")) {
-            keyLen = Math.min(56, secret.length);
-        } else if (algorithm.equalsIgnoreCase("TlsPremasterSecret")) {
-            keyLen = secret.length;
-        } else {
-            throw new NoSuchAlgorithmException
-                ("Unknown algorithm " + algorithm);
-        }
-        if (secret.length < keyLen) {
-            throw new InvalidKeyException("Secret too short");
-        }
-        if (algorithm.equalsIgnoreCase("DES") ||
-            algorithm.equalsIgnoreCase("DESede")) {
-                for (int i = 0; i < keyLen; i+=8) {
-                    P11SecretKeyFactory.fixDESParity(secret, i);
-                }
-        }
-        return new SecretKeySpec(secret, 0, keyLen, algorithm);
-    }
-
-    private SecretKey nativeGenerateSecret(String algorithm)
-            throws IllegalStateException, NoSuchAlgorithmException,
-            InvalidKeyException {
-        if ((privateKey == null) || (publicValue == null)) {
-            throw new IllegalStateException("Not initialized correctly");
-        }
-        long keyType = CKK_GENERIC_SECRET;
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
-            };
-            attributes = token.getAttributes
-                (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
-            long keyID = token.p11.C_DeriveKey(session.id(),
-                new CK_MECHANISM(mechanism, publicValue), privateKey.keyID,
-                attributes);
-            CK_ATTRIBUTE[] lenAttributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE_LEN),
-            };
-            token.p11.C_GetAttributeValue(session.id(), keyID, lenAttributes);
-            int keyLen = (int)lenAttributes[0].getLong();
-            SecretKey key = P11Key.secretKey
-                        (session, keyID, algorithm, keyLen << 3, attributes);
-            if ("RAW".equals(key.getFormat())) {
-                // Workaround for Solaris bug 6318543.
-                // Strip leading zeroes ourselves if possible (key not sensitive).
-                // This should be removed once the Solaris fix is available
-                // as here we always retrieve the CKA_VALUE even for tokens
-                // that do not have that bug.
-                byte[] keyBytes = key.getEncoded();
-                byte[] newBytes = KeyUtil.trimZeroes(keyBytes);
-                if (keyBytes != newBytes) {
-                    key = new SecretKeySpec(newBytes, algorithm);
-                }
-            }
-            return key;
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not derive key", e);
-        } finally {
-            publicValue = null;
-            token.releaseSession(session);
-        }
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyFactory.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.security.*;
-import java.security.spec.*;
-
-import sun.security.pkcs11.wrapper.PKCS11Exception;
-
-/**
- * KeyFactory base class. Provides common infrastructure for the RSA, DSA,
- * and DH implementations.
- *
- * The subclasses support conversion between keys and keyspecs
- * using X.509, PKCS#8, and their individual algorithm specific formats,
- * assuming keys are extractable.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-abstract class P11KeyFactory extends KeyFactorySpi {
-
-    // token instance
-    final Token token;
-
-    // algorithm name, currently one of RSA, DSA, DH
-    final String algorithm;
-
-    P11KeyFactory(Token token, String algorithm) {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-    }
-
-    /**
-     * Convert an arbitrary key of algorithm into a P11Key of token.
-     * Used by P11Signature.init() and RSACipher.init().
-     */
-    static P11Key convertKey(Token token, Key key, String algorithm)
-            throws InvalidKeyException {
-        return (P11Key)token.getKeyFactory(algorithm).engineTranslateKey(key);
-    }
-
-    // see JCA spec
-    protected final <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if ((key == null) || (keySpec == null)) {
-            throw new InvalidKeySpecException
-                ("key and keySpec must not be null");
-        }
-        // delegate to our Java based providers for PKCS#8 and X.509
-        if (PKCS8EncodedKeySpec.class.isAssignableFrom(keySpec)
-                || X509EncodedKeySpec.class.isAssignableFrom(keySpec)) {
-            try {
-                return implGetSoftwareFactory().getKeySpec(key, keySpec);
-            } catch (GeneralSecurityException e) {
-                throw new InvalidKeySpecException("Could not encode key", e);
-            }
-        }
-        // first translate into a key of this token, if it is not already
-        P11Key p11Key;
-        try {
-            p11Key = (P11Key)engineTranslateKey(key);
-        } catch (InvalidKeyException e) {
-            throw new InvalidKeySpecException("Could not convert key", e);
-        }
-        Session[] session = new Session[1];
-        try {
-            if (p11Key.isPublic()) {
-                return implGetPublicKeySpec(p11Key, keySpec, session);
-            } else {
-                return implGetPrivateKeySpec(p11Key, keySpec, session);
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeySpecException("Could not generate KeySpec", e);
-        } finally {
-            session[0] = token.releaseSession(session[0]);
-        }
-    }
-
-    // see JCA spec
-    protected final Key engineTranslateKey(Key key) throws InvalidKeyException {
-        token.ensureValid();
-        if (key == null) {
-            throw new InvalidKeyException("Key must not be null");
-        }
-        if (key.getAlgorithm().equals(this.algorithm) == false) {
-            throw new InvalidKeyException
-                ("Key algorithm must be " + algorithm);
-        }
-        if (key instanceof P11Key) {
-            P11Key p11Key = (P11Key)key;
-            if (p11Key.token == token) {
-                // already a key of this token, no need to translate
-                return key;
-            }
-        }
-        P11Key p11Key = token.privateCache.get(key);
-        if (p11Key != null) {
-            return p11Key;
-        }
-        if (key instanceof PublicKey) {
-            PublicKey publicKey = implTranslatePublicKey((PublicKey)key);
-            token.privateCache.put(key, (P11Key)publicKey);
-            return publicKey;
-        } else if (key instanceof PrivateKey) {
-            PrivateKey privateKey = implTranslatePrivateKey((PrivateKey)key);
-            token.privateCache.put(key, (P11Key)privateKey);
-            return privateKey;
-        } else {
-            throw new InvalidKeyException
-                ("Key must be instance of PublicKey or PrivateKey");
-        }
-    }
-
-    abstract <T extends KeySpec> T  implGetPublicKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException;
-
-    abstract <T extends KeySpec> T  implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException;
-
-    abstract PublicKey implTranslatePublicKey(PublicKey key)
-            throws InvalidKeyException;
-
-    abstract PrivateKey implTranslatePrivateKey(PrivateKey key)
-            throws InvalidKeyException;
-
-    abstract KeyFactory implGetSoftwareFactory() throws GeneralSecurityException;
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyGenerator.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 2003, 2008, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * KeyGenerator implementation class. This class currently supports
- * DES, DESede, AES, ARCFOUR, and Blowfish.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11KeyGenerator extends KeyGeneratorSpi {
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id
-    private long mechanism;
-
-    // raw key size in bits, e.g. 64 for DES. Always valid.
-    private int keySize;
-
-    // bits of entropy in the key, e.g. 56 for DES. Always valid.
-    private int significantKeySize;
-
-    // keyType (CKK_*), needed for TemplateManager call only.
-    private long keyType;
-
-    // for determining if both 112 and 168 bits of DESede key lengths
-    // are supported.
-    private boolean supportBothKeySizes;
-
-    /**
-     * Utility method for checking if the specified key size is valid
-     * and within the supported range. Return the significant key size
-     * upon successful validation.
-     * @param keyGenMech the PKCS#11 key generation mechanism.
-     * @param keySize the to-be-checked key size for this mechanism.
-     * @param token token which provides this mechanism.
-     * @return the significant key size (in bits) corresponding to the
-     * specified key size.
-     * @throws InvalidParameterException if the specified key size is invalid.
-     * @throws ProviderException if this mechanism isn't supported by SunPKCS11
-     * or underlying native impl.
-     */
-    static int checkKeySize(long keyGenMech, int keySize, Token token)
-        throws InvalidAlgorithmParameterException, ProviderException {
-        int sigKeySize;
-        switch ((int)keyGenMech) {
-            case (int)CKM_DES_KEY_GEN:
-                if ((keySize != 64) && (keySize != 56)) {
-                    throw new InvalidAlgorithmParameterException
-                            ("DES key length must be 56 bits");
-                }
-                sigKeySize = 56;
-                break;
-            case (int)CKM_DES2_KEY_GEN:
-            case (int)CKM_DES3_KEY_GEN:
-                if ((keySize == 112) || (keySize == 128)) {
-                    sigKeySize = 112;
-                } else if ((keySize == 168) || (keySize == 192)) {
-                    sigKeySize = 168;
-                } else {
-                    throw new InvalidAlgorithmParameterException
-                            ("DESede key length must be 112, or 168 bits");
-                }
-                break;
-            default:
-                // Handle all variable-key-length algorithms here
-                CK_MECHANISM_INFO info = null;
-                try {
-                    info = token.getMechanismInfo(keyGenMech);
-                } catch (PKCS11Exception p11e) {
-                    // Should never happen
-                    throw new ProviderException
-                            ("Cannot retrieve mechanism info", p11e);
-                }
-                if (info == null) {
-                    // XXX Unable to retrieve the supported key length from
-                    // the underlying native impl. Skip the checking for now.
-                    return keySize;
-                }
-                // PKCS#11 defines these to be in number of bytes except for
-                // RC4 which is in bits. However, some PKCS#11 impls still use
-                // bytes for all mechs, e.g. NSS. We try to detect this
-                // inconsistency if the minKeySize seems unreasonably small.
-                int minKeySize = (int)info.ulMinKeySize;
-                int maxKeySize = (int)info.ulMaxKeySize;
-                if (keyGenMech != CKM_RC4_KEY_GEN || minKeySize < 8) {
-                    minKeySize = (int)info.ulMinKeySize << 3;
-                    maxKeySize = (int)info.ulMaxKeySize << 3;
-                }
-                // Explicitly disallow keys shorter than 40-bits for security
-                if (minKeySize < 40) minKeySize = 40;
-                if (keySize < minKeySize || keySize > maxKeySize) {
-                    throw new InvalidAlgorithmParameterException
-                            ("Key length must be between " + minKeySize +
-                            " and " + maxKeySize + " bits");
-                }
-                if (keyGenMech == CKM_AES_KEY_GEN) {
-                    if ((keySize != 128) && (keySize != 192) &&
-                        (keySize != 256)) {
-                        throw new InvalidAlgorithmParameterException
-                                ("AES key length must be " + minKeySize +
-                                (maxKeySize >= 192? ", 192":"") +
-                                (maxKeySize >= 256? ", or 256":"") + " bits");
-                    }
-                }
-                sigKeySize = keySize;
-        }
-        return sigKeySize;
-    }
-
-    P11KeyGenerator(Token token, String algorithm, long mechanism)
-            throws PKCS11Exception {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-
-        if (this.mechanism == CKM_DES3_KEY_GEN) {
-            /* Given the current lookup order specified in SunPKCS11.java,
-               if CKM_DES2_KEY_GEN is used to construct this object, it
-               means that CKM_DES3_KEY_GEN is disabled or unsupported.
-            */
-            supportBothKeySizes =
-                (token.provider.config.isEnabled(CKM_DES2_KEY_GEN) &&
-                 (token.getMechanismInfo(CKM_DES2_KEY_GEN) != null));
-        }
-        setDefaultKeySize();
-    }
-
-    // set default keysize and also initialize keyType
-    private void setDefaultKeySize() {
-        switch ((int)mechanism) {
-        case (int)CKM_DES_KEY_GEN:
-            keySize = 64;
-            keyType = CKK_DES;
-            break;
-        case (int)CKM_DES2_KEY_GEN:
-            keySize = 128;
-            keyType = CKK_DES2;
-            break;
-        case (int)CKM_DES3_KEY_GEN:
-            keySize = 192;
-            keyType = CKK_DES3;
-            break;
-        case (int)CKM_AES_KEY_GEN:
-            keySize = 128;
-            keyType = CKK_AES;
-            break;
-        case (int)CKM_RC4_KEY_GEN:
-            keySize = 128;
-            keyType = CKK_RC4;
-            break;
-        case (int)CKM_BLOWFISH_KEY_GEN:
-            keySize = 128;
-            keyType = CKK_BLOWFISH;
-            break;
-        default:
-            throw new ProviderException("Unknown mechanism " + mechanism);
-        }
-        try {
-            significantKeySize = checkKeySize(mechanism, keySize, token);
-        } catch (InvalidAlgorithmParameterException iape) {
-            throw new ProviderException("Unsupported default key size", iape);
-        }
-    }
-
-    // see JCE spec
-    protected void engineInit(SecureRandom random) {
-        token.ensureValid();
-        setDefaultKeySize();
-    }
-
-    // see JCE spec
-    protected void engineInit(AlgorithmParameterSpec params,
-            SecureRandom random) throws InvalidAlgorithmParameterException {
-        throw new InvalidAlgorithmParameterException
-                ("AlgorithmParameterSpec not supported");
-    }
-
-    // see JCE spec
-    protected void engineInit(int keySize, SecureRandom random) {
-        token.ensureValid();
-        int newSignificantKeySize;
-        try {
-            newSignificantKeySize = checkKeySize(mechanism, keySize, token);
-        } catch (InvalidAlgorithmParameterException iape) {
-            throw (InvalidParameterException)
-                    (new InvalidParameterException().initCause(iape));
-        }
-        if ((mechanism == CKM_DES2_KEY_GEN) ||
-            (mechanism == CKM_DES3_KEY_GEN))  {
-            long newMechanism = (newSignificantKeySize == 112 ?
-                CKM_DES2_KEY_GEN : CKM_DES3_KEY_GEN);
-            if (mechanism != newMechanism) {
-                if (supportBothKeySizes) {
-                    mechanism = newMechanism;
-                    // Adjust keyType to reflect the mechanism change
-                    keyType = (mechanism == CKM_DES2_KEY_GEN ?
-                        CKK_DES2 : CKK_DES3);
-                } else {
-                    throw new InvalidParameterException
-                            ("Only " + significantKeySize +
-                             "-bit DESede is supported");
-                }
-            }
-        }
-        this.keySize = keySize;
-        this.significantKeySize = newSignificantKeySize;
-    }
-
-    // see JCE spec
-    protected SecretKey engineGenerateKey() {
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            CK_ATTRIBUTE[] attributes;
-            switch ((int)keyType) {
-            case (int)CKK_DES:
-            case (int)CKK_DES2:
-            case (int)CKK_DES3:
-                // fixed length, do not specify CKA_VALUE_LEN
-                attributes = new CK_ATTRIBUTE[] {
-                    new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
-                };
-                break;
-            default:
-                attributes = new CK_ATTRIBUTE[] {
-                    new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
-                    new CK_ATTRIBUTE(CKA_VALUE_LEN, keySize >> 3),
-                };
-                break;
-            }
-            attributes = token.getAttributes
-                (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
-            long keyID = token.p11.C_GenerateKey
-                (session.id(), new CK_MECHANISM(mechanism), attributes);
-            return P11Key.secretKey
-                (session, keyID, algorithm, significantKeySize, attributes);
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("Could not generate key", e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyPairGenerator.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,429 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.math.BigInteger;
-
-import java.security.*;
-import java.security.spec.*;
-
-import javax.crypto.spec.DHParameterSpec;
-
-import sun.security.provider.ParameterCache;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-import sun.security.rsa.RSAKeyFactory;
-
-/**
- * KeyPairGenerator implementation class. This class currently supports
- * RSA, DSA, DH, and EC.
- *
- * Note that for DSA and DH we rely on the Sun and SunJCE providers to
- * obtain the parameters from.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11KeyPairGenerator extends KeyPairGeneratorSpi {
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id
-    private final long mechanism;
-
-    // selected or default key size, always valid
-    private int keySize;
-
-    // parameters specified via init, if any
-    private AlgorithmParameterSpec params;
-
-    // for RSA, selected or default value of public exponent, always valid
-    private BigInteger rsaPublicExponent = RSAKeyGenParameterSpec.F4;
-
-    // the supported keysize range of the native PKCS11 library
-    // if the value cannot be retrieved or unspecified, -1 is used.
-    private final int minKeySize;
-    private final int maxKeySize;
-
-    // SecureRandom instance, if specified in init
-    private SecureRandom random;
-
-    P11KeyPairGenerator(Token token, String algorithm, long mechanism)
-            throws PKCS11Exception {
-        super();
-        int minKeyLen = -1;
-        int maxKeyLen = -1;
-        try {
-            CK_MECHANISM_INFO mechInfo = token.getMechanismInfo(mechanism);
-            if (mechInfo != null) {
-                minKeyLen = (int) mechInfo.ulMinKeySize;
-                maxKeyLen = (int) mechInfo.ulMaxKeySize;
-            }
-        } catch (PKCS11Exception p11e) {
-            // Should never happen
-            throw new ProviderException
-                        ("Unexpected error while getting mechanism info", p11e);
-        }
-        // set default key sizes and apply our own algorithm-specific limits
-        // override lower limit to disallow unsecure keys being generated
-        // override upper limit to deter DOS attack
-        if (algorithm.equals("EC")) {
-            keySize = 256;
-            if ((minKeyLen == -1) || (minKeyLen < 112)) {
-                minKeyLen = 112;
-            }
-            if ((maxKeyLen == -1) || (maxKeyLen > 2048)) {
-                maxKeyLen = 2048;
-            }
-        } else {
-            if (algorithm.equals("DSA")) {
-                // keep default keysize at 1024 since larger keysizes may be
-                // incompatible with SHA1withDSA and SHA-2 Signature algs
-                // may not be supported by native pkcs11 implementations
-                keySize = 1024;
-            } else {
-                // RSA and DH
-                keySize = 2048;
-            }
-            if ((minKeyLen == -1) || (minKeyLen < 512)) {
-                minKeyLen = 512;
-            }
-            if (algorithm.equals("RSA")) {
-                if ((maxKeyLen == -1) || (maxKeyLen > 64 * 1024)) {
-                    maxKeyLen = 64 * 1024;
-                }
-            }
-        }
-
-        // auto-adjust default keysize in case it's out-of-range
-        if ((minKeyLen != -1) && (keySize < minKeyLen)) {
-            keySize = minKeyLen;
-        }
-        if ((maxKeyLen != -1) && (keySize > maxKeyLen)) {
-            keySize = maxKeyLen;
-        }
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-        this.minKeySize = minKeyLen;
-        this.maxKeySize = maxKeyLen;
-        initialize(keySize, null);
-    }
-
-    // see JCA spec
-    @Override
-    public void initialize(int keySize, SecureRandom random) {
-        token.ensureValid();
-        try {
-            checkKeySize(keySize, null);
-        } catch (InvalidAlgorithmParameterException e) {
-            throw new InvalidParameterException(e.getMessage());
-        }
-        this.params = null;
-        if (algorithm.equals("EC")) {
-            params = P11ECKeyFactory.getECParameterSpec(keySize);
-            if (params == null) {
-                throw new InvalidParameterException(
-                    "No EC parameters available for key size "
-                    + keySize + " bits");
-            }
-        }
-        this.keySize = keySize;
-        this.random = random;
-    }
-
-    // see JCA spec
-    @Override
-    public void initialize(AlgorithmParameterSpec params, SecureRandom random)
-            throws InvalidAlgorithmParameterException {
-        token.ensureValid();
-        int tmpKeySize;
-        if (algorithm.equals("DH")) {
-            if (params instanceof DHParameterSpec == false) {
-                throw new InvalidAlgorithmParameterException
-                        ("DHParameterSpec required for Diffie-Hellman");
-            }
-            DHParameterSpec dhParams = (DHParameterSpec) params;
-            tmpKeySize = dhParams.getP().bitLength();
-            checkKeySize(tmpKeySize, dhParams);
-            // XXX sanity check params
-        } else if (algorithm.equals("RSA")) {
-            if (params instanceof RSAKeyGenParameterSpec == false) {
-                throw new InvalidAlgorithmParameterException
-                        ("RSAKeyGenParameterSpec required for RSA");
-            }
-            RSAKeyGenParameterSpec rsaParams =
-                (RSAKeyGenParameterSpec) params;
-            tmpKeySize = rsaParams.getKeysize();
-            checkKeySize(tmpKeySize, rsaParams);
-            // override the supplied params to null
-            params = null;
-            this.rsaPublicExponent = rsaParams.getPublicExponent();
-            // XXX sanity check params
-        } else if (algorithm.equals("DSA")) {
-            if (params instanceof DSAParameterSpec == false) {
-                throw new InvalidAlgorithmParameterException
-                        ("DSAParameterSpec required for DSA");
-            }
-            DSAParameterSpec dsaParams = (DSAParameterSpec) params;
-            tmpKeySize = dsaParams.getP().bitLength();
-            checkKeySize(tmpKeySize, dsaParams);
-            // XXX sanity check params
-        } else if (algorithm.equals("EC")) {
-            ECParameterSpec ecParams;
-            if (params instanceof ECParameterSpec) {
-                ecParams = P11ECKeyFactory.getECParameterSpec(
-                    (ECParameterSpec)params);
-                if (ecParams == null) {
-                    throw new InvalidAlgorithmParameterException
-                        ("Unsupported curve: " + params);
-                }
-            } else if (params instanceof ECGenParameterSpec) {
-                String name = ((ECGenParameterSpec) params).getName();
-                ecParams = P11ECKeyFactory.getECParameterSpec(name);
-                if (ecParams == null) {
-                    throw new InvalidAlgorithmParameterException
-                        ("Unknown curve name: " + name);
-                }
-                // override the supplied params with the derived one
-                params = ecParams;
-            } else {
-                throw new InvalidAlgorithmParameterException
-                    ("ECParameterSpec or ECGenParameterSpec required for EC");
-            }
-            tmpKeySize = ecParams.getCurve().getField().getFieldSize();
-            checkKeySize(tmpKeySize, ecParams);
-        } else {
-            throw new ProviderException("Unknown algorithm: " + algorithm);
-        }
-        this.keySize = tmpKeySize;
-        this.params = params;
-        this.random = random;
-    }
-
-    private void checkKeySize(int keySize, AlgorithmParameterSpec params)
-        throws InvalidAlgorithmParameterException {
-        // check native range first
-        if ((minKeySize != -1) && (keySize < minKeySize)) {
-            throw new InvalidAlgorithmParameterException(algorithm +
-                " key must be at least " + minKeySize + " bits. " +
-                "The specific key size " + keySize + " is not supported");
-        }
-        if ((maxKeySize != -1) && (keySize > maxKeySize)) {
-            throw new InvalidAlgorithmParameterException(algorithm +
-                " key must be at most " + maxKeySize + " bits. " +
-                "The specific key size " + keySize + " is not supported");
-        }
-
-        // check our own algorithm-specific limits also
-        if (algorithm.equals("EC")) {
-            if (keySize < 112) {
-                throw new InvalidAlgorithmParameterException(
-                    "EC key size must be at least 112 bit. " +
-                    "The specific key size " + keySize + " is not supported");
-            }
-            if (keySize > 2048) {
-                // sanity check, nobody really wants keys this large
-                throw new InvalidAlgorithmParameterException(
-                    "EC key size must be at most 2048 bit. " +
-                    "The specific key size " + keySize + " is not supported");
-            }
-        } else {
-            // RSA, DH, DSA
-            if (keySize < 512) {
-                throw new InvalidAlgorithmParameterException(algorithm +
-                    " key size must be at least 512 bit. " +
-                    "The specific key size " + keySize + " is not supported");
-            }
-            if (algorithm.equals("RSA")) {
-                BigInteger tmpExponent = rsaPublicExponent;
-                if (params != null) {
-                    tmpExponent =
-                        ((RSAKeyGenParameterSpec)params).getPublicExponent();
-                }
-                try {
-                    // Reuse the checking in SunRsaSign provider.
-                    // If maxKeySize is -1, then replace it with
-                    // Integer.MAX_VALUE to indicate no limit.
-                    RSAKeyFactory.checkKeyLengths(keySize, tmpExponent,
-                        minKeySize,
-                        (maxKeySize==-1? Integer.MAX_VALUE:maxKeySize));
-                } catch (InvalidKeyException e) {
-                    throw new InvalidAlgorithmParameterException(e);
-                }
-            } else if (algorithm.equals("DH")) {
-                if (params != null) {   // initialized with specified parameters
-                    // sanity check, nobody really wants keys this large
-                    if (keySize > 64 * 1024) {
-                        throw new InvalidAlgorithmParameterException(
-                            "DH key size must be at most 65536 bit. " +
-                            "The specific key size " +
-                            keySize + " is not supported");
-                    }
-                } else {        // default parameters will be used.
-                    // Range is based on the values in
-                    // sun.security.provider.ParameterCache class.
-                    if ((keySize > 8192) || (keySize < 512) ||
-                            ((keySize & 0x3f) != 0)) {
-                        throw new InvalidAlgorithmParameterException(
-                            "DH key size must be multiple of 64, and can " +
-                            "only range from 512 to 8192 (inclusive). " +
-                            "The specific key size " +
-                            keySize + " is not supported");
-                    }
-
-                    DHParameterSpec cache =
-                            ParameterCache.getCachedDHParameterSpec(keySize);
-                    // Except 2048 and 3072, not yet support generation of
-                    // parameters bigger than 1024 bits.
-                    if ((cache == null) && (keySize > 1024)) {
-                        throw new InvalidAlgorithmParameterException(
-                                "Unsupported " + keySize +
-                                "-bit DH parameter generation");
-                    }
-                }
-            } else {
-                // this restriction is in the spec for DSA
-                if ((keySize != 3072) && (keySize != 2048) &&
-                        ((keySize > 1024) || ((keySize & 0x3f) != 0))) {
-                    throw new InvalidAlgorithmParameterException(
-                        "DSA key must be multiples of 64 if less than " +
-                        "1024 bits, or 2048, 3072 bits. " +
-                        "The specific key size " +
-                        keySize + " is not supported");
-                }
-            }
-        }
-    }
-
-    // see JCA spec
-    @Override
-    public KeyPair generateKeyPair() {
-        token.ensureValid();
-        CK_ATTRIBUTE[] publicKeyTemplate;
-        CK_ATTRIBUTE[] privateKeyTemplate;
-        long keyType;
-        if (algorithm.equals("RSA")) {
-            keyType = CKK_RSA;
-            publicKeyTemplate = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_MODULUS_BITS, keySize),
-                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, rsaPublicExponent),
-            };
-            privateKeyTemplate = new CK_ATTRIBUTE[] {
-                // empty
-            };
-        } else if (algorithm.equals("DSA")) {
-            keyType = CKK_DSA;
-            DSAParameterSpec dsaParams;
-            if (params == null) {
-                try {
-                    dsaParams = ParameterCache.getDSAParameterSpec
-                                                    (keySize, random);
-                } catch (GeneralSecurityException e) {
-                    throw new ProviderException
-                            ("Could not generate DSA parameters", e);
-                }
-            } else {
-                dsaParams = (DSAParameterSpec)params;
-            }
-            publicKeyTemplate = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_PRIME, dsaParams.getP()),
-                new CK_ATTRIBUTE(CKA_SUBPRIME, dsaParams.getQ()),
-                new CK_ATTRIBUTE(CKA_BASE, dsaParams.getG()),
-            };
-            privateKeyTemplate = new CK_ATTRIBUTE[] {
-                // empty
-            };
-        } else if (algorithm.equals("DH")) {
-            keyType = CKK_DH;
-            DHParameterSpec dhParams;
-            int privateBits;
-            if (params == null) {
-                try {
-                    dhParams = ParameterCache.getDHParameterSpec
-                                                    (keySize, random);
-                } catch (GeneralSecurityException e) {
-                    throw new ProviderException
-                            ("Could not generate DH parameters", e);
-                }
-                privateBits = 0;
-            } else {
-                dhParams = (DHParameterSpec)params;
-                privateBits = dhParams.getL();
-            }
-            if (privateBits <= 0) {
-                // XXX find better defaults
-                privateBits = (keySize >= 1024) ? 768 : 512;
-            }
-            publicKeyTemplate = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_PRIME, dhParams.getP()),
-                new CK_ATTRIBUTE(CKA_BASE, dhParams.getG())
-            };
-            privateKeyTemplate = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_VALUE_BITS, privateBits),
-            };
-        } else if (algorithm.equals("EC")) {
-            keyType = CKK_EC;
-            byte[] encodedParams =
-                    P11ECKeyFactory.encodeParameters((ECParameterSpec)params);
-            publicKeyTemplate = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
-            };
-            privateKeyTemplate = new CK_ATTRIBUTE[] {
-                // empty
-            };
-        } else {
-            throw new ProviderException("Unknown algorithm: " + algorithm);
-        }
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            publicKeyTemplate = token.getAttributes
-                (O_GENERATE, CKO_PUBLIC_KEY, keyType, publicKeyTemplate);
-            privateKeyTemplate = token.getAttributes
-                (O_GENERATE, CKO_PRIVATE_KEY, keyType, privateKeyTemplate);
-            long[] keyIDs = token.p11.C_GenerateKeyPair
-                (session.id(), new CK_MECHANISM(mechanism),
-                publicKeyTemplate, privateKeyTemplate);
-            PublicKey publicKey = P11Key.publicKey
-                (session, keyIDs[0], algorithm, keySize, publicKeyTemplate);
-            PrivateKey privateKey = P11Key.privateKey
-                (session, keyIDs[1], algorithm, keySize, privateKeyTemplate);
-            return new KeyPair(publicKey, privateKey);
-        } catch (PKCS11Exception e) {
-            throw new ProviderException(e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11KeyStore.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2683 +0,0 @@
-/*
- * Copyright (c) 2003, 2015, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.math.BigInteger;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-import java.io.ByteArrayInputStream;
-import java.io.UnsupportedEncodingException;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Set;
-
-import java.security.*;
-import java.security.KeyStore.*;
-
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.security.cert.CertificateFactory;
-import java.security.cert.CertificateException;
-
-import java.security.interfaces.*;
-import java.security.spec.*;
-
-import javax.crypto.SecretKey;
-import javax.crypto.interfaces.*;
-
-import javax.security.auth.x500.X500Principal;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-
-import sun.security.util.Debug;
-import sun.security.util.DerValue;
-import sun.security.util.ECUtil;
-
-import sun.security.pkcs11.Secmod.*;
-import static sun.security.pkcs11.P11Util.*;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-import sun.security.rsa.RSAKeyFactory;
-
-final class P11KeyStore extends KeyStoreSpi {
-
-    private static final CK_ATTRIBUTE ATTR_CLASS_CERT =
-                        new CK_ATTRIBUTE(CKA_CLASS, CKO_CERTIFICATE);
-    private static final CK_ATTRIBUTE ATTR_CLASS_PKEY =
-                        new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY);
-    private static final CK_ATTRIBUTE ATTR_CLASS_SKEY =
-                        new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
-
-    private static final CK_ATTRIBUTE ATTR_X509_CERT_TYPE =
-                        new CK_ATTRIBUTE(CKA_CERTIFICATE_TYPE, CKC_X_509);
-
-    private static final CK_ATTRIBUTE ATTR_TOKEN_TRUE =
-                        new CK_ATTRIBUTE(CKA_TOKEN, true);
-
-    // XXX for testing purposes only
-    //  - NSS doesn't support persistent secret keys
-    //    (key type gets mangled if secret key is a token key)
-    //  - if debug is turned on, then this is set to false
-    private static CK_ATTRIBUTE ATTR_SKEY_TOKEN_TRUE = ATTR_TOKEN_TRUE;
-
-    private static final CK_ATTRIBUTE ATTR_TRUSTED_TRUE =
-                        new CK_ATTRIBUTE(CKA_TRUSTED, true);
-    private static final CK_ATTRIBUTE ATTR_PRIVATE_TRUE =
-                        new CK_ATTRIBUTE(CKA_PRIVATE, true);
-
-    private static final long NO_HANDLE = -1;
-    private static final long FINDOBJECTS_MAX = 100;
-    private static final String ALIAS_SEP = "/";
-
-    private static final boolean NSS_TEST = false;
-    private static final Debug debug =
-                        Debug.getInstance("pkcs11keystore");
-    private static boolean CKA_TRUSTED_SUPPORTED = true;
-
-    private final Token token;
-
-    // If multiple certs are found to share the same CKA_LABEL
-    // at load time (NSS-style keystore), then the keystore is read
-    // and the unique keystore aliases are mapped to the entries.
-    // However, write capabilities are disabled.
-    private boolean writeDisabled = false;
-
-    // Map of unique keystore aliases to entries in the token
-    private HashMap<String, AliasInfo> aliasMap;
-
-    // whether to use NSS Secmod info for trust attributes
-    private final boolean useSecmodTrust;
-
-    // if useSecmodTrust == true, which type of trust we are interested in
-    private Secmod.TrustType nssTrustType;
-
-    /**
-     * The underlying token may contain multiple certs belonging to the
-     * same "personality" (for example, a signing cert and encryption cert),
-     * all sharing the same CKA_LABEL.  These must be resolved
-     * into unique keystore aliases.
-     *
-     * In addition, private keys and certs may not have a CKA_LABEL.
-     * It is assumed that a private key and corresponding certificate
-     * share the same CKA_ID, and that the CKA_ID is unique across the token.
-     * The CKA_ID may not be human-readable.
-     * These pairs must be resolved into unique keystore aliases.
-     *
-     * Furthermore, secret keys are assumed to have a CKA_LABEL
-     * unique across the entire token.
-     *
-     * When the KeyStore is loaded, instances of this class are
-     * created to represent the private keys/secret keys/certs
-     * that reside on the token.
-     */
-    private static class AliasInfo {
-
-        // CKA_CLASS - entry type
-        private CK_ATTRIBUTE type = null;
-
-        // CKA_LABEL of cert and secret key
-        private String label = null;
-
-        // CKA_ID of the private key/cert pair
-        private byte[] id = null;
-
-        // CKA_TRUSTED - true if cert is trusted
-        private boolean trusted = false;
-
-        // either end-entity cert or trusted cert depending on 'type'
-        private X509Certificate cert = null;
-
-        // chain
-        private X509Certificate[] chain = null;
-
-        // true if CKA_ID for private key and cert match up
-        private boolean matched = false;
-
-        // SecretKeyEntry
-        public AliasInfo(String label) {
-            this.type = ATTR_CLASS_SKEY;
-            this.label = label;
-        }
-
-        // PrivateKeyEntry
-        public AliasInfo(String label,
-                        byte[] id,
-                        boolean trusted,
-                        X509Certificate cert) {
-            this.type = ATTR_CLASS_PKEY;
-            this.label = label;
-            this.id = id;
-            this.trusted = trusted;
-            this.cert = cert;
-        }
-
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            if (type == ATTR_CLASS_PKEY) {
-                sb.append("\ttype=[private key]\n");
-            } else if (type == ATTR_CLASS_SKEY) {
-                sb.append("\ttype=[secret key]\n");
-            } else if (type == ATTR_CLASS_CERT) {
-                sb.append("\ttype=[trusted cert]\n");
-            }
-            sb.append("\tlabel=[" + label + "]\n");
-            if (id == null) {
-                sb.append("\tid=[null]\n");
-            } else {
-                sb.append("\tid=" + P11KeyStore.getID(id) + "\n");
-            }
-            sb.append("\ttrusted=[" + trusted + "]\n");
-            sb.append("\tmatched=[" + matched + "]\n");
-            if (cert == null) {
-                sb.append("\tcert=[null]\n");
-            } else {
-                sb.append("\tcert=[\tsubject: " +
-                        cert.getSubjectX500Principal() +
-                        "\n\t\tissuer: " +
-                        cert.getIssuerX500Principal() +
-                        "\n\t\tserialNum: " +
-                        cert.getSerialNumber().toString() +
-                        "]");
-            }
-            return sb.toString();
-        }
-    }
-
-    /**
-     * callback handler for passing password to Provider.login method
-     */
-    private static class PasswordCallbackHandler implements CallbackHandler {
-
-        private char[] password;
-
-        private PasswordCallbackHandler(char[] password) {
-            if (password != null) {
-                this.password = password.clone();
-            }
-        }
-
-        public void handle(Callback[] callbacks)
-                throws IOException, UnsupportedCallbackException {
-            if (!(callbacks[0] instanceof PasswordCallback)) {
-                throw new UnsupportedCallbackException(callbacks[0]);
-            }
-            PasswordCallback pc = (PasswordCallback)callbacks[0];
-            pc.setPassword(password);  // this clones the password if not null
-        }
-
-        protected void finalize() throws Throwable {
-            if (password != null) {
-                Arrays.fill(password, ' ');
-            }
-            super.finalize();
-        }
-    }
-
-    /**
-     * getTokenObject return value.
-     *
-     * if object is not found, type is set to null.
-     * otherwise, type is set to the requested type.
-     */
-    private static class THandle {
-        private final long handle;              // token object handle
-        private final CK_ATTRIBUTE type;        // CKA_CLASS
-
-        private THandle(long handle, CK_ATTRIBUTE type) {
-            this.handle = handle;
-            this.type = type;
-        }
-    }
-
-    P11KeyStore(Token token) {
-        this.token = token;
-        this.useSecmodTrust = token.provider.nssUseSecmodTrust;
-    }
-
-    /**
-     * Returns the key associated with the given alias.
-     * The key must have been associated with
-     * the alias by a call to <code>setKeyEntry</code>,
-     * or by a call to <code>setEntry</code> with a
-     * <code>PrivateKeyEntry</code> or <code>SecretKeyEntry</code>.
-     *
-     * @param alias the alias name
-     * @param password the password, which must be <code>null</code>
-     *
-     * @return the requested key, or null if the given alias does not exist
-     * or does not identify a key-related entry.
-     *
-     * @exception NoSuchAlgorithmException if the algorithm for recovering the
-     * key cannot be found
-     * @exception UnrecoverableKeyException if the key cannot be recovered
-     */
-    public synchronized Key engineGetKey(String alias, char[] password)
-                throws NoSuchAlgorithmException, UnrecoverableKeyException {
-
-        token.ensureValid();
-        if (password != null && !token.config.getKeyStoreCompatibilityMode()) {
-            throw new NoSuchAlgorithmException("password must be null");
-        }
-
-        AliasInfo aliasInfo = aliasMap.get(alias);
-        if (aliasInfo == null || aliasInfo.type == ATTR_CLASS_CERT) {
-            return null;
-        }
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            if (aliasInfo.type == ATTR_CLASS_PKEY) {
-                THandle h = getTokenObject(session,
-                                        aliasInfo.type,
-                                        aliasInfo.id,
-                                        null);
-                if (h.type == ATTR_CLASS_PKEY) {
-                    return loadPkey(session, h.handle);
-                }
-            } else {
-                THandle h = getTokenObject(session,
-                                        ATTR_CLASS_SKEY,
-                                        null,
-                                        alias);
-                if (h.type == ATTR_CLASS_SKEY) {
-                    return loadSkey(session, h.handle);
-                }
-            }
-
-            // did not find anything
-            return null;
-        } catch (PKCS11Exception | KeyStoreException e) {
-            throw new ProviderException(e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    /**
-     * Returns the certificate chain associated with the given alias.
-     * The certificate chain must have been associated with the alias
-     * by a call to <code>setKeyEntry</code>,
-     * or by a call to <code>setEntry</code> with a
-     * <code>PrivateKeyEntry</code>.
-     *
-     * @param alias the alias name
-     *
-     * @return the certificate chain (ordered with the user's certificate first
-     * and the root certificate authority last), or null if the given alias
-     * does not exist or does not contain a certificate chain
-     */
-    public synchronized Certificate[] engineGetCertificateChain(String alias) {
-
-        token.ensureValid();
-
-        AliasInfo aliasInfo = aliasMap.get(alias);
-        if (aliasInfo == null || aliasInfo.type != ATTR_CLASS_PKEY) {
-            return null;
-        }
-        return aliasInfo.chain;
-    }
-
-    /**
-     * Returns the certificate associated with the given alias.
-     *
-     * <p> If the given alias name identifies an entry
-     * created by a call to <code>setCertificateEntry</code>,
-     * or created by a call to <code>setEntry</code> with a
-     * <code>TrustedCertificateEntry</code>,
-     * then the trusted certificate contained in that entry is returned.
-     *
-     * <p> If the given alias name identifies an entry
-     * created by a call to <code>setKeyEntry</code>,
-     * or created by a call to <code>setEntry</code> with a
-     * <code>PrivateKeyEntry</code>,
-     * then the first element of the certificate chain in that entry
-     * (if a chain exists) is returned.
-     *
-     * @param alias the alias name
-     *
-     * @return the certificate, or null if the given alias does not exist or
-     * does not contain a certificate.
-     */
-    public synchronized Certificate engineGetCertificate(String alias) {
-        token.ensureValid();
-
-        AliasInfo aliasInfo = aliasMap.get(alias);
-        if (aliasInfo == null) {
-            return null;
-        }
-        return aliasInfo.cert;
-    }
-
-    /**
-     * Returns the creation date of the entry identified by the given alias.
-     *
-     * @param alias the alias name
-     *
-     * @return the creation date of this entry, or null if the given alias does
-     * not exist
-     */
-    public Date engineGetCreationDate(String alias) {
-        token.ensureValid();
-        throw new ProviderException(new UnsupportedOperationException());
-    }
-
-    /**
-     * Assigns the given key to the given alias, protecting it with the given
-     * password.
-     *
-     * <p>If the given key is of type <code>java.security.PrivateKey</code>,
-     * it must be accompanied by a certificate chain certifying the
-     * corresponding public key.
-     *
-     * <p>If the given alias already exists, the keystore information
-     * associated with it is overridden by the given key (and possibly
-     * certificate chain).
-     *
-     * @param alias the alias name
-     * @param key the key to be associated with the alias
-     * @param password the password to protect the key
-     * @param chain the certificate chain for the corresponding public
-     * key (only required if the given key is of type
-     * <code>java.security.PrivateKey</code>).
-     *
-     * @exception KeyStoreException if the given key cannot be protected, or
-     * this operation fails for some other reason
-     */
-    public synchronized void engineSetKeyEntry(String alias, Key key,
-                                   char[] password,
-                                   Certificate[] chain)
-                throws KeyStoreException {
-
-        token.ensureValid();
-        checkWrite();
-
-        if (!(key instanceof PrivateKey) && !(key instanceof SecretKey)) {
-            throw new KeyStoreException("key must be PrivateKey or SecretKey");
-        } else if (key instanceof PrivateKey && chain == null) {
-            throw new KeyStoreException
-                ("PrivateKey must be accompanied by non-null chain");
-        } else if (key instanceof SecretKey && chain != null) {
-            throw new KeyStoreException
-                ("SecretKey must be accompanied by null chain");
-        } else if (password != null &&
-                    !token.config.getKeyStoreCompatibilityMode()) {
-            throw new KeyStoreException("Password must be null");
-        }
-
-        KeyStore.Entry entry = null;
-        try {
-            if (key instanceof PrivateKey) {
-                entry = new KeyStore.PrivateKeyEntry((PrivateKey)key, chain);
-            } else if (key instanceof SecretKey) {
-                entry = new KeyStore.SecretKeyEntry((SecretKey)key);
-            }
-        } catch (NullPointerException | IllegalArgumentException e) {
-            throw new KeyStoreException(e);
-        }
-        engineSetEntry(alias, entry, new KeyStore.PasswordProtection(password));
-    }
-
-    /**
-     * Assigns the given key (that has already been protected) to the given
-     * alias.
-     *
-     * <p>If the protected key is of type
-     * <code>java.security.PrivateKey</code>,
-     * it must be accompanied by a certificate chain certifying the
-     * corresponding public key.
-     *
-     * <p>If the given alias already exists, the keystore information
-     * associated with it is overridden by the given key (and possibly
-     * certificate chain).
-     *
-     * @param alias the alias name
-     * @param key the key (in protected format) to be associated with the alias
-     * @param chain the certificate chain for the corresponding public
-     * key (only useful if the protected key is of type
-     * <code>java.security.PrivateKey</code>).
-     *
-     * @exception KeyStoreException if this operation fails.
-     */
-    public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain)
-                throws KeyStoreException {
-        token.ensureValid();
-        throw new ProviderException(new UnsupportedOperationException());
-    }
-
-    /**
-     * Assigns the given certificate to the given alias.
-     *
-     * <p> If the given alias identifies an existing entry
-     * created by a call to <code>setCertificateEntry</code>,
-     * or created by a call to <code>setEntry</code> with a
-     * <code>TrustedCertificateEntry</code>,
-     * the trusted certificate in the existing entry
-     * is overridden by the given certificate.
-     *
-     * @param alias the alias name
-     * @param cert the certificate
-     *
-     * @exception KeyStoreException if the given alias already exists and does
-     * not identify an entry containing a trusted certificate,
-     * or this operation fails for some other reason.
-     */
-    public synchronized void engineSetCertificateEntry
-        (String alias, Certificate cert) throws KeyStoreException {
-
-        token.ensureValid();
-        checkWrite();
-
-        if (cert == null) {
-            throw new KeyStoreException("invalid null certificate");
-        }
-
-        KeyStore.Entry entry = null;
-        entry = new KeyStore.TrustedCertificateEntry(cert);
-        engineSetEntry(alias, entry, null);
-    }
-
-    /**
-     * Deletes the entry identified by the given alias from this keystore.
-     *
-     * @param alias the alias name
-     *
-     * @exception KeyStoreException if the entry cannot be removed.
-     */
-    public synchronized void engineDeleteEntry(String alias)
-                throws KeyStoreException {
-        token.ensureValid();
-
-        if (token.isWriteProtected()) {
-            throw new KeyStoreException("token write-protected");
-        }
-        checkWrite();
-        deleteEntry(alias);
-    }
-
-    /**
-     * XXX - not sure whether to keep this
-     */
-    private boolean deleteEntry(String alias) throws KeyStoreException {
-        AliasInfo aliasInfo = aliasMap.get(alias);
-        if (aliasInfo != null) {
-
-            aliasMap.remove(alias);
-
-            try {
-                if (aliasInfo.type == ATTR_CLASS_CERT) {
-                    // trusted certificate entry
-                    return destroyCert(aliasInfo.id);
-                } else if (aliasInfo.type == ATTR_CLASS_PKEY) {
-                    // private key entry
-                    return destroyPkey(aliasInfo.id) &&
-                                destroyChain(aliasInfo.id);
-                } else if (aliasInfo.type == ATTR_CLASS_SKEY) {
-                    // secret key entry
-                    return destroySkey(alias);
-                } else {
-                    throw new KeyStoreException("unexpected entry type");
-                }
-            } catch (PKCS11Exception | CertificateException e) {
-                throw new KeyStoreException(e);
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Lists all the alias names of this keystore.
-     *
-     * @return enumeration of the alias names
-     */
-    public synchronized Enumeration<String> engineAliases() {
-        token.ensureValid();
-
-        // don't want returned enumeration to iterate off actual keySet -
-        // otherwise applications that iterate and modify the keystore
-        // may run into concurrent modification problems
-        return Collections.enumeration(new HashSet<String>(aliasMap.keySet()));
-    }
-
-    /**
-     * Checks if the given alias exists in this keystore.
-     *
-     * @param alias the alias name
-     *
-     * @return true if the alias exists, false otherwise
-     */
-    public synchronized boolean engineContainsAlias(String alias) {
-        token.ensureValid();
-        return aliasMap.containsKey(alias);
-    }
-
-    /**
-     * Retrieves the number of entries in this keystore.
-     *
-     * @return the number of entries in this keystore
-     */
-    public synchronized int engineSize() {
-        token.ensureValid();
-        return aliasMap.size();
-    }
-
-    /**
-     * Returns true if the entry identified by the given alias
-     * was created by a call to <code>setKeyEntry</code>,
-     * or created by a call to <code>setEntry</code> with a
-     * <code>PrivateKeyEntry</code> or a <code>SecretKeyEntry</code>.
-     *
-     * @param alias the alias for the keystore entry to be checked
-     *
-     * @return true if the entry identified by the given alias is a
-     * key-related, false otherwise.
-     */
-    public synchronized boolean engineIsKeyEntry(String alias) {
-        token.ensureValid();
-
-        AliasInfo aliasInfo = aliasMap.get(alias);
-        if (aliasInfo == null || aliasInfo.type == ATTR_CLASS_CERT) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Returns true if the entry identified by the given alias
-     * was created by a call to <code>setCertificateEntry</code>,
-     * or created by a call to <code>setEntry</code> with a
-     * <code>TrustedCertificateEntry</code>.
-     *
-     * @param alias the alias for the keystore entry to be checked
-     *
-     * @return true if the entry identified by the given alias contains a
-     * trusted certificate, false otherwise.
-     */
-    public synchronized boolean engineIsCertificateEntry(String alias) {
-        token.ensureValid();
-
-        AliasInfo aliasInfo = aliasMap.get(alias);
-        if (aliasInfo == null || aliasInfo.type != ATTR_CLASS_CERT) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Returns the (alias) name of the first keystore entry whose certificate
-     * matches the given certificate.
-     *
-     * <p>This method attempts to match the given certificate with each
-     * keystore entry. If the entry being considered was
-     * created by a call to <code>setCertificateEntry</code>,
-     * or created by a call to <code>setEntry</code> with a
-     * <code>TrustedCertificateEntry</code>,
-     * then the given certificate is compared to that entry's certificate.
-     *
-     * <p> If the entry being considered was
-     * created by a call to <code>setKeyEntry</code>,
-     * or created by a call to <code>setEntry</code> with a
-     * <code>PrivateKeyEntry</code>,
-     * then the given certificate is compared to the first
-     * element of that entry's certificate chain.
-     *
-     * @param cert the certificate to match with.
-     *
-     * @return the alias name of the first entry with matching certificate,
-     * or null if no such entry exists in this keystore.
-     */
-    public synchronized String engineGetCertificateAlias(Certificate cert) {
-        token.ensureValid();
-        Enumeration<String> e = engineAliases();
-        while (e.hasMoreElements()) {
-            String alias = e.nextElement();
-            Certificate tokenCert = engineGetCertificate(alias);
-            if (tokenCert != null && tokenCert.equals(cert)) {
-                return alias;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * engineStore currently is a No-op.
-     * Entries are stored to the token during engineSetEntry
-     *
-     * @param stream this must be <code>null</code>
-     * @param password this must be <code>null</code>
-     */
-    public synchronized void engineStore(OutputStream stream, char[] password)
-        throws IOException, NoSuchAlgorithmException, CertificateException {
-        token.ensureValid();
-        if (stream != null && !token.config.getKeyStoreCompatibilityMode()) {
-            throw new IOException("output stream must be null");
-        }
-
-        if (password != null && !token.config.getKeyStoreCompatibilityMode()) {
-            throw new IOException("password must be null");
-        }
-    }
-
-    /**
-     * engineStore currently is a No-op.
-     * Entries are stored to the token during engineSetEntry
-     *
-     * @param param this must be <code>null</code>
-     *
-     * @exception IllegalArgumentException if the given
-     *          <code>KeyStore.LoadStoreParameter</code>
-     *          input is not <code>null</code>
-     */
-    public synchronized void engineStore(KeyStore.LoadStoreParameter param)
-        throws IOException, NoSuchAlgorithmException, CertificateException {
-        token.ensureValid();
-        if (param != null) {
-            throw new IllegalArgumentException
-                ("LoadStoreParameter must be null");
-        }
-    }
-
-    /**
-     * Loads the keystore.
-     *
-     * @param stream the input stream, which must be <code>null</code>
-     * @param password the password used to unlock the keystore,
-     *          or <code>null</code> if the token supports a
-     *          CKF_PROTECTED_AUTHENTICATION_PATH
-     *
-     * @exception IOException if the given <code>stream</code> is not
-     *          <code>null</code>, if the token supports a
-     *          CKF_PROTECTED_AUTHENTICATION_PATH and a non-null
-     *          password is given, of if the token login operation failed
-     */
-    public synchronized void engineLoad(InputStream stream, char[] password)
-        throws IOException, NoSuchAlgorithmException, CertificateException {
-
-        token.ensureValid();
-
-        if (NSS_TEST) {
-            ATTR_SKEY_TOKEN_TRUE = new CK_ATTRIBUTE(CKA_TOKEN, false);
-        }
-
-        if (stream != null && !token.config.getKeyStoreCompatibilityMode()) {
-            throw new IOException("input stream must be null");
-        }
-
-        if (useSecmodTrust) {
-            nssTrustType = Secmod.TrustType.ALL;
-        }
-
-        try {
-            if (password == null) {
-                login(null);
-            } else {
-                login(new PasswordCallbackHandler(password));
-            }
-        } catch(LoginException e) {
-            Throwable cause = e.getCause();
-            if (cause instanceof PKCS11Exception) {
-                PKCS11Exception pe = (PKCS11Exception) cause;
-                if (pe.getErrorCode() == CKR_PIN_INCORRECT) {
-                    // if password is wrong, the cause of the IOException
-                    // should be an UnrecoverableKeyException
-                    throw new IOException("load failed",
-                            new UnrecoverableKeyException().initCause(e));
-                }
-            }
-            throw new IOException("load failed", e);
-        }
-
-        try {
-            if (mapLabels() == true) {
-                // CKA_LABELs are shared by multiple certs
-                writeDisabled = true;
-            }
-            if (debug != null) {
-                dumpTokenMap();
-            }
-        } catch (KeyStoreException | PKCS11Exception e) {
-            throw new IOException("load failed", e);
-        }
-    }
-
-    /**
-     * Loads the keystore using the given
-     * <code>KeyStore.LoadStoreParameter</code>.
-     *
-     * <p> The <code>LoadStoreParameter.getProtectionParameter()</code>
-     * method is expected to return a <code>KeyStore.PasswordProtection</code>
-     * object.  The password is retrieved from that object and used
-     * to unlock the PKCS#11 token.
-     *
-     * <p> If the token supports a CKF_PROTECTED_AUTHENTICATION_PATH
-     * then the provided password must be <code>null</code>.
-     *
-     * @param param the <code>KeyStore.LoadStoreParameter</code>
-     *
-     * @exception IllegalArgumentException if the given
-     *          <code>KeyStore.LoadStoreParameter</code> is <code>null</code>,
-     *          or if that parameter returns a <code>null</code>
-     *          <code>ProtectionParameter</code> object.
-     *          input is not recognized
-     * @exception IOException if the token supports a
-     *          CKF_PROTECTED_AUTHENTICATION_PATH and the provided password
-     *          is non-null, or if the token login operation fails
-     */
-    public synchronized void engineLoad(KeyStore.LoadStoreParameter param)
-                throws IOException, NoSuchAlgorithmException,
-                CertificateException {
-
-        token.ensureValid();
-
-        if (NSS_TEST) {
-            ATTR_SKEY_TOKEN_TRUE = new CK_ATTRIBUTE(CKA_TOKEN, false);
-        }
-
-        // if caller wants to pass a NULL password,
-        // force it to pass a non-NULL PasswordProtection that returns
-        // a NULL password
-
-        if (param == null) {
-            throw new IllegalArgumentException
-                        ("invalid null LoadStoreParameter");
-        }
-        if (useSecmodTrust) {
-            if (param instanceof Secmod.KeyStoreLoadParameter) {
-                nssTrustType = ((Secmod.KeyStoreLoadParameter)param).getTrustType();
-            } else {
-                nssTrustType = Secmod.TrustType.ALL;
-            }
-        }
-
-        CallbackHandler handler;
-        KeyStore.ProtectionParameter pp = param.getProtectionParameter();
-        if (pp instanceof PasswordProtection) {
-            char[] password = ((PasswordProtection)pp).getPassword();
-            if (password == null) {
-                handler = null;
-            } else {
-                handler = new PasswordCallbackHandler(password);
-            }
-        } else if (pp instanceof CallbackHandlerProtection) {
-            handler = ((CallbackHandlerProtection)pp).getCallbackHandler();
-        } else {
-            throw new IllegalArgumentException
-                        ("ProtectionParameter must be either " +
-                        "PasswordProtection or CallbackHandlerProtection");
-        }
-
-        try {
-            login(handler);
-            if (mapLabels() == true) {
-                // CKA_LABELs are shared by multiple certs
-                writeDisabled = true;
-            }
-            if (debug != null) {
-                dumpTokenMap();
-            }
-        } catch (LoginException | KeyStoreException | PKCS11Exception e) {
-            throw new IOException("load failed", e);
-        }
-    }
-
-    private void login(CallbackHandler handler) throws LoginException {
-        if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
-            token.provider.login(null, handler);
-        } else {
-            // token supports protected authentication path
-            // (external pin-pad, for example)
-            if (handler != null &&
-                !token.config.getKeyStoreCompatibilityMode()) {
-                throw new LoginException("can not specify password if token " +
-                                "supports protected authentication path");
-            }
-
-            // must rely on application-set or default handler
-            // if one is necessary
-            token.provider.login(null, null);
-        }
-    }
-
-    /**
-     * Get a <code>KeyStore.Entry</code> for the specified alias
-     *
-     * @param alias get the <code>KeyStore.Entry</code> for this alias
-     * @param protParam this must be <code>null</code>
-     *
-     * @return the <code>KeyStore.Entry</code> for the specified alias,
-     *          or <code>null</code> if there is no such entry
-     *
-     * @exception KeyStoreException if the operation failed
-     * @exception NoSuchAlgorithmException if the algorithm for recovering the
-     *          entry cannot be found
-     * @exception UnrecoverableEntryException if the specified
-     *          <code>protParam</code> were insufficient or invalid
-     *
-     * @since 1.5
-     */
-    public synchronized KeyStore.Entry engineGetEntry(String alias,
-                        KeyStore.ProtectionParameter protParam)
-                throws KeyStoreException, NoSuchAlgorithmException,
-                UnrecoverableEntryException {
-
-        token.ensureValid();
-
-        if (protParam != null &&
-            protParam instanceof KeyStore.PasswordProtection &&
-            ((KeyStore.PasswordProtection)protParam).getPassword() != null &&
-            !token.config.getKeyStoreCompatibilityMode()) {
-            throw new KeyStoreException("ProtectionParameter must be null");
-        }
-
-        AliasInfo aliasInfo = aliasMap.get(alias);
-        if (aliasInfo == null) {
-            if (debug != null) {
-                debug.println("engineGetEntry did not find alias [" +
-                        alias +
-                        "] in map");
-            }
-            return null;
-        }
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            if (aliasInfo.type == ATTR_CLASS_CERT) {
-                // trusted certificate entry
-                if (debug != null) {
-                    debug.println("engineGetEntry found trusted cert entry");
-                }
-                return new KeyStore.TrustedCertificateEntry(aliasInfo.cert);
-            } else if (aliasInfo.type == ATTR_CLASS_SKEY) {
-                // secret key entry
-                if (debug != null) {
-                    debug.println("engineGetEntry found secret key entry");
-                }
-
-                THandle h = getTokenObject
-                        (session, ATTR_CLASS_SKEY, null, aliasInfo.label);
-                if (h.type != ATTR_CLASS_SKEY) {
-                    throw new KeyStoreException
-                        ("expected but could not find secret key");
-                } else {
-                    SecretKey skey = loadSkey(session, h.handle);
-                    return new KeyStore.SecretKeyEntry(skey);
-                }
-            } else {
-                // private key entry
-                if (debug != null) {
-                    debug.println("engineGetEntry found private key entry");
-                }
-
-                THandle h = getTokenObject
-                        (session, ATTR_CLASS_PKEY, aliasInfo.id, null);
-                if (h.type != ATTR_CLASS_PKEY) {
-                    throw new KeyStoreException
-                        ("expected but could not find private key");
-                } else {
-                    PrivateKey pkey = loadPkey(session, h.handle);
-                    Certificate[] chain = aliasInfo.chain;
-                    if ((pkey != null) && (chain != null)) {
-                        return new KeyStore.PrivateKeyEntry(pkey, chain);
-                    } else {
-                        if (debug != null) {
-                            debug.println
-                                ("engineGetEntry got null cert chain or private key");
-                        }
-                    }
-                }
-            }
-            return null;
-        } catch (PKCS11Exception pe) {
-            throw new KeyStoreException(pe);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    /**
-     * Save a <code>KeyStore.Entry</code> under the specified alias.
-     *
-     * <p> If an entry already exists for the specified alias,
-     * it is overridden.
-     *
-     * <p> This KeyStore implementation only supports the standard
-     * entry types, and only supports X509Certificates in
-     * TrustedCertificateEntries.  Also, this implementation does not support
-     * protecting entries using a different password
-     * from the one used for token login.
-     *
-     * <p> Entries are immediately stored on the token.
-     *
-     * @param alias save the <code>KeyStore.Entry</code> under this alias
-     * @param entry the <code>Entry</code> to save
-     * @param protParam this must be <code>null</code>
-     *
-     * @exception KeyStoreException if this operation fails
-     *
-     * @since 1.5
-     */
-    public synchronized void engineSetEntry(String alias, KeyStore.Entry entry,
-                        KeyStore.ProtectionParameter protParam)
-                throws KeyStoreException {
-
-        token.ensureValid();
-        checkWrite();
-
-        if (protParam != null &&
-            protParam instanceof KeyStore.PasswordProtection &&
-            ((KeyStore.PasswordProtection)protParam).getPassword() != null &&
-            !token.config.getKeyStoreCompatibilityMode()) {
-            throw new KeyStoreException(new UnsupportedOperationException
-                                ("ProtectionParameter must be null"));
-        }
-
-        if (token.isWriteProtected()) {
-            throw new KeyStoreException("token write-protected");
-        }
-
-        if (entry instanceof KeyStore.TrustedCertificateEntry) {
-
-            if (useSecmodTrust == false) {
-                // PKCS #11 does not allow app to modify trusted certs -
-                throw new KeyStoreException(new UnsupportedOperationException
-                                    ("trusted certificates may only be set by " +
-                                    "token initialization application"));
-            }
-            Module module = token.provider.nssModule;
-            if ((module.type != ModuleType.KEYSTORE) && (module.type != ModuleType.FIPS)) {
-                // XXX allow TRUSTANCHOR module
-                throw new KeyStoreException("Trusted certificates can only be "
-                    + "added to the NSS KeyStore module");
-            }
-            Certificate cert = ((TrustedCertificateEntry)entry).getTrustedCertificate();
-            if (cert instanceof X509Certificate == false) {
-                throw new KeyStoreException("Certificate must be an X509Certificate");
-            }
-            X509Certificate xcert = (X509Certificate)cert;
-            AliasInfo info = aliasMap.get(alias);
-            if (info != null) {
-                // XXX try to update
-                deleteEntry(alias);
-            }
-            try {
-                storeCert(alias, xcert);
-                module.setTrust(token, xcert);
-                mapLabels();
-            } catch (PKCS11Exception | CertificateException e) {
-                throw new KeyStoreException(e);
-            }
-
-        } else {
-
-            if (entry instanceof KeyStore.PrivateKeyEntry) {
-
-                PrivateKey key =
-                        ((KeyStore.PrivateKeyEntry)entry).getPrivateKey();
-                if (!(key instanceof P11Key) &&
-                    !(key instanceof RSAPrivateKey) &&
-                    !(key instanceof DSAPrivateKey) &&
-                    !(key instanceof DHPrivateKey) &&
-                    !(key instanceof ECPrivateKey)) {
-                    throw new KeyStoreException("unsupported key type: " +
-                                                key.getClass().getName());
-                }
-
-                // only support X509Certificate chains
-                Certificate[] chain =
-                    ((KeyStore.PrivateKeyEntry)entry).getCertificateChain();
-                if (!(chain instanceof X509Certificate[])) {
-                    throw new KeyStoreException
-                        (new UnsupportedOperationException
-                                ("unsupported certificate array type: " +
-                                chain.getClass().getName()));
-                }
-
-                try {
-                    boolean updatedAlias = false;
-                    Set<String> aliases = aliasMap.keySet();
-                    for (String oldAlias : aliases) {
-
-                        // see if there's an existing entry with the same info
-
-                        AliasInfo aliasInfo = aliasMap.get(oldAlias);
-                        if (aliasInfo.type == ATTR_CLASS_PKEY &&
-                            aliasInfo.cert.getPublicKey().equals
-                                        (chain[0].getPublicKey())) {
-
-                            // found existing entry -
-                            // caller is renaming entry or updating cert chain
-                            //
-                            // set new CKA_LABEL/CKA_ID
-                            // and update certs if necessary
-
-                            updatePkey(alias,
-                                        aliasInfo.id,
-                                        (X509Certificate[])chain,
-                                        !aliasInfo.cert.equals(chain[0]));
-                            updatedAlias = true;
-                            break;
-                        }
-                    }
-
-                    if (!updatedAlias) {
-                        // caller adding new entry
-                        engineDeleteEntry(alias);
-                        storePkey(alias, (KeyStore.PrivateKeyEntry)entry);
-                    }
-
-                } catch (PKCS11Exception | CertificateException pe) {
-                    throw new KeyStoreException(pe);
-                }
-
-            } else if (entry instanceof KeyStore.SecretKeyEntry) {
-
-                KeyStore.SecretKeyEntry ske = (KeyStore.SecretKeyEntry)entry;
-                SecretKey skey = ske.getSecretKey();
-
-                try {
-                    // first check if the key already exists
-                    AliasInfo aliasInfo = aliasMap.get(alias);
-
-                    if (aliasInfo != null) {
-                        engineDeleteEntry(alias);
-                    }
-                    storeSkey(alias, ske);
-
-                } catch (PKCS11Exception pe) {
-                    throw new KeyStoreException(pe);
-                }
-
-            } else {
-                throw new KeyStoreException(new UnsupportedOperationException
-                    ("unsupported entry type: " + entry.getClass().getName()));
-            }
-
-            try {
-
-                // XXX  NSS does not write out the CKA_ID we pass to them
-                //
-                // therefore we must re-map labels
-                // (can not simply update aliasMap)
-
-                mapLabels();
-                if (debug != null) {
-                    dumpTokenMap();
-                }
-            } catch (PKCS11Exception | CertificateException pe) {
-                throw new KeyStoreException(pe);
-            }
-        }
-
-        if (debug != null) {
-            debug.println
-                ("engineSetEntry added new entry for [" +
-                alias +
-                "] to token");
-        }
-    }
-
-    /**
-     * Determines if the keystore <code>Entry</code> for the specified
-     * <code>alias</code> is an instance or subclass of the specified
-     * <code>entryClass</code>.
-     *
-     * @param alias the alias name
-     * @param entryClass the entry class
-     *
-     * @return true if the keystore <code>Entry</code> for the specified
-     *          <code>alias</code> is an instance or subclass of the
-     *          specified <code>entryClass</code>, false otherwise
-     */
-    public synchronized boolean engineEntryInstanceOf
-                (String alias, Class<? extends KeyStore.Entry> entryClass) {
-        token.ensureValid();
-        return super.engineEntryInstanceOf(alias, entryClass);
-    }
-
-    private X509Certificate loadCert(Session session, long oHandle)
-                throws PKCS11Exception, CertificateException {
-
-        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[]
-                        { new CK_ATTRIBUTE(CKA_VALUE) };
-        token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
-
-        byte[] bytes = attrs[0].getByteArray();
-        if (bytes == null) {
-            throw new CertificateException
-                        ("unexpectedly retrieved null byte array");
-        }
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-        return (X509Certificate)cf.generateCertificate
-                        (new ByteArrayInputStream(bytes));
-    }
-
-    private X509Certificate[] loadChain(Session session,
-                                        X509Certificate endCert)
-                throws PKCS11Exception, CertificateException {
-
-        ArrayList<X509Certificate> lChain = null;
-
-        if (endCert.getSubjectX500Principal().equals
-            (endCert.getIssuerX500Principal())) {
-            // self signed
-            return new X509Certificate[] { endCert };
-        } else {
-            lChain = new ArrayList<X509Certificate>();
-            lChain.add(endCert);
-        }
-
-        // try loading remaining certs in chain by following
-        // issuer->subject links
-
-        X509Certificate next = endCert;
-        while (true) {
-            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                        ATTR_TOKEN_TRUE,
-                        ATTR_CLASS_CERT,
-                        new CK_ATTRIBUTE(CKA_SUBJECT,
-                                next.getIssuerX500Principal().getEncoded()) };
-            long[] ch = findObjects(session, attrs);
-
-            if (ch == null || ch.length == 0) {
-                // done
-                break;
-            } else {
-                // if more than one found, use first
-                if (debug != null && ch.length > 1) {
-                    debug.println("engineGetEntry found " +
-                                ch.length +
-                                " certificate entries for subject [" +
-                                next.getIssuerX500Principal().toString() +
-                                "] in token - using first entry");
-                }
-
-                next = loadCert(session, ch[0]);
-                lChain.add(next);
-                if (next.getSubjectX500Principal().equals
-                    (next.getIssuerX500Principal())) {
-                    // self signed
-                    break;
-                }
-            }
-        }
-
-        return lChain.toArray(new X509Certificate[lChain.size()]);
-    }
-
-    private SecretKey loadSkey(Session session, long oHandle)
-                throws PKCS11Exception {
-
-        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                        new CK_ATTRIBUTE(CKA_KEY_TYPE) };
-        token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
-        long kType = attrs[0].getLong();
-
-        String keyType = null;
-        int keyLength = -1;
-
-        // XXX NSS mangles the stored key type for secret key token objects
-
-        if (kType == CKK_DES || kType == CKK_DES3) {
-            if (kType == CKK_DES) {
-                keyType = "DES";
-                keyLength = 64;
-            } else if (kType == CKK_DES3) {
-                keyType = "DESede";
-                keyLength = 192;
-            }
-        } else {
-            if (kType == CKK_AES) {
-                keyType = "AES";
-            } else if (kType == CKK_BLOWFISH) {
-                keyType = "Blowfish";
-            } else if (kType == CKK_RC4) {
-                keyType = "ARCFOUR";
-            } else {
-                if (debug != null) {
-                    debug.println("unknown key type [" +
-                                kType +
-                                "] - using 'Generic Secret'");
-                }
-                keyType = "Generic Secret";
-            }
-
-            // XXX NSS problem CKR_ATTRIBUTE_TYPE_INVALID?
-            if (NSS_TEST) {
-                keyLength = 128;
-            } else {
-                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_VALUE_LEN) };
-                token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
-                keyLength = (int)attrs[0].getLong();
-            }
-        }
-
-        return P11Key.secretKey(session, oHandle, keyType, keyLength, null);
-    }
-
-    private PrivateKey loadPkey(Session session, long oHandle)
-        throws PKCS11Exception, KeyStoreException {
-
-        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                        new CK_ATTRIBUTE(CKA_KEY_TYPE) };
-        token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
-        long kType = attrs[0].getLong();
-        String keyType = null;
-        int keyLength = 0;
-
-        if (kType == CKK_RSA) {
-
-            keyType = "RSA";
-
-            attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_MODULUS) };
-            token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
-            BigInteger modulus = attrs[0].getBigInteger();
-            keyLength = modulus.bitLength();
-
-            // This check will combine our "don't care" values here
-            // with the system-wide min/max values.
-            try {
-                RSAKeyFactory.checkKeyLengths(keyLength, null,
-                    -1, Integer.MAX_VALUE);
-            } catch (InvalidKeyException e) {
-                throw new KeyStoreException(e.getMessage());
-            }
-
-            return P11Key.privateKey(session,
-                                oHandle,
-                                keyType,
-                                keyLength,
-                                null);
-
-        } else if (kType == CKK_DSA) {
-
-            keyType = "DSA";
-
-            attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
-            token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
-            BigInteger prime = attrs[0].getBigInteger();
-            keyLength = prime.bitLength();
-
-            return P11Key.privateKey(session,
-                                oHandle,
-                                keyType,
-                                keyLength,
-                                null);
-
-        } else if (kType == CKK_DH) {
-
-            keyType = "DH";
-
-            attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_PRIME) };
-            token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
-            BigInteger prime = attrs[0].getBigInteger();
-            keyLength = prime.bitLength();
-
-            return P11Key.privateKey(session,
-                                oHandle,
-                                keyType,
-                                keyLength,
-                                null);
-
-        } else if (kType == CKK_EC) {
-
-            attrs = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_EC_PARAMS),
-            };
-            token.p11.C_GetAttributeValue(session.id(), oHandle, attrs);
-            byte[] encodedParams = attrs[0].getByteArray();
-            try {
-                ECParameterSpec params =
-                    ECUtil.getECParameterSpec(null, encodedParams);
-                keyLength = params.getCurve().getField().getFieldSize();
-            } catch (IOException e) {
-                // we do not want to accept key with unsupported parameters
-                throw new KeyStoreException("Unsupported parameters", e);
-            }
-
-            return P11Key.privateKey(session, oHandle, "EC", keyLength, null);
-
-        } else {
-            if (debug != null) {
-                debug.println("unknown key type [" + kType + "]");
-            }
-            throw new KeyStoreException("unknown key type");
-        }
-    }
-
-
-    /**
-     * XXX  On ibutton, when you C_SetAttribute(CKA_ID) for a private key
-     *      it not only changes the CKA_ID of the private key,
-     *      it changes the CKA_ID of the corresponding cert too.
-     *      And vice versa.
-     *
-     * XXX  On ibutton, CKR_DEVICE_ERROR if you C_SetAttribute(CKA_ID)
-     *      for a private key, and then try to delete the corresponding cert.
-     *      So this code reverses the order.
-     *      After the cert is first destroyed (if necessary),
-     *      then the CKA_ID of the private key can be changed successfully.
-     *
-     * @param replaceCert if true, then caller is updating alias info for
-     *                  existing cert (only update CKA_ID/CKA_LABEL).
-     *                  if false, then caller is updating cert chain
-     *                  (delete old end cert and add new chain).
-     */
-    private void updatePkey(String alias,
-                        byte[] cka_id,
-                        X509Certificate[] chain,
-                        boolean replaceCert) throws
-                KeyStoreException, CertificateException, PKCS11Exception {
-
-        // XXX
-        //
-        // always set replaceCert to true
-        //
-        // NSS does not allow resetting of CKA_LABEL on an existing cert
-        // (C_SetAttribute call succeeds, but is ignored)
-
-        replaceCert = true;
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            // first get private key object handle and hang onto it
-
-            THandle h = getTokenObject(session, ATTR_CLASS_PKEY, cka_id, null);
-            long pKeyHandle;
-            if (h.type == ATTR_CLASS_PKEY) {
-                pKeyHandle = h.handle;
-            } else {
-                throw new KeyStoreException
-                        ("expected but could not find private key " +
-                        "with CKA_ID " +
-                        getID(cka_id));
-            }
-
-            // next find existing end entity cert
-
-            h = getTokenObject(session, ATTR_CLASS_CERT, cka_id, null);
-            if (h.type != ATTR_CLASS_CERT) {
-                throw new KeyStoreException
-                        ("expected but could not find certificate " +
-                        "with CKA_ID " +
-                        getID(cka_id));
-            } else {
-                if (replaceCert) {
-                    // replacing existing cert and chain
-                    destroyChain(cka_id);
-                } else {
-                    // renaming alias for existing cert
-                    CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                        new CK_ATTRIBUTE(CKA_LABEL, alias),
-                        new CK_ATTRIBUTE(CKA_ID, alias) };
-                    token.p11.C_SetAttributeValue
-                        (session.id(), h.handle, attrs);
-                }
-            }
-
-            // add new chain
-
-            if (replaceCert) {
-                // add all certs in chain
-                storeChain(alias, chain);
-            } else {
-                // already updated alias info for existing end cert -
-                // just update CA certs
-                storeCaCerts(chain, 1);
-            }
-
-            // finally update CKA_ID for private key
-            //
-            // ibutton may have already done this (that is ok)
-
-            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                                new CK_ATTRIBUTE(CKA_ID, alias) };
-            token.p11.C_SetAttributeValue(session.id(), pKeyHandle, attrs);
-
-            if (debug != null) {
-                debug.println("updatePkey set new alias [" +
-                                alias +
-                                "] for private key entry");
-            }
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private void updateP11Pkey(String alias, CK_ATTRIBUTE attribute, P11Key key)
-                throws PKCS11Exception {
-
-        // if token key, update alias.
-        // if session key, convert to token key.
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            if (key.tokenObject == true) {
-
-                // token key - set new CKA_ID
-
-                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                                new CK_ATTRIBUTE(CKA_ID, alias) };
-                token.p11.C_SetAttributeValue
-                                (session.id(), key.keyID, attrs);
-                if (debug != null) {
-                    debug.println("updateP11Pkey set new alias [" +
-                                alias +
-                                "] for key entry");
-                }
-            } else {
-
-                // session key - convert to token key and set CKA_ID
-
-                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                    ATTR_TOKEN_TRUE,
-                    new CK_ATTRIBUTE(CKA_ID, alias),
-                };
-                if (attribute != null) {
-                    attrs = addAttribute(attrs, attribute);
-                }
-                token.p11.C_CopyObject(session.id(), key.keyID, attrs);
-                if (debug != null) {
-                    debug.println("updateP11Pkey copied private session key " +
-                                "for [" +
-                                alias +
-                                "] to token entry");
-                }
-            }
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private void storeCert(String alias, X509Certificate cert)
-                throws PKCS11Exception, CertificateException {
-
-        ArrayList<CK_ATTRIBUTE> attrList = new ArrayList<CK_ATTRIBUTE>();
-        attrList.add(ATTR_TOKEN_TRUE);
-        attrList.add(ATTR_CLASS_CERT);
-        attrList.add(ATTR_X509_CERT_TYPE);
-        attrList.add(new CK_ATTRIBUTE(CKA_SUBJECT,
-                                cert.getSubjectX500Principal().getEncoded()));
-        attrList.add(new CK_ATTRIBUTE(CKA_ISSUER,
-                                cert.getIssuerX500Principal().getEncoded()));
-        attrList.add(new CK_ATTRIBUTE(CKA_SERIAL_NUMBER,
-                                cert.getSerialNumber().toByteArray()));
-        attrList.add(new CK_ATTRIBUTE(CKA_VALUE, cert.getEncoded()));
-
-        if (alias != null) {
-            attrList.add(new CK_ATTRIBUTE(CKA_LABEL, alias));
-            attrList.add(new CK_ATTRIBUTE(CKA_ID, alias));
-        } else {
-            // ibutton requires something to be set
-            // - alias must be unique
-            attrList.add(new CK_ATTRIBUTE(CKA_ID,
-                        getID(cert.getSubjectX500Principal().getName
-                                        (X500Principal.CANONICAL), cert)));
-        }
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            token.p11.C_CreateObject(session.id(),
-                        attrList.toArray(new CK_ATTRIBUTE[attrList.size()]));
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private void storeChain(String alias, X509Certificate[] chain)
-                throws PKCS11Exception, CertificateException {
-
-        // add new chain
-        //
-        // end cert has CKA_LABEL and CKA_ID set to alias.
-        // other certs in chain have neither set.
-
-        storeCert(alias, chain[0]);
-        storeCaCerts(chain, 1);
-    }
-
-    private void storeCaCerts(X509Certificate[] chain, int start)
-                throws PKCS11Exception, CertificateException {
-
-        // do not add duplicate CA cert if already in token
-        //
-        // XXX   ibutton stores duplicate CA certs, NSS does not
-
-        Session session = null;
-        HashSet<X509Certificate> cacerts = new HashSet<X509Certificate>();
-        try {
-            session = token.getOpSession();
-            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                        ATTR_TOKEN_TRUE,
-                        ATTR_CLASS_CERT };
-            long[] handles = findObjects(session, attrs);
-
-            // load certs currently on the token
-            for (long handle : handles) {
-                cacerts.add(loadCert(session, handle));
-            }
-        } finally {
-            token.releaseSession(session);
-        }
-
-        for (int i = start; i < chain.length; i++) {
-            if (!cacerts.contains(chain[i])) {
-                storeCert(null, chain[i]);
-            } else if (debug != null) {
-                debug.println("ignoring duplicate CA cert for [" +
-                        chain[i].getSubjectX500Principal() +
-                        "]");
-            }
-        }
-    }
-
-    private void storeSkey(String alias, KeyStore.SecretKeyEntry ske)
-                throws PKCS11Exception, KeyStoreException {
-
-        SecretKey skey = ske.getSecretKey();
-        // No need to specify CKA_CLASS, CKA_KEY_TYPE, CKA_VALUE since
-        // they are handled in P11SecretKeyFactory.createKey() method.
-        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-            ATTR_SKEY_TOKEN_TRUE,
-            ATTR_PRIVATE_TRUE,
-            new CK_ATTRIBUTE(CKA_LABEL, alias),
-        };
-        try {
-            P11SecretKeyFactory.convertKey(token, skey, null, attrs);
-        } catch (InvalidKeyException ike) {
-            // re-throw KeyStoreException to match javadoc
-            throw new KeyStoreException("Cannot convert to PKCS11 keys", ike);
-        }
-
-        // update global alias map
-        aliasMap.put(alias, new AliasInfo(alias));
-
-        if (debug != null) {
-            debug.println("storeSkey created token secret key for [" +
-                          alias + "]");
-        }
-    }
-
-    private static CK_ATTRIBUTE[] addAttribute(CK_ATTRIBUTE[] attrs, CK_ATTRIBUTE attr) {
-        int n = attrs.length;
-        CK_ATTRIBUTE[] newAttrs = new CK_ATTRIBUTE[n + 1];
-        System.arraycopy(attrs, 0, newAttrs, 0, n);
-        newAttrs[n] = attr;
-        return newAttrs;
-    }
-
-    private void storePkey(String alias, KeyStore.PrivateKeyEntry pke)
-        throws PKCS11Exception, CertificateException, KeyStoreException  {
-
-        PrivateKey key = pke.getPrivateKey();
-        CK_ATTRIBUTE[] attrs = null;
-
-        // If the key is a token object on this token, update it instead
-        // of creating a duplicate key object.
-        // Otherwise, treat a P11Key like any other key, if it is extractable.
-        if (key instanceof P11Key) {
-            P11Key p11Key = (P11Key)key;
-            if (p11Key.tokenObject && (p11Key.token == this.token)) {
-                updateP11Pkey(alias, null, p11Key);
-                storeChain(alias, (X509Certificate[])pke.getCertificateChain());
-                return;
-            }
-        }
-
-        boolean useNDB = token.config.getNssNetscapeDbWorkaround();
-        PublicKey publicKey = pke.getCertificate().getPublicKey();
-
-        if (key instanceof RSAPrivateKey) {
-
-            X509Certificate cert = (X509Certificate)pke.getCertificate();
-            attrs = getRsaPrivKeyAttrs
-                (alias, (RSAPrivateKey)key, cert.getSubjectX500Principal());
-
-        } else if (key instanceof DSAPrivateKey) {
-
-            DSAPrivateKey dsaKey = (DSAPrivateKey)key;
-
-            CK_ATTRIBUTE[] idAttrs = getIdAttributes(key, publicKey, false, useNDB);
-            if (idAttrs[0] == null) {
-                idAttrs[0] = new CK_ATTRIBUTE(CKA_ID, alias);
-            }
-
-            attrs = new CK_ATTRIBUTE[] {
-                ATTR_TOKEN_TRUE,
-                ATTR_CLASS_PKEY,
-                ATTR_PRIVATE_TRUE,
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DSA),
-                idAttrs[0],
-                new CK_ATTRIBUTE(CKA_PRIME, dsaKey.getParams().getP()),
-                new CK_ATTRIBUTE(CKA_SUBPRIME, dsaKey.getParams().getQ()),
-                new CK_ATTRIBUTE(CKA_BASE, dsaKey.getParams().getG()),
-                new CK_ATTRIBUTE(CKA_VALUE, dsaKey.getX()),
-            };
-            if (idAttrs[1] != null) {
-                attrs = addAttribute(attrs, idAttrs[1]);
-            }
-
-            attrs = token.getAttributes
-                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_DSA, attrs);
-
-            if (debug != null) {
-                debug.println("storePkey created DSA template");
-            }
-
-        } else if (key instanceof DHPrivateKey) {
-
-            DHPrivateKey dhKey = (DHPrivateKey)key;
-
-            CK_ATTRIBUTE[] idAttrs = getIdAttributes(key, publicKey, false, useNDB);
-            if (idAttrs[0] == null) {
-                idAttrs[0] = new CK_ATTRIBUTE(CKA_ID, alias);
-            }
-
-            attrs = new CK_ATTRIBUTE[] {
-                ATTR_TOKEN_TRUE,
-                ATTR_CLASS_PKEY,
-                ATTR_PRIVATE_TRUE,
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_DH),
-                idAttrs[0],
-                new CK_ATTRIBUTE(CKA_PRIME, dhKey.getParams().getP()),
-                new CK_ATTRIBUTE(CKA_BASE, dhKey.getParams().getG()),
-                new CK_ATTRIBUTE(CKA_VALUE, dhKey.getX()),
-            };
-            if (idAttrs[1] != null) {
-                attrs = addAttribute(attrs, idAttrs[1]);
-            }
-
-            attrs = token.getAttributes
-                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_DH, attrs);
-
-        } else if (key instanceof ECPrivateKey) {
-
-            ECPrivateKey ecKey = (ECPrivateKey)key;
-
-            CK_ATTRIBUTE[] idAttrs = getIdAttributes(key, publicKey, false, useNDB);
-            if (idAttrs[0] == null) {
-                idAttrs[0] = new CK_ATTRIBUTE(CKA_ID, alias);
-            }
-
-            byte[] encodedParams =
-                ECUtil.encodeECParameterSpec(null, ecKey.getParams());
-            attrs = new CK_ATTRIBUTE[] {
-                ATTR_TOKEN_TRUE,
-                ATTR_CLASS_PKEY,
-                ATTR_PRIVATE_TRUE,
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_EC),
-                idAttrs[0],
-                new CK_ATTRIBUTE(CKA_VALUE, ecKey.getS()),
-                new CK_ATTRIBUTE(CKA_EC_PARAMS, encodedParams),
-            };
-            if (idAttrs[1] != null) {
-                attrs = addAttribute(attrs, idAttrs[1]);
-            }
-
-            attrs = token.getAttributes
-                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_EC, attrs);
-
-            if (debug != null) {
-                debug.println("storePkey created EC template");
-            }
-
-        } else if (key instanceof P11Key) {
-            // sensitive/non-extractable P11Key
-            P11Key p11Key = (P11Key)key;
-            if (p11Key.token != this.token) {
-                throw new KeyStoreException
-                    ("Cannot move sensitive keys across tokens");
-            }
-            CK_ATTRIBUTE netscapeDB = null;
-            if (useNDB) {
-                // Note that this currently fails due to an NSS bug.
-                // They do not allow the CKA_NETSCAPE_DB attribute to be
-                // specified during C_CopyObject() and fail with
-                // CKR_ATTRIBUTE_READ_ONLY.
-                // But if we did not specify it, they would fail with
-                // CKA_TEMPLATE_INCOMPLETE, so leave this code in here.
-                CK_ATTRIBUTE[] idAttrs = getIdAttributes(key, publicKey, false, true);
-                netscapeDB = idAttrs[1];
-            }
-            // Update the key object.
-            updateP11Pkey(alias, netscapeDB, p11Key);
-            storeChain(alias, (X509Certificate[])pke.getCertificateChain());
-            return;
-
-        } else {
-            throw new KeyStoreException("unsupported key type: " + key);
-        }
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            // create private key entry
-            token.p11.C_CreateObject(session.id(), attrs);
-            if (debug != null) {
-                debug.println("storePkey created token key for [" +
-                                alias +
-                                "]");
-            }
-        } finally {
-            token.releaseSession(session);
-        }
-
-        storeChain(alias, (X509Certificate[])pke.getCertificateChain());
-    }
-
-    private CK_ATTRIBUTE[] getRsaPrivKeyAttrs(String alias,
-                                RSAPrivateKey key,
-                                X500Principal subject) throws PKCS11Exception {
-
-        // subject is currently ignored - could be used to set CKA_SUBJECT
-
-        CK_ATTRIBUTE[] attrs = null;
-        if (key instanceof RSAPrivateCrtKey) {
-
-            if (debug != null) {
-                debug.println("creating RSAPrivateCrtKey attrs");
-            }
-
-            RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
-
-            attrs = new CK_ATTRIBUTE[] {
-                ATTR_TOKEN_TRUE,
-                ATTR_CLASS_PKEY,
-                ATTR_PRIVATE_TRUE,
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
-                new CK_ATTRIBUTE(CKA_ID, alias),
-                new CK_ATTRIBUTE(CKA_MODULUS,
-                                rsaKey.getModulus()),
-                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT,
-                                rsaKey.getPrivateExponent()),
-                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT,
-                                rsaKey.getPublicExponent()),
-                new CK_ATTRIBUTE(CKA_PRIME_1,
-                                rsaKey.getPrimeP()),
-                new CK_ATTRIBUTE(CKA_PRIME_2,
-                                rsaKey.getPrimeQ()),
-                new CK_ATTRIBUTE(CKA_EXPONENT_1,
-                                rsaKey.getPrimeExponentP()),
-                new CK_ATTRIBUTE(CKA_EXPONENT_2,
-                                rsaKey.getPrimeExponentQ()),
-                new CK_ATTRIBUTE(CKA_COEFFICIENT,
-                                rsaKey.getCrtCoefficient()) };
-            attrs = token.getAttributes
-                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attrs);
-
-        } else {
-
-            if (debug != null) {
-                debug.println("creating RSAPrivateKey attrs");
-            }
-
-            RSAPrivateKey rsaKey = key;
-
-            attrs = new CK_ATTRIBUTE[] {
-                ATTR_TOKEN_TRUE,
-                ATTR_CLASS_PKEY,
-                ATTR_PRIVATE_TRUE,
-                new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
-                new CK_ATTRIBUTE(CKA_ID, alias),
-                new CK_ATTRIBUTE(CKA_MODULUS,
-                                rsaKey.getModulus()),
-                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT,
-                                rsaKey.getPrivateExponent()) };
-            attrs = token.getAttributes
-                (TemplateManager.O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attrs);
-        }
-
-        return attrs;
-    }
-
-    /**
-     * Compute the CKA_ID and/or CKA_NETSCAPE_DB attributes that should be
-     * used for this private key. It uses the same algorithm to calculate the
-     * values as NSS. The public and private keys MUST match for the result to
-     * be correct.
-     *
-     * It returns a 2 element array with CKA_ID at index 0 and CKA_NETSCAPE_DB
-     * at index 1. The boolean flags determine what is to be calculated.
-     * If false or if we could not calculate the value, that element is null.
-     *
-     * NOTE that we currently do not use the CKA_ID value calculated by this
-     * method.
-     */
-    private CK_ATTRIBUTE[] getIdAttributes(PrivateKey privateKey,
-            PublicKey publicKey, boolean id, boolean netscapeDb) {
-        CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[2];
-        if ((id || netscapeDb) == false) {
-            return attrs;
-        }
-        String alg = privateKey.getAlgorithm();
-        if (id && alg.equals("RSA") && (publicKey instanceof RSAPublicKey)) {
-            // CKA_NETSCAPE_DB not needed for RSA public keys
-            BigInteger n = ((RSAPublicKey)publicKey).getModulus();
-            attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(n)));
-        } else if (alg.equals("DSA") && (publicKey instanceof DSAPublicKey)) {
-            BigInteger y = ((DSAPublicKey)publicKey).getY();
-            if (id) {
-                attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(y)));
-            }
-            if (netscapeDb) {
-                attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, y);
-            }
-        } else if (alg.equals("DH") && (publicKey instanceof DHPublicKey)) {
-            BigInteger y = ((DHPublicKey)publicKey).getY();
-            if (id) {
-                attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(getMagnitude(y)));
-            }
-            if (netscapeDb) {
-                attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, y);
-            }
-        } else if (alg.equals("EC") && (publicKey instanceof ECPublicKey)) {
-            ECPublicKey ecPub = (ECPublicKey)publicKey;
-            ECPoint point = ecPub.getW();
-            ECParameterSpec params = ecPub.getParams();
-            byte[] encodedPoint = ECUtil.encodePoint(point, params.getCurve());
-            if (id) {
-                attrs[0] = new CK_ATTRIBUTE(CKA_ID, sha1(encodedPoint));
-            }
-            if (netscapeDb) {
-                attrs[1] = new CK_ATTRIBUTE(CKA_NETSCAPE_DB, encodedPoint);
-            }
-        } else {
-            throw new RuntimeException("Unknown key algorithm " + alg);
-        }
-        return attrs;
-    }
-
-    /**
-     * return true if cert destroyed
-     */
-    private boolean destroyCert(byte[] cka_id)
-                throws PKCS11Exception, KeyStoreException {
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            THandle h = getTokenObject(session, ATTR_CLASS_CERT, cka_id, null);
-            if (h.type != ATTR_CLASS_CERT) {
-                return false;
-            }
-
-            token.p11.C_DestroyObject(session.id(), h.handle);
-            if (debug != null) {
-                debug.println("destroyCert destroyed cert with CKA_ID [" +
-                                                getID(cka_id) +
-                                                "]");
-            }
-            return true;
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    /**
-     * return true if chain destroyed
-     */
-    private boolean destroyChain(byte[] cka_id)
-        throws PKCS11Exception, CertificateException, KeyStoreException {
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            THandle h = getTokenObject(session, ATTR_CLASS_CERT, cka_id, null);
-            if (h.type != ATTR_CLASS_CERT) {
-                if (debug != null) {
-                    debug.println("destroyChain could not find " +
-                        "end entity cert with CKA_ID [0x" +
-                        Functions.toHexString(cka_id) +
-                        "]");
-                }
-                return false;
-            }
-
-            X509Certificate endCert = loadCert(session, h.handle);
-            token.p11.C_DestroyObject(session.id(), h.handle);
-            if (debug != null) {
-                debug.println("destroyChain destroyed end entity cert " +
-                        "with CKA_ID [" +
-                        getID(cka_id) +
-                        "]");
-            }
-
-            // build chain following issuer->subject links
-
-            X509Certificate next = endCert;
-            while (true) {
-
-                if (next.getSubjectX500Principal().equals
-                    (next.getIssuerX500Principal())) {
-                    // self signed - done
-                    break;
-                }
-
-                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                        ATTR_TOKEN_TRUE,
-                        ATTR_CLASS_CERT,
-                        new CK_ATTRIBUTE(CKA_SUBJECT,
-                                  next.getIssuerX500Principal().getEncoded()) };
-                long[] ch = findObjects(session, attrs);
-
-                if (ch == null || ch.length == 0) {
-                    // done
-                    break;
-                } else {
-                    // if more than one found, use first
-                    if (debug != null && ch.length > 1) {
-                        debug.println("destroyChain found " +
-                                ch.length +
-                                " certificate entries for subject [" +
-                                next.getIssuerX500Principal() +
-                                "] in token - using first entry");
-                    }
-
-                    next = loadCert(session, ch[0]);
-
-                    // only delete if not part of any other chain
-
-                    attrs = new CK_ATTRIBUTE[] {
-                        ATTR_TOKEN_TRUE,
-                        ATTR_CLASS_CERT,
-                        new CK_ATTRIBUTE(CKA_ISSUER,
-                                next.getSubjectX500Principal().getEncoded()) };
-                    long[] issuers = findObjects(session, attrs);
-
-                    boolean destroyIt = false;
-                    if (issuers == null || issuers.length == 0) {
-                        // no other certs with this issuer -
-                        // destroy it
-                        destroyIt = true;
-                    } else if (issuers.length == 1) {
-                        X509Certificate iCert = loadCert(session, issuers[0]);
-                        if (next.equals(iCert)) {
-                            // only cert with issuer is itself (self-signed) -
-                            // destroy it
-                            destroyIt = true;
-                        }
-                    }
-
-                    if (destroyIt) {
-                        token.p11.C_DestroyObject(session.id(), ch[0]);
-                        if (debug != null) {
-                            debug.println
-                                ("destroyChain destroyed cert in chain " +
-                                "with subject [" +
-                                next.getSubjectX500Principal() + "]");
-                        }
-                    } else {
-                        if (debug != null) {
-                            debug.println("destroyChain did not destroy " +
-                                "shared cert in chain with subject [" +
-                                next.getSubjectX500Principal() + "]");
-                        }
-                    }
-                }
-            }
-
-            return true;
-
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    /**
-     * return true if secret key destroyed
-     */
-    private boolean destroySkey(String alias)
-                throws PKCS11Exception, KeyStoreException {
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            THandle h = getTokenObject(session, ATTR_CLASS_SKEY, null, alias);
-            if (h.type != ATTR_CLASS_SKEY) {
-                if (debug != null) {
-                    debug.println("destroySkey did not find secret key " +
-                        "with CKA_LABEL [" +
-                        alias +
-                        "]");
-                }
-                return false;
-            }
-            token.p11.C_DestroyObject(session.id(), h.handle);
-            return true;
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    /**
-     * return true if private key destroyed
-     */
-    private boolean destroyPkey(byte[] cka_id)
-                throws PKCS11Exception, KeyStoreException {
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            THandle h = getTokenObject(session, ATTR_CLASS_PKEY, cka_id, null);
-            if (h.type != ATTR_CLASS_PKEY) {
-                if (debug != null) {
-                    debug.println
-                        ("destroyPkey did not find private key with CKA_ID [" +
-                        getID(cka_id) +
-                        "]");
-                }
-                return false;
-            }
-            token.p11.C_DestroyObject(session.id(), h.handle);
-            return true;
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    /**
-     * build [alias + issuer + serialNumber] string from a cert
-     */
-    private String getID(String alias, X509Certificate cert) {
-        X500Principal issuer = cert.getIssuerX500Principal();
-        BigInteger serialNum = cert.getSerialNumber();
-
-        return alias +
-                ALIAS_SEP +
-                issuer.getName(X500Principal.CANONICAL) +
-                ALIAS_SEP +
-                serialNum.toString();
-    }
-
-    /**
-     * build CKA_ID string from bytes
-     */
-    private static String getID(byte[] bytes) {
-        boolean printable = true;
-        for (int i = 0; i < bytes.length; i++) {
-            if (!DerValue.isPrintableStringChar((char)bytes[i])) {
-                printable = false;
-                break;
-            }
-        }
-
-        if (!printable) {
-            return "0x" + Functions.toHexString(bytes);
-        } else {
-            try {
-                return new String(bytes, "UTF-8");
-            } catch (UnsupportedEncodingException uee) {
-                return "0x" + Functions.toHexString(bytes);
-            }
-        }
-    }
-
-    /**
-     * find an object on the token
-     *
-     * @param type either ATTR_CLASS_CERT, ATTR_CLASS_PKEY, or ATTR_CLASS_SKEY
-     * @param cka_id the CKA_ID if type is ATTR_CLASS_CERT or ATTR_CLASS_PKEY
-     * @param cka_label the CKA_LABEL if type is ATTR_CLASS_SKEY
-     */
-    private THandle getTokenObject(Session session,
-                                CK_ATTRIBUTE type,
-                                byte[] cka_id,
-                                String cka_label)
-                throws PKCS11Exception, KeyStoreException {
-
-        CK_ATTRIBUTE[] attrs;
-        if (type == ATTR_CLASS_SKEY) {
-            attrs = new CK_ATTRIBUTE[] {
-                        ATTR_SKEY_TOKEN_TRUE,
-                        new CK_ATTRIBUTE(CKA_LABEL, cka_label),
-                        type };
-        } else {
-            attrs = new CK_ATTRIBUTE[] {
-                        ATTR_TOKEN_TRUE,
-                        new CK_ATTRIBUTE(CKA_ID, cka_id),
-                        type };
-        }
-        long[] h = findObjects(session, attrs);
-        if (h.length == 0) {
-            if (debug != null) {
-                if (type == ATTR_CLASS_SKEY) {
-                    debug.println("getTokenObject did not find secret key " +
-                                "with CKA_LABEL [" +
-                                cka_label +
-                                "]");
-                } else if (type == ATTR_CLASS_CERT) {
-                    debug.println
-                        ("getTokenObject did not find cert with CKA_ID [" +
-                        getID(cka_id) +
-                        "]");
-                } else {
-                    debug.println("getTokenObject did not find private key " +
-                        "with CKA_ID [" +
-                        getID(cka_id) +
-                        "]");
-                }
-            }
-        } else if (h.length == 1) {
-
-            // found object handle - return it
-            return new THandle(h[0], type);
-
-        } else {
-
-            // found multiple object handles -
-            // see if token ignored CKA_LABEL during search (e.g. NSS)
-
-            if (type == ATTR_CLASS_SKEY) {
-
-                ArrayList<THandle> list = new ArrayList<THandle>(h.length);
-                for (int i = 0; i < h.length; i++) {
-
-                    CK_ATTRIBUTE[] label = new CK_ATTRIBUTE[]
-                                        { new CK_ATTRIBUTE(CKA_LABEL) };
-                    token.p11.C_GetAttributeValue(session.id(), h[i], label);
-                    if (label[0].pValue != null &&
-                        cka_label.equals(new String(label[0].getCharArray()))) {
-                        list.add(new THandle(h[i], ATTR_CLASS_SKEY));
-                    }
-                }
-                if (list.size() == 1) {
-                    // yes, there was only one CKA_LABEL that matched
-                    return list.get(0);
-                } else {
-                    throw new KeyStoreException("invalid KeyStore state: " +
-                        "found " +
-                        list.size() +
-                        " secret keys sharing CKA_LABEL [" +
-                        cka_label +
-                        "]");
-                }
-            } else if (type == ATTR_CLASS_CERT) {
-                throw new KeyStoreException("invalid KeyStore state: " +
-                        "found " +
-                        h.length +
-                        " certificates sharing CKA_ID " +
-                        getID(cka_id));
-            } else {
-                throw new KeyStoreException("invalid KeyStore state: " +
-                        "found " +
-                        h.length +
-                        " private keys sharing CKA_ID " +
-                        getID(cka_id));
-            }
-        }
-        return new THandle(NO_HANDLE, null);
-    }
-
-    /**
-     * Create a mapping of all key pairs, trusted certs, and secret keys
-     * on the token into logical KeyStore entries unambiguously
-     * accessible via an alias.
-     *
-     * If the token is removed, the map may contain stale values.
-     * KeyStore.load should be called to re-create the map.
-     *
-     * Assume all private keys and matching certs share a unique CKA_ID.
-     *
-     * Assume all secret keys have a unique CKA_LABEL.
-     *
-     * @return true if multiple certs found sharing the same CKA_LABEL
-     *          (if so, write capabilities are disabled)
-     */
-    private boolean mapLabels() throws
-                PKCS11Exception, CertificateException, KeyStoreException {
-
-        CK_ATTRIBUTE[] trustedAttr = new CK_ATTRIBUTE[] {
-                                new CK_ATTRIBUTE(CKA_TRUSTED) };
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            // get all private key CKA_IDs
-
-            ArrayList<byte[]> pkeyIDs = new ArrayList<byte[]>();
-            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                ATTR_TOKEN_TRUE,
-                ATTR_CLASS_PKEY,
-            };
-            long[] handles = findObjects(session, attrs);
-
-            for (long handle : handles) {
-                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_ID) };
-                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
-
-                if (attrs[0].pValue != null) {
-                    pkeyIDs.add(attrs[0].getByteArray());
-                }
-            }
-
-            // Get all certificates
-            //
-            // If cert does not have a CKA_LABEL nor CKA_ID, it is ignored.
-            //
-            // Get the CKA_LABEL for each cert
-            // (if the cert does not have a CKA_LABEL, use the CKA_ID).
-            //
-            // Map each cert to the its CKA_LABEL
-            // (multiple certs may be mapped to a single CKA_LABEL)
-
-            HashMap<String, HashSet<AliasInfo>> certMap =
-                                new HashMap<String, HashSet<AliasInfo>>();
-
-            attrs = new CK_ATTRIBUTE[] {
-                ATTR_TOKEN_TRUE,
-                ATTR_CLASS_CERT,
-            };
-            handles = findObjects(session, attrs);
-
-            for (long handle : handles) {
-                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_LABEL) };
-
-                String cka_label = null;
-                byte[] cka_id = null;
-                try {
-                    token.p11.C_GetAttributeValue(session.id(), handle, attrs);
-                    if (attrs[0].pValue != null) {
-                        // there is a CKA_LABEL
-                        cka_label = new String(attrs[0].getCharArray());
-                    }
-                } catch (PKCS11Exception pe) {
-                    if (pe.getErrorCode() != CKR_ATTRIBUTE_TYPE_INVALID) {
-                        throw pe;
-                    }
-
-                    // GetAttributeValue for CKA_LABEL not supported
-                    //
-                    // XXX SCA1000
-                }
-
-                // get CKA_ID
-
-                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_ID) };
-                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
-                if (attrs[0].pValue == null) {
-                    if (cka_label == null) {
-                        // no cka_label nor cka_id - ignore
-                        continue;
-                    }
-                } else {
-                    if (cka_label == null) {
-                        // use CKA_ID as CKA_LABEL
-                        cka_label = getID(attrs[0].getByteArray());
-                    }
-                    cka_id = attrs[0].getByteArray();
-                }
-
-                X509Certificate cert = loadCert(session, handle);
-
-                // get CKA_TRUSTED
-
-                boolean cka_trusted = false;
-
-                if (useSecmodTrust) {
-                    cka_trusted = Secmod.getInstance().isTrusted(cert, nssTrustType);
-                } else {
-                    if (CKA_TRUSTED_SUPPORTED) {
-                        try {
-                            token.p11.C_GetAttributeValue
-                                    (session.id(), handle, trustedAttr);
-                            cka_trusted = trustedAttr[0].getBoolean();
-                        } catch (PKCS11Exception pe) {
-                            if (pe.getErrorCode() == CKR_ATTRIBUTE_TYPE_INVALID) {
-                                // XXX  NSS, ibutton, sca1000
-                                CKA_TRUSTED_SUPPORTED = false;
-                                if (debug != null) {
-                                    debug.println
-                                            ("CKA_TRUSTED attribute not supported");
-                                }
-                            }
-                        }
-                    }
-                }
-
-                HashSet<AliasInfo> infoSet = certMap.get(cka_label);
-                if (infoSet == null) {
-                    infoSet = new HashSet<AliasInfo>(2);
-                    certMap.put(cka_label, infoSet);
-                }
-
-                // initially create private key entry AliasInfo entries -
-                // these entries will get resolved into their true
-                // entry types later
-
-                infoSet.add(new AliasInfo
-                                (cka_label,
-                                cka_id,
-                                cka_trusted,
-                                cert));
-            }
-
-            // create list secret key CKA_LABELS -
-            // if there are duplicates (either between secret keys,
-            // or between a secret key and another object),
-            // throw an exception
-            HashMap<String, AliasInfo> sKeyMap =
-                    new HashMap<String, AliasInfo>();
-
-            attrs = new CK_ATTRIBUTE[] {
-                ATTR_SKEY_TOKEN_TRUE,
-                ATTR_CLASS_SKEY,
-            };
-            handles = findObjects(session, attrs);
-
-            for (long handle : handles) {
-                attrs = new CK_ATTRIBUTE[] { new CK_ATTRIBUTE(CKA_LABEL) };
-                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
-                if (attrs[0].pValue != null) {
-
-                    // there is a CKA_LABEL
-                    String cka_label = new String(attrs[0].getCharArray());
-                    if (sKeyMap.get(cka_label) == null) {
-                        sKeyMap.put(cka_label, new AliasInfo(cka_label));
-                    } else {
-                        throw new KeyStoreException("invalid KeyStore state: " +
-                                "found multiple secret keys sharing same " +
-                                "CKA_LABEL [" +
-                                cka_label +
-                                "]");
-                    }
-                }
-            }
-
-            // update global aliasMap with alias mappings
-            ArrayList<AliasInfo> matchedCerts =
-                                mapPrivateKeys(pkeyIDs, certMap);
-            boolean sharedLabel = mapCerts(matchedCerts, certMap);
-            mapSecretKeys(sKeyMap);
-
-            return sharedLabel;
-
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    /**
-     * for each private key CKA_ID, find corresponding cert with same CKA_ID.
-     * if found cert, see if cert CKA_LABEL is unique.
-     *     if CKA_LABEL unique, map private key/cert alias to that CKA_LABEL.
-     *     if CKA_LABEL not unique, map private key/cert alias to:
-     *                   CKA_LABEL + ALIAS_SEP + ISSUER + ALIAS_SEP + SERIAL
-     * if cert not found, ignore private key
-     * (don't support private key entries without a cert chain yet)
-     *
-     * @return a list of AliasInfo entries that represents all matches
-     */
-    private ArrayList<AliasInfo> mapPrivateKeys(ArrayList<byte[]> pkeyIDs,
-                        HashMap<String, HashSet<AliasInfo>> certMap)
-                throws PKCS11Exception, CertificateException {
-
-        // reset global alias map
-        aliasMap = new HashMap<String, AliasInfo>();
-
-        // list of matched certs that we will return
-        ArrayList<AliasInfo> matchedCerts = new ArrayList<AliasInfo>();
-
-        for (byte[] pkeyID : pkeyIDs) {
-
-            // try to find a matching CKA_ID in a certificate
-
-            boolean foundMatch = false;
-            Set<String> certLabels = certMap.keySet();
-            for (String certLabel : certLabels) {
-
-                // get cert CKA_IDs (if present) for each cert
-
-                HashSet<AliasInfo> infoSet = certMap.get(certLabel);
-                for (AliasInfo aliasInfo : infoSet) {
-                    if (Arrays.equals(pkeyID, aliasInfo.id)) {
-
-                        // found private key with matching cert
-
-                        if (infoSet.size() == 1) {
-                            // unique CKA_LABEL - use certLabel as alias
-                            aliasInfo.matched = true;
-                            aliasMap.put(certLabel, aliasInfo);
-                        } else {
-                            // create new alias
-                            aliasInfo.matched = true;
-                            aliasMap.put(getID(certLabel, aliasInfo.cert),
-                                        aliasInfo);
-                        }
-                        matchedCerts.add(aliasInfo);
-                        foundMatch = true;
-                        break;
-                    }
-                }
-                if (foundMatch) {
-                    break;
-                }
-            }
-
-            if (!foundMatch) {
-                if (debug != null) {
-                    debug.println
-                        ("did not find match for private key with CKA_ID [" +
-                        getID(pkeyID) +
-                        "] (ignoring entry)");
-                }
-            }
-        }
-
-        return matchedCerts;
-    }
-
-    /**
-     * for each cert not matched with a private key but is CKA_TRUSTED:
-     *     if CKA_LABEL unique, map cert to CKA_LABEL.
-     *     if CKA_LABEL not unique, map cert to [label+issuer+serialNum]
-     *
-     * if CKA_TRUSTED not supported, treat all certs not part of a chain
-     * as trusted
-     *
-     * @return true if multiple certs found sharing the same CKA_LABEL
-     */
-    private boolean mapCerts(ArrayList<AliasInfo> matchedCerts,
-                        HashMap<String, HashSet<AliasInfo>> certMap)
-                throws PKCS11Exception, CertificateException {
-
-        // load all cert chains
-        for (AliasInfo aliasInfo : matchedCerts) {
-            Session session = null;
-            try {
-                session = token.getOpSession();
-                aliasInfo.chain = loadChain(session, aliasInfo.cert);
-            } finally {
-                token.releaseSession(session);
-            }
-        }
-
-        // find all certs in certMap not part of a cert chain
-        // - these are trusted
-
-        boolean sharedLabel = false;
-
-        Set<String> certLabels = certMap.keySet();
-        for (String certLabel : certLabels) {
-            HashSet<AliasInfo> infoSet = certMap.get(certLabel);
-            for (AliasInfo aliasInfo : infoSet) {
-
-                if (aliasInfo.matched == true) {
-                    // already found a private key match for this cert -
-                    // just continue
-                    aliasInfo.trusted = false;
-                    continue;
-                }
-
-                // cert in this aliasInfo is not matched yet
-                //
-                // if CKA_TRUSTED_SUPPORTED == true,
-                // then check if cert is trusted
-
-                if (CKA_TRUSTED_SUPPORTED) {
-                    if (aliasInfo.trusted) {
-                        // trusted certificate
-                        if (mapTrustedCert
-                                (certLabel, aliasInfo, infoSet) == true) {
-                            sharedLabel = true;
-                        }
-                    }
-                    continue;
-                }
-
-                // CKA_TRUSTED_SUPPORTED == false
-                //
-                // XXX treat all certs not part of a chain as trusted
-                // XXX
-                // XXX Unsupported
-                //
-                // boolean partOfChain = false;
-                // for (AliasInfo matchedInfo : matchedCerts) {
-                //     for (int i = 0; i < matchedInfo.chain.length; i++) {
-                //      if (matchedInfo.chain[i].equals(aliasInfo.cert)) {
-                //          partOfChain = true;
-                //          break;
-                //      }
-                //     }
-                //     if (partOfChain) {
-                //      break;
-                //     }
-                // }
-                //
-                // if (!partOfChain) {
-                //     if (mapTrustedCert(certLabel,aliasInfo,infoSet) == true){
-                //      sharedLabel = true;
-                //     }
-                // } else {
-                //    if (debug != null) {
-                //      debug.println("ignoring unmatched/untrusted cert " +
-                //          "that is part of cert chain - cert subject is [" +
-                //          aliasInfo.cert.getSubjectX500Principal().getName
-                //                              (X500Principal.CANONICAL) +
-                //          "]");
-                //     }
-                // }
-            }
-        }
-
-        return sharedLabel;
-    }
-
-    private boolean mapTrustedCert(String certLabel,
-                                AliasInfo aliasInfo,
-                                HashSet<AliasInfo> infoSet) {
-
-        boolean sharedLabel = false;
-
-        aliasInfo.type = ATTR_CLASS_CERT;
-        aliasInfo.trusted = true;
-        if (infoSet.size() == 1) {
-            // unique CKA_LABEL - use certLabel as alias
-            aliasMap.put(certLabel, aliasInfo);
-        } else {
-            // create new alias
-            sharedLabel = true;
-            aliasMap.put(getID(certLabel, aliasInfo.cert), aliasInfo);
-        }
-
-        return sharedLabel;
-    }
-
-    /**
-     * If the secret key shares a CKA_LABEL with another entry,
-     * throw an exception
-     */
-    private void mapSecretKeys(HashMap<String, AliasInfo> sKeyMap)
-                throws KeyStoreException {
-        for (String label : sKeyMap.keySet()) {
-            if (aliasMap.containsKey(label)) {
-                throw new KeyStoreException("invalid KeyStore state: " +
-                        "found secret key sharing CKA_LABEL [" +
-                        label +
-                        "] with another token object");
-            }
-        }
-        aliasMap.putAll(sKeyMap);
-    }
-
-    private void dumpTokenMap() {
-        Set<String> aliases = aliasMap.keySet();
-        System.out.println("Token Alias Map:");
-        if (aliases.isEmpty()) {
-            System.out.println("  [empty]");
-        } else {
-            for (String s : aliases) {
-                System.out.println("  " + s + aliasMap.get(s));
-            }
-        }
-    }
-
-    private void checkWrite() throws KeyStoreException {
-        if (writeDisabled) {
-            throw new KeyStoreException
-                ("This PKCS11KeyStore does not support write capabilities");
-        }
-    }
-
-    private final static long[] LONG0 = new long[0];
-
-    private static long[] findObjects(Session session, CK_ATTRIBUTE[] attrs)
-            throws PKCS11Exception {
-        Token token = session.token;
-        long[] handles = LONG0;
-        token.p11.C_FindObjectsInit(session.id(), attrs);
-        while (true) {
-            long[] h = token.p11.C_FindObjects(session.id(), FINDOBJECTS_MAX);
-            if (h.length == 0) {
-                break;
-            }
-            handles = P11Util.concat(handles, h);
-        }
-        token.p11.C_FindObjectsFinal(session.id());
-        return handles;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Mac.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,269 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.util.*;
-import java.nio.ByteBuffer;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.MacSpi;
-
-import sun.nio.ch.DirectBuffer;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * MAC implementation class. This class currently supports HMAC using
- * MD5, SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 and the SSL3 MAC
- * using MD5 and SHA-1.
- *
- * Note that unlike other classes (e.g. Signature), this does not
- * composite various operations if the token only supports part of the
- * required functionality. The MAC implementations in SunJCE already
- * do exactly that by implementing an MAC on top of MessageDigests. We
- * could not do any better than they.
- *
- * @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;
-
-    // key instance used, if operation active
-    private P11Key p11Key;
-
-    // associated session, if any
-    private Session session;
-
-    // state, one of S_* above
-    private int state;
-
-    // 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;
-        case (int)CKM_SHA_1_HMAC:
-            macLength = 20;
-            break;
-        case (int)CKM_SHA224_HMAC:
-            macLength = 28;
-            break;
-        case (int)CKM_SHA256_HMAC:
-            macLength = 32;
-            break;
-        case (int)CKM_SHA384_HMAC:
-            macLength = 48;
-            break;
-        case (int)CKM_SHA512_HMAC:
-            macLength = 64;
-            break;
-        case (int)CKM_SSL3_MD5_MAC:
-            macLength = 16;
-            params = Long.valueOf(16);
-            break;
-        case (int)CKM_SSL3_SHA1_MAC:
-            macLength = 20;
-            params = Long.valueOf(20);
-            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();
-        }
-    }
-
-    private void cancelOperation() {
-        token.ensureValid();
-        if (state == S_UNINIT) {
-            return;
-        }
-        state = S_UNINIT;
-        if ((session == null) || (token.explicitCancel == false)) {
-            return;
-        }
-        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) {
-            return;
-        }
-        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;
-        }
-    }
-
-    // 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);
-        }
-    }
-
-    // see JCE spec
-    protected void engineInit(Key key, AlgorithmParameterSpec params)
-            throws InvalidKeyException, InvalidAlgorithmParameterException {
-        if (params != null) {
-            throw new InvalidAlgorithmParameterException
-                ("Parameters not supported");
-        }
-        cancelOperation();
-        p11Key = P11SecretKeyFactory.convertKey(token, key, algorithm);
-        try {
-            initialize();
-        } 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;
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("doFinal() failed", e);
-        } finally {
-            session = token.releaseSession(session);
-        }
-    }
-
-    // see JCE spec
-    protected void engineUpdate(byte input) {
-        if (oneByte == null) {
-           oneByte = new byte[1];
-        }
-        oneByte[0] = input;
-        engineUpdate(oneByte, 0, 1);
-    }
-
-    // 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);
-        }
-    }
-
-    // see JCE spec
-    protected void engineUpdate(ByteBuffer byteBuffer) {
-        try {
-            ensureInitialized();
-            int len = byteBuffer.remaining();
-            if (len <= 0) {
-                return;
-            }
-            if (byteBuffer instanceof DirectBuffer == false) {
-                super.engineUpdate(byteBuffer);
-                return;
-            }
-            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);
-        }
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11RSACipher.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,677 +0,0 @@
-/*
- * Copyright (c) 2003, 2015, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.*;
-
-import java.util.Locale;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
-import sun.security.util.KeyUtil;
-
-/**
- * RSA Cipher implementation class. We currently only support
- * PKCS#1 v1.5 padding on top of CKM_RSA_PKCS.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11RSACipher extends CipherSpi {
-
-    // minimum length of PKCS#1 v1.5 padding
-    private final static int PKCS1_MIN_PADDING_LENGTH = 11;
-
-    // constant byte[] of length 0
-    private final static byte[] B0 = new byte[0];
-
-    // mode constant for public key encryption
-    private final static int MODE_ENCRYPT = 1;
-    // mode constant for private key decryption
-    private final static int MODE_DECRYPT = 2;
-    // mode constant for private key encryption (signing)
-    private final static int MODE_SIGN    = 3;
-    // mode constant for public key decryption (verifying)
-    private final static int MODE_VERIFY  = 4;
-
-    // padding type constant for NoPadding
-    private final static int PAD_NONE = 1;
-    // padding type constant for PKCS1Padding
-    private final static int PAD_PKCS1 = 2;
-
-    // token instance
-    private final Token token;
-
-    // algorithm name (always "RSA")
-    private final String algorithm;
-
-    // mechanism id
-    private final long mechanism;
-
-    // associated session, if any
-    private Session session;
-
-    // mode, one of MODE_* above
-    private int mode;
-
-    // padding, one of PAD_* above
-    private int padType;
-
-    private byte[] buffer;
-    private int bufOfs;
-
-    // key, if init() was called
-    private P11Key p11Key;
-
-    // flag indicating whether an operation is initialized
-    private boolean initialized;
-
-    // maximum input data size allowed
-    // for decryption, this is the length of the key
-    // for encryption, length of the key minus minimum padding length
-    private int maxInputSize;
-
-    // maximum output size. this is the length of the key
-    private int outputSize;
-
-    // cipher parameter for TLS RSA premaster secret
-    private AlgorithmParameterSpec spec = null;
-
-    // the source of randomness
-    private SecureRandom random;
-
-    P11RSACipher(Token token, String algorithm, long mechanism)
-            throws PKCS11Exception {
-        super();
-        this.token = token;
-        this.algorithm = "RSA";
-        this.mechanism = mechanism;
-    }
-
-    // modes do not make sense for RSA, but allow ECB
-    // see JCE spec
-    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
-        if (mode.equalsIgnoreCase("ECB") == false) {
-            throw new NoSuchAlgorithmException("Unsupported mode " + mode);
-        }
-    }
-
-    protected void engineSetPadding(String padding)
-            throws NoSuchPaddingException {
-        String lowerPadding = padding.toLowerCase(Locale.ENGLISH);
-        if (lowerPadding.equals("pkcs1padding")) {
-            padType = PAD_PKCS1;
-        } else if (lowerPadding.equals("nopadding")) {
-            padType = PAD_NONE;
-        } else {
-            throw new NoSuchPaddingException("Unsupported padding " + padding);
-        }
-    }
-
-    // return 0 as block size, we are not a block cipher
-    // see JCE spec
-    protected int engineGetBlockSize() {
-        return 0;
-    }
-
-    // return the output size
-    // see JCE spec
-    protected int engineGetOutputSize(int inputLen) {
-        return outputSize;
-    }
-
-    // no IV, return null
-    // see JCE spec
-    protected byte[] engineGetIV() {
-        return null;
-    }
-
-    // no parameters, return null
-    // see JCE spec
-    protected AlgorithmParameters engineGetParameters() {
-        return null;
-    }
-
-    // see JCE spec
-    protected void engineInit(int opmode, Key key, SecureRandom random)
-            throws InvalidKeyException {
-        implInit(opmode, key);
-    }
-
-    // see JCE spec
-    @SuppressWarnings("deprecation")
-    protected void engineInit(int opmode, Key key,
-            AlgorithmParameterSpec params, SecureRandom random)
-            throws InvalidKeyException, InvalidAlgorithmParameterException {
-        if (params != null) {
-            if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
-                throw new InvalidAlgorithmParameterException(
-                        "Parameters not supported");
-            }
-            spec = params;
-            this.random = random;   // for TLS RSA premaster secret
-        }
-        implInit(opmode, key);
-    }
-
-    // see JCE spec
-    protected void engineInit(int opmode, Key key, AlgorithmParameters params,
-            SecureRandom random)
-            throws InvalidKeyException, InvalidAlgorithmParameterException {
-        if (params != null) {
-            throw new InvalidAlgorithmParameterException(
-                        "Parameters not supported");
-        }
-        implInit(opmode, key);
-    }
-
-    private void implInit(int opmode, Key key) throws InvalidKeyException {
-        cancelOperation();
-        p11Key = P11KeyFactory.convertKey(token, key, algorithm);
-        boolean encrypt;
-        if (opmode == Cipher.ENCRYPT_MODE) {
-            encrypt = true;
-        } else if (opmode == Cipher.DECRYPT_MODE) {
-            encrypt = false;
-        } else if (opmode == Cipher.WRAP_MODE) {
-            if (p11Key.isPublic() == false) {
-                throw new InvalidKeyException
-                                ("Wrap has to be used with public keys");
-            }
-            // No further setup needed for C_Wrap(). We'll initialize later if
-            // we can't use C_Wrap().
-            return;
-        } else if (opmode == Cipher.UNWRAP_MODE) {
-            if (p11Key.isPrivate() == false) {
-                throw new InvalidKeyException
-                                ("Unwrap has to be used with private keys");
-            }
-            // No further setup needed for C_Unwrap(). We'll initialize later
-            // if we can't use C_Unwrap().
-            return;
-        } else {
-            throw new InvalidKeyException("Unsupported mode: " + opmode);
-        }
-        if (p11Key.isPublic()) {
-            mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
-        } else if (p11Key.isPrivate()) {
-            mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
-        } else {
-            throw new InvalidKeyException("Unknown key type: " + p11Key);
-        }
-        int n = (p11Key.length() + 7) >> 3;
-        outputSize = n;
-        buffer = new byte[n];
-        maxInputSize = ((padType == PAD_PKCS1 && encrypt) ?
-                            (n - PKCS1_MIN_PADDING_LENGTH) : n);
-        try {
-            initialize();
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("init() failed", e);
-        }
-    }
-
-    private void cancelOperation() {
-        token.ensureValid();
-        if (initialized == false) {
-            return;
-        }
-        initialized = false;
-        if ((session == null) || (token.explicitCancel == false)) {
-            return;
-        }
-        if (session.hasObjects() == false) {
-            session = token.killSession(session);
-            return;
-        }
-        try {
-            PKCS11 p11 = token.p11;
-            int inLen = maxInputSize;
-            int outLen = buffer.length;
-            switch (mode) {
-            case MODE_ENCRYPT:
-                p11.C_Encrypt
-                        (session.id(), buffer, 0, inLen, buffer, 0, outLen);
-                break;
-            case MODE_DECRYPT:
-                p11.C_Decrypt
-                        (session.id(), buffer, 0, inLen, buffer, 0, outLen);
-                break;
-            case MODE_SIGN:
-                byte[] tmpBuffer = new byte[maxInputSize];
-                p11.C_Sign
-                        (session.id(), tmpBuffer);
-                break;
-            case MODE_VERIFY:
-                p11.C_VerifyRecover
-                        (session.id(), buffer, 0, inLen, buffer, 0, outLen);
-                break;
-            default:
-                throw new ProviderException("internal error");
-            }
-        } catch (PKCS11Exception e) {
-            // XXX ensure this always works, ignore error
-        }
-    }
-
-    private void ensureInitialized() throws PKCS11Exception {
-        token.ensureValid();
-        if (initialized == false) {
-            initialize();
-        }
-    }
-
-    private void initialize() throws PKCS11Exception {
-        if (session == null) {
-            session = token.getOpSession();
-        }
-        PKCS11 p11 = token.p11;
-        CK_MECHANISM ckMechanism = new CK_MECHANISM(mechanism);
-        switch (mode) {
-        case MODE_ENCRYPT:
-            p11.C_EncryptInit(session.id(), ckMechanism, p11Key.keyID);
-            break;
-        case MODE_DECRYPT:
-            p11.C_DecryptInit(session.id(), ckMechanism, p11Key.keyID);
-            break;
-        case MODE_SIGN:
-            p11.C_SignInit(session.id(), ckMechanism, p11Key.keyID);
-            break;
-        case MODE_VERIFY:
-            p11.C_VerifyRecoverInit(session.id(), ckMechanism, p11Key.keyID);
-            break;
-        default:
-            throw new AssertionError("internal error");
-        }
-        bufOfs = 0;
-        initialized = true;
-    }
-
-    private void implUpdate(byte[] in, int inOfs, int inLen) {
-        try {
-            ensureInitialized();
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("update() failed", e);
-        }
-        if ((inLen == 0) || (in == null)) {
-            return;
-        }
-        if (bufOfs + inLen > maxInputSize) {
-            bufOfs = maxInputSize + 1;
-            return;
-        }
-        System.arraycopy(in, inOfs, buffer, bufOfs, inLen);
-        bufOfs += inLen;
-    }
-
-    private int implDoFinal(byte[] out, int outOfs, int outLen)
-            throws BadPaddingException, IllegalBlockSizeException {
-        if (bufOfs > maxInputSize) {
-            throw new IllegalBlockSizeException("Data must not be longer "
-                + "than " + maxInputSize + " bytes");
-        }
-        try {
-            ensureInitialized();
-            PKCS11 p11 = token.p11;
-            int n;
-            switch (mode) {
-            case MODE_ENCRYPT:
-                n = p11.C_Encrypt
-                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
-                break;
-            case MODE_DECRYPT:
-                n = p11.C_Decrypt
-                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
-                break;
-            case MODE_SIGN:
-                byte[] tmpBuffer = new byte[bufOfs];
-                System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
-                tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
-                if (tmpBuffer.length > outLen) {
-                    throw new BadPaddingException(
-                        "Output buffer (" + outLen + ") is too small to " +
-                        "hold the produced data (" + tmpBuffer.length + ")");
-                }
-                System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
-                n = tmpBuffer.length;
-                break;
-            case MODE_VERIFY:
-                n = p11.C_VerifyRecover
-                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
-                break;
-            default:
-                throw new ProviderException("internal error");
-            }
-            return n;
-        } catch (PKCS11Exception e) {
-            throw (BadPaddingException)new BadPaddingException
-                ("doFinal() failed").initCause(e);
-        } finally {
-            initialized = false;
-            session = token.releaseSession(session);
-        }
-    }
-
-    // see JCE spec
-    protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
-        implUpdate(in, inOfs, inLen);
-        return B0;
-    }
-
-    // see JCE spec
-    protected int engineUpdate(byte[] in, int inOfs, int inLen,
-            byte[] out, int outOfs) throws ShortBufferException {
-        implUpdate(in, inOfs, inLen);
-        return 0;
-    }
-
-    // see JCE spec
-    protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
-            throws IllegalBlockSizeException, BadPaddingException {
-        implUpdate(in, inOfs, inLen);
-        int n = implDoFinal(buffer, 0, buffer.length);
-        byte[] out = new byte[n];
-        System.arraycopy(buffer, 0, out, 0, n);
-        return out;
-    }
-
-    // see JCE spec
-    protected int engineDoFinal(byte[] in, int inOfs, int inLen,
-            byte[] out, int outOfs) throws ShortBufferException,
-            IllegalBlockSizeException, BadPaddingException {
-        implUpdate(in, inOfs, inLen);
-        return implDoFinal(out, outOfs, out.length - outOfs);
-    }
-
-    private byte[] doFinal() throws BadPaddingException,
-            IllegalBlockSizeException {
-        byte[] t = new byte[2048];
-        int n = implDoFinal(t, 0, t.length);
-        byte[] out = new byte[n];
-        System.arraycopy(t, 0, out, 0, n);
-        return out;
-    }
-
-    // see JCE spec
-    protected byte[] engineWrap(Key key) throws InvalidKeyException,
-            IllegalBlockSizeException {
-        String keyAlg = key.getAlgorithm();
-        P11Key sKey = null;
-        try {
-            // The conversion may fail, e.g. trying to wrap an AES key on
-            // a token that does not support AES, or when the key size is
-            // not within the range supported by the token.
-            sKey = P11SecretKeyFactory.convertKey(token, key, keyAlg);
-        } catch (InvalidKeyException ike) {
-            byte[] toBeWrappedKey = key.getEncoded();
-            if (toBeWrappedKey == null) {
-                throw new InvalidKeyException
-                        ("wrap() failed, no encoding available", ike);
-            }
-            // Directly encrypt the key encoding when key conversion failed
-            implInit(Cipher.ENCRYPT_MODE, p11Key);
-            implUpdate(toBeWrappedKey, 0, toBeWrappedKey.length);
-            try {
-                return doFinal();
-            } catch (BadPaddingException bpe) {
-                // should not occur
-                throw new InvalidKeyException("wrap() failed", bpe);
-            } finally {
-                // Restore original mode
-                implInit(Cipher.WRAP_MODE, p11Key);
-            }
-        }
-        Session s = null;
-        try {
-            s = token.getOpSession();
-            return token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism),
-                p11Key.keyID, sKey.keyID);
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("wrap() failed", e);
-        } finally {
-            token.releaseSession(s);
-        }
-    }
-
-    // see JCE spec
-    @SuppressWarnings("deprecation")
-    protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
-            int type) throws InvalidKeyException, NoSuchAlgorithmException {
-
-        boolean isTlsRsaPremasterSecret =
-                algorithm.equals("TlsRsaPremasterSecret");
-        Exception failover = null;
-
-        // Should C_Unwrap be preferred for non-TLS RSA premaster secret?
-        if (token.supportsRawSecretKeyImport()) {
-            // XXX implement unwrap using C_Unwrap() for all keys
-            implInit(Cipher.DECRYPT_MODE, p11Key);
-            try {
-                if (wrappedKey.length > maxInputSize) {
-                    throw new InvalidKeyException("Key is too long for unwrapping");
-                }
-
-                byte[] encoded = null;
-                implUpdate(wrappedKey, 0, wrappedKey.length);
-                try {
-                    encoded = doFinal();
-                } catch (BadPaddingException e) {
-                    if (isTlsRsaPremasterSecret) {
-                        failover = e;
-                    } else {
-                        throw new InvalidKeyException("Unwrapping failed", e);
-                    }
-                } catch (IllegalBlockSizeException e) {
-                    // should not occur, handled with length check above
-                    throw new InvalidKeyException("Unwrapping failed", e);
-                }
-
-                if (isTlsRsaPremasterSecret) {
-                    if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
-                        throw new IllegalStateException(
-                                "No TlsRsaPremasterSecretParameterSpec specified");
-                    }
-
-                    // polish the TLS premaster secret
-                    TlsRsaPremasterSecretParameterSpec psps =
-                            (TlsRsaPremasterSecretParameterSpec)spec;
-                    encoded = KeyUtil.checkTlsPreMasterSecretKey(
-                            psps.getClientVersion(), psps.getServerVersion(),
-                            random, encoded, (failover != null));
-                }
-
-                return ConstructKeys.constructKey(encoded, algorithm, type);
-            } finally {
-                // Restore original mode
-                implInit(Cipher.UNWRAP_MODE, p11Key);
-            }
-        } else {
-            Session s = null;
-            SecretKey secretKey = null;
-            try {
-                try {
-                    s = token.getObjSession();
-                    long keyType = CKK_GENERIC_SECRET;
-                    CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                            new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
-                            new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
-                        };
-                    attributes = token.getAttributes(
-                            O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
-                    long keyID = token.p11.C_UnwrapKey(s.id(),
-                            new CK_MECHANISM(mechanism), p11Key.keyID,
-                            wrappedKey, attributes);
-                    secretKey = P11Key.secretKey(s, keyID,
-                            algorithm, 48 << 3, attributes);
-                } catch (PKCS11Exception e) {
-                    if (isTlsRsaPremasterSecret) {
-                        failover = e;
-                    } else {
-                        throw new InvalidKeyException("unwrap() failed", e);
-                    }
-                }
-
-                if (isTlsRsaPremasterSecret) {
-                    TlsRsaPremasterSecretParameterSpec psps =
-                            (TlsRsaPremasterSecretParameterSpec)spec;
-
-                    // Please use the tricky failover as the parameter so that
-                    // smart compiler won't dispose the unused variable.
-                    secretKey = polishPreMasterSecretKey(token, s,
-                            failover, secretKey,
-                            psps.getClientVersion(), psps.getServerVersion());
-                }
-
-                return secretKey;
-            } finally {
-                token.releaseSession(s);
-            }
-        }
-    }
-
-    // see JCE spec
-    protected int engineGetKeySize(Key key) throws InvalidKeyException {
-        int n = P11KeyFactory.convertKey(token, key, algorithm).length();
-        return n;
-    }
-
-    private static SecretKey polishPreMasterSecretKey(
-            Token token, Session session,
-            Exception failover, SecretKey unwrappedKey,
-            int clientVersion, int serverVersion) {
-
-        SecretKey newKey;
-        CK_VERSION version = new CK_VERSION(
-                (clientVersion >>> 8) & 0xFF, clientVersion & 0xFF);
-        try {
-            CK_ATTRIBUTE[] attributes = token.getAttributes(
-                    O_GENERATE, CKO_SECRET_KEY,
-                    CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
-            long keyID = token.p11.C_GenerateKey(session.id(),
-                    new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version),
-                    attributes);
-            newKey = P11Key.secretKey(session,
-                    keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
-        } catch (PKCS11Exception e) {
-            throw new ProviderException(
-                    "Could not generate premaster secret", e);
-        }
-
-        return (failover == null) ? unwrappedKey : newKey;
-    }
-
-}
-
-final class ConstructKeys {
-    /**
-     * Construct a public key from its encoding.
-     *
-     * @param encodedKey the encoding of a public key.
-     *
-     * @param encodedKeyAlgorithm the algorithm the encodedKey is for.
-     *
-     * @return a public key constructed from the encodedKey.
-     */
-    private static final PublicKey constructPublicKey(byte[] encodedKey,
-            String encodedKeyAlgorithm)
-            throws InvalidKeyException, NoSuchAlgorithmException {
-        try {
-            KeyFactory keyFactory =
-                KeyFactory.getInstance(encodedKeyAlgorithm);
-            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
-            return keyFactory.generatePublic(keySpec);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new NoSuchAlgorithmException("No installed providers " +
-                                               "can create keys for the " +
-                                               encodedKeyAlgorithm +
-                                               "algorithm", nsae);
-        } catch (InvalidKeySpecException ike) {
-            throw new InvalidKeyException("Cannot construct public key", ike);
-        }
-    }
-
-    /**
-     * Construct a private key from its encoding.
-     *
-     * @param encodedKey the encoding of a private key.
-     *
-     * @param encodedKeyAlgorithm the algorithm the wrapped key is for.
-     *
-     * @return a private key constructed from the encodedKey.
-     */
-    private static final PrivateKey constructPrivateKey(byte[] encodedKey,
-            String encodedKeyAlgorithm) throws InvalidKeyException,
-            NoSuchAlgorithmException {
-        try {
-            KeyFactory keyFactory =
-                KeyFactory.getInstance(encodedKeyAlgorithm);
-            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
-            return keyFactory.generatePrivate(keySpec);
-        } catch (NoSuchAlgorithmException nsae) {
-            throw new NoSuchAlgorithmException("No installed providers " +
-                                               "can create keys for the " +
-                                               encodedKeyAlgorithm +
-                                               "algorithm", nsae);
-        } catch (InvalidKeySpecException ike) {
-            throw new InvalidKeyException("Cannot construct private key", ike);
-        }
-    }
-
-    /**
-     * Construct a secret key from its encoding.
-     *
-     * @param encodedKey the encoding of a secret key.
-     *
-     * @param encodedKeyAlgorithm the algorithm the secret key is for.
-     *
-     * @return a secret key constructed from the encodedKey.
-     */
-    private static final SecretKey constructSecretKey(byte[] encodedKey,
-            String encodedKeyAlgorithm) {
-        return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
-    }
-
-    static final Key constructKey(byte[] encoding, String keyAlgorithm,
-            int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
-        switch (keyType) {
-        case Cipher.SECRET_KEY:
-            return constructSecretKey(encoding, keyAlgorithm);
-        case Cipher.PRIVATE_KEY:
-            return constructPrivateKey(encoding, keyAlgorithm);
-        case Cipher.PUBLIC_KEY:
-            return constructPublicKey(encoding, keyAlgorithm);
-        default:
-            throw new InvalidKeyException("Unknown keytype " + keyType);
-        }
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11RSAKeyFactory.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,325 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.math.BigInteger;
-
-import java.security.*;
-import java.security.interfaces.*;
-import java.security.spec.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-import sun.security.rsa.RSAKeyFactory;
-
-/**
- * RSA KeyFactory implementation.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11RSAKeyFactory extends P11KeyFactory {
-
-    P11RSAKeyFactory(Token token, String algorithm) {
-        super(token, algorithm);
-    }
-
-    PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException {
-        try {
-            if (key instanceof RSAPublicKey) {
-                RSAPublicKey rsaKey = (RSAPublicKey)key;
-                return generatePublic(
-                    rsaKey.getModulus(),
-                    rsaKey.getPublicExponent()
-                );
-            } else if ("X.509".equals(key.getFormat())) {
-                // let SunRsaSign provider parse for us, then recurse
-                byte[] encoded = key.getEncoded();
-                key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
-                return implTranslatePublicKey(key);
-            } else {
-                throw new InvalidKeyException("PublicKey must be instance "
-                        + "of RSAPublicKey or have X.509 encoding");
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create RSA public key", e);
-        }
-    }
-
-    PrivateKey implTranslatePrivateKey(PrivateKey key)
-            throws InvalidKeyException {
-        try {
-            if (key instanceof RSAPrivateCrtKey) {
-                RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
-                return generatePrivate(
-                    rsaKey.getModulus(),
-                    rsaKey.getPublicExponent(),
-                    rsaKey.getPrivateExponent(),
-                    rsaKey.getPrimeP(),
-                    rsaKey.getPrimeQ(),
-                    rsaKey.getPrimeExponentP(),
-                    rsaKey.getPrimeExponentQ(),
-                    rsaKey.getCrtCoefficient()
-                );
-            } else if (key instanceof RSAPrivateKey) {
-                RSAPrivateKey rsaKey = (RSAPrivateKey)key;
-                return generatePrivate(
-                    rsaKey.getModulus(),
-                    rsaKey.getPrivateExponent()
-                );
-            } else if ("PKCS#8".equals(key.getFormat())) {
-                // let SunRsaSign provider parse for us, then recurse
-                byte[] encoded = key.getEncoded();
-                key = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
-                return implTranslatePrivateKey(key);
-            } else {
-                throw new InvalidKeyException("Private key must be instance "
-                        + "of RSAPrivate(Crt)Key or have PKCS#8 encoding");
-            }
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create RSA private key", e);
-        }
-    }
-
-    // see JCA spec
-    protected PublicKey engineGeneratePublic(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec instanceof X509EncodedKeySpec) {
-            try {
-                byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded();
-                PublicKey key = new sun.security.rsa.RSAPublicKeyImpl(encoded);
-                return implTranslatePublicKey(key);
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeySpecException
-                        ("Could not create RSA public key", e);
-            }
-        }
-        if (keySpec instanceof RSAPublicKeySpec == false) {
-            throw new InvalidKeySpecException("Only RSAPublicKeySpec and "
-                + "X509EncodedKeySpec supported for RSA public keys");
-        }
-        try {
-            RSAPublicKeySpec rs = (RSAPublicKeySpec)keySpec;
-            return generatePublic(
-                rs.getModulus(),
-                rs.getPublicExponent()
-            );
-        } catch (PKCS11Exception | InvalidKeyException e) {
-            throw new InvalidKeySpecException
-                ("Could not create RSA public key", e);
-        }
-    }
-
-    // see JCA spec
-    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec instanceof PKCS8EncodedKeySpec) {
-            try {
-                byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded();
-                PrivateKey key =
-                        sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded);
-                return implTranslatePrivateKey(key);
-            } catch (GeneralSecurityException e) {
-                throw new InvalidKeySpecException
-                        ("Could not create RSA private key", e);
-            }
-        }
-        try {
-            if (keySpec instanceof RSAPrivateCrtKeySpec) {
-                RSAPrivateCrtKeySpec rs = (RSAPrivateCrtKeySpec)keySpec;
-                return generatePrivate(
-                    rs.getModulus(),
-                    rs.getPublicExponent(),
-                    rs.getPrivateExponent(),
-                    rs.getPrimeP(),
-                    rs.getPrimeQ(),
-                    rs.getPrimeExponentP(),
-                    rs.getPrimeExponentQ(),
-                    rs.getCrtCoefficient()
-                );
-            } else if (keySpec instanceof RSAPrivateKeySpec) {
-                RSAPrivateKeySpec rs = (RSAPrivateKeySpec)keySpec;
-                return generatePrivate(
-                    rs.getModulus(),
-                    rs.getPrivateExponent()
-                );
-            } else {
-                throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
-                    + "and PKCS8EncodedKeySpec supported for RSA private keys");
-            }
-        } catch (PKCS11Exception | InvalidKeyException e) {
-            throw new InvalidKeySpecException
-                ("Could not create RSA private key", e);
-        }
-    }
-
-    private PublicKey generatePublic(BigInteger n, BigInteger e)
-            throws PKCS11Exception, InvalidKeyException {
-        RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
-            new CK_ATTRIBUTE(CKA_MODULUS, n),
-            new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PUBLIC_KEY, CKK_RSA, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.publicKey
-                (session, keyID, "RSA", n.bitLength(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private PrivateKey generatePrivate(BigInteger n, BigInteger d)
-            throws PKCS11Exception, InvalidKeyException {
-        RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024);
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
-            new CK_ATTRIBUTE(CKA_MODULUS, n),
-            new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.privateKey
-                (session,  keyID, "RSA", n.bitLength(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private PrivateKey generatePrivate(BigInteger n, BigInteger e,
-            BigInteger d, BigInteger p, BigInteger q, BigInteger pe,
-            BigInteger qe, BigInteger coeff) throws PKCS11Exception,
-            InvalidKeyException {
-        RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024);
-        CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-            new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY),
-            new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA),
-            new CK_ATTRIBUTE(CKA_MODULUS, n),
-            new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e),
-            new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d),
-            new CK_ATTRIBUTE(CKA_PRIME_1, p),
-            new CK_ATTRIBUTE(CKA_PRIME_2, q),
-            new CK_ATTRIBUTE(CKA_EXPONENT_1, pe),
-            new CK_ATTRIBUTE(CKA_EXPONENT_2, qe),
-            new CK_ATTRIBUTE(CKA_COEFFICIENT, coeff),
-        };
-        attributes = token.getAttributes
-                (O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes);
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            return P11Key.privateKey
-                (session, keyID, "RSA", n.bitLength(), attributes);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
-        if (RSAPublicKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_MODULUS),
-                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            KeySpec spec = new RSAPublicKeySpec(
-                attributes[0].getBigInteger(),
-                attributes[1].getBigInteger()
-            );
-            return keySpec.cast(spec);
-        } else { // X.509 handled in superclass
-            throw new InvalidKeySpecException("Only RSAPublicKeySpec and "
-                + "X509EncodedKeySpec supported for RSA public keys");
-        }
-    }
-
-    <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec,
-            Session[] session) throws PKCS11Exception, InvalidKeySpecException {
-        if (RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_MODULUS),
-                new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT),
-                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
-                new CK_ATTRIBUTE(CKA_PRIME_1),
-                new CK_ATTRIBUTE(CKA_PRIME_2),
-                new CK_ATTRIBUTE(CKA_EXPONENT_1),
-                new CK_ATTRIBUTE(CKA_EXPONENT_2),
-                new CK_ATTRIBUTE(CKA_COEFFICIENT),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            KeySpec spec = new RSAPrivateCrtKeySpec(
-                attributes[0].getBigInteger(),
-                attributes[1].getBigInteger(),
-                attributes[2].getBigInteger(),
-                attributes[3].getBigInteger(),
-                attributes[4].getBigInteger(),
-                attributes[5].getBigInteger(),
-                attributes[6].getBigInteger(),
-                attributes[7].getBigInteger()
-            );
-            return keySpec.cast(spec);
-        } else if (RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) {
-            session[0] = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_MODULUS),
-                new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT),
-            };
-            token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes);
-            KeySpec spec = new RSAPrivateKeySpec(
-                attributes[0].getBigInteger(),
-                attributes[1].getBigInteger()
-            );
-            return keySpec.cast(spec);
-        } else { // PKCS#8 handled in superclass
-            throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec "
-                + "and PKCS8EncodedKeySpec supported for RSA private keys");
-        }
-    }
-
-    KeyFactory implGetSoftwareFactory() throws GeneralSecurityException {
-        return KeyFactory.getInstance("RSA", P11Util.getSunRsaSignProvider());
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11SecretKeyFactory.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,358 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.util.*;
-
-import java.security.*;
-import java.security.spec.*;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * SecretKeyFactory implementation class. This class currently supports
- * DES, DESede, AES, ARCFOUR, and Blowfish.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11SecretKeyFactory extends SecretKeyFactorySpi {
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    P11SecretKeyFactory(Token token, String algorithm) {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-    }
-
-    private static final Map<String,Long> keyTypes;
-
-    static {
-        keyTypes = new HashMap<String,Long>();
-        addKeyType("RC4",      CKK_RC4);
-        addKeyType("ARCFOUR",  CKK_RC4);
-        addKeyType("DES",      CKK_DES);
-        addKeyType("DESede",   CKK_DES3);
-        addKeyType("AES",      CKK_AES);
-        addKeyType("Blowfish", CKK_BLOWFISH);
-
-        // we don't implement RC2 or IDEA, but we want to be able to generate
-        // keys for those SSL/TLS ciphersuites.
-        addKeyType("RC2",      CKK_RC2);
-        addKeyType("IDEA",     CKK_IDEA);
-
-        addKeyType("TlsPremasterSecret",    PCKK_TLSPREMASTER);
-        addKeyType("TlsRsaPremasterSecret", PCKK_TLSRSAPREMASTER);
-        addKeyType("TlsMasterSecret",       PCKK_TLSMASTER);
-        addKeyType("Generic",               CKK_GENERIC_SECRET);
-    }
-
-    private static void addKeyType(String name, long id) {
-        Long l = Long.valueOf(id);
-        keyTypes.put(name, l);
-        keyTypes.put(name.toUpperCase(Locale.ENGLISH), l);
-    }
-
-    static long getKeyType(String algorithm) {
-        Long l = keyTypes.get(algorithm);
-        if (l == null) {
-            algorithm = algorithm.toUpperCase(Locale.ENGLISH);
-            l = keyTypes.get(algorithm);
-            if (l == null) {
-                if (algorithm.startsWith("HMAC")) {
-                    return PCKK_HMAC;
-                } else if (algorithm.startsWith("SSLMAC")) {
-                    return PCKK_SSLMAC;
-                }
-            }
-        }
-        return (l != null) ? l.longValue() : -1;
-    }
-
-    /**
-     * Convert an arbitrary key of algorithm into a P11Key of provider.
-     * Used in engineTranslateKey(), P11Cipher.init(), and P11Mac.init().
-     */
-    static P11Key convertKey(Token token, Key key, String algo)
-            throws InvalidKeyException {
-        return convertKey(token, key, algo, null);
-    }
-
-    /**
-     * Convert an arbitrary key of algorithm w/ custom attributes into a
-     * P11Key of provider.
-     * Used in P11KeyStore.storeSkey.
-     */
-    static P11Key convertKey(Token token, Key key, String algo,
-            CK_ATTRIBUTE[] extraAttrs)
-            throws InvalidKeyException {
-        token.ensureValid();
-        if (key == null) {
-            throw new InvalidKeyException("Key must not be null");
-        }
-        if (key instanceof SecretKey == false) {
-            throw new InvalidKeyException("Key must be a SecretKey");
-        }
-        long algoType;
-        if (algo == null) {
-            algo = key.getAlgorithm();
-            algoType = getKeyType(algo);
-        } else {
-            algoType = getKeyType(algo);
-            long keyAlgorithmType = getKeyType(key.getAlgorithm());
-            if (algoType != keyAlgorithmType) {
-                if ((algoType == PCKK_HMAC) || (algoType == PCKK_SSLMAC)) {
-                    // ignore key algorithm for MACs
-                } else {
-                    throw new InvalidKeyException
-                            ("Key algorithm must be " + algo);
-                }
-            }
-        }
-        if (key instanceof P11Key) {
-            P11Key p11Key = (P11Key)key;
-            if (p11Key.token == token) {
-                if (extraAttrs != null) {
-                    Session session = null;
-                    try {
-                        session = token.getObjSession();
-                        long newKeyID = token.p11.C_CopyObject(session.id(),
-                                p11Key.keyID, extraAttrs);
-                        p11Key = (P11Key) (P11Key.secretKey(session,
-                                newKeyID, p11Key.algorithm, p11Key.keyLength,
-                                extraAttrs));
-                    } catch (PKCS11Exception p11e) {
-                        throw new InvalidKeyException
-                                ("Cannot duplicate the PKCS11 key", p11e);
-                    } finally {
-                        token.releaseSession(session);
-                    }
-                }
-                return p11Key;
-            }
-        }
-        P11Key p11Key = token.secretCache.get(key);
-        if (p11Key != null) {
-            return p11Key;
-        }
-        if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
-            throw new InvalidKeyException("Encoded format must be RAW");
-        }
-        byte[] encoded = key.getEncoded();
-        p11Key = createKey(token, encoded, algo, algoType, extraAttrs);
-        token.secretCache.put(key, p11Key);
-        return p11Key;
-    }
-
-    static void fixDESParity(byte[] key, int offset) {
-        for (int i = 0; i < 8; i++) {
-            int b = key[offset] & 0xfe;
-            b |= (Integer.bitCount(b) & 1) ^ 1;
-            key[offset++] = (byte)b;
-        }
-    }
-
-    private static P11Key createKey(Token token, byte[] encoded,
-            String algorithm, long keyType, CK_ATTRIBUTE[] extraAttrs)
-            throws InvalidKeyException {
-        int n = encoded.length << 3;
-        int keyLength = n;
-        try {
-            switch ((int)keyType) {
-                case (int)CKK_DES:
-                    keyLength =
-                        P11KeyGenerator.checkKeySize(CKM_DES_KEY_GEN, n, token);
-                    fixDESParity(encoded, 0);
-                    break;
-                case (int)CKK_DES3:
-                    keyLength =
-                        P11KeyGenerator.checkKeySize(CKM_DES3_KEY_GEN, n, token);
-                    fixDESParity(encoded, 0);
-                    fixDESParity(encoded, 8);
-                    if (keyLength == 112) {
-                        keyType = CKK_DES2;
-                    } else {
-                        keyType = CKK_DES3;
-                        fixDESParity(encoded, 16);
-                    }
-                    break;
-                case (int)CKK_AES:
-                    keyLength =
-                        P11KeyGenerator.checkKeySize(CKM_AES_KEY_GEN, n, token);
-                    break;
-                case (int)CKK_RC4:
-                    keyLength =
-                        P11KeyGenerator.checkKeySize(CKM_RC4_KEY_GEN, n, token);
-                    break;
-                case (int)CKK_BLOWFISH:
-                    keyLength =
-                        P11KeyGenerator.checkKeySize(CKM_BLOWFISH_KEY_GEN, n,
-                        token);
-                    break;
-                case (int)CKK_GENERIC_SECRET:
-                case (int)PCKK_TLSPREMASTER:
-                case (int)PCKK_TLSRSAPREMASTER:
-                case (int)PCKK_TLSMASTER:
-                    keyType = CKK_GENERIC_SECRET;
-                    break;
-                case (int)PCKK_SSLMAC:
-                case (int)PCKK_HMAC:
-                    if (n == 0) {
-                        throw new InvalidKeyException
-                                ("MAC keys must not be empty");
-                    }
-                    keyType = CKK_GENERIC_SECRET;
-                    break;
-                default:
-                    throw new InvalidKeyException("Unknown algorithm " +
-                            algorithm);
-            }
-        } catch (InvalidAlgorithmParameterException iape) {
-            throw new InvalidKeyException("Invalid key for " + algorithm,
-                    iape);
-        } catch (ProviderException pe) {
-            throw new InvalidKeyException("Could not create key", pe);
-        }
-        Session session = null;
-        try {
-            CK_ATTRIBUTE[] attributes;
-            if (extraAttrs != null) {
-                attributes = new CK_ATTRIBUTE[3 + extraAttrs.length];
-                System.arraycopy(extraAttrs, 0, attributes, 3,
-                        extraAttrs.length);
-            } else {
-                attributes = new CK_ATTRIBUTE[3];
-            }
-            attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
-            attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType);
-            attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
-            attributes = token.getAttributes
-                (O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
-            session = token.getObjSession();
-            long keyID = token.p11.C_CreateObject(session.id(), attributes);
-            P11Key p11Key = (P11Key)P11Key.secretKey
-                (session, keyID, algorithm, keyLength, attributes);
-            return p11Key;
-        } catch (PKCS11Exception e) {
-            throw new InvalidKeyException("Could not create key", e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    // see JCE spec
-    protected SecretKey engineGenerateSecret(KeySpec keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if (keySpec == null) {
-            throw new InvalidKeySpecException("KeySpec must not be null");
-        }
-        if (keySpec instanceof SecretKeySpec) {
-            try {
-                Key key = convertKey(token, (SecretKey)keySpec, algorithm);
-                return (SecretKey)key;
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeySpecException(e);
-            }
-        } else if (algorithm.equalsIgnoreCase("DES")) {
-            if (keySpec instanceof DESKeySpec) {
-                byte[] keyBytes = ((DESKeySpec)keySpec).getKey();
-                keySpec = new SecretKeySpec(keyBytes, "DES");
-                return engineGenerateSecret(keySpec);
-            }
-        } else if (algorithm.equalsIgnoreCase("DESede")) {
-            if (keySpec instanceof DESedeKeySpec) {
-                byte[] keyBytes = ((DESedeKeySpec)keySpec).getKey();
-                keySpec = new SecretKeySpec(keyBytes, "DESede");
-                return engineGenerateSecret(keySpec);
-            }
-        }
-        throw new InvalidKeySpecException
-                ("Unsupported spec: " + keySpec.getClass().getName());
-    }
-
-    private byte[] getKeyBytes(SecretKey key) throws InvalidKeySpecException {
-        try {
-            key = engineTranslateKey(key);
-            if ("RAW".equalsIgnoreCase(key.getFormat()) == false) {
-                throw new InvalidKeySpecException
-                    ("Could not obtain key bytes");
-            }
-            byte[] k = key.getEncoded();
-            return k;
-        } catch (InvalidKeyException e) {
-            throw new InvalidKeySpecException(e);
-        }
-    }
-
-    // see JCE spec
-    protected KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpec)
-            throws InvalidKeySpecException {
-        token.ensureValid();
-        if ((key == null) || (keySpec == null)) {
-            throw new InvalidKeySpecException
-                ("key and keySpec must not be null");
-        }
-        if (SecretKeySpec.class.isAssignableFrom(keySpec)) {
-            return new SecretKeySpec(getKeyBytes(key), algorithm);
-        } else if (algorithm.equalsIgnoreCase("DES")) {
-            try {
-                if (DESKeySpec.class.isAssignableFrom(keySpec)) {
-                    return new DESKeySpec(getKeyBytes(key));
-                }
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeySpecException(e);
-            }
-        } else if (algorithm.equalsIgnoreCase("DESede")) {
-            try {
-                if (DESedeKeySpec.class.isAssignableFrom(keySpec)) {
-                    return new DESedeKeySpec(getKeyBytes(key));
-                }
-            } catch (InvalidKeyException e) {
-                throw new InvalidKeySpecException(e);
-            }
-        }
-        throw new InvalidKeySpecException
-                ("Unsupported spec: " + keySpec.getName());
-    }
-
-    // see JCE spec
-    protected SecretKey engineTranslateKey(SecretKey key)
-            throws InvalidKeyException {
-        return (SecretKey)convertKey(token, key, algorithm);
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11SecureRandom.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.io.*;
-import java.security.*;
-import sun.security.pkcs11.wrapper.*;
-
-/**
- * SecureRandom implementation class. Some tokens support only
- * C_GenerateRandom() and not C_SeedRandom(). In order not to lose an
- * application specified seed, we create a SHA1PRNG that we mix with in that
- * case.
- *
- * Note that since SecureRandom is thread safe, we only need one
- * instance per PKCS#11 token instance. It is created on demand and cached
- * in the SunPKCS11 class.
- *
- * Also note that we obtain the PKCS#11 session on demand, no need to tie one
- * up.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11SecureRandom extends SecureRandomSpi {
-
-    private static final long serialVersionUID = -8939510236124553291L;
-
-    // token instance
-    private final Token token;
-
-    // PRNG for mixing, non-null if active (i.e. setSeed() has been called)
-    private volatile SecureRandom mixRandom;
-
-    // buffer, if mixing is used
-    private byte[] mixBuffer;
-
-    // bytes remaining in mixBuffer, if mixing is used
-    private int buffered;
-
-    /*
-     * we buffer data internally for efficiency but limit the lifetime
-     * to avoid using stale bits.
-     */
-    // lifetime in ms, currently 100 ms (0.1 s)
-    private static final long MAX_IBUFFER_TIME = 100;
-
-    // size of the internal buffer
-    private static final int IBUFFER_SIZE = 32;
-
-    // internal buffer for the random bits
-    private transient byte[] iBuffer = new byte[IBUFFER_SIZE];
-
-    // number of bytes remain in iBuffer
-    private transient int ibuffered = 0;
-
-    // time that data was read into iBuffer
-    private transient long lastRead = 0L;
-
-    P11SecureRandom(Token token) {
-        this.token = token;
-    }
-
-    // see JCA spec
-    @Override
-    protected synchronized void engineSetSeed(byte[] seed) {
-        if (seed == null) {
-            throw new NullPointerException("seed must not be null");
-        }
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            token.p11.C_SeedRandom(session.id(), seed);
-        } catch (PKCS11Exception e) {
-            // cannot set seed
-            // let a SHA1PRNG use that seed instead
-            SecureRandom random = mixRandom;
-            if (random != null) {
-                random.setSeed(seed);
-            } else {
-                try {
-                    mixBuffer = new byte[20];
-                    random = SecureRandom.getInstance("SHA1PRNG");
-                    // initialize object before assigning to class field
-                    random.setSeed(seed);
-                    mixRandom = random;
-                } catch (NoSuchAlgorithmException ee) {
-                    throw new ProviderException(ee);
-                }
-            }
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    // see JCA spec
-    @Override
-    protected void engineNextBytes(byte[] bytes) {
-        if ((bytes == null) || (bytes.length == 0)) {
-            return;
-        }
-        if (bytes.length <= IBUFFER_SIZE)  {
-            int ofs = 0;
-            synchronized (iBuffer) {
-                while (ofs < bytes.length) {
-                    long time = System.currentTimeMillis();
-                    // refill the internal buffer if empty or stale
-                    if ((ibuffered == 0) ||
-                            !(time - lastRead < MAX_IBUFFER_TIME)) {
-                        lastRead = time;
-                        implNextBytes(iBuffer);
-                        ibuffered = IBUFFER_SIZE;
-                    }
-                    // copy the buffered bytes into 'bytes'
-                    while ((ofs < bytes.length) && (ibuffered > 0)) {
-                        bytes[ofs++] = iBuffer[IBUFFER_SIZE - ibuffered--];
-                    }
-                }
-            }
-        } else {
-            // avoid using the buffer - just fill bytes directly
-            implNextBytes(bytes);
-        }
-
-    }
-
-    // see JCA spec
-    @Override
-    protected byte[] engineGenerateSeed(int numBytes) {
-        byte[] b = new byte[numBytes];
-        engineNextBytes(b);
-        return b;
-    }
-
-    private void mix(byte[] b) {
-        SecureRandom random = mixRandom;
-        if (random == null) {
-            // avoid mixing if setSeed() has never been called
-            return;
-        }
-        synchronized (this) {
-            int ofs = 0;
-            int len = b.length;
-            while (len-- > 0) {
-                if (buffered == 0) {
-                    random.nextBytes(mixBuffer);
-                    buffered = mixBuffer.length;
-                }
-                b[ofs++] ^= mixBuffer[mixBuffer.length - buffered];
-                buffered--;
-            }
-        }
-    }
-
-    // fill up the specified buffer with random bytes, and mix them
-    private void implNextBytes(byte[] bytes) {
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            token.p11.C_GenerateRandom(session.id(), bytes);
-            mix(bytes);
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("nextBytes() failed", e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    private void readObject(ObjectInputStream in)
-            throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-        // assign default values to non-null transient fields
-        iBuffer = new byte[IBUFFER_SIZE];
-        ibuffered = 0;
-        lastRead = 0L;
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Signature.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,833 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.io.IOException;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-
-import java.security.*;
-import java.security.interfaces.*;
-import sun.nio.ch.DirectBuffer;
-
-import sun.security.util.*;
-import sun.security.x509.AlgorithmId;
-
-import sun.security.rsa.RSASignature;
-import sun.security.rsa.RSAPadding;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-import sun.security.util.KeyUtil;
-
-/**
- * Signature implementation class. This class currently supports the
- * following algorithms:
- *
- * . DSA
- *   . NONEwithDSA (RawDSA)
- *   . SHA1withDSA
- *   . NONEwithDSAinP1363Format (RawDSAinP1363Format)
- *   . SHA1withDSAinP1363Format
- * . RSA:
- *   . MD2withRSA
- *   . MD5withRSA
- *   . SHA1withRSA
- *   . SHA224withRSA
- *   . SHA256withRSA
- *   . SHA384withRSA
- *   . SHA512withRSA
- * . ECDSA
- *   . NONEwithECDSA
- *   . SHA1withECDSA
- *   . SHA224withECDSA
- *   . SHA256withECDSA
- *   . SHA384withECDSA
- *   . SHA512withECDSA
- *   . NONEwithECDSAinP1363Format
- *   . SHA1withECDSAinP1363Format
- *   . SHA224withECDSAinP1363Format
- *   . SHA256withECDSAinP1363Format
- *   . SHA384withECDSAinP1363Format
- *   . SHA512withECDSAinP1363Format
- *
- * Note that the underlying PKCS#11 token may support complete signature
- * algorithm (e.g. CKM_DSA_SHA1, CKM_MD5_RSA_PKCS), or it may just
- * implement the signature algorithm without hashing (e.g. CKM_DSA, CKM_PKCS),
- * or it may only implement the raw public key operation (CKM_RSA_X_509).
- * This class uses what is available and adds whatever extra processing
- * is needed.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class P11Signature extends SignatureSpi {
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // name of the key algorithm, currently either RSA or DSA
-    private final String keyAlgorithm;
-
-    // mechanism id
-    private final long mechanism;
-
-    // digest algorithm OID, if we encode RSA signature ourselves
-    private final ObjectIdentifier digestOID;
-
-    // type, one of T_* below
-    private final int type;
-
-    // key instance used, if init*() was called
-    private P11Key p11Key;
-
-    // message digest, if we do the digesting ourselves
-    private final MessageDigest md;
-
-    // associated session, if any
-    private Session session;
-
-    // mode, one of M_* below
-    private int mode;
-
-    // flag indicating whether an operation is initialized
-    private boolean initialized;
-
-    // buffer, for update(byte) or DSA
-    private final byte[] buffer;
-
-    // total number of bytes processed in current operation
-    private int bytesProcessed;
-
-    // The format, to be used for DSA and ECDSA signatures.
-    // If true, the IEEE P1363 format will be used, the concatenation of
-    // r and s. If false (default), the signature will be formatted as a
-    // DER-encoded ASN.1 sequence of r and s.
-    private boolean p1363Format = false;
-
-    // constant for signing mode
-    private final static int M_SIGN   = 1;
-    // constant for verification mode
-    private final static int M_VERIFY = 2;
-
-    // constant for type digesting, we do the hashing ourselves
-    private final static int T_DIGEST = 1;
-    // constant for type update, token does everything
-    private final static int T_UPDATE = 2;
-    // constant for type raw, used with RawDSA and NONEwithECDSA only
-    private final static int T_RAW    = 3;
-
-    // XXX PKCS#11 v2.20 says "should not be longer than 1024 bits",
-    // but this is a little arbitrary
-    private final static int RAW_ECDSA_MAX = 128;
-
-    P11Signature(Token token, String algorithm, long mechanism)
-            throws NoSuchAlgorithmException, PKCS11Exception {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-        byte[] buffer = null;
-        ObjectIdentifier digestOID = null;
-        MessageDigest md = null;
-        switch ((int)mechanism) {
-        case (int)CKM_MD2_RSA_PKCS:
-        case (int)CKM_MD5_RSA_PKCS:
-        case (int)CKM_SHA1_RSA_PKCS:
-        case (int)CKM_SHA224_RSA_PKCS:
-        case (int)CKM_SHA256_RSA_PKCS:
-        case (int)CKM_SHA384_RSA_PKCS:
-        case (int)CKM_SHA512_RSA_PKCS:
-            keyAlgorithm = "RSA";
-            type = T_UPDATE;
-            buffer = new byte[1];
-            break;
-        case (int)CKM_DSA_SHA1:
-            keyAlgorithm = "DSA";
-            type = T_UPDATE;
-            buffer = new byte[1];
-            break;
-        case (int)CKM_ECDSA_SHA1:
-            keyAlgorithm = "EC";
-            type = T_UPDATE;
-            buffer = new byte[1];
-            break;
-        case (int)CKM_DSA:
-            keyAlgorithm = "DSA";
-            if (algorithm.equals("DSA") ||
-                algorithm.equals("DSAinP1363Format")) {
-                type = T_DIGEST;
-                md = MessageDigest.getInstance("SHA-1");
-            } else if (algorithm.equals("RawDSA") ||
-                       algorithm.equals("RawDSAinP1363Format")) {
-                type = T_RAW;
-                buffer = new byte[20];
-            } else {
-                throw new ProviderException(algorithm);
-            }
-            break;
-        case (int)CKM_ECDSA:
-            keyAlgorithm = "EC";
-            if (algorithm.equals("NONEwithECDSA") ||
-                algorithm.equals("NONEwithECDSAinP1363Format")) {
-                type = T_RAW;
-                buffer = new byte[RAW_ECDSA_MAX];
-            } else {
-                String digestAlg;
-                if (algorithm.equals("SHA1withECDSA") ||
-                    algorithm.equals("SHA1withECDSAinP1363Format")) {
-                    digestAlg = "SHA-1";
-                } else if (algorithm.equals("SHA224withECDSA") ||
-                           algorithm.equals("SHA224withECDSAinP1363Format")) {
-                    digestAlg = "SHA-224";
-                } else if (algorithm.equals("SHA256withECDSA") ||
-                           algorithm.equals("SHA256withECDSAinP1363Format")) {
-                    digestAlg = "SHA-256";
-                } else if (algorithm.equals("SHA384withECDSA") ||
-                           algorithm.equals("SHA384withECDSAinP1363Format")) {
-                    digestAlg = "SHA-384";
-                } else if (algorithm.equals("SHA512withECDSA") ||
-                           algorithm.equals("SHA512withECDSAinP1363Format")) {
-                    digestAlg = "SHA-512";
-                } else {
-                    throw new ProviderException(algorithm);
-                }
-                type = T_DIGEST;
-                md = MessageDigest.getInstance(digestAlg);
-            }
-            break;
-        case (int)CKM_RSA_PKCS:
-        case (int)CKM_RSA_X_509:
-            keyAlgorithm = "RSA";
-            type = T_DIGEST;
-            if (algorithm.equals("MD5withRSA")) {
-                md = MessageDigest.getInstance("MD5");
-                digestOID = AlgorithmId.MD5_oid;
-            } else if (algorithm.equals("SHA1withRSA")) {
-                md = MessageDigest.getInstance("SHA-1");
-                digestOID = AlgorithmId.SHA_oid;
-            } else if (algorithm.equals("MD2withRSA")) {
-                md = MessageDigest.getInstance("MD2");
-                digestOID = AlgorithmId.MD2_oid;
-            } else if (algorithm.equals("SHA224withRSA")) {
-                md = MessageDigest.getInstance("SHA-224");
-                digestOID = AlgorithmId.SHA224_oid;
-            } else if (algorithm.equals("SHA256withRSA")) {
-                md = MessageDigest.getInstance("SHA-256");
-                digestOID = AlgorithmId.SHA256_oid;
-            } else if (algorithm.equals("SHA384withRSA")) {
-                md = MessageDigest.getInstance("SHA-384");
-                digestOID = AlgorithmId.SHA384_oid;
-            } else if (algorithm.equals("SHA512withRSA")) {
-                md = MessageDigest.getInstance("SHA-512");
-                digestOID = AlgorithmId.SHA512_oid;
-            } else {
-                throw new ProviderException("Unknown signature: " + algorithm);
-            }
-            break;
-        default:
-            throw new ProviderException("Unknown mechanism: " + mechanism);
-        }
-        this.buffer = buffer;
-        this.digestOID = digestOID;
-        this.md = md;
-        if (algorithm.endsWith("inP1363Format")) {
-            this.p1363Format = true;
-        }
-    }
-
-    private void ensureInitialized() {
-        token.ensureValid();
-        if (initialized == false) {
-            initialize();
-        }
-    }
-
-    private void cancelOperation() {
-        token.ensureValid();
-        if (initialized == false) {
-            return;
-        }
-        initialized = false;
-        if ((session == null) || (token.explicitCancel == false)) {
-            return;
-        }
-        if (session.hasObjects() == false) {
-            session = token.killSession(session);
-            return;
-        }
-        // "cancel" operation by finishing it
-        // XXX make sure all this always works correctly
-        if (mode == M_SIGN) {
-            try {
-                if (type == T_UPDATE) {
-                    token.p11.C_SignFinal(session.id(), 0);
-                } else {
-                    byte[] digest;
-                    if (type == T_DIGEST) {
-                        digest = md.digest();
-                    } else { // T_RAW
-                        digest = buffer;
-                    }
-                    token.p11.C_Sign(session.id(), digest);
-                }
-            } catch (PKCS11Exception e) {
-                throw new ProviderException("cancel failed", e);
-            }
-        } else { // M_VERIFY
-            try {
-                byte[] signature;
-                if (keyAlgorithm.equals("DSA")) {
-                    signature = new byte[40];
-                } else {
-                    signature = new byte[(p11Key.length() + 7) >> 3];
-                }
-                if (type == T_UPDATE) {
-                    token.p11.C_VerifyFinal(session.id(), signature);
-                } else {
-                    byte[] digest;
-                    if (type == T_DIGEST) {
-                        digest = md.digest();
-                    } else { // T_RAW
-                        digest = buffer;
-                    }
-                    token.p11.C_Verify(session.id(), digest, signature);
-                }
-            } catch (PKCS11Exception e) {
-                // will fail since the signature is incorrect
-                // XXX check error code
-            }
-        }
-    }
-
-    // assumes current state is initialized == false
-    private void initialize() {
-        try {
-            if (session == null) {
-                session = token.getOpSession();
-            }
-            if (mode == M_SIGN) {
-                token.p11.C_SignInit(session.id(),
-                        new CK_MECHANISM(mechanism), p11Key.keyID);
-            } else {
-                token.p11.C_VerifyInit(session.id(),
-                        new CK_MECHANISM(mechanism), p11Key.keyID);
-            }
-            initialized = true;
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("Initialization failed", e);
-        }
-        if (bytesProcessed != 0) {
-            bytesProcessed = 0;
-            if (md != null) {
-                md.reset();
-            }
-        }
-    }
-
-    private void checkKeySize(String keyAlgo, Key key)
-        throws InvalidKeyException {
-        CK_MECHANISM_INFO mechInfo = null;
-        try {
-            mechInfo = token.getMechanismInfo(mechanism);
-        } catch (PKCS11Exception e) {
-            // should not happen, ignore for now.
-        }
-        if (mechInfo == null) {
-            // skip the check if no native info available
-            return;
-        }
-        int minKeySize = (int) mechInfo.ulMinKeySize;
-        int maxKeySize = (int) mechInfo.ulMaxKeySize;
-        // need to override the MAX keysize for SHA1withDSA
-        if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
-               maxKeySize = 1024;
-        }
-        int keySize = 0;
-        if (key instanceof P11Key) {
-            keySize = ((P11Key) key).length();
-        } else {
-            if (keyAlgo.equals("RSA")) {
-                keySize = ((RSAKey) key).getModulus().bitLength();
-            } else if (keyAlgo.equals("DSA")) {
-                keySize = ((DSAKey) key).getParams().getP().bitLength();
-            } else if (keyAlgo.equals("EC")) {
-                keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();
-            } else {
-                throw new ProviderException("Error: unsupported algo " + keyAlgo);
-            }
-        }
-        if ((minKeySize != -1) && (keySize < minKeySize)) {
-            throw new InvalidKeyException(keyAlgo +
-                " key must be at least " + minKeySize + " bits");
-        }
-        if ((maxKeySize != -1) && (keySize > maxKeySize)) {
-            throw new InvalidKeyException(keyAlgo +
-                " key must be at most " + maxKeySize + " bits");
-        }
-        if (keyAlgo.equals("RSA")) {
-            checkRSAKeyLength(keySize);
-        }
-    }
-
-    private void checkRSAKeyLength(int len) throws InvalidKeyException {
-        RSAPadding padding;
-        try {
-            padding = RSAPadding.getInstance
-                (RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);
-        } catch (InvalidAlgorithmParameterException iape) {
-            throw new InvalidKeyException(iape.getMessage());
-        }
-        int maxDataSize = padding.getMaxDataSize();
-        int encodedLength;
-        if (algorithm.equals("MD5withRSA") ||
-            algorithm.equals("MD2withRSA")) {
-            encodedLength = 34;
-        } else if (algorithm.equals("SHA1withRSA")) {
-            encodedLength = 35;
-        } else if (algorithm.equals("SHA224withRSA")) {
-            encodedLength = 47;
-        } else if (algorithm.equals("SHA256withRSA")) {
-            encodedLength = 51;
-        } else if (algorithm.equals("SHA384withRSA")) {
-            encodedLength = 67;
-        } else if (algorithm.equals("SHA512withRSA")) {
-            encodedLength = 83;
-        } else {
-            throw new ProviderException("Unknown signature algo: " + algorithm);
-        }
-        if (encodedLength > maxDataSize) {
-            throw new InvalidKeyException
-                ("Key is too short for this signature algorithm");
-        }
-    }
-
-    // see JCA spec
-    protected void engineInitVerify(PublicKey publicKey)
-            throws InvalidKeyException {
-        if (publicKey == null) {
-            throw new InvalidKeyException("Key must not be null");
-        }
-        // Need to check key length whenever a new key is set
-        if (publicKey != p11Key) {
-            checkKeySize(keyAlgorithm, publicKey);
-        }
-        cancelOperation();
-        mode = M_VERIFY;
-        p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
-        initialize();
-    }
-
-    // see JCA spec
-    protected void engineInitSign(PrivateKey privateKey)
-            throws InvalidKeyException {
-        if (privateKey == null) {
-            throw new InvalidKeyException("Key must not be null");
-        }
-        // Need to check RSA key length whenever a new key is set
-        if (privateKey != p11Key) {
-            checkKeySize(keyAlgorithm, privateKey);
-        }
-        cancelOperation();
-        mode = M_SIGN;
-        p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
-        initialize();
-    }
-
-    // see JCA spec
-    protected void engineUpdate(byte b) throws SignatureException {
-        ensureInitialized();
-        switch (type) {
-        case T_UPDATE:
-            buffer[0] = b;
-            engineUpdate(buffer, 0, 1);
-            break;
-        case T_DIGEST:
-            md.update(b);
-            bytesProcessed++;
-            break;
-        case T_RAW:
-            if (bytesProcessed >= buffer.length) {
-                bytesProcessed = buffer.length + 1;
-                return;
-            }
-            buffer[bytesProcessed++] = b;
-            break;
-        default:
-            throw new ProviderException("Internal error");
-        }
-    }
-
-    // see JCA spec
-    protected void engineUpdate(byte[] b, int ofs, int len)
-            throws SignatureException {
-        ensureInitialized();
-        if (len == 0) {
-            return;
-        }
-        switch (type) {
-        case T_UPDATE:
-            try {
-                if (mode == M_SIGN) {
-                    token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
-                } else {
-                    token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
-                }
-                bytesProcessed += len;
-            } catch (PKCS11Exception e) {
-                throw new ProviderException(e);
-            }
-            break;
-        case T_DIGEST:
-            md.update(b, ofs, len);
-            bytesProcessed += len;
-            break;
-        case T_RAW:
-            if (bytesProcessed + len > buffer.length) {
-                bytesProcessed = buffer.length + 1;
-                return;
-            }
-            System.arraycopy(b, ofs, buffer, bytesProcessed, len);
-            bytesProcessed += len;
-            break;
-        default:
-            throw new ProviderException("Internal error");
-        }
-    }
-
-    // see JCA spec
-    protected void engineUpdate(ByteBuffer byteBuffer) {
-        ensureInitialized();
-        int len = byteBuffer.remaining();
-        if (len <= 0) {
-            return;
-        }
-        switch (type) {
-        case T_UPDATE:
-            if (byteBuffer instanceof DirectBuffer == false) {
-                // cannot do better than default impl
-                super.engineUpdate(byteBuffer);
-                return;
-            }
-            long addr = ((DirectBuffer)byteBuffer).address();
-            int ofs = byteBuffer.position();
-            try {
-                if (mode == M_SIGN) {
-                    token.p11.C_SignUpdate
-                        (session.id(), addr + ofs, null, 0, len);
-                } else {
-                    token.p11.C_VerifyUpdate
-                        (session.id(), addr + ofs, null, 0, len);
-                }
-                bytesProcessed += len;
-                byteBuffer.position(ofs + len);
-            } catch (PKCS11Exception e) {
-                throw new ProviderException("Update failed", e);
-            }
-            break;
-        case T_DIGEST:
-            md.update(byteBuffer);
-            bytesProcessed += len;
-            break;
-        case T_RAW:
-            if (bytesProcessed + len > buffer.length) {
-                bytesProcessed = buffer.length + 1;
-                return;
-            }
-            byteBuffer.get(buffer, bytesProcessed, len);
-            bytesProcessed += len;
-            break;
-        default:
-            throw new ProviderException("Internal error");
-        }
-    }
-
-    // see JCA spec
-    protected byte[] engineSign() throws SignatureException {
-        ensureInitialized();
-        try {
-            byte[] signature;
-            if (type == T_UPDATE) {
-                int len = keyAlgorithm.equals("DSA") ? 40 : 0;
-                signature = token.p11.C_SignFinal(session.id(), len);
-            } else {
-                byte[] digest;
-                if (type == T_DIGEST) {
-                    digest = md.digest();
-                } else { // T_RAW
-                    if (mechanism == CKM_DSA) {
-                        if (bytesProcessed != buffer.length) {
-                            throw new SignatureException
-                            ("Data for RawDSA must be exactly 20 bytes long");
-                        }
-                        digest = buffer;
-                    } else { // CKM_ECDSA
-                        if (bytesProcessed > buffer.length) {
-                            throw new SignatureException("Data for NONEwithECDSA"
-                            + " must be at most " + RAW_ECDSA_MAX + " bytes long");
-                        }
-                        digest = new byte[bytesProcessed];
-                        System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
-                    }
-                }
-                if (keyAlgorithm.equals("RSA") == false) {
-                    // DSA and ECDSA
-                    signature = token.p11.C_Sign(session.id(), digest);
-                } else { // RSA
-                    byte[] data = encodeSignature(digest);
-                    if (mechanism == CKM_RSA_X_509) {
-                        data = pkcs1Pad(data);
-                    }
-                    signature = token.p11.C_Sign(session.id(), data);
-                }
-            }
-            if (keyAlgorithm.equals("RSA")) {
-                return signature;
-            } else {
-                if (p1363Format) {
-                    return signature;
-                } else {
-                    return dsaToASN1(signature);
-                }
-            }
-        } catch (PKCS11Exception pe) {
-            throw new ProviderException(pe);
-        } catch (SignatureException | ProviderException e) {
-            cancelOperation();
-            throw e;
-        } finally {
-            initialized = false;
-            session = token.releaseSession(session);
-        }
-    }
-
-    // see JCA spec
-    protected boolean engineVerify(byte[] signature) throws SignatureException {
-        ensureInitialized();
-        try {
-            if (!p1363Format) {
-                if (keyAlgorithm.equals("DSA")) {
-                    signature = asn1ToDSA(signature);
-                } else if (keyAlgorithm.equals("EC")) {
-                    signature = asn1ToECDSA(signature);
-                }
-            }
-            if (type == T_UPDATE) {
-                token.p11.C_VerifyFinal(session.id(), signature);
-            } else {
-                byte[] digest;
-                if (type == T_DIGEST) {
-                    digest = md.digest();
-                } else { // T_RAW
-                    if (mechanism == CKM_DSA) {
-                        if (bytesProcessed != buffer.length) {
-                            throw new SignatureException
-                            ("Data for RawDSA must be exactly 20 bytes long");
-                        }
-                        digest = buffer;
-                    } else {
-                        if (bytesProcessed > buffer.length) {
-                            throw new SignatureException("Data for NONEwithECDSA"
-                            + " must be at most " + RAW_ECDSA_MAX + " bytes long");
-                        }
-                        digest = new byte[bytesProcessed];
-                        System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
-                    }
-                }
-                if (keyAlgorithm.equals("RSA") == false) {
-                    // DSA and ECDSA
-                    token.p11.C_Verify(session.id(), digest, signature);
-                } else { // RSA
-                    byte[] data = encodeSignature(digest);
-                    if (mechanism == CKM_RSA_X_509) {
-                        data = pkcs1Pad(data);
-                    }
-                    token.p11.C_Verify(session.id(), data, signature);
-                }
-            }
-            return true;
-        } catch (PKCS11Exception pe) {
-            long errorCode = pe.getErrorCode();
-            if (errorCode == CKR_SIGNATURE_INVALID) {
-                return false;
-            }
-            if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
-                // return false rather than throwing an exception
-                return false;
-            }
-            // ECF bug?
-            if (errorCode == CKR_DATA_LEN_RANGE) {
-                return false;
-            }
-            throw new ProviderException(pe);
-        }  catch (SignatureException | ProviderException e) {
-            cancelOperation();
-            throw e;
-        } finally {
-            initialized = false;
-            session = token.releaseSession(session);
-        }
-    }
-
-    private byte[] pkcs1Pad(byte[] data) {
-        try {
-            int len = (p11Key.length() + 7) >> 3;
-            RSAPadding padding = RSAPadding.getInstance
-                                        (RSAPadding.PAD_BLOCKTYPE_1, len);
-            byte[] padded = padding.pad(data);
-            return padded;
-        } catch (GeneralSecurityException e) {
-            throw new ProviderException(e);
-        }
-    }
-
-    private byte[] encodeSignature(byte[] digest) throws SignatureException {
-        try {
-            return RSASignature.encodeSignature(digestOID, digest);
-        } catch (IOException e) {
-            throw new SignatureException("Invalid encoding", e);
-        }
-    }
-
-//    private static byte[] decodeSignature(byte[] signature) throws IOException {
-//      return RSASignature.decodeSignature(digestOID, signature);
-//    }
-
-    // For DSA and ECDSA signatures, PKCS#11 represents them as a simple
-    // byte array that contains the concatenation of r and s.
-    // For DSA, r and s are always exactly 20 bytes long.
-    // For ECDSA, r and s are of variable length, but we know that each
-    // occupies half of the array.
-    private static byte[] dsaToASN1(byte[] signature) {
-        int n = signature.length >> 1;
-        BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));
-        BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));
-        try {
-            DerOutputStream outseq = new DerOutputStream(100);
-            outseq.putInteger(r);
-            outseq.putInteger(s);
-            DerValue result = new DerValue(DerValue.tag_Sequence,
-                                           outseq.toByteArray());
-            return result.toByteArray();
-        } catch (java.io.IOException e) {
-            throw new RuntimeException("Internal error", e);
-        }
-    }
-
-    private static byte[] asn1ToDSA(byte[] sig) throws SignatureException {
-        try {
-            // Enforce strict DER checking for signatures
-            DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
-            DerValue[] values = in.getSequence(2);
-
-            // check number of components in the read sequence
-            // and trailing data
-            if ((values.length != 2) || (in.available() != 0)) {
-                throw new IOException("Invalid encoding for signature");
-            }
-
-            BigInteger r = values[0].getPositiveBigInteger();
-            BigInteger s = values[1].getPositiveBigInteger();
-
-            byte[] br = toByteArray(r, 20);
-            byte[] bs = toByteArray(s, 20);
-            if ((br == null) || (bs == null)) {
-                throw new SignatureException("Out of range value for R or S");
-            }
-            return P11Util.concat(br, bs);
-        } catch (SignatureException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new SignatureException("Invalid encoding for signature", e);
-        }
-    }
-
-    private byte[] asn1ToECDSA(byte[] sig) throws SignatureException {
-        try {
-            // Enforce strict DER checking for signatures
-            DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
-            DerValue[] values = in.getSequence(2);
-
-            // check number of components in the read sequence
-            // and trailing data
-            if ((values.length != 2) || (in.available() != 0)) {
-                throw new IOException("Invalid encoding for signature");
-            }
-
-            BigInteger r = values[0].getPositiveBigInteger();
-            BigInteger s = values[1].getPositiveBigInteger();
-
-            // trim leading zeroes
-            byte[] br = KeyUtil.trimZeroes(r.toByteArray());
-            byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
-            int k = Math.max(br.length, bs.length);
-            // r and s each occupy half the array
-            byte[] res = new byte[k << 1];
-            System.arraycopy(br, 0, res, k - br.length, br.length);
-            System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);
-            return res;
-        } catch (Exception e) {
-            throw new SignatureException("Invalid encoding for signature", e);
-        }
-    }
-
-    private static byte[] toByteArray(BigInteger bi, int len) {
-        byte[] b = bi.toByteArray();
-        int n = b.length;
-        if (n == len) {
-            return b;
-        }
-        if ((n == len + 1) && (b[0] == 0)) {
-            byte[] t = new byte[len];
-            System.arraycopy(b, 1, t, 0, len);
-            return t;
-        }
-        if (n > len) {
-            return null;
-        }
-        // must be smaller
-        byte[] t = new byte[len];
-        System.arraycopy(b, 0, t, (len - n), n);
-        return t;
-    }
-
-    // see JCA spec
-    @SuppressWarnings("deprecation")
-    protected void engineSetParameter(String param, Object value)
-            throws InvalidParameterException {
-        throw new UnsupportedOperationException("setParameter() not supported");
-    }
-
-    // see JCA spec
-    @SuppressWarnings("deprecation")
-    protected Object engineGetParameter(String param)
-            throws InvalidParameterException {
-        throw new UnsupportedOperationException("getParameter() not supported");
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11TlsKeyMaterialGenerator.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.util.*;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import sun.security.internal.spec.*;
-import sun.security.internal.interfaces.TlsMasterSecret;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * KeyGenerator to calculate the SSL/TLS key material (cipher keys and ivs,
- * mac keys) from the master secret.
- *
- * @author  Andreas Sterbenz
- * @since   1.6
- */
-public final class P11TlsKeyMaterialGenerator extends KeyGeneratorSpi {
-
-    private final static String MSG = "TlsKeyMaterialGenerator must be "
-        + "initialized using a TlsKeyMaterialParameterSpec";
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id
-    private long mechanism;
-
-    // parameter spec
-    @SuppressWarnings("deprecation")
-    private TlsKeyMaterialParameterSpec spec;
-
-    // master secret as a P11Key
-    private P11Key p11Key;
-
-    // whether SSLv3 is supported
-    private final boolean supportSSLv3;
-
-    P11TlsKeyMaterialGenerator(Token token, String algorithm, long mechanism)
-            throws PKCS11Exception {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-
-        // Given the current lookup order specified in SunPKCS11.java,
-        // if CKM_SSL3_KEY_AND_MAC_DERIVE is not used to construct this object,
-        // it means that this mech is disabled or unsupported.
-        this.supportSSLv3 = (mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE);
-    }
-
-    protected void engineInit(SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    @SuppressWarnings("deprecation")
-    protected void engineInit(AlgorithmParameterSpec params,
-            SecureRandom random) throws InvalidAlgorithmParameterException {
-        if (params instanceof TlsKeyMaterialParameterSpec == false) {
-            throw new InvalidAlgorithmParameterException(MSG);
-        }
-
-        TlsKeyMaterialParameterSpec spec = (TlsKeyMaterialParameterSpec)params;
-        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-
-        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
-            (version > 0x0302)) {
-             throw new InvalidAlgorithmParameterException
-                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
-                     " TLS 1.0, and TLS 1.1 are supported (0x" +
-                     Integer.toHexString(version) + ")");
-        }
-        try {
-            p11Key = P11SecretKeyFactory.convertKey
-                            (token, spec.getMasterSecret(), "TlsMasterSecret");
-        } catch (InvalidKeyException e) {
-            throw new InvalidAlgorithmParameterException("init() failed", e);
-        }
-        this.spec = spec;
-        this.mechanism = (version == 0x0300)?
-            CKM_SSL3_KEY_AND_MAC_DERIVE : CKM_TLS_KEY_AND_MAC_DERIVE;
-    }
-
-    protected void engineInit(int keysize, SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    @SuppressWarnings("deprecation")
-    protected SecretKey engineGenerateKey() {
-        if (spec == null) {
-            throw new IllegalStateException
-                ("TlsKeyMaterialGenerator must be initialized");
-        }
-        int macBits = spec.getMacKeyLength() << 3;
-        int ivBits = spec.getIvLength() << 3;
-
-        int expandedKeyBits = spec.getExpandedCipherKeyLength() << 3;
-        int keyBits = spec.getCipherKeyLength() << 3;
-        boolean isExportable;
-        if (expandedKeyBits != 0) {
-            isExportable = true;
-        } else {
-            isExportable = false;
-            expandedKeyBits = keyBits;
-        }
-
-        CK_SSL3_RANDOM_DATA random = new CK_SSL3_RANDOM_DATA
-                            (spec.getClientRandom(), spec.getServerRandom());
-        CK_SSL3_KEY_MAT_PARAMS params = new CK_SSL3_KEY_MAT_PARAMS
-                            (macBits, keyBits, ivBits, isExportable, random);
-
-        String cipherAlgorithm = spec.getCipherAlgorithm();
-        long keyType = P11SecretKeyFactory.getKeyType(cipherAlgorithm);
-        if (keyType < 0) {
-            if (keyBits != 0) {
-                throw new ProviderException
-                            ("Unknown algorithm: " + spec.getCipherAlgorithm());
-            } else {
-                // NULL encryption ciphersuites
-                keyType = CKK_GENERIC_SECRET;
-            }
-        }
-
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            CK_ATTRIBUTE[] attributes;
-            if (keyBits != 0) {
-                attributes = new CK_ATTRIBUTE[] {
-                    new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
-                    new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
-                    new CK_ATTRIBUTE(CKA_VALUE_LEN, expandedKeyBits >> 3),
-                };
-            } else {
-                // ciphersuites with NULL ciphers
-                attributes = new CK_ATTRIBUTE[0];
-            }
-            attributes = token.getAttributes
-                (O_GENERATE, CKO_SECRET_KEY, keyType, attributes);
-            // the returned keyID is a dummy, ignore
-            long keyID = token.p11.C_DeriveKey(session.id(),
-                new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes);
-
-            CK_SSL3_KEY_MAT_OUT out = params.pReturnedKeyMaterial;
-            // Note that the MAC keys do not inherit all attributes from the
-            // template, but they do inherit the sensitive/extractable/token
-            // flags, which is all P11Key cares about.
-            SecretKey clientMacKey, serverMacKey;
-
-            // The MAC size may be zero for GCM mode.
-            //
-            // PKCS11 does not support GCM mode as the author made the comment,
-            // so the macBits is unlikely to be zero. It's only a place holder.
-            if (macBits != 0) {
-                clientMacKey = P11Key.secretKey
-                    (session, out.hClientMacSecret, "MAC", macBits, attributes);
-                serverMacKey = P11Key.secretKey
-                    (session, out.hServerMacSecret, "MAC", macBits, attributes);
-            } else {
-                clientMacKey = null;
-                serverMacKey = null;
-            }
-
-            SecretKey clientCipherKey, serverCipherKey;
-            if (keyBits != 0) {
-                clientCipherKey = P11Key.secretKey(session, out.hClientKey,
-                        cipherAlgorithm, expandedKeyBits, attributes);
-                serverCipherKey = P11Key.secretKey(session, out.hServerKey,
-                        cipherAlgorithm, expandedKeyBits, attributes);
-            } else {
-                clientCipherKey = null;
-                serverCipherKey = null;
-            }
-            IvParameterSpec clientIv = (out.pIVClient == null)
-                                    ? null : new IvParameterSpec(out.pIVClient);
-            IvParameterSpec serverIv = (out.pIVServer == null)
-                                    ? null : new IvParameterSpec(out.pIVServer);
-
-            return new TlsKeyMaterialSpec(clientMacKey, serverMacKey,
-                    clientCipherKey, clientIv, serverCipherKey, serverIv);
-
-        } catch (Exception e) {
-            throw new ProviderException("Could not generate key", e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11TlsMasterSecretGenerator.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import sun.security.internal.spec.TlsMasterSecretParameterSpec;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * KeyGenerator for the SSL/TLS master secret.
- *
- * @author  Andreas Sterbenz
- * @since   1.6
- */
-public final class P11TlsMasterSecretGenerator extends KeyGeneratorSpi {
-
-    private final static String MSG = "TlsMasterSecretGenerator must be "
-        + "initialized using a TlsMasterSecretParameterSpec";
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id
-    private long mechanism;
-
-    @SuppressWarnings("deprecation")
-    private TlsMasterSecretParameterSpec spec;
-    private P11Key p11Key;
-
-    CK_VERSION ckVersion;
-
-    // whether SSLv3 is supported
-    private final boolean supportSSLv3;
-
-    P11TlsMasterSecretGenerator(Token token, String algorithm, long mechanism)
-            throws PKCS11Exception {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-
-        // Given the current lookup order specified in SunPKCS11.java, if
-        // CKM_SSL3_MASTER_KEY_DERIVE is not used to construct this object,
-        // it means that this mech is disabled or unsupported.
-        supportSSLv3 = (mechanism == CKM_SSL3_MASTER_KEY_DERIVE);
-    }
-
-    protected void engineInit(SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    @SuppressWarnings("deprecation")
-    protected void engineInit(AlgorithmParameterSpec params,
-            SecureRandom random) throws InvalidAlgorithmParameterException {
-        if (params instanceof TlsMasterSecretParameterSpec == false) {
-            throw new InvalidAlgorithmParameterException(MSG);
-        }
-
-        TlsMasterSecretParameterSpec spec = (TlsMasterSecretParameterSpec)params;
-        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
-            (version > 0x0302)) {
-             throw new InvalidAlgorithmParameterException
-                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
-                     " TLS 1.0, and TLS 1.1 are supported (0x" +
-                     Integer.toHexString(version) + ")");
-        }
-
-        SecretKey key = spec.getPremasterSecret();
-        // algorithm should be either TlsRsaPremasterSecret or TlsPremasterSecret,
-        // but we omit the check
-        try {
-            p11Key = P11SecretKeyFactory.convertKey(token, key, null);
-        } catch (InvalidKeyException e) {
-            throw new InvalidAlgorithmParameterException("init() failed", e);
-        }
-        this.spec = spec;
-        if (p11Key.getAlgorithm().equals("TlsRsaPremasterSecret")) {
-            mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE
-                                             : CKM_TLS_MASTER_KEY_DERIVE;
-            ckVersion = new CK_VERSION(0, 0);
-        } else {
-            // Note: we use DH for all non-RSA premaster secrets. That includes
-            // Kerberos. That should not be a problem because master secret
-            // calculation is always a straightforward application of the
-            // TLS PRF (or the SSL equivalent).
-            // The only thing special about RSA master secret calculation is
-            // that it extracts the version numbers from the premaster secret.
-            mechanism = (version == 0x0300) ? CKM_SSL3_MASTER_KEY_DERIVE_DH
-                                             : CKM_TLS_MASTER_KEY_DERIVE_DH;
-            ckVersion = null;
-        }
-    }
-
-    protected void engineInit(int keysize, SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    protected SecretKey engineGenerateKey() {
-        if (spec == null) {
-            throw new IllegalStateException
-                ("TlsMasterSecretGenerator must be initialized");
-        }
-        byte[] clientRandom = spec.getClientRandom();
-        byte[] serverRandom = spec.getServerRandom();
-        CK_SSL3_RANDOM_DATA random =
-                new CK_SSL3_RANDOM_DATA(clientRandom, serverRandom);
-        CK_SSL3_MASTER_KEY_DERIVE_PARAMS params =
-                new CK_SSL3_MASTER_KEY_DERIVE_PARAMS(random, ckVersion);
-
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = token.getAttributes(O_GENERATE,
-                CKO_SECRET_KEY, CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
-            long keyID = token.p11.C_DeriveKey(session.id(),
-                new CK_MECHANISM(mechanism, params), p11Key.keyID, attributes);
-            int major, minor;
-            if (params.pVersion == null) {
-                major = -1;
-                minor = -1;
-            } else {
-                major = params.pVersion.major;
-                minor = params.pVersion.minor;
-            }
-            SecretKey key = P11Key.masterSecretKey(session, keyID,
-                "TlsMasterSecret", 48 << 3, attributes, major, minor);
-            return key;
-        } catch (Exception e) {
-            throw new ProviderException("Could not generate key", e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11TlsPrfGenerator.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2005, 2014, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import sun.security.internal.spec.TlsPrfParameterSpec;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * KeyGenerator for the TLS PRF. Note that although the PRF is used in a number
- * of places during the handshake, this class is usually only used to calculate
- * the Finished messages. The reason is that for those other uses more specific
- * PKCS#11 mechanisms have been defined (CKM_SSL3_MASTER_KEY_DERIVE, etc.).
- *
- * <p>This class supports the CKM_TLS_PRF mechanism from PKCS#11 v2.20 and
- * the older NSS private mechanism.
- *
- * @author  Andreas Sterbenz
- * @since   1.6
- */
-final class P11TlsPrfGenerator extends KeyGeneratorSpi {
-
-    private final static String MSG =
-            "TlsPrfGenerator must be initialized using a TlsPrfParameterSpec";
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id
-    private final long mechanism;
-
-    @SuppressWarnings("deprecation")
-    private TlsPrfParameterSpec spec;
-
-    private P11Key p11Key;
-
-    P11TlsPrfGenerator(Token token, String algorithm, long mechanism)
-            throws PKCS11Exception {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-    }
-
-    protected void engineInit(SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    @SuppressWarnings("deprecation")
-    protected void engineInit(AlgorithmParameterSpec params,
-            SecureRandom random) throws InvalidAlgorithmParameterException {
-        if (params instanceof TlsPrfParameterSpec == false) {
-            throw new InvalidAlgorithmParameterException(MSG);
-        }
-        this.spec = (TlsPrfParameterSpec)params;
-        SecretKey key = spec.getSecret();
-        if (key == null) {
-            key = NULL_KEY;
-        }
-        try {
-            p11Key = P11SecretKeyFactory.convertKey(token, key, null);
-        } catch (InvalidKeyException e) {
-            throw new InvalidAlgorithmParameterException("init() failed", e);
-        }
-    }
-
-    // SecretKeySpec does not allow zero length keys, so we define our
-    // own class.
-    //
-    // As an anonymous class cannot make any guarantees about serialization
-    // compatibility, it is nonsensical for an anonymous class to define a
-    // serialVersionUID. Suppress warnings relative to missing serialVersionUID
-    // field in the anonymous subclass of serializable SecretKey.
-    @SuppressWarnings("serial")
-    private static final SecretKey NULL_KEY = new SecretKey() {
-        public byte[] getEncoded() {
-            return new byte[0];
-        }
-        public String getFormat() {
-            return "RAW";
-        }
-        public String getAlgorithm() {
-            return "Generic";
-        }
-    };
-
-    protected void engineInit(int keysize, SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    protected SecretKey engineGenerateKey() {
-        if (spec == null) {
-            throw new IllegalStateException("TlsPrfGenerator must be initialized");
-        }
-        byte[] label = P11Util.getBytesUTF8(spec.getLabel());
-        byte[] seed = spec.getSeed();
-
-        if (mechanism == CKM_NSS_TLS_PRF_GENERAL) {
-            Session session = null;
-            try {
-                session = token.getOpSession();
-                token.p11.C_SignInit
-                    (session.id(), new CK_MECHANISM(mechanism), p11Key.keyID);
-                token.p11.C_SignUpdate(session.id(), 0, label, 0, label.length);
-                token.p11.C_SignUpdate(session.id(), 0, seed, 0, seed.length);
-                byte[] out = token.p11.C_SignFinal
-                                    (session.id(), spec.getOutputLength());
-                return new SecretKeySpec(out, "TlsPrf");
-            } catch (PKCS11Exception e) {
-                throw new ProviderException("Could not calculate PRF", e);
-            } finally {
-                token.releaseSession(session);
-            }
-        }
-
-        // mechanism == CKM_TLS_PRF
-
-        byte[] out = new byte[spec.getOutputLength()];
-        CK_TLS_PRF_PARAMS params = new CK_TLS_PRF_PARAMS(seed, label, out);
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            long keyID = token.p11.C_DeriveKey(session.id(),
-                new CK_MECHANISM(mechanism, params), p11Key.keyID, null);
-            // ignore keyID, returned PRF bytes are in 'out'
-            return new SecretKeySpec(out, "TlsPrf");
-        } catch (PKCS11Exception e) {
-            throw new ProviderException("Could not calculate PRF", e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11TlsRsaPremasterSecretGenerator.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.security.*;
-import java.security.spec.AlgorithmParameterSpec;
-
-import javax.crypto.*;
-import javax.crypto.spec.*;
-
-import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
-
-import static sun.security.pkcs11.TemplateManager.*;
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * KeyGenerator for the SSL/TLS RSA premaster secret.
- *
- * @author  Andreas Sterbenz
- * @since   1.6
- */
-final class P11TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi {
-
-    private final static String MSG = "TlsRsaPremasterSecretGenerator must be "
-        + "initialized using a TlsRsaPremasterSecretParameterSpec";
-
-    // token instance
-    private final Token token;
-
-    // algorithm name
-    private final String algorithm;
-
-    // mechanism id
-    private long mechanism;
-
-    @SuppressWarnings("deprecation")
-    private TlsRsaPremasterSecretParameterSpec spec;
-
-    // whether SSLv3 is supported
-    private final boolean supportSSLv3;
-
-    P11TlsRsaPremasterSecretGenerator(Token token, String algorithm, long mechanism)
-            throws PKCS11Exception {
-        super();
-        this.token = token;
-        this.algorithm = algorithm;
-        this.mechanism = mechanism;
-
-        // Given the current lookup order specified in SunPKCS11.java,
-        // if CKM_SSL3_PRE_MASTER_KEY_GEN is not used to construct this object,
-        // it means that this mech is disabled or unsupported.
-        this.supportSSLv3 = (mechanism == CKM_SSL3_PRE_MASTER_KEY_GEN);
-    }
-
-    protected void engineInit(SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    @SuppressWarnings("deprecation")
-    protected void engineInit(AlgorithmParameterSpec params,
-            SecureRandom random) throws InvalidAlgorithmParameterException {
-        if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
-            throw new InvalidAlgorithmParameterException(MSG);
-        }
-
-        TlsRsaPremasterSecretParameterSpec spec =
-            (TlsRsaPremasterSecretParameterSpec) params;
-
-        int version = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
-
-        if ((version == 0x0300 && !supportSSLv3) || (version < 0x0300) ||
-            (version > 0x0302)) {
-             throw new InvalidAlgorithmParameterException
-                    ("Only" + (supportSSLv3? " SSL 3.0,": "") +
-                     " TLS 1.0, and TLS 1.1 are supported (0x" +
-                     Integer.toHexString(version) + ")");
-        }
-        this.spec = spec;
-    }
-
-    protected void engineInit(int keysize, SecureRandom random) {
-        throw new InvalidParameterException(MSG);
-    }
-
-    // Only can be used in client side to generate TLS RSA premaster secret.
-    protected SecretKey engineGenerateKey() {
-        if (spec == null) {
-            throw new IllegalStateException
-                        ("TlsRsaPremasterSecretGenerator must be initialized");
-        }
-
-        CK_VERSION version = new CK_VERSION(
-                        spec.getMajorVersion(), spec.getMinorVersion());
-        Session session = null;
-        try {
-            session = token.getObjSession();
-            CK_ATTRIBUTE[] attributes = token.getAttributes(
-                    O_GENERATE, CKO_SECRET_KEY,
-                    CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
-            long keyID = token.p11.C_GenerateKey(session.id(),
-                    new CK_MECHANISM(mechanism, version), attributes);
-            SecretKey key = P11Key.secretKey(session,
-                    keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
-            return key;
-        } catch (PKCS11Exception e) {
-            throw new ProviderException(
-                    "Could not generate premaster secret", e);
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/P11Util.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.math.BigInteger;
-import java.security.*;
-
-/**
- * Collection of static utility methods.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-public final class P11Util {
-
-    private static Object LOCK = new Object();
-
-    private static volatile Provider sun, sunRsaSign, sunJce;
-
-    private P11Util() {
-        // empty
-    }
-
-    static Provider getSunProvider() {
-        Provider p = sun;
-        if (p == null) {
-            synchronized (LOCK) {
-                p = getProvider
-                    (sun, "SUN", "sun.security.provider.Sun");
-                sun = p;
-            }
-        }
-        return p;
-    }
-
-    static Provider getSunRsaSignProvider() {
-        Provider p = sunRsaSign;
-        if (p == null) {
-            synchronized (LOCK) {
-                p = getProvider
-                    (sunRsaSign, "SunRsaSign", "sun.security.rsa.SunRsaSign");
-                sunRsaSign = p;
-            }
-        }
-        return p;
-    }
-
-    static Provider getSunJceProvider() {
-        Provider p = sunJce;
-        if (p == null) {
-            synchronized (LOCK) {
-                p = getProvider
-                    (sunJce, "SunJCE", "com.sun.crypto.provider.SunJCE");
-                sunJce = p;
-            }
-        }
-        return p;
-    }
-
-    private static Provider getProvider(Provider p, String providerName,
-            String className) {
-        if (p != null) {
-            return p;
-        }
-        p = Security.getProvider(providerName);
-        if (p == null) {
-            try {
-                @SuppressWarnings("deprecation")
-                Object o = Class.forName(className).newInstance();
-                p = (Provider)o;
-            } catch (Exception e) {
-                throw new ProviderException
-                        ("Could not find provider " + providerName, e);
-            }
-        }
-        return p;
-    }
-
-    static byte[] convert(byte[] input, int offset, int len) {
-        if ((offset == 0) && (len == input.length)) {
-            return input;
-        } else {
-            byte[] t = new byte[len];
-            System.arraycopy(input, offset, t, 0, len);
-            return t;
-        }
-    }
-
-    static byte[] subarray(byte[] b, int ofs, int len) {
-        byte[] out = new byte[len];
-        System.arraycopy(b, ofs, out, 0, len);
-        return out;
-    }
-
-    static byte[] concat(byte[] b1, byte[] b2) {
-        byte[] b = new byte[b1.length + b2.length];
-        System.arraycopy(b1, 0, b, 0, b1.length);
-        System.arraycopy(b2, 0, b, b1.length, b2.length);
-        return b;
-    }
-
-    static long[] concat(long[] b1, long[] b2) {
-        if (b1.length == 0) {
-            return b2;
-        }
-        long[] b = new long[b1.length + b2.length];
-        System.arraycopy(b1, 0, b, 0, b1.length);
-        System.arraycopy(b2, 0, b, b1.length, b2.length);
-        return b;
-    }
-
-    public static byte[] getMagnitude(BigInteger bi) {
-        byte[] b = bi.toByteArray();
-        if ((b.length > 1) && (b[0] == 0)) {
-            int n = b.length - 1;
-            byte[] newarray = new byte[n];
-            System.arraycopy(b, 1, newarray, 0, n);
-            b = newarray;
-        }
-        return b;
-    }
-
-    static byte[] getBytesUTF8(String s) {
-        try {
-            return s.getBytes("UTF8");
-        } catch (java.io.UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    static byte[] sha1(byte[] data) {
-        try {
-            MessageDigest md = MessageDigest.getInstance("SHA-1");
-            md.update(data);
-            return md.digest();
-        } catch (GeneralSecurityException e) {
-            throw new ProviderException(e);
-        }
-    }
-
-    private final static char[] hexDigits = "0123456789abcdef".toCharArray();
-
-    static String toString(byte[] b) {
-        if (b == null) {
-            return "(null)";
-        }
-        StringBuilder sb = new StringBuilder(b.length * 3);
-        for (int i = 0; i < b.length; i++) {
-            int k = b[i] & 0xff;
-            if (i != 0) {
-                sb.append(':');
-            }
-            sb.append(hexDigits[k >>> 4]);
-            sb.append(hexDigits[k & 0xf]);
-        }
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/Secmod.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,787 +0,0 @@
-/*
- * Copyright (c) 2005, 2015, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.KeyStore.*;
-import java.security.cert.X509Certificate;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-
-/**
- * The Secmod class defines the interface to the native NSS
- * library and the configuration information it stores in its
- * secmod.db file.
- *
- * <p>Example code:
- * <pre>
- *   Secmod secmod = Secmod.getInstance();
- *   if (secmod.isInitialized() == false) {
- *       secmod.initialize("/home/myself/.mozilla");
- *   }
- *
- *   Provider p = secmod.getModule(ModuleType.KEYSTORE).getProvider();
- *   KeyStore ks = KeyStore.getInstance("PKCS11", p);
- *   ks.load(null, password);
- * </pre>
- *
- * @since   1.6
- * @author  Andreas Sterbenz
- */
-public final class Secmod {
-
-    private final static boolean DEBUG = false;
-
-    private final static Secmod INSTANCE;
-
-    static {
-        sun.security.pkcs11.wrapper.PKCS11.loadNative();
-        INSTANCE = new Secmod();
-    }
-
-    private final static String NSS_LIB_NAME = "nss3";
-
-    private final static String SOFTTOKEN_LIB_NAME = "softokn3";
-
-    private final static String TRUST_LIB_NAME = "nssckbi";
-
-    // handle to be passed to the native code, 0 means not initialized
-    private long nssHandle;
-
-    // whether this is a supported version of NSS
-    private boolean supported;
-
-    // list of the modules
-    private List<Module> modules;
-
-    private String configDir;
-
-    private String nssLibDir;
-
-    private Secmod() {
-        // empty
-    }
-
-    /**
-     * Return the singleton Secmod instance.
-     */
-    public static Secmod getInstance() {
-        return INSTANCE;
-    }
-
-    private boolean isLoaded() {
-        if (nssHandle == 0) {
-            nssHandle = nssGetLibraryHandle(System.mapLibraryName(NSS_LIB_NAME));
-            if (nssHandle != 0) {
-                fetchVersions();
-            }
-        }
-        return (nssHandle != 0);
-    }
-
-    private void fetchVersions() {
-        supported = nssVersionCheck(nssHandle, "3.7");
-    }
-
-    /**
-     * Test whether this Secmod has been initialized. Returns true
-     * if NSS has been initialized using either the initialize() method
-     * or by directly calling the native NSS APIs. The latter may be
-     * the case if the current process contains components that use
-     * NSS directly.
-     *
-     * @throws IOException if an incompatible version of NSS
-     *   has been loaded
-     */
-    public synchronized boolean isInitialized() throws IOException {
-        // NSS does not allow us to check if it is initialized already
-        // assume that if it is loaded it is also initialized
-        if (isLoaded() == false) {
-            return false;
-        }
-        if (supported == false) {
-            throw new IOException
-                ("An incompatible version of NSS is already loaded, "
-                + "3.7 or later required");
-        }
-        return true;
-    }
-
-    String getConfigDir() {
-        return configDir;
-    }
-
-    String getLibDir() {
-        return nssLibDir;
-    }
-
-    /**
-     * Initialize this Secmod.
-     *
-     * @param configDir the directory containing the NSS configuration
-     *   files such as secmod.db
-     * @param nssLibDir the directory containing the NSS libraries
-     *   (libnss3.so or nss3.dll) or null if the library is on
-     *   the system default shared library path
-     *
-     * @throws IOException if NSS has already been initialized,
-     *   the specified directories are invalid, or initialization
-     *   fails for any other reason
-     */
-    public void initialize(String configDir, String nssLibDir)
-            throws IOException {
-        initialize(DbMode.READ_WRITE, configDir, nssLibDir, false);
-    }
-
-    public void initialize(DbMode dbMode, String configDir, String nssLibDir)
-            throws IOException {
-        initialize(dbMode, configDir, nssLibDir, false);
-    }
-
-    public synchronized void initialize(DbMode dbMode, String configDir,
-        String nssLibDir, boolean nssOptimizeSpace) throws IOException {
-
-        if (isInitialized()) {
-            throw new IOException("NSS is already initialized");
-        }
-
-        if (dbMode == null) {
-            throw new NullPointerException();
-        }
-        if ((dbMode != DbMode.NO_DB) && (configDir == null)) {
-            throw new NullPointerException();
-        }
-        String platformLibName = System.mapLibraryName("nss3");
-        String platformPath;
-        if (nssLibDir == null) {
-            platformPath = platformLibName;
-        } else {
-            File base = new File(nssLibDir);
-            if (base.isDirectory() == false) {
-                throw new IOException("nssLibDir must be a directory:" + nssLibDir);
-            }
-            File platformFile = new File(base, platformLibName);
-            if (platformFile.isFile() == false) {
-                throw new FileNotFoundException(platformFile.getPath());
-            }
-            platformPath = platformFile.getPath();
-        }
-
-        if (configDir != null) {
-            File configBase = new File(configDir);
-            if (configBase.isDirectory() == false ) {
-                throw new IOException("configDir must be a directory: " + configDir);
-            }
-            File secmodFile = new File(configBase, "secmod.db");
-            if (secmodFile.isFile() == false) {
-                throw new FileNotFoundException(secmodFile.getPath());
-            }
-        }
-
-        if (DEBUG) System.out.println("lib: " + platformPath);
-        nssHandle = nssLoadLibrary(platformPath);
-        if (DEBUG) System.out.println("handle: " + nssHandle);
-        fetchVersions();
-        if (supported == false) {
-            throw new IOException
-                ("The specified version of NSS is incompatible, "
-                + "3.7 or later required");
-        }
-
-        if (DEBUG) System.out.println("dir: " + configDir);
-        boolean initok = nssInitialize(dbMode.functionName, nssHandle,
-            configDir, nssOptimizeSpace);
-        if (DEBUG) System.out.println("init: " + initok);
-        if (initok == false) {
-            throw new IOException("NSS initialization failed");
-        }
-
-        this.configDir = configDir;
-        this.nssLibDir = nssLibDir;
-    }
-
-    /**
-     * Return an immutable list of all available modules.
-     *
-     * @throws IllegalStateException if this Secmod is misconfigured
-     *   or not initialized
-     */
-    public synchronized List<Module> getModules() {
-        try {
-            if (isInitialized() == false) {
-                throw new IllegalStateException("NSS not initialized");
-            }
-        } catch (IOException e) {
-            // IOException if misconfigured
-            throw new IllegalStateException(e);
-        }
-        if (modules == null) {
-            @SuppressWarnings("unchecked")
-            List<Module> modules = (List<Module>)nssGetModuleList(nssHandle,
-                nssLibDir);
-            this.modules = Collections.unmodifiableList(modules);
-        }
-        return modules;
-    }
-
-    private static byte[] getDigest(X509Certificate cert, String algorithm) {
-        try {
-            MessageDigest md = MessageDigest.getInstance(algorithm);
-            return md.digest(cert.getEncoded());
-        } catch (GeneralSecurityException e) {
-            throw new ProviderException(e);
-        }
-    }
-
-    boolean isTrusted(X509Certificate cert, TrustType trustType) {
-        Bytes bytes = new Bytes(getDigest(cert, "SHA-1"));
-        TrustAttributes attr = getModuleTrust(ModuleType.KEYSTORE, bytes);
-        if (attr == null) {
-            attr = getModuleTrust(ModuleType.FIPS, bytes);
-            if (attr == null) {
-                attr = getModuleTrust(ModuleType.TRUSTANCHOR, bytes);
-            }
-        }
-        return (attr == null) ? false : attr.isTrusted(trustType);
-    }
-
-    private TrustAttributes getModuleTrust(ModuleType type, Bytes bytes) {
-        Module module = getModule(type);
-        TrustAttributes t = (module == null) ? null : module.getTrust(bytes);
-        return t;
-    }
-
-    /**
-     * Constants describing the different types of NSS modules.
-     * For this API, NSS modules are classified as either one
-     * of the internal modules delivered as part of NSS or
-     * as an external module provided by a 3rd party.
-     */
-    public static enum ModuleType {
-        /**
-         * The NSS Softtoken crypto module. This is the first
-         * slot of the softtoken object.
-         * This module provides
-         * implementations for cryptographic algorithms but no KeyStore.
-         */
-        CRYPTO,
-        /**
-         * The NSS Softtoken KeyStore module. This is the second
-         * slot of the softtoken object.
-         * This module provides
-         * implementations for cryptographic algorithms (after login)
-         * and the KeyStore.
-         */
-        KEYSTORE,
-        /**
-         * The NSS Softtoken module in FIPS mode. Note that in FIPS mode the
-         * softtoken presents only one slot, not separate CRYPTO and KEYSTORE
-         * slots as in non-FIPS mode.
-         */
-        FIPS,
-        /**
-         * The NSS builtin trust anchor module. This is the
-         * NSSCKBI object. It provides no crypto functions.
-         */
-        TRUSTANCHOR,
-        /**
-         * An external module.
-         */
-        EXTERNAL,
-    }
-
-    /**
-     * Returns the first module of the specified type. If no such
-     * module exists, this method returns null.
-     *
-     * @throws IllegalStateException if this Secmod is misconfigured
-     *   or not initialized
-     */
-    public Module getModule(ModuleType type) {
-        for (Module module : getModules()) {
-            if (module.getType() == type) {
-                return module;
-            }
-        }
-        return null;
-    }
-
-    static final String TEMPLATE_EXTERNAL =
-        "library = %s\n"
-        + "name = \"%s\"\n"
-        + "slotListIndex = %d\n";
-
-    static final String TEMPLATE_TRUSTANCHOR =
-        "library = %s\n"
-        + "name = \"NSS Trust Anchors\"\n"
-        + "slotListIndex = 0\n"
-        + "enabledMechanisms = { KeyStore }\n"
-        + "nssUseSecmodTrust = true\n";
-
-    static final String TEMPLATE_CRYPTO =
-        "library = %s\n"
-        + "name = \"NSS SoftToken Crypto\"\n"
-        + "slotListIndex = 0\n"
-        + "disabledMechanisms = { KeyStore }\n";
-
-    static final String TEMPLATE_KEYSTORE =
-        "library = %s\n"
-        + "name = \"NSS SoftToken KeyStore\"\n"
-        + "slotListIndex = 1\n"
-        + "nssUseSecmodTrust = true\n";
-
-    static final String TEMPLATE_FIPS =
-        "library = %s\n"
-        + "name = \"NSS FIPS SoftToken\"\n"
-        + "slotListIndex = 0\n"
-        + "nssUseSecmodTrust = true\n";
-
-    /**
-     * A representation of one PKCS#11 slot in a PKCS#11 module.
-     */
-    public static final class Module {
-        // path of the native library
-        final String libraryName;
-        // descriptive name used by NSS
-        final String commonName;
-        final int slot;
-        final ModuleType type;
-
-        private String config;
-        private SunPKCS11 provider;
-
-        // trust attributes. Used for the KEYSTORE and TRUSTANCHOR modules only
-        private Map<Bytes,TrustAttributes> trust;
-
-        Module(String libraryDir, String libraryName, String commonName,
-                boolean fips, int slot) {
-            ModuleType type;
-
-            if ((libraryName == null) || (libraryName.length() == 0)) {
-                // must be softtoken
-                libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME);
-                if (fips == false) {
-                    type = (slot == 0) ? ModuleType.CRYPTO : ModuleType.KEYSTORE;
-                } else {
-                    type = ModuleType.FIPS;
-                    if (slot != 0) {
-                        throw new RuntimeException
-                            ("Slot index should be 0 for FIPS slot");
-                    }
-                }
-            } else {
-                if (libraryName.endsWith(System.mapLibraryName(TRUST_LIB_NAME))
-                        || commonName.equals("Builtin Roots Module")) {
-                    type = ModuleType.TRUSTANCHOR;
-                } else {
-                    type = ModuleType.EXTERNAL;
-                }
-                if (fips) {
-                    throw new RuntimeException("FIPS flag set for non-internal "
-                        + "module: " + libraryName + ", " + commonName);
-                }
-            }
-            // On Ubuntu the libsoftokn3 library is located in a subdirectory
-            // of the system libraries directory. (Since Ubuntu 11.04.)
-            File libraryFile = new File(libraryDir, libraryName);
-            if (!libraryFile.isFile()) {
-               File failover = new File(libraryDir, "nss/" + libraryName);
-               if (failover.isFile()) {
-                   libraryFile = failover;
-               }
-            }
-            this.libraryName = libraryFile.getPath();
-            this.commonName = commonName;
-            this.slot = slot;
-            this.type = type;
-            initConfiguration();
-        }
-
-        private void initConfiguration() {
-            switch (type) {
-            case EXTERNAL:
-                config = String.format(TEMPLATE_EXTERNAL, libraryName,
-                                            commonName + " " + slot, slot);
-                break;
-            case CRYPTO:
-                config = String.format(TEMPLATE_CRYPTO, libraryName);
-                break;
-            case KEYSTORE:
-                config = String.format(TEMPLATE_KEYSTORE, libraryName);
-                break;
-            case FIPS:
-                config = String.format(TEMPLATE_FIPS, libraryName);
-                break;
-            case TRUSTANCHOR:
-                config = String.format(TEMPLATE_TRUSTANCHOR, libraryName);
-                break;
-            default:
-                throw new RuntimeException("Unknown module type: " + type);
-            }
-        }
-
-        /**
-         * Get the configuration for this module. This is a string
-         * in the SunPKCS11 configuration format. It can be
-         * customized with additional options and then made
-         * current using the setConfiguration() method.
-         */
-        @Deprecated
-        public synchronized String getConfiguration() {
-            return config;
-        }
-
-        /**
-         * Set the configuration for this module.
-         *
-         * @throws IllegalStateException if the associated provider
-         *   instance has already been created.
-         */
-        @Deprecated
-        public synchronized void setConfiguration(String config) {
-            if (provider != null) {
-                throw new IllegalStateException("Provider instance already created");
-            }
-            this.config = config;
-        }
-
-        /**
-         * Return the pathname of the native library that implements
-         * this module. For example, /usr/lib/libpkcs11.so.
-         */
-        public String getLibraryName() {
-            return libraryName;
-        }
-
-        /**
-         * Returns the type of this module.
-         */
-        public ModuleType getType() {
-            return type;
-        }
-
-        /**
-         * Returns the provider instance that is associated with this
-         * module. The first call to this method creates the provider
-         * instance.
-         */
-        @Deprecated
-        public synchronized Provider getProvider() {
-            if (provider == null) {
-                provider = newProvider();
-            }
-            return provider;
-        }
-
-        synchronized boolean hasInitializedProvider() {
-            return provider != null;
-        }
-
-        void setProvider(SunPKCS11 p) {
-            if (provider != null) {
-                throw new ProviderException("Secmod provider already initialized");
-            }
-            provider = p;
-        }
-
-        private SunPKCS11 newProvider() {
-            try {
-                return new SunPKCS11(new Config("--" + config));
-            } catch (Exception e) {
-                // XXX
-                throw new ProviderException(e);
-            }
-        }
-
-        synchronized void setTrust(Token token, X509Certificate cert) {
-            Bytes bytes = new Bytes(getDigest(cert, "SHA-1"));
-            TrustAttributes attr = getTrust(bytes);
-            if (attr == null) {
-                attr = new TrustAttributes(token, cert, bytes, CKT_NETSCAPE_TRUSTED_DELEGATOR);
-                trust.put(bytes, attr);
-            } else {
-                // does it already have the correct trust settings?
-                if (attr.isTrusted(TrustType.ALL) == false) {
-                    // XXX not yet implemented
-                    throw new ProviderException("Cannot change existing trust attributes");
-                }
-            }
-        }
-
-        TrustAttributes getTrust(Bytes hash) {
-            if (trust == null) {
-                // If provider is not set, create a temporary provider to
-                // retrieve the trust information. This can happen if we need
-                // to get the trust information for the trustanchor module
-                // because we need to look for user customized settings in the
-                // keystore module (which may not have a provider created yet).
-                // Creating a temporary provider and then dropping it on the
-                // floor immediately is flawed, but it's the best we can do
-                // for now.
-                synchronized (this) {
-                    SunPKCS11 p = provider;
-                    if (p == null) {
-                        p = newProvider();
-                    }
-                    try {
-                        trust = Secmod.getTrust(p);
-                    } catch (PKCS11Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            }
-            return trust.get(hash);
-        }
-
-        public String toString() {
-            return
-            commonName + " (" + type + ", " + libraryName + ", slot " + slot + ")";
-        }
-
-    }
-
-    /**
-     * Constants representing NSS trust categories.
-     */
-    public static enum TrustType {
-        /** Trusted for all purposes */
-        ALL,
-        /** Trusted for SSL client authentication */
-        CLIENT_AUTH,
-        /** Trusted for SSL server authentication */
-        SERVER_AUTH,
-        /** Trusted for code signing */
-        CODE_SIGNING,
-        /** Trusted for email protection */
-        EMAIL_PROTECTION,
-    }
-
-    public static enum DbMode {
-        READ_WRITE("NSS_InitReadWrite"),
-        READ_ONLY ("NSS_Init"),
-        NO_DB     ("NSS_NoDB_Init");
-
-        final String functionName;
-        DbMode(String functionName) {
-            this.functionName = functionName;
-        }
-    }
-
-    /**
-     * A LoadStoreParameter for use with the NSS Softtoken or
-     * NSS TrustAnchor KeyStores.
-     * <p>
-     * It allows the set of trusted certificates that are returned by
-     * the KeyStore to be specified.
-     */
-    public static final class KeyStoreLoadParameter implements LoadStoreParameter {
-        final TrustType trustType;
-        final ProtectionParameter protection;
-        public KeyStoreLoadParameter(TrustType trustType, char[] password) {
-            this(trustType, new PasswordProtection(password));
-
-        }
-        public KeyStoreLoadParameter(TrustType trustType, ProtectionParameter prot) {
-            if (trustType == null) {
-                throw new NullPointerException("trustType must not be null");
-            }
-            this.trustType = trustType;
-            this.protection = prot;
-        }
-        public ProtectionParameter getProtectionParameter() {
-            return protection;
-        }
-        public TrustType getTrustType() {
-            return trustType;
-        }
-    }
-
-    static class TrustAttributes {
-        final long handle;
-        final long clientAuth, serverAuth, codeSigning, emailProtection;
-        final byte[] shaHash;
-        TrustAttributes(Token token, X509Certificate cert, Bytes bytes, long trustValue) {
-            Session session = null;
-            try {
-                session = token.getOpSession();
-                // XXX use KeyStore TrustType settings to determine which
-                // attributes to set
-                CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                    new CK_ATTRIBUTE(CKA_TOKEN, true),
-                    new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST),
-                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH, trustValue),
-                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING, trustValue),
-                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, trustValue),
-                    new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH, trustValue),
-                    new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH, bytes.b),
-                    new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_MD5_HASH, getDigest(cert, "MD5")),
-                    new CK_ATTRIBUTE(CKA_ISSUER, cert.getIssuerX500Principal().getEncoded()),
-                    new CK_ATTRIBUTE(CKA_SERIAL_NUMBER, cert.getSerialNumber().toByteArray()),
-                    // XXX per PKCS#11 spec, the serial number should be in ASN.1
-                };
-                handle = token.p11.C_CreateObject(session.id(), attrs);
-                shaHash = bytes.b;
-                clientAuth = trustValue;
-                serverAuth = trustValue;
-                codeSigning = trustValue;
-                emailProtection = trustValue;
-            } catch (PKCS11Exception e) {
-                throw new ProviderException("Could not create trust object", e);
-            } finally {
-                token.releaseSession(session);
-            }
-        }
-        TrustAttributes(Token token, Session session, long handle)
-                        throws PKCS11Exception {
-            this.handle = handle;
-            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_SERVER_AUTH),
-                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CODE_SIGNING),
-                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION),
-                new CK_ATTRIBUTE(CKA_NETSCAPE_CERT_SHA1_HASH),
-            };
-
-            token.p11.C_GetAttributeValue(session.id(), handle, attrs);
-            serverAuth = attrs[0].getLong();
-            codeSigning = attrs[1].getLong();
-            emailProtection = attrs[2].getLong();
-            shaHash = attrs[3].getByteArray();
-
-            attrs = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_NETSCAPE_TRUST_CLIENT_AUTH),
-            };
-            long c;
-            try {
-                token.p11.C_GetAttributeValue(session.id(), handle, attrs);
-                c = attrs[0].getLong();
-            } catch (PKCS11Exception e) {
-                // trust anchor module does not support this attribute
-                c = serverAuth;
-            }
-            clientAuth = c;
-        }
-        Bytes getHash() {
-            return new Bytes(shaHash);
-        }
-        boolean isTrusted(TrustType type) {
-            switch (type) {
-            case CLIENT_AUTH:
-                return isTrusted(clientAuth);
-            case SERVER_AUTH:
-                return isTrusted(serverAuth);
-            case CODE_SIGNING:
-                return isTrusted(codeSigning);
-            case EMAIL_PROTECTION:
-                return isTrusted(emailProtection);
-            case ALL:
-                return isTrusted(TrustType.CLIENT_AUTH)
-                    && isTrusted(TrustType.SERVER_AUTH)
-                    && isTrusted(TrustType.CODE_SIGNING)
-                    && isTrusted(TrustType.EMAIL_PROTECTION);
-            default:
-                return false;
-            }
-        }
-
-        private boolean isTrusted(long l) {
-            // XXX CKT_TRUSTED?
-            return (l == CKT_NETSCAPE_TRUSTED_DELEGATOR);
-        }
-
-    }
-
-    private static class Bytes {
-        final byte[] b;
-        Bytes(byte[] b) {
-            this.b = b;
-        }
-        public int hashCode() {
-            return Arrays.hashCode(b);
-        }
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o instanceof Bytes == false) {
-                return false;
-            }
-            Bytes other = (Bytes)o;
-            return Arrays.equals(this.b, other.b);
-        }
-    }
-
-    private static Map<Bytes,TrustAttributes> getTrust(SunPKCS11 provider)
-            throws PKCS11Exception {
-        Map<Bytes,TrustAttributes> trustMap = new HashMap<Bytes,TrustAttributes>();
-        Token token = provider.getToken();
-        Session session = null;
-        boolean exceptionOccurred = true;
-        try {
-            session = token.getOpSession();
-            int MAX_NUM = 8192;
-            CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[] {
-                new CK_ATTRIBUTE(CKA_CLASS, CKO_NETSCAPE_TRUST),
-            };
-            token.p11.C_FindObjectsInit(session.id(), attrs);
-            long[] handles = token.p11.C_FindObjects(session.id(), MAX_NUM);
-            token.p11.C_FindObjectsFinal(session.id());
-            if (DEBUG) System.out.println("handles: " + handles.length);
-
-            for (long handle : handles) {
-                try {
-                    TrustAttributes trust = new TrustAttributes(token, session, handle);
-                    trustMap.put(trust.getHash(), trust);
-                } catch (PKCS11Exception e) {
-                    // skip put on pkcs11 error
-                }
-            }
-            exceptionOccurred = false;
-        } finally {
-            if (exceptionOccurred) {
-                token.killSession(session);
-            } else {
-                token.releaseSession(session);
-            }
-        }
-        return trustMap;
-    }
-
-    private static native long nssGetLibraryHandle(String libraryName);
-
-    private static native long nssLoadLibrary(String name) throws IOException;
-
-    private static native boolean nssVersionCheck(long handle, String minVersion);
-
-    private static native boolean nssInitialize(String functionName, long handle, String configDir, boolean nssOptimizeSpace);
-
-    private static native Object nssGetModuleList(long handle, String libDir);
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/Session.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.lang.ref.*;
-import java.util.*;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import java.security.*;
-
-import sun.security.pkcs11.wrapper.*;
-
-/**
- * A session object. Sessions are obtained via the SessionManager,
- * see there for details. Most code will only ever need one method in
- * this class, the id() method to obtain the session id.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class Session implements Comparable<Session> {
-
-    // time after which to close idle sessions, in milliseconds (3 minutes)
-    private final static long MAX_IDLE_TIME = 3 * 60 * 1000;
-
-    // token instance
-    final Token token;
-
-    // session id
-    private final long id;
-
-    // number of objects created within this session
-    private final AtomicInteger createdObjects;
-
-    // time this session was last used
-    // not synchronized/volatile for performance, so may be unreliable
-    // this could lead to idle sessions being closed early, but that is harmless
-    private long lastAccess;
-
-    private final SessionRef sessionRef;
-
-    Session(Token token, long id) {
-        this.token = token;
-        this.id = id;
-        createdObjects = new AtomicInteger();
-        id();
-        sessionRef = new SessionRef(this, id, token);
-    }
-
-    public int compareTo(Session other) {
-        if (this.lastAccess == other.lastAccess) {
-            return 0;
-        } else {
-            return (this.lastAccess < other.lastAccess) ? -1 : 1;
-        }
-    }
-
-    boolean isLive(long currentTime) {
-        return currentTime - lastAccess < MAX_IDLE_TIME;
-    }
-
-    long idInternal() {
-        return id;
-    }
-
-    long id() {
-        if (token.isPresent(this.id) == false) {
-            throw new ProviderException("Token has been removed");
-        }
-        lastAccess = System.currentTimeMillis();
-        return id;
-    }
-
-    void addObject() {
-        int n = createdObjects.incrementAndGet();
-        // XXX update statistics in session manager if n == 1
-    }
-
-    void removeObject() {
-        int n = createdObjects.decrementAndGet();
-        if (n == 0) {
-            token.sessionManager.demoteObjSession(this);
-        } else if (n < 0) {
-            throw new ProviderException("Internal error: objects created " + n);
-        }
-    }
-
-    boolean hasObjects() {
-        return createdObjects.get() != 0;
-    }
-
-    void close() {
-        if (hasObjects()) {
-            throw new ProviderException(
-                "Internal error: close session with active objects");
-        }
-        sessionRef.dispose();
-    }
-}
-
-/*
- * NOTE: Use PhantomReference here and not WeakReference
- * otherwise the sessions maybe closed before other objects
- * which are still being finalized.
- */
-final class SessionRef extends PhantomReference<Session>
-        implements Comparable<SessionRef> {
-
-    private static ReferenceQueue<Session> refQueue =
-        new ReferenceQueue<Session>();
-
-    private static Set<SessionRef> refList =
-        Collections.synchronizedSortedSet(new TreeSet<SessionRef>());
-
-    static ReferenceQueue<Session> referenceQueue() {
-        return refQueue;
-    }
-
-    static int totalCount() {
-        return refList.size();
-    }
-
-    private static void drainRefQueueBounded() {
-        while (true) {
-            SessionRef next = (SessionRef) refQueue.poll();
-            if (next == null) break;
-            next.dispose();
-        }
-    }
-
-    // handle to the native session
-    private long id;
-    private Token token;
-
-    SessionRef(Session session, long id, Token token) {
-        super(session, refQueue);
-        this.id = id;
-        this.token = token;
-        refList.add(this);
-        // TBD: run at some interval and not every time?
-        drainRefQueueBounded();
-    }
-
-    void dispose() {
-        refList.remove(this);
-        try {
-            if (token.isPresent(id)) {
-                token.p11.C_CloseSession(id);
-            }
-        } catch (PKCS11Exception e1) {
-            // ignore
-        } catch (ProviderException e2) {
-            // ignore
-        } finally {
-            this.clear();
-        }
-    }
-
-    public int compareTo(SessionRef other) {
-        if (this.id == other.id) {
-            return 0;
-        } else {
-            return (this.id < other.id) ? -1 : 1;
-        }
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/SessionManager.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.util.*;
-
-import java.security.ProviderException;
-
-import sun.security.util.Debug;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Session manager. There is one session manager object per PKCS#11
- * provider. It allows code to checkout a session, release it
- * back to the pool, or force it to be closed.
- *
- * The session manager pools sessions to minimize the number of
- * C_OpenSession() and C_CloseSession() that have to be made. It
- * maintains two pools: one for "object" sessions and one for
- * "operation" sessions.
- *
- * The reason for this separation is how PKCS#11 deals with session objects.
- * It defines that when a session is closed, all objects created within
- * that session are destroyed. In other words, we may never close a session
- * while a Key created it in is still in use. We would like to keep the
- * number of such sessions low. Note that we occasionally want to explicitly
- * close a session, see P11Signature.
- *
- * NOTE that sessions obtained from this class SHOULD be returned using
- * either releaseSession() or closeSession() using a finally block when
- * not needed anymore. Otherwise, they will be left for cleanup via the
- * PhantomReference mechanism when GC kicks in, but it's best not to rely
- * on that since GC may not run timely enough since the native PKCS11 library
- * is also consuming memory.
- *
- * Note that sessions are automatically closed when they are not used for a
- * period of time, see Session.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class SessionManager {
-
-    private final static int DEFAULT_MAX_SESSIONS = 32;
-
-    private final static Debug debug = Debug.getInstance("pkcs11");
-
-    // token instance
-    private final Token token;
-
-    // maximum number of sessions to open with this token
-    private final int maxSessions;
-
-    // total number of active sessions
-    private AtomicInteger activeSessions = new AtomicInteger();
-
-    // pool of available object sessions
-    private final Pool objSessions;
-
-    // pool of available operation sessions
-    private final Pool opSessions;
-
-    // maximum number of active sessions during this invocation, for debugging
-    private int maxActiveSessions;
-    private Object maxActiveSessionsLock;
-
-    // flags to use in the C_OpenSession() call
-    private final long openSessionFlags;
-
-    SessionManager(Token token) {
-        long n;
-        if (token.isWriteProtected()) {
-            openSessionFlags = CKF_SERIAL_SESSION;
-            n = token.tokenInfo.ulMaxSessionCount;
-        } else {
-            openSessionFlags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
-            n = token.tokenInfo.ulMaxRwSessionCount;
-        }
-        if (n == CK_EFFECTIVELY_INFINITE) {
-            n = Integer.MAX_VALUE;
-        } else if ((n == CK_UNAVAILABLE_INFORMATION) || (n < 0)) {
-            // choose an arbitrary concrete value
-            n = DEFAULT_MAX_SESSIONS;
-        }
-        maxSessions = (int)Math.min(n, Integer.MAX_VALUE);
-        this.token = token;
-        this.objSessions = new Pool(this, true);
-        this.opSessions = new Pool(this, false);
-        if (debug != null) {
-            maxActiveSessionsLock = new Object();
-        }
-    }
-
-    // returns whether only a fairly low number of sessions are
-    // supported by this token.
-    boolean lowMaxSessions() {
-        return (maxSessions <= DEFAULT_MAX_SESSIONS);
-    }
-
-    Session getObjSession() throws PKCS11Exception {
-        Session session = objSessions.poll();
-        if (session != null) {
-            return ensureValid(session);
-        }
-        session = opSessions.poll();
-        if (session != null) {
-            return ensureValid(session);
-        }
-        session = openSession();
-        return ensureValid(session);
-    }
-
-    Session getOpSession() throws PKCS11Exception {
-        Session session = opSessions.poll();
-        if (session != null) {
-            return ensureValid(session);
-        }
-        // create a new session rather than re-using an obj session
-        // that avoids potential expensive cancels() for Signatures & RSACipher
-        if (maxSessions == Integer.MAX_VALUE ||
-                activeSessions.get() < maxSessions) {
-            session = openSession();
-            return ensureValid(session);
-        }
-        session = objSessions.poll();
-        if (session != null) {
-            return ensureValid(session);
-        }
-        throw new ProviderException("Could not obtain session");
-    }
-
-    private Session ensureValid(Session session) {
-        session.id();
-        return session;
-    }
-
-    Session killSession(Session session) {
-        if ((session == null) || (token.isValid() == false)) {
-            return null;
-        }
-        if (debug != null) {
-            String location = new Exception().getStackTrace()[2].toString();
-            System.out.println("Killing session (" + location + ") active: "
-                + activeSessions.get());
-        }
-        closeSession(session);
-        return null;
-    }
-
-    Session releaseSession(Session session) {
-        if ((session == null) || (token.isValid() == false)) {
-            return null;
-        }
-
-        if (session.hasObjects()) {
-            objSessions.release(session);
-        } else {
-            opSessions.release(session);
-        }
-        return null;
-    }
-
-    void demoteObjSession(Session session) {
-        if (token.isValid() == false) {
-            return;
-        }
-        if (debug != null) {
-            System.out.println("Demoting session, active: " +
-                activeSessions.get());
-        }
-        boolean present = objSessions.remove(session);
-        if (present == false) {
-            // session is currently in use
-            // will be added to correct pool on release, nothing to do now
-            return;
-        }
-        opSessions.release(session);
-    }
-
-    private Session openSession() throws PKCS11Exception {
-        if ((maxSessions != Integer.MAX_VALUE) &&
-                (activeSessions.get() >= maxSessions)) {
-            throw new ProviderException("No more sessions available");
-        }
-
-        long id = token.p11.C_OpenSession
-                    (token.provider.slotID, openSessionFlags, null, null);
-        Session session = new Session(token, id);
-        activeSessions.incrementAndGet();
-        if (debug != null) {
-            synchronized(maxActiveSessionsLock) {
-                if (activeSessions.get() > maxActiveSessions) {
-                    maxActiveSessions = activeSessions.get();
-                    if (maxActiveSessions % 10 == 0) {
-                        System.out.println("Open sessions: " + maxActiveSessions);
-                    }
-                }
-            }
-        }
-        return session;
-    }
-
-    private void closeSession(Session session) {
-        session.close();
-        activeSessions.decrementAndGet();
-    }
-
-    public static final class Pool {
-
-        private final SessionManager mgr;
-        private final AbstractQueue<Session> pool;
-        private final int SESSION_MAX = 5;
-
-        // Object session pools can contain unlimited sessions.
-        // Operation session pools are limited and enforced by the queue.
-        Pool(SessionManager mgr, boolean obj) {
-            this.mgr = mgr;
-            if (obj) {
-                pool = new LinkedBlockingQueue<Session>();
-            } else {
-                pool = new LinkedBlockingQueue<Session>(SESSION_MAX);
-            }
-        }
-
-        boolean remove(Session session) {
-            return pool.remove(session);
-        }
-
-        Session poll() {
-            return pool.poll();
-        }
-
-        void release(Session session) {
-            // Object session pools never return false, only Operation ones
-            if (!pool.offer(session)) {
-                mgr.closeSession(session);
-                free();
-            }
-        }
-
-        // Free any old operation session if this queue is full
-        void free() {
-            int n = SESSION_MAX;
-            int i = 0;
-            Session oldestSession;
-            long time = System.currentTimeMillis();
-            // Check if the session head is too old and continue through pool
-            // until only one is left.
-            do {
-                oldestSession = pool.peek();
-                if (oldestSession == null || oldestSession.isLive(time) ||
-                        !pool.remove(oldestSession)) {
-                    break;
-                }
-
-                i++;
-                mgr.closeSession(oldestSession);
-            } while ((n - i) > 1);
-
-            if (debug != null) {
-                System.out.println("Closing " + i + " idle sessions, active: "
-                        + mgr.activeSessions);
-            }
-        }
-
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/SunPKCS11.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1506 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.io.*;
-import java.util.*;
-
-import java.security.*;
-import java.security.interfaces.*;
-
-import javax.crypto.interfaces.*;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.login.FailedLoginException;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.ConfirmationCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.TextOutputCallback;
-
-import sun.security.util.Debug;
-import sun.security.util.ResourcesMgr;
-import static sun.security.util.SecurityConstants.PROVIDER_VER;
-
-import sun.security.pkcs11.Secmod.*;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * PKCS#11 provider main class.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-public final class SunPKCS11 extends AuthProvider {
-
-    private static final long serialVersionUID = -1354835039035306505L;
-
-    static final Debug debug = Debug.getInstance("sunpkcs11");
-
-    // the PKCS11 object through which we make the native calls
-    final PKCS11 p11;
-
-    // configuration information
-    final Config config;
-
-    // id of the PKCS#11 slot we are using
-    final long slotID;
-
-    private CallbackHandler pHandler;
-    private final Object LOCK_HANDLER = new Object();
-
-    final boolean removable;
-
-    final Module nssModule;
-
-    final boolean nssUseSecmodTrust;
-
-    private volatile Token token;
-
-    private TokenPoller poller;
-
-    Token getToken() {
-        return token;
-    }
-
-    public SunPKCS11() {
-        super("SunPKCS11", PROVIDER_VER,
-            "Unconfigured and unusable PKCS11 provider");
-        p11 = null;
-        config = null;
-        slotID = 0;
-        pHandler = null;
-        removable = false;
-        nssModule = null;
-        nssUseSecmodTrust = false;
-        token = null;
-        poller = null;
-    }
-
-    @Override
-    public Provider configure(String configArg) throws InvalidParameterException {
-        final String newConfigName = checkNull(configArg);
-        try {
-            return AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
-                @Override
-                public SunPKCS11 run() throws Exception {
-                    return new SunPKCS11(new Config(newConfigName));
-                }
-            });
-        } catch (PrivilegedActionException pae) {
-            InvalidParameterException ipe =
-                new InvalidParameterException("Error configuring SunPKCS11 provider");
-            throw (InvalidParameterException) ipe.initCause(pae.getException());
-        }
-    }
-
-    @Override
-    public boolean isConfigured() {
-        return (config != null);
-    }
-
-    private static <T> T checkNull(T obj) {
-        if (obj == null) {
-            throw new NullPointerException();
-        }
-        return obj;
-    }
-
-    // Used by Secmod
-    SunPKCS11(Config c) {
-        super("SunPKCS11-" + c.getName(), PROVIDER_VER, c.getDescription());
-        this.config = c;
-
-        if (debug != null) {
-            System.out.println("SunPKCS11 loading " + config.getFileName());
-        }
-
-        String library = config.getLibrary();
-        String functionList = config.getFunctionList();
-        long slotID = config.getSlotID();
-        int slotListIndex = config.getSlotListIndex();
-
-        boolean useSecmod = config.getNssUseSecmod();
-        boolean nssUseSecmodTrust = config.getNssUseSecmodTrust();
-        Module nssModule = null;
-
-        //
-        // Initialization via Secmod. The way this works is as follows:
-        // SunPKCS11 is either in normal mode or in NSS Secmod mode.
-        // Secmod is activated by specifying one or more of the following
-        // options in the config file:
-        // nssUseSecmod, nssSecmodDirectory, nssLibrary, nssModule
-        //
-        // XXX add more explanation here
-        //
-        // If we are in Secmod mode and configured to use either the
-        // nssKeyStore or the nssTrustAnchors module, we automatically
-        // switch to using the NSS trust attributes for trusted certs
-        // (KeyStore).
-        //
-
-        if (useSecmod) {
-            // note: Config ensures library/slot/slotListIndex not specified
-            // in secmod mode.
-            Secmod secmod = Secmod.getInstance();
-            DbMode nssDbMode = config.getNssDbMode();
-            try {
-                String nssLibraryDirectory = config.getNssLibraryDirectory();
-                String nssSecmodDirectory = config.getNssSecmodDirectory();
-                boolean nssOptimizeSpace = config.getNssOptimizeSpace();
-
-                if (secmod.isInitialized()) {
-                    if (nssSecmodDirectory != null) {
-                        String s = secmod.getConfigDir();
-                        if ((s != null) &&
-                                (s.equals(nssSecmodDirectory) == false)) {
-                            throw new ProviderException("Secmod directory "
-                                + nssSecmodDirectory
-                                + " invalid, NSS already initialized with "
-                                + s);
-                        }
-                    }
-                    if (nssLibraryDirectory != null) {
-                        String s = secmod.getLibDir();
-                        if ((s != null) &&
-                                (s.equals(nssLibraryDirectory) == false)) {
-                            throw new ProviderException("NSS library directory "
-                                + nssLibraryDirectory
-                                + " invalid, NSS already initialized with "
-                                + s);
-                        }
-                    }
-                } else {
-                    if (nssDbMode != DbMode.NO_DB) {
-                        if (nssSecmodDirectory == null) {
-                            throw new ProviderException(
-                                "Secmod not initialized and "
-                                 + "nssSecmodDirectory not specified");
-                        }
-                    } else {
-                        if (nssSecmodDirectory != null) {
-                            throw new ProviderException(
-                                "nssSecmodDirectory must not be "
-                                + "specified in noDb mode");
-                        }
-                    }
-                    secmod.initialize(nssDbMode, nssSecmodDirectory,
-                        nssLibraryDirectory, nssOptimizeSpace);
-                }
-            } catch (IOException e) {
-                // XXX which exception to throw
-                throw new ProviderException("Could not initialize NSS", e);
-            }
-            List<Module> modules = secmod.getModules();
-            if (config.getShowInfo()) {
-                System.out.println("NSS modules: " + modules);
-            }
-
-            String moduleName = config.getNssModule();
-            if (moduleName == null) {
-                nssModule = secmod.getModule(ModuleType.FIPS);
-                if (nssModule != null) {
-                    moduleName = "fips";
-                } else {
-                    moduleName = (nssDbMode == DbMode.NO_DB) ?
-                        "crypto" : "keystore";
-                }
-            }
-            if (moduleName.equals("fips")) {
-                nssModule = secmod.getModule(ModuleType.FIPS);
-                nssUseSecmodTrust = true;
-                functionList = "FC_GetFunctionList";
-            } else if (moduleName.equals("keystore")) {
-                nssModule = secmod.getModule(ModuleType.KEYSTORE);
-                nssUseSecmodTrust = true;
-            } else if (moduleName.equals("crypto")) {
-                nssModule = secmod.getModule(ModuleType.CRYPTO);
-            } else if (moduleName.equals("trustanchors")) {
-                // XXX should the option be called trustanchor or trustanchors??
-                nssModule = secmod.getModule(ModuleType.TRUSTANCHOR);
-                nssUseSecmodTrust = true;
-            } else if (moduleName.startsWith("external-")) {
-                int moduleIndex;
-                try {
-                    moduleIndex = Integer.parseInt
-                            (moduleName.substring("external-".length()));
-                } catch (NumberFormatException e) {
-                    moduleIndex = -1;
-                }
-                if (moduleIndex < 1) {
-                    throw new ProviderException
-                            ("Invalid external module: " + moduleName);
-                }
-                int k = 0;
-                for (Module module : modules) {
-                    if (module.getType() == ModuleType.EXTERNAL) {
-                        if (++k == moduleIndex) {
-                            nssModule = module;
-                            break;
-                        }
-                    }
-                }
-                if (nssModule == null) {
-                    throw new ProviderException("Invalid module " + moduleName
-                        + ": only " + k + " external NSS modules available");
-                }
-            } else {
-                throw new ProviderException(
-                    "Unknown NSS module: " + moduleName);
-            }
-            if (nssModule == null) {
-                throw new ProviderException(
-                    "NSS module not available: " + moduleName);
-            }
-            if (nssModule.hasInitializedProvider()) {
-                throw new ProviderException("Secmod module already configured");
-            }
-            library = nssModule.libraryName;
-            slotListIndex = nssModule.slot;
-        }
-        this.nssUseSecmodTrust = nssUseSecmodTrust;
-        this.nssModule = nssModule;
-
-        File libraryFile = new File(library);
-        // if the filename is a simple filename without path
-        // (e.g. "libpkcs11.so"), it may refer to a library somewhere on the
-        // OS library search path. Omit the test for file existance as that
-        // only looks in the current directory.
-        if (libraryFile.getName().equals(library) == false) {
-            if (new File(library).isFile() == false) {
-                String msg = "Library " + library + " does not exist";
-                if (config.getHandleStartupErrors() == Config.ERR_HALT) {
-                    throw new ProviderException(msg);
-                } else {
-                    throw new UnsupportedOperationException(msg);
-                }
-            }
-        }
-
-        try {
-            if (debug != null) {
-                debug.println("Initializing PKCS#11 library " + library);
-            }
-            CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
-            String nssArgs = config.getNssArgs();
-            if (nssArgs != null) {
-                initArgs.pReserved = nssArgs;
-            }
-            // request multithreaded access first
-            initArgs.flags = CKF_OS_LOCKING_OK;
-            PKCS11 tmpPKCS11;
-            try {
-                tmpPKCS11 = PKCS11.getInstance(
-                    library, functionList, initArgs,
-                    config.getOmitInitialize());
-            } catch (PKCS11Exception e) {
-                if (debug != null) {
-                    debug.println("Multi-threaded initialization failed: " + e);
-                }
-                if (config.getAllowSingleThreadedModules() == false) {
-                    throw e;
-                }
-                // fall back to single threaded access
-                if (nssArgs == null) {
-                    // if possible, use null initArgs for better compatibility
-                    initArgs = null;
-                } else {
-                    initArgs.flags = 0;
-                }
-                tmpPKCS11 = PKCS11.getInstance(library,
-                    functionList, initArgs, config.getOmitInitialize());
-            }
-            p11 = tmpPKCS11;
-
-            CK_INFO p11Info = p11.C_GetInfo();
-            if (p11Info.cryptokiVersion.major < 2) {
-                throw new ProviderException("Only PKCS#11 v2.0 and later "
-                + "supported, library version is v" + p11Info.cryptokiVersion);
-            }
-            boolean showInfo = config.getShowInfo();
-            if (showInfo) {
-                System.out.println("Information for provider " + getName());
-                System.out.println("Library info:");
-                System.out.println(p11Info);
-            }
-
-            if ((slotID < 0) || showInfo) {
-                long[] slots = p11.C_GetSlotList(false);
-                if (showInfo) {
-                    System.out.println("All slots: " + toString(slots));
-                    slots = p11.C_GetSlotList(true);
-                    System.out.println("Slots with tokens: " + toString(slots));
-                }
-                if (slotID < 0) {
-                    if ((slotListIndex < 0)
-                            || (slotListIndex >= slots.length)) {
-                        throw new ProviderException("slotListIndex is "
-                            + slotListIndex
-                            + " but token only has " + slots.length + " slots");
-                    }
-                    slotID = slots[slotListIndex];
-                }
-            }
-            this.slotID = slotID;
-            CK_SLOT_INFO slotInfo = p11.C_GetSlotInfo(slotID);
-            removable = (slotInfo.flags & CKF_REMOVABLE_DEVICE) != 0;
-            initToken(slotInfo);
-            if (nssModule != null) {
-                nssModule.setProvider(this);
-            }
-        } catch (Exception e) {
-            if (config.getHandleStartupErrors() == Config.ERR_IGNORE_ALL) {
-                throw new UnsupportedOperationException
-                        ("Initialization failed", e);
-            } else {
-                throw new ProviderException
-                        ("Initialization failed", e);
-            }
-        }
-    }
-
-    private static String toString(long[] longs) {
-        if (longs.length == 0) {
-            return "(none)";
-        }
-        StringBuilder sb = new StringBuilder();
-        sb.append(longs[0]);
-        for (int i = 1; i < longs.length; i++) {
-            sb.append(", ");
-            sb.append(longs[i]);
-        }
-        return sb.toString();
-    }
-
-    public boolean equals(Object obj) {
-        return this == obj;
-    }
-
-    public int hashCode() {
-        return System.identityHashCode(this);
-    }
-
-    private static String[] s(String ...aliases) {
-        return aliases;
-    }
-
-    private static final class Descriptor {
-        final String type;
-        final String algorithm;
-        final String className;
-        final String[] aliases;
-        final int[] mechanisms;
-
-        private Descriptor(String type, String algorithm, String className,
-                String[] aliases, int[] mechanisms) {
-            this.type = type;
-            this.algorithm = algorithm;
-            this.className = className;
-            this.aliases = aliases;
-            this.mechanisms = mechanisms;
-        }
-        private P11Service service(Token token, int mechanism) {
-            return new P11Service
-                (token, type, algorithm, className, aliases, mechanism);
-        }
-        public String toString() {
-            return type + "." + algorithm;
-        }
-    }
-
-    // Map from mechanism to List of Descriptors that should be
-    // registered if the mechanism is supported
-    private final static Map<Integer,List<Descriptor>> descriptors =
-        new HashMap<Integer,List<Descriptor>>();
-
-    private static int[] m(long m1) {
-        return new int[] {(int)m1};
-    }
-
-    private static int[] m(long m1, long m2) {
-        return new int[] {(int)m1, (int)m2};
-    }
-
-    private static int[] m(long m1, long m2, long m3) {
-        return new int[] {(int)m1, (int)m2, (int)m3};
-    }
-
-    private static int[] m(long m1, long m2, long m3, long m4) {
-        return new int[] {(int)m1, (int)m2, (int)m3, (int)m4};
-    }
-
-    private static void d(String type, String algorithm, String className,
-            int[] m) {
-        register(new Descriptor(type, algorithm, className, null, m));
-    }
-
-    private static void d(String type, String algorithm, String className,
-            String[] aliases, int[] m) {
-        register(new Descriptor(type, algorithm, className, aliases, m));
-    }
-
-    private static void register(Descriptor d) {
-        for (int i = 0; i < d.mechanisms.length; i++) {
-            int m = d.mechanisms[i];
-            Integer key = Integer.valueOf(m);
-            List<Descriptor> list = descriptors.get(key);
-            if (list == null) {
-                list = new ArrayList<Descriptor>();
-                descriptors.put(key, list);
-            }
-            list.add(d);
-        }
-    }
-
-    private final static String MD  = "MessageDigest";
-
-    private final static String SIG = "Signature";
-
-    private final static String KPG = "KeyPairGenerator";
-
-    private final static String KG  = "KeyGenerator";
-
-    private final static String AGP = "AlgorithmParameters";
-
-    private final static String KF  = "KeyFactory";
-
-    private final static String SKF = "SecretKeyFactory";
-
-    private final static String CIP = "Cipher";
-
-    private final static String MAC = "Mac";
-
-    private final static String KA  = "KeyAgreement";
-
-    private final static String KS  = "KeyStore";
-
-    private final static String SR  = "SecureRandom";
-
-    static {
-        // names of all the implementation classes
-        // use local variables, only used here
-        String P11Digest           = "sun.security.pkcs11.P11Digest";
-        String P11MAC              = "sun.security.pkcs11.P11MAC";
-        String P11KeyPairGenerator = "sun.security.pkcs11.P11KeyPairGenerator";
-        String P11KeyGenerator     = "sun.security.pkcs11.P11KeyGenerator";
-        String P11RSAKeyFactory    = "sun.security.pkcs11.P11RSAKeyFactory";
-        String P11DSAKeyFactory    = "sun.security.pkcs11.P11DSAKeyFactory";
-        String P11DHKeyFactory     = "sun.security.pkcs11.P11DHKeyFactory";
-        String P11KeyAgreement     = "sun.security.pkcs11.P11KeyAgreement";
-        String P11SecretKeyFactory = "sun.security.pkcs11.P11SecretKeyFactory";
-        String P11Cipher           = "sun.security.pkcs11.P11Cipher";
-        String P11RSACipher        = "sun.security.pkcs11.P11RSACipher";
-        String P11Signature        = "sun.security.pkcs11.P11Signature";
-
-        // XXX register all aliases
-
-        d(MD, "MD2",            P11Digest,
-                m(CKM_MD2));
-        d(MD, "MD5",            P11Digest,
-                m(CKM_MD5));
-        d(MD, "SHA1",           P11Digest,
-                s("SHA", "SHA-1", "1.3.14.3.2.26", "OID.1.3.14.3.2.26"),
-                m(CKM_SHA_1));
-
-        d(MD, "SHA-224",        P11Digest,
-                s("2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4"),
-                m(CKM_SHA224));
-        d(MD, "SHA-256",        P11Digest,
-                s("2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1"),
-                m(CKM_SHA256));
-        d(MD, "SHA-384",        P11Digest,
-                s("2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2"),
-                m(CKM_SHA384));
-        d(MD, "SHA-512",        P11Digest,
-                s("2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3"),
-                m(CKM_SHA512));
-
-        d(MAC, "HmacMD5",       P11MAC,
-                m(CKM_MD5_HMAC));
-        d(MAC, "HmacSHA1",      P11MAC,
-                s("1.2.840.113549.2.7", "OID.1.2.840.113549.2.7"),
-                m(CKM_SHA_1_HMAC));
-        d(MAC, "HmacSHA224",    P11MAC,
-                s("1.2.840.113549.2.8", "OID.1.2.840.113549.2.8"),
-                m(CKM_SHA224_HMAC));
-        d(MAC, "HmacSHA256",    P11MAC,
-                s("1.2.840.113549.2.9", "OID.1.2.840.113549.2.9"),
-                m(CKM_SHA256_HMAC));
-        d(MAC, "HmacSHA384",    P11MAC,
-                s("1.2.840.113549.2.10", "OID.1.2.840.113549.2.10"),
-                m(CKM_SHA384_HMAC));
-        d(MAC, "HmacSHA512",    P11MAC,
-                s("1.2.840.113549.2.11", "OID.1.2.840.113549.2.11"),
-                m(CKM_SHA512_HMAC));
-        d(MAC, "SslMacMD5",     P11MAC,
-                m(CKM_SSL3_MD5_MAC));
-        d(MAC, "SslMacSHA1",    P11MAC,
-                m(CKM_SSL3_SHA1_MAC));
-
-        d(KPG, "RSA",           P11KeyPairGenerator,
-                m(CKM_RSA_PKCS_KEY_PAIR_GEN));
-        d(KPG, "DSA",           P11KeyPairGenerator,
-                s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
-                m(CKM_DSA_KEY_PAIR_GEN));
-        d(KPG, "DH",            P11KeyPairGenerator,    s("DiffieHellman"),
-                m(CKM_DH_PKCS_KEY_PAIR_GEN));
-        d(KPG, "EC",            P11KeyPairGenerator,
-                m(CKM_EC_KEY_PAIR_GEN));
-
-        d(KG,  "ARCFOUR",       P11KeyGenerator,        s("RC4"),
-                m(CKM_RC4_KEY_GEN));
-        d(KG,  "DES",           P11KeyGenerator,
-                m(CKM_DES_KEY_GEN));
-        d(KG,  "DESede",        P11KeyGenerator,
-                m(CKM_DES3_KEY_GEN, CKM_DES2_KEY_GEN));
-        d(KG,  "AES",           P11KeyGenerator,
-                m(CKM_AES_KEY_GEN));
-        d(KG,  "Blowfish",      P11KeyGenerator,
-                m(CKM_BLOWFISH_KEY_GEN));
-
-        // register (Secret)KeyFactories if there are any mechanisms
-        // for a particular algorithm that we support
-        d(KF, "RSA",            P11RSAKeyFactory,
-                m(CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_RSA_PKCS, CKM_RSA_X_509));
-        d(KF, "DSA",            P11DSAKeyFactory,
-                s("1.3.14.3.2.12", "1.2.840.10040.4.1", "OID.1.2.840.10040.4.1"),
-                m(CKM_DSA_KEY_PAIR_GEN, CKM_DSA, CKM_DSA_SHA1));
-        d(KF, "DH",             P11DHKeyFactory,        s("DiffieHellman"),
-                m(CKM_DH_PKCS_KEY_PAIR_GEN, CKM_DH_PKCS_DERIVE));
-        d(KF, "EC",             P11DHKeyFactory,
-                m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
-                    CKM_ECDSA, CKM_ECDSA_SHA1));
-
-        // AlgorithmParameters for EC.
-        // Only needed until we have an EC implementation in the SUN provider.
-        d(AGP, "EC",            "sun.security.util.ECParameters",
-                                                s("1.2.840.10045.2.1"),
-                m(CKM_EC_KEY_PAIR_GEN, CKM_ECDH1_DERIVE,
-                    CKM_ECDSA, CKM_ECDSA_SHA1));
-
-        d(KA, "DH",             P11KeyAgreement,        s("DiffieHellman"),
-                m(CKM_DH_PKCS_DERIVE));
-        d(KA, "ECDH",           "sun.security.pkcs11.P11ECDHKeyAgreement",
-                m(CKM_ECDH1_DERIVE));
-
-        d(SKF, "ARCFOUR",       P11SecretKeyFactory,    s("RC4"),
-                m(CKM_RC4));
-        d(SKF, "DES",           P11SecretKeyFactory,
-                m(CKM_DES_CBC));
-        d(SKF, "DESede",        P11SecretKeyFactory,
-                m(CKM_DES3_CBC));
-        d(SKF, "AES",           P11SecretKeyFactory,
-                s("2.16.840.1.101.3.4.1", "OID.2.16.840.1.101.3.4.1"),
-                m(CKM_AES_CBC));
-        d(SKF, "Blowfish",      P11SecretKeyFactory,
-                m(CKM_BLOWFISH_CBC));
-
-        // XXX attributes for Ciphers (supported modes, padding)
-        d(CIP, "ARCFOUR",                       P11Cipher,      s("RC4"),
-                m(CKM_RC4));
-        d(CIP, "DES/CBC/NoPadding",             P11Cipher,
-                m(CKM_DES_CBC));
-        d(CIP, "DES/CBC/PKCS5Padding",          P11Cipher,
-                m(CKM_DES_CBC_PAD, CKM_DES_CBC));
-        d(CIP, "DES/ECB/NoPadding",             P11Cipher,
-                m(CKM_DES_ECB));
-        d(CIP, "DES/ECB/PKCS5Padding",          P11Cipher,      s("DES"),
-                m(CKM_DES_ECB));
-
-        d(CIP, "DESede/CBC/NoPadding",          P11Cipher,
-                m(CKM_DES3_CBC));
-        d(CIP, "DESede/CBC/PKCS5Padding",       P11Cipher,
-                m(CKM_DES3_CBC_PAD, CKM_DES3_CBC));
-        d(CIP, "DESede/ECB/NoPadding",          P11Cipher,
-                m(CKM_DES3_ECB));
-        d(CIP, "DESede/ECB/PKCS5Padding",       P11Cipher,      s("DESede"),
-                m(CKM_DES3_ECB));
-        d(CIP, "AES/CBC/NoPadding",             P11Cipher,
-                m(CKM_AES_CBC));
-        d(CIP, "AES_128/CBC/NoPadding",          P11Cipher,
-                s("2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"),
-                m(CKM_AES_CBC));
-        d(CIP, "AES_192/CBC/NoPadding",          P11Cipher,
-                s("2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"),
-                m(CKM_AES_CBC));
-        d(CIP, "AES_256/CBC/NoPadding",          P11Cipher,
-                s("2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42"),
-                m(CKM_AES_CBC));
-        d(CIP, "AES/CBC/PKCS5Padding",          P11Cipher,
-                m(CKM_AES_CBC_PAD, CKM_AES_CBC));
-        d(CIP, "AES/ECB/NoPadding",             P11Cipher,
-                m(CKM_AES_ECB));
-        d(CIP, "AES_128/ECB/NoPadding",          P11Cipher,
-                s("2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"),
-                m(CKM_AES_ECB));
-        d(CIP, "AES_192/ECB/NoPadding",          P11Cipher,
-                s("2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"),
-                m(CKM_AES_ECB));
-        d(CIP, "AES_256/ECB/NoPadding",          P11Cipher,
-                s("2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41"),
-                m(CKM_AES_ECB));
-        d(CIP, "AES/ECB/PKCS5Padding",          P11Cipher,      s("AES"),
-                m(CKM_AES_ECB));
-        d(CIP, "AES/CTR/NoPadding",             P11Cipher,
-                m(CKM_AES_CTR));
-        d(CIP, "Blowfish/CBC/NoPadding",        P11Cipher,
-                m(CKM_BLOWFISH_CBC));
-        d(CIP, "Blowfish/CBC/PKCS5Padding",     P11Cipher,
-                m(CKM_BLOWFISH_CBC));
-
-        // XXX RSA_X_509, RSA_OAEP not yet supported
-        d(CIP, "RSA/ECB/PKCS1Padding",          P11RSACipher,   s("RSA"),
-                m(CKM_RSA_PKCS));
-        d(CIP, "RSA/ECB/NoPadding",             P11RSACipher,
-                m(CKM_RSA_X_509));
-
-        d(SIG, "RawDSA",        P11Signature,   s("NONEwithDSA"),
-                m(CKM_DSA));
-        d(SIG, "DSA",           P11Signature,
-                s("SHA1withDSA", "1.3.14.3.2.13", "1.3.14.3.2.27",
-                  "1.2.840.10040.4.3", "OID.1.2.840.10040.4.3"),
-                m(CKM_DSA_SHA1, CKM_DSA));
-        d(SIG, "RawDSAinP1363Format",   P11Signature,
-                s("NONEwithDSAinP1363Format"),
-                m(CKM_DSA));
-        d(SIG, "DSAinP1363Format",      P11Signature,
-                s("SHA1withDSAinP1363Format"),
-                m(CKM_DSA_SHA1, CKM_DSA));
-        d(SIG, "NONEwithECDSA", P11Signature,
-                m(CKM_ECDSA));
-        d(SIG, "SHA1withECDSA", P11Signature,
-                s("ECDSA", "1.2.840.10045.4.1", "OID.1.2.840.10045.4.1"),
-                m(CKM_ECDSA_SHA1, CKM_ECDSA));
-        d(SIG, "SHA224withECDSA",       P11Signature,
-                s("1.2.840.10045.4.3.1", "OID.1.2.840.10045.4.3.1"),
-                m(CKM_ECDSA));
-        d(SIG, "SHA256withECDSA",       P11Signature,
-                s("1.2.840.10045.4.3.2", "OID.1.2.840.10045.4.3.2"),
-                m(CKM_ECDSA));
-        d(SIG, "SHA384withECDSA",       P11Signature,
-                s("1.2.840.10045.4.3.3", "OID.1.2.840.10045.4.3.3"),
-                m(CKM_ECDSA));
-        d(SIG, "SHA512withECDSA",       P11Signature,
-                s("1.2.840.10045.4.3.4", "OID.1.2.840.10045.4.3.4"),
-                m(CKM_ECDSA));
-        d(SIG, "NONEwithECDSAinP1363Format",   P11Signature,
-                m(CKM_ECDSA));
-        d(SIG, "SHA1withECDSAinP1363Format",   P11Signature,
-                m(CKM_ECDSA_SHA1, CKM_ECDSA));
-        d(SIG, "SHA224withECDSAinP1363Format", P11Signature,
-                m(CKM_ECDSA));
-        d(SIG, "SHA256withECDSAinP1363Format", P11Signature,
-                m(CKM_ECDSA));
-        d(SIG, "SHA384withECDSAinP1363Format", P11Signature,
-                m(CKM_ECDSA));
-        d(SIG, "SHA512withECDSAinP1363Format", P11Signature,
-                m(CKM_ECDSA));
-        d(SIG, "MD2withRSA",    P11Signature,
-                s("1.2.840.113549.1.1.2", "OID.1.2.840.113549.1.1.2"),
-                m(CKM_MD2_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
-        d(SIG, "MD5withRSA",    P11Signature,
-                s("1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4"),
-                m(CKM_MD5_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
-        d(SIG, "SHA1withRSA",   P11Signature,
-                s("1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5",
-                  "1.3.14.3.2.29"),
-                m(CKM_SHA1_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
-        d(SIG, "SHA224withRSA", P11Signature,
-                s("1.2.840.113549.1.1.14", "OID.1.2.840.113549.1.1.14"),
-                m(CKM_SHA224_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
-        d(SIG, "SHA256withRSA", P11Signature,
-                s("1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11"),
-                m(CKM_SHA256_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
-        d(SIG, "SHA384withRSA", P11Signature,
-                s("1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12"),
-                m(CKM_SHA384_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
-        d(SIG, "SHA512withRSA", P11Signature,
-                s("1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13"),
-                m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
-
-        /*
-         * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the
-         * PRF calculations.  As of 2010, there is no PKCS11-level
-         * support for TLS 1.2 PRF calculations, and no known OS's have
-         * an internal variant we could use.  Therefore for TLS 1.2, we
-         * are updating JSSE to request different provider algorithms
-         * (e.g. "SunTls12Prf"), and currently only SunJCE has these
-         * TLS 1.2 algorithms.
-         *
-         * If we reused the names such as "SunTlsPrf", the PKCS11
-         * providers would need be updated to fail correctly when
-         * presented with the wrong version number (via
-         * Provider.Service.supportsParameters()), and we would also
-         * need to add the appropriate supportsParamters() checks into
-         * KeyGenerators (not currently there).
-         *
-         * In the future, if PKCS11 support is added, we will restructure
-         * this.
-         */
-        d(KG, "SunTlsRsaPremasterSecret",
-                    "sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
-                m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN));
-        d(KG, "SunTlsMasterSecret",
-                    "sun.security.pkcs11.P11TlsMasterSecretGenerator",
-                m(CKM_SSL3_MASTER_KEY_DERIVE, CKM_TLS_MASTER_KEY_DERIVE,
-                    CKM_SSL3_MASTER_KEY_DERIVE_DH,
-                    CKM_TLS_MASTER_KEY_DERIVE_DH));
-        d(KG, "SunTlsKeyMaterial",
-                    "sun.security.pkcs11.P11TlsKeyMaterialGenerator",
-                m(CKM_SSL3_KEY_AND_MAC_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE));
-        d(KG, "SunTlsPrf", "sun.security.pkcs11.P11TlsPrfGenerator",
-                m(CKM_TLS_PRF, CKM_NSS_TLS_PRF_GENERAL));
-    }
-
-    // background thread that periodically checks for token insertion
-    // if no token is present. We need to do that in a separate thread because
-    // the insertion check may block for quite a long time on some tokens.
-    private static class TokenPoller implements Runnable {
-        private final SunPKCS11 provider;
-        private volatile boolean enabled;
-        private TokenPoller(SunPKCS11 provider) {
-            this.provider = provider;
-            enabled = true;
-        }
-        public void run() {
-            int interval = provider.config.getInsertionCheckInterval();
-            while (enabled) {
-                try {
-                    Thread.sleep(interval);
-                } catch (InterruptedException e) {
-                    break;
-                }
-                if (enabled == false) {
-                    break;
-                }
-                try {
-                    provider.initToken(null);
-                } catch (PKCS11Exception e) {
-                    // ignore
-                }
-            }
-        }
-        void disable() {
-            enabled = false;
-        }
-    }
-
-    // create the poller thread, if not already active
-    private void createPoller() {
-        if (poller != null) {
-            return;
-        }
-        final TokenPoller poller = new TokenPoller(this);
-        Thread t = new Thread(null, poller, "Poller " + getName(), 0, false);
-        t.setContextClassLoader(null);
-        t.setDaemon(true);
-        t.setPriority(Thread.MIN_PRIORITY);
-        t.start();
-        this.poller = poller;
-    }
-
-    // destroy the poller thread, if active
-    private void destroyPoller() {
-        if (poller != null) {
-            poller.disable();
-            poller = null;
-        }
-    }
-
-    private boolean hasValidToken() {
-        /* Commented out to work with Solaris softtoken impl which
-           returns 0-value flags, e.g. both REMOVABLE_DEVICE and
-           TOKEN_PRESENT are false, when it can't access the token.
-        if (removable == false) {
-            return true;
-        }
-        */
-        Token token = this.token;
-        return (token != null) && token.isValid();
-    }
-
-    // destroy the token. Called if we detect that it has been removed
-    synchronized void uninitToken(Token token) {
-        if (this.token != token) {
-            // mismatch, our token must already be destroyed
-            return;
-        }
-        destroyPoller();
-        this.token = null;
-        // unregister all algorithms
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
-                clear();
-                return null;
-            }
-        });
-        createPoller();
-    }
-
-    // test if a token is present and initialize this provider for it if so.
-    // does nothing if no token is found
-    // called from constructor and by poller
-    private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception {
-        if (slotInfo == null) {
-            slotInfo = p11.C_GetSlotInfo(slotID);
-        }
-        if (removable && (slotInfo.flags & CKF_TOKEN_PRESENT) == 0) {
-            createPoller();
-            return;
-        }
-        destroyPoller();
-        boolean showInfo = config.getShowInfo();
-        if (showInfo) {
-            System.out.println("Slot info for slot " + slotID + ":");
-            System.out.println(slotInfo);
-        }
-        final Token token = new Token(this);
-        if (showInfo) {
-            System.out.println
-                ("Token info for token in slot " + slotID + ":");
-            System.out.println(token.tokenInfo);
-        }
-        long[] supportedMechanisms = p11.C_GetMechanismList(slotID);
-
-        // Create a map from the various Descriptors to the "most
-        // preferred" mechanism that was defined during the
-        // static initialization.  For example, DES/CBC/PKCS5Padding
-        // could be mapped to CKM_DES_CBC_PAD or CKM_DES_CBC.  Prefer
-        // the earliest entry.  When asked for "DES/CBC/PKCS5Padding", we
-        // return a CKM_DES_CBC_PAD.
-        final Map<Descriptor,Integer> supportedAlgs =
-                                        new HashMap<Descriptor,Integer>();
-        for (int i = 0; i < supportedMechanisms.length; i++) {
-            long longMech = supportedMechanisms[i];
-            boolean isEnabled = config.isEnabled(longMech);
-            if (showInfo) {
-                CK_MECHANISM_INFO mechInfo =
-                        p11.C_GetMechanismInfo(slotID, longMech);
-                System.out.println("Mechanism " +
-                        Functions.getMechanismName(longMech) + ":");
-                if (isEnabled == false) {
-                    System.out.println("DISABLED in configuration");
-                }
-                System.out.println(mechInfo);
-            }
-            if (isEnabled == false) {
-                continue;
-            }
-            // we do not know of mechs with the upper 32 bits set
-            if (longMech >>> 32 != 0) {
-                continue;
-            }
-            int mech = (int)longMech;
-            Integer integerMech = Integer.valueOf(mech);
-            List<Descriptor> ds = descriptors.get(integerMech);
-            if (ds == null) {
-                continue;
-            }
-            for (Descriptor d : ds) {
-                Integer oldMech = supportedAlgs.get(d);
-                if (oldMech == null) {
-                    supportedAlgs.put(d, integerMech);
-                    continue;
-                }
-                // See if there is something "more preferred"
-                // than what we currently have in the supportedAlgs
-                // map.
-                int intOldMech = oldMech.intValue();
-                for (int j = 0; j < d.mechanisms.length; j++) {
-                    int nextMech = d.mechanisms[j];
-                    if (mech == nextMech) {
-                        supportedAlgs.put(d, integerMech);
-                        break;
-                    } else if (intOldMech == nextMech) {
-                        break;
-                    }
-                }
-            }
-
-        }
-
-        // register algorithms in provider
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
-                for (Map.Entry<Descriptor,Integer> entry
-                        : supportedAlgs.entrySet()) {
-                    Descriptor d = entry.getKey();
-                    int mechanism = entry.getValue().intValue();
-                    Service s = d.service(token, mechanism);
-                    putService(s);
-                }
-                if (((token.tokenInfo.flags & CKF_RNG) != 0)
-                        && config.isEnabled(PCKM_SECURERANDOM)
-                        && !token.sessionManager.lowMaxSessions()) {
-                    // do not register SecureRandom if the token does
-                    // not support many sessions. if we did, we might
-                    // run out of sessions in the middle of a
-                    // nextBytes() call where we cannot fail over.
-                    putService(new P11Service(token, SR, "PKCS11",
-                        "sun.security.pkcs11.P11SecureRandom", null,
-                        PCKM_SECURERANDOM));
-                }
-                if (config.isEnabled(PCKM_KEYSTORE)) {
-                    putService(new P11Service(token, KS, "PKCS11",
-                        "sun.security.pkcs11.P11KeyStore",
-                        s("PKCS11-" + config.getName()),
-                        PCKM_KEYSTORE));
-                }
-                return null;
-            }
-        });
-
-        this.token = token;
-    }
-
-    private static final class P11Service extends Service {
-
-        private final Token token;
-
-        private final long mechanism;
-
-        P11Service(Token token, String type, String algorithm,
-                String className, String[] al, long mechanism) {
-            super(token.provider, type, algorithm, className, toList(al),
-                    type.equals(SR) ? Map.of("ThreadSafe", "true") : null);
-            this.token = token;
-            this.mechanism = mechanism & 0xFFFFFFFFL;
-        }
-
-        private static List<String> toList(String[] aliases) {
-            return (aliases == null) ? null : Arrays.asList(aliases);
-        }
-
-        public Object newInstance(Object param)
-                throws NoSuchAlgorithmException {
-            if (token.isValid() == false) {
-                throw new NoSuchAlgorithmException("Token has been removed");
-            }
-            try {
-                return newInstance0(param);
-            } catch (PKCS11Exception e) {
-                throw new NoSuchAlgorithmException(e);
-            }
-        }
-
-        public Object newInstance0(Object param) throws
-                PKCS11Exception, NoSuchAlgorithmException {
-            String algorithm = getAlgorithm();
-            String type = getType();
-            if (type == MD) {
-                return new P11Digest(token, algorithm, mechanism);
-            } else if (type == CIP) {
-                if (algorithm.startsWith("RSA")) {
-                    return new P11RSACipher(token, algorithm, mechanism);
-                } else {
-                    return new P11Cipher(token, algorithm, mechanism);
-                }
-            } else if (type == SIG) {
-                return new P11Signature(token, algorithm, mechanism);
-            } else if (type == MAC) {
-                return new P11Mac(token, algorithm, mechanism);
-            } else if (type == KPG) {
-                return new P11KeyPairGenerator(token, algorithm, mechanism);
-            } else if (type == KA) {
-                if (algorithm.equals("ECDH")) {
-                    return new P11ECDHKeyAgreement(token, algorithm, mechanism);
-                } else {
-                    return new P11KeyAgreement(token, algorithm, mechanism);
-                }
-            } else if (type == KF) {
-                return token.getKeyFactory(algorithm);
-            } else if (type == SKF) {
-                return new P11SecretKeyFactory(token, algorithm);
-            } else if (type == KG) {
-                // reference equality
-                if (algorithm == "SunTlsRsaPremasterSecret") {
-                    return new P11TlsRsaPremasterSecretGenerator(
-                        token, algorithm, mechanism);
-                } else if (algorithm == "SunTlsMasterSecret") {
-                    return new P11TlsMasterSecretGenerator(
-                        token, algorithm, mechanism);
-                } else if (algorithm == "SunTlsKeyMaterial") {
-                    return new P11TlsKeyMaterialGenerator(
-                        token, algorithm, mechanism);
-                } else if (algorithm == "SunTlsPrf") {
-                    return new P11TlsPrfGenerator(token, algorithm, mechanism);
-                } else {
-                    return new P11KeyGenerator(token, algorithm, mechanism);
-                }
-            } else if (type == SR) {
-                return token.getRandom();
-            } else if (type == KS) {
-                return token.getKeyStore();
-            } else if (type == AGP) {
-                return new sun.security.util.ECParameters();
-            } else {
-                throw new NoSuchAlgorithmException("Unknown type: " + type);
-            }
-        }
-
-        public boolean supportsParameter(Object param) {
-            if ((param == null) || (token.isValid() == false)) {
-                return false;
-            }
-            if (param instanceof Key == false) {
-                throw new InvalidParameterException("Parameter must be a Key");
-            }
-            String algorithm = getAlgorithm();
-            String type = getType();
-            Key key = (Key)param;
-            String keyAlgorithm = key.getAlgorithm();
-            // RSA signatures and cipher
-            if (((type == CIP) && algorithm.startsWith("RSA"))
-                    || (type == SIG) && algorithm.endsWith("RSA")) {
-                if (keyAlgorithm.equals("RSA") == false) {
-                    return false;
-                }
-                return isLocalKey(key)
-                        || (key instanceof RSAPrivateKey)
-                        || (key instanceof RSAPublicKey);
-            }
-            // EC
-            if (((type == KA) && algorithm.equals("ECDH"))
-                    || ((type == SIG) && algorithm.contains("ECDSA"))) {
-                if (keyAlgorithm.equals("EC") == false) {
-                    return false;
-                }
-                return isLocalKey(key)
-                        || (key instanceof ECPrivateKey)
-                        || (key instanceof ECPublicKey);
-            }
-            // DSA signatures
-            if ((type == SIG) && algorithm.contains("DSA") &&
-                    !algorithm.contains("ECDSA")) {
-                if (keyAlgorithm.equals("DSA") == false) {
-                    return false;
-                }
-                return isLocalKey(key)
-                        || (key instanceof DSAPrivateKey)
-                        || (key instanceof DSAPublicKey);
-            }
-            // MACs and symmetric ciphers
-            if ((type == CIP) || (type == MAC)) {
-                // do not check algorithm name, mismatch is unlikely anyway
-                return isLocalKey(key) || "RAW".equals(key.getFormat());
-            }
-            // DH key agreement
-            if (type == KA) {
-                if (keyAlgorithm.equals("DH") == false) {
-                    return false;
-                }
-                return isLocalKey(key)
-                        || (key instanceof DHPrivateKey)
-                        || (key instanceof DHPublicKey);
-            }
-            // should not reach here,
-            // unknown engine type or algorithm
-            throw new AssertionError
-                ("SunPKCS11 error: " + type + ", " + algorithm);
-        }
-
-        private boolean isLocalKey(Key key) {
-            return (key instanceof P11Key) && (((P11Key)key).token == token);
-        }
-
-        public String toString() {
-            return super.toString() +
-                " (" + Functions.getMechanismName(mechanism) + ")";
-        }
-
-    }
-
-    /**
-     * Log in to this provider.
-     *
-     * <p> If the token expects a PIN to be supplied by the caller,
-     * the <code>handler</code> implementation must support
-     * a <code>PasswordCallback</code>.
-     *
-     * <p> To determine if the token supports a protected authentication path,
-     * the CK_TOKEN_INFO flag, CKF_PROTECTED_AUTHENTICATION_PATH, is consulted.
-     *
-     * @param subject this parameter is ignored
-     * @param handler the <code>CallbackHandler</code> used by
-     *  this provider to communicate with the caller
-     *
-     * @throws IllegalStateException if the provider requires configuration
-     * and Provider.configure has not been called
-     * @throws LoginException if the login operation fails
-     * @throws SecurityException if the does not pass a security check for
-     *  <code>SecurityPermission("authProvider.<i>name</i>")</code>,
-     *  where <i>name</i> is the value returned by
-     *  this provider's <code>getName</code> method
-     */
-    public void login(Subject subject, CallbackHandler handler)
-        throws LoginException {
-
-        if (!isConfigured()) {
-            throw new IllegalStateException("Configuration is required");
-        }
-
-        // security check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            if (debug != null) {
-                debug.println("checking login permission");
-            }
-            sm.checkPermission(new SecurityPermission
-                        ("authProvider." + this.getName()));
-        }
-
-        if (hasValidToken() == false) {
-            throw new LoginException("No token present");
-        }
-
-        // see if a login is required
-
-        if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) {
-            if (debug != null) {
-                debug.println("login operation not required for token - " +
-                                "ignoring login request");
-            }
-            return;
-        }
-
-        // see if user already logged in
-
-        try {
-            if (token.isLoggedInNow(null)) {
-                // user already logged in
-                if (debug != null) {
-                    debug.println("user already logged in");
-                }
-                return;
-            }
-        } catch (PKCS11Exception e) {
-            // ignore - fall thru and attempt login
-        }
-
-        // get the pin if necessary
-
-        char[] pin = null;
-        if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
-
-            // get password
-
-            CallbackHandler myHandler = getCallbackHandler(handler);
-            if (myHandler == null) {
-                // XXX PolicyTool is dependent on this message text
-                throw new LoginException
-                        ("no password provided, and no callback handler " +
-                        "available for retrieving password");
-            }
-
-            java.text.MessageFormat form = new java.text.MessageFormat
-                        (ResourcesMgr.getString
-                        ("PKCS11.Token.providerName.Password."));
-            Object[] source = { getName() };
-
-            PasswordCallback pcall = new PasswordCallback(form.format(source),
-                                                        false);
-            Callback[] callbacks = { pcall };
-            try {
-                myHandler.handle(callbacks);
-            } catch (Exception e) {
-                LoginException le = new LoginException
-                        ("Unable to perform password callback");
-                le.initCause(e);
-                throw le;
-            }
-
-            pin = pcall.getPassword();
-            pcall.clearPassword();
-            if (pin == null) {
-                if (debug != null) {
-                    debug.println("caller passed NULL pin");
-                }
-            }
-        }
-
-        // perform token login
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-
-            // pin is NULL if using CKF_PROTECTED_AUTHENTICATION_PATH
-            p11.C_Login(session.id(), CKU_USER, pin);
-            if (debug != null) {
-                debug.println("login succeeded");
-            }
-        } catch (PKCS11Exception pe) {
-            if (pe.getErrorCode() == CKR_USER_ALREADY_LOGGED_IN) {
-                // let this one go
-                if (debug != null) {
-                    debug.println("user already logged in");
-                }
-                return;
-            } else if (pe.getErrorCode() == CKR_PIN_INCORRECT) {
-                FailedLoginException fle = new FailedLoginException();
-                fle.initCause(pe);
-                throw fle;
-            } else {
-                LoginException le = new LoginException();
-                le.initCause(pe);
-                throw le;
-            }
-        } finally {
-            token.releaseSession(session);
-            if (pin != null) {
-                Arrays.fill(pin, ' ');
-            }
-        }
-
-        // we do not store the PIN in the subject for now
-    }
-
-    /**
-     * Log out from this provider
-     *
-     * @throws IllegalStateException if the provider requires configuration
-     * and Provider.configure has not been called
-     * @throws LoginException if the logout operation fails
-     * @throws SecurityException if the does not pass a security check for
-     *  <code>SecurityPermission("authProvider.<i>name</i>")</code>,
-     *  where <i>name</i> is the value returned by
-     *  this provider's <code>getName</code> method
-     */
-    public void logout() throws LoginException {
-
-        if (!isConfigured()) {
-            throw new IllegalStateException("Configuration is required");
-        }
-
-        // security check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission
-                (new SecurityPermission("authProvider." + this.getName()));
-        }
-
-        if (hasValidToken() == false) {
-            // app may call logout for cleanup, allow
-            return;
-        }
-
-        if ((token.tokenInfo.flags & CKF_LOGIN_REQUIRED) == 0) {
-            if (debug != null) {
-                debug.println("logout operation not required for token - " +
-                                "ignoring logout request");
-            }
-            return;
-        }
-
-        try {
-            if (token.isLoggedInNow(null) == false) {
-                if (debug != null) {
-                    debug.println("user not logged in");
-                }
-                return;
-            }
-        } catch (PKCS11Exception e) {
-            // ignore
-        }
-
-        // perform token logout
-
-        Session session = null;
-        try {
-            session = token.getOpSession();
-            p11.C_Logout(session.id());
-            if (debug != null) {
-                debug.println("logout succeeded");
-            }
-        } catch (PKCS11Exception pe) {
-            if (pe.getErrorCode() == CKR_USER_NOT_LOGGED_IN) {
-                // let this one go
-                if (debug != null) {
-                    debug.println("user not logged in");
-                }
-                return;
-            }
-            LoginException le = new LoginException();
-            le.initCause(pe);
-            throw le;
-        } finally {
-            token.releaseSession(session);
-        }
-    }
-
-    /**
-     * Set a <code>CallbackHandler</code>
-     *
-     * <p> The provider uses this handler if one is not passed to the
-     * <code>login</code> method.  The provider also uses this handler
-     * if it invokes <code>login</code> on behalf of callers.
-     * In either case if a handler is not set via this method,
-     * the provider queries the
-     * <i>auth.login.defaultCallbackHandler</i> security property
-     * for the fully qualified class name of a default handler implementation.
-     * If the security property is not set,
-     * the provider is assumed to have alternative means
-     * for obtaining authentication information.
-     *
-     * @param handler a <code>CallbackHandler</code> for obtaining
-     *          authentication information, which may be <code>null</code>
-     *
-     * @throws IllegalStateException if the provider requires configuration
-     * and Provider.configure has not been called
-     * @throws SecurityException if the caller does not pass a
-     *  security check for
-     *  <code>SecurityPermission("authProvider.<i>name</i>")</code>,
-     *  where <i>name</i> is the value returned by
-     *  this provider's <code>getName</code> method
-     */
-    public void setCallbackHandler(CallbackHandler handler) {
-
-        if (!isConfigured()) {
-            throw new IllegalStateException("Configuration is required");
-        }
-
-        // security check
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission
-                (new SecurityPermission("authProvider." + this.getName()));
-        }
-
-        synchronized (LOCK_HANDLER) {
-            pHandler = handler;
-        }
-    }
-
-    private CallbackHandler getCallbackHandler(CallbackHandler handler) {
-
-        // get default handler if necessary
-
-        if (handler != null) {
-            return handler;
-        }
-
-        if (debug != null) {
-            debug.println("getting provider callback handler");
-        }
-
-        synchronized (LOCK_HANDLER) {
-            // see if handler was set via setCallbackHandler
-            if (pHandler != null) {
-                return pHandler;
-            }
-
-            try {
-                if (debug != null) {
-                    debug.println("getting default callback handler");
-                }
-
-                CallbackHandler myHandler = AccessController.doPrivileged
-                    (new PrivilegedExceptionAction<CallbackHandler>() {
-                    public CallbackHandler run() throws Exception {
-
-                        String defaultHandler =
-                                java.security.Security.getProperty
-                                ("auth.login.defaultCallbackHandler");
-
-                        if (defaultHandler == null ||
-                            defaultHandler.length() == 0) {
-
-                            // ok
-                            if (debug != null) {
-                                debug.println("no default handler set");
-                            }
-                            return null;
-                        }
-
-                        Class<?> c = Class.forName
-                                   (defaultHandler,
-                                   true,
-                                   Thread.currentThread().getContextClassLoader());
-                        if (!javax.security.auth.callback.CallbackHandler.class.isAssignableFrom(c)) {
-                            // not the right subtype
-                            if (debug != null) {
-                                debug.println("default handler " + defaultHandler +
-                                              " is not a CallbackHandler");
-                            }
-                            return null;
-                        }
-                        @SuppressWarnings("deprecation")
-                        Object result = c.newInstance();
-                        return (CallbackHandler)result;
-                    }
-                });
-                // save it
-                pHandler = myHandler;
-                return myHandler;
-
-            } catch (PrivilegedActionException pae) {
-                // ok
-                if (debug != null) {
-                    debug.println("Unable to load default callback handler");
-                    pae.printStackTrace();
-                }
-            }
-        }
-        return null;
-    }
-
-    private Object writeReplace() throws ObjectStreamException {
-        return new SunPKCS11Rep(this);
-    }
-
-    /**
-     * Serialized representation of the SunPKCS11 provider.
-     */
-    private static class SunPKCS11Rep implements Serializable {
-
-        static final long serialVersionUID = -2896606995897745419L;
-
-        private final String providerName;
-
-        private final String configName;
-
-        SunPKCS11Rep(SunPKCS11 provider) throws NotSerializableException {
-            providerName = provider.getName();
-            configName = provider.config.getFileName();
-            if (Security.getProvider(providerName) != provider) {
-                throw new NotSerializableException("Only SunPKCS11 providers "
-                    + "installed in java.security.Security can be serialized");
-            }
-        }
-
-        private Object readResolve() throws ObjectStreamException {
-            SunPKCS11 p = (SunPKCS11)Security.getProvider(providerName);
-            if ((p == null) || (p.config.getFileName().equals(configName) == false)) {
-                throw new NotSerializableException("Could not find "
-                        + providerName + " in installed providers");
-            }
-            return p;
-        }
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/TemplateManager.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2003, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.util.*;
-import java.util.concurrent.*;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * TemplateManager class.
- *
- * Not all PKCS#11 tokens are created equal. One token may require that one
- * value is specified when creating a certain type of object. Another token
- * may require a different value. Yet another token may only work if the
- * attribute is not specified at all.
- *
- * In order to allow an application to work unmodified with all those
- * different tokens, the SunPKCS11 provider makes the attributes that are
- * specified and their value configurable. Hence, only the SunPKCS11
- * configuration file has to be tweaked at deployment time to allow all
- * existing applications to be used.
- *
- * The template manager is responsible for reading the attribute configuration
- * information and to make it available to the various internal components
- * of the SunPKCS11 provider.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-final class TemplateManager {
-
-    private final static boolean DEBUG = false;
-
-    // constant for any operation (either O_IMPORT or O_GENERATE)
-    final static String O_ANY      = "*";
-    // constant for operation create ("importing" existing key material)
-    final static String O_IMPORT   = "import";
-    // constant for operation generate (generating new key material)
-    final static String O_GENERATE = "generate";
-
-    private static class KeyAndTemplate {
-        final TemplateKey key;
-        final Template template;
-
-        KeyAndTemplate(TemplateKey key, Template template) {
-            this.key = key;
-            this.template = template;
-        }
-    }
-
-    // primitive templates contains the individual template configuration
-    // entries from the configuration file
-    private final List<KeyAndTemplate> primitiveTemplates;
-
-    // composite templates is a cache of the exact configuration template for
-    // each specific TemplateKey (no wildcards). the entries are created
-    // on demand during first use by compositing all applicable
-    // primitive template entries. the result is then stored in this map
-    // for performance
-    private final Map<TemplateKey,Template> compositeTemplates;
-
-    TemplateManager() {
-        primitiveTemplates = new ArrayList<KeyAndTemplate>();
-        compositeTemplates = new ConcurrentHashMap<TemplateKey,Template>();
-    }
-
-    // add a template. Called by Config.
-    void addTemplate(String op, long objectClass, long keyAlgorithm,
-            CK_ATTRIBUTE[] attrs) {
-        TemplateKey key = new TemplateKey(op, objectClass, keyAlgorithm);
-        Template template = new Template(attrs);
-        if (DEBUG) {
-            System.out.println("Adding " + key + " -> " + template);
-        }
-        primitiveTemplates.add(new KeyAndTemplate(key, template));
-    }
-
-    private Template getTemplate(TemplateKey key) {
-        Template template = compositeTemplates.get(key);
-        if (template == null) {
-            template = buildCompositeTemplate(key);
-            compositeTemplates.put(key, template);
-        }
-        return template;
-    }
-
-    // Get the attributes for the requested op and combine them with attrs.
-    // This is the method called by the implementation to obtain the
-    // attributes.
-    CK_ATTRIBUTE[] getAttributes(String op, long type, long alg,
-            CK_ATTRIBUTE[] attrs) {
-        TemplateKey key = new TemplateKey(op, type, alg);
-        Template template = getTemplate(key);
-        CK_ATTRIBUTE[] newAttrs = template.getAttributes(attrs);
-        if (DEBUG) {
-            System.out.println(key + " -> " + Arrays.asList(newAttrs));
-        }
-        return newAttrs;
-    }
-
-    // build a composite template for the given key
-    private Template buildCompositeTemplate(TemplateKey key) {
-        Template comp = new Template();
-        // iterate through primitive templates and add all that apply
-        for (KeyAndTemplate entry : primitiveTemplates) {
-            if (entry.key.appliesTo(key)) {
-                comp.add(entry.template);
-            }
-        }
-        return comp;
-    }
-
-    /**
-     * Nested class representing a template identifier.
-     */
-    private static final class TemplateKey {
-        final String operation;
-        final long keyType;
-        final long keyAlgorithm;
-        TemplateKey(String operation, long keyType, long keyAlgorithm) {
-            this.operation = operation;
-            this.keyType = keyType;
-            this.keyAlgorithm = keyAlgorithm;
-        }
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof TemplateKey == false) {
-                return false;
-            }
-            TemplateKey other = (TemplateKey)obj;
-            boolean match = this.operation.equals(other.operation)
-                        && (this.keyType == other.keyType)
-                        && (this.keyAlgorithm == other.keyAlgorithm);
-            return match;
-        }
-        public int hashCode() {
-            return operation.hashCode() + (int)keyType + (int)keyAlgorithm;
-        }
-        boolean appliesTo(TemplateKey key) {
-            if (operation.equals(O_ANY) || operation.equals(key.operation)) {
-                if ((keyType == PCKO_ANY) || (keyType == key.keyType)) {
-                    if ((keyAlgorithm == PCKK_ANY)
-                                || (keyAlgorithm == key.keyAlgorithm)) {
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
-        public String toString() {
-            return "(" + operation + ","
-                + Functions.getObjectClassName(keyType)
-                + "," + Functions.getKeyName(keyAlgorithm) + ")";
-        }
-    }
-
-    /**
-     * Nested class representing template attributes.
-     */
-    private static final class Template {
-
-        private final static CK_ATTRIBUTE[] A0 = new CK_ATTRIBUTE[0];
-
-        private CK_ATTRIBUTE[] attributes;
-
-        Template() {
-            attributes = A0;
-        }
-
-        Template(CK_ATTRIBUTE[] attributes) {
-            this.attributes = attributes;
-        }
-
-        void add(Template template) {
-            attributes = getAttributes(template.attributes);
-        }
-
-        CK_ATTRIBUTE[] getAttributes(CK_ATTRIBUTE[] attrs) {
-            return combine(attributes, attrs);
-        }
-
-        /**
-         * Combine two sets of attributes. The second set has precedence
-         * over the first and overrides its settings.
-         */
-        private static CK_ATTRIBUTE[] combine(CK_ATTRIBUTE[] attrs1,
-                CK_ATTRIBUTE[] attrs2) {
-            List<CK_ATTRIBUTE> attrs = new ArrayList<CK_ATTRIBUTE>();
-            for (CK_ATTRIBUTE attr : attrs1) {
-                if (attr.pValue != null) {
-                    attrs.add(attr);
-                }
-            }
-            for (CK_ATTRIBUTE attr2 : attrs2) {
-                long type = attr2.type;
-                for (CK_ATTRIBUTE attr1 : attrs1) {
-                    if (attr1.type == type) {
-                        attrs.remove(attr1);
-                    }
-                }
-                if (attr2.pValue != null) {
-                    attrs.add(attr2);
-                }
-            }
-            return attrs.toArray(A0);
-        }
-
-        public String toString() {
-            return Arrays.asList(attributes).toString();
-        }
-
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/Token.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,450 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11;
-
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.io.*;
-import java.lang.ref.*;
-
-import java.security.*;
-import javax.security.auth.login.LoginException;
-
-import sun.security.jca.JCAUtil;
-
-import sun.security.pkcs11.wrapper.*;
-import static sun.security.pkcs11.TemplateManager.*;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * PKCS#11 token.
- *
- * @author  Andreas Sterbenz
- * @since   1.5
- */
-class Token implements Serializable {
-
-    // need to be serializable to allow SecureRandom to be serialized
-    private static final long serialVersionUID = 2541527649100571747L;
-
-    // how often to check if the token is still present (in ms)
-    // this is different from checking if a token has been inserted,
-    // that is done in SunPKCS11. Currently 50 ms.
-    private final static long CHECK_INTERVAL = 50;
-
-    final SunPKCS11 provider;
-
-    final PKCS11 p11;
-
-    final Config config;
-
-    final CK_TOKEN_INFO tokenInfo;
-
-    // session manager to pool sessions
-    final SessionManager sessionManager;
-
-    // template manager to customize the attributes used when creating objects
-    private final TemplateManager templateManager;
-
-    // flag indicating whether we need to explicitly cancel operations
-    // we started on the token. If false, we assume operations are
-    // automatically cancelled once we start another one
-    final boolean explicitCancel;
-
-    // translation cache for secret keys
-    final KeyCache secretCache;
-
-    // translation cache for asymmetric keys (public and private)
-    final KeyCache privateCache;
-
-    // cached instances of the various key factories, initialized on demand
-    private volatile P11KeyFactory rsaFactory, dsaFactory, dhFactory, ecFactory;
-
-    // table which maps mechanisms to the corresponding cached
-    // MechanismInfo objects
-    private final Map<Long, CK_MECHANISM_INFO> mechInfoMap;
-
-    // single SecureRandomSpi instance we use per token
-    // initialized on demand (if supported)
-    private volatile P11SecureRandom secureRandom;
-
-    // single KeyStoreSpi instance we use per provider
-    // initialized on demand
-    private volatile P11KeyStore keyStore;
-
-    // whether this token is a removable token
-    private final boolean removable;
-
-    // for removable tokens: whether this token is valid or has been removed
-    private volatile boolean valid;
-
-    // for removable tokens: time last checked for token presence
-    private long lastPresentCheck;
-
-    // unique token id, used for serialization only
-    private byte[] tokenId;
-
-    // flag indicating whether the token is write protected
-    private boolean writeProtected;
-
-    // flag indicating whether we are logged in
-    private volatile boolean loggedIn;
-
-    // time we last checked login status
-    private long lastLoginCheck;
-
-    // mutex for token-present-check
-    private final static Object CHECK_LOCK = new Object();
-
-    // object for indicating unsupported mechanism in 'mechInfoMap'
-    private final static CK_MECHANISM_INFO INVALID_MECH =
-        new CK_MECHANISM_INFO(0, 0, 0);
-
-    // flag indicating whether the token supports raw secret key material import
-    private Boolean supportsRawSecretKeyImport;
-
-    Token(SunPKCS11 provider) throws PKCS11Exception {
-        this.provider = provider;
-        this.removable = provider.removable;
-        this.valid = true;
-        p11 = provider.p11;
-        config = provider.config;
-        tokenInfo = p11.C_GetTokenInfo(provider.slotID);
-        writeProtected = (tokenInfo.flags & CKF_WRITE_PROTECTED) != 0;
-        // create session manager and open a test session
-        SessionManager sessionManager;
-        try {
-            sessionManager = new SessionManager(this);
-            Session s = sessionManager.getOpSession();
-            sessionManager.releaseSession(s);
-        } catch (PKCS11Exception e) {
-            if (writeProtected) {
-                throw e;
-            }
-            // token might not permit RW sessions even though
-            // CKF_WRITE_PROTECTED is not set
-            writeProtected = true;
-            sessionManager = new SessionManager(this);
-            Session s = sessionManager.getOpSession();
-            sessionManager.releaseSession(s);
-        }
-        this.sessionManager = sessionManager;
-        secretCache = new KeyCache();
-        privateCache = new KeyCache();
-        templateManager = config.getTemplateManager();
-        explicitCancel = config.getExplicitCancel();
-        mechInfoMap =
-            new ConcurrentHashMap<Long, CK_MECHANISM_INFO>(10);
-    }
-
-    boolean isWriteProtected() {
-        return writeProtected;
-    }
-
-    // return whether the token supports raw secret key material import
-    boolean supportsRawSecretKeyImport() {
-        if (supportsRawSecretKeyImport == null) {
-            SecureRandom random = JCAUtil.getSecureRandom();
-            byte[] encoded = new byte[48];
-            random.nextBytes(encoded);
-
-            CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[3];
-            attributes[0] = new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY);
-            attributes[1] = new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_GENERIC_SECRET);
-            attributes[2] = new CK_ATTRIBUTE(CKA_VALUE, encoded);
-
-            Session session = null;
-            try {
-                attributes = getAttributes(O_IMPORT,
-                        CKO_SECRET_KEY, CKK_GENERIC_SECRET, attributes);
-                session = getObjSession();
-                long keyID = p11.C_CreateObject(session.id(), attributes);
-
-                supportsRawSecretKeyImport = Boolean.TRUE;
-            } catch (PKCS11Exception e) {
-                supportsRawSecretKeyImport = Boolean.FALSE;
-            } finally {
-                releaseSession(session);
-            }
-        }
-
-        return supportsRawSecretKeyImport;
-    }
-
-    // return whether we are logged in
-    // uses cached result if current. session is optional and may be null
-    boolean isLoggedIn(Session session) throws PKCS11Exception {
-        // volatile load first
-        boolean loggedIn = this.loggedIn;
-        long time = System.currentTimeMillis();
-        if (time - lastLoginCheck > CHECK_INTERVAL) {
-            loggedIn = isLoggedInNow(session);
-            lastLoginCheck = time;
-        }
-        return loggedIn;
-    }
-
-    // return whether we are logged in now
-    // does not use cache
-    boolean isLoggedInNow(Session session) throws PKCS11Exception {
-        boolean allocSession = (session == null);
-        try {
-            if (allocSession) {
-                session = getOpSession();
-            }
-            CK_SESSION_INFO info = p11.C_GetSessionInfo(session.id());
-            boolean loggedIn = (info.state == CKS_RO_USER_FUNCTIONS) ||
-                                (info.state == CKS_RW_USER_FUNCTIONS);
-            this.loggedIn = loggedIn;
-            return loggedIn;
-        } finally {
-            if (allocSession) {
-                releaseSession(session);
-            }
-        }
-    }
-
-    // ensure that we are logged in
-    // call provider.login() if not
-    void ensureLoggedIn(Session session) throws PKCS11Exception, LoginException {
-        if (isLoggedIn(session) == false) {
-            provider.login(null, null);
-        }
-    }
-
-    // return whether this token object is valid (i.e. token not removed)
-    // returns value from last check, does not perform new check
-    boolean isValid() {
-        if (removable == false) {
-            return true;
-        }
-        return valid;
-    }
-
-    void ensureValid() {
-        if (isValid() == false) {
-            throw new ProviderException("Token has been removed");
-        }
-    }
-
-    // return whether a token is present (i.e. token not removed)
-    // returns cached value if current, otherwise performs new check
-    boolean isPresent(long sessionID) {
-        if (removable == false) {
-            return true;
-        }
-        if (valid == false) {
-            return false;
-        }
-        long time = System.currentTimeMillis();
-        if ((time - lastPresentCheck) >= CHECK_INTERVAL) {
-            synchronized (CHECK_LOCK) {
-                if ((time - lastPresentCheck) >= CHECK_INTERVAL) {
-                    boolean ok = false;
-                    try {
-                        // check if token still present
-                        CK_SLOT_INFO slotInfo =
-                                provider.p11.C_GetSlotInfo(provider.slotID);
-                        if ((slotInfo.flags & CKF_TOKEN_PRESENT) != 0) {
-                            // if the token has been removed and re-inserted,
-                            // the token should return an error
-                            CK_SESSION_INFO sessInfo =
-                                    provider.p11.C_GetSessionInfo
-                                    (sessionID);
-                            ok = true;
-                        }
-                    } catch (PKCS11Exception e) {
-                        // empty
-                    }
-                    valid = ok;
-                    lastPresentCheck = System.currentTimeMillis();
-                    if (ok == false) {
-                        destroy();
-                    }
-                }
-            }
-        }
-        return valid;
-    }
-
-    void destroy() {
-        valid = false;
-        provider.uninitToken(this);
-    }
-
-    Session getObjSession() throws PKCS11Exception {
-        return sessionManager.getObjSession();
-    }
-
-    Session getOpSession() throws PKCS11Exception {
-        return sessionManager.getOpSession();
-    }
-
-    Session releaseSession(Session session) {
-        return sessionManager.releaseSession(session);
-    }
-
-    Session killSession(Session session) {
-        return sessionManager.killSession(session);
-    }
-
-    CK_ATTRIBUTE[] getAttributes(String op, long type, long alg,
-            CK_ATTRIBUTE[] attrs) throws PKCS11Exception {
-        CK_ATTRIBUTE[] newAttrs =
-                    templateManager.getAttributes(op, type, alg, attrs);
-        for (CK_ATTRIBUTE attr : newAttrs) {
-            if (attr.type == CKA_TOKEN) {
-                if (attr.getBoolean()) {
-                    try {
-                        ensureLoggedIn(null);
-                    } catch (LoginException e) {
-                        throw new ProviderException("Login failed", e);
-                    }
-                }
-                // break once we have found a CKA_TOKEN attribute
-                break;
-            }
-        }
-        return newAttrs;
-    }
-
-    P11KeyFactory getKeyFactory(String algorithm) {
-        P11KeyFactory f;
-        if (algorithm.equals("RSA")) {
-            f = rsaFactory;
-            if (f == null) {
-                f = new P11RSAKeyFactory(this, algorithm);
-                rsaFactory = f;
-            }
-        } else if (algorithm.equals("DSA")) {
-            f = dsaFactory;
-            if (f == null) {
-                f = new P11DSAKeyFactory(this, algorithm);
-                dsaFactory = f;
-            }
-        } else if (algorithm.equals("DH")) {
-            f = dhFactory;
-            if (f == null) {
-                f = new P11DHKeyFactory(this, algorithm);
-                dhFactory = f;
-            }
-        } else if (algorithm.equals("EC")) {
-            f = ecFactory;
-            if (f == null) {
-                f = new P11ECKeyFactory(this, algorithm);
-                ecFactory = f;
-            }
-        } else {
-            throw new ProviderException("Unknown algorithm " + algorithm);
-        }
-        return f;
-    }
-
-    P11SecureRandom getRandom() {
-        if (secureRandom == null) {
-            secureRandom = new P11SecureRandom(this);
-        }
-        return secureRandom;
-    }
-
-    P11KeyStore getKeyStore() {
-        if (keyStore == null) {
-            keyStore = new P11KeyStore(this);
-        }
-        return keyStore;
-    }
-
-    CK_MECHANISM_INFO getMechanismInfo(long mechanism) throws PKCS11Exception {
-        CK_MECHANISM_INFO result = mechInfoMap.get(mechanism);
-        if (result == null) {
-            try {
-                result = p11.C_GetMechanismInfo(provider.slotID,
-                                                mechanism);
-                mechInfoMap.put(mechanism, result);
-            } catch (PKCS11Exception e) {
-                if (e.getErrorCode() != PKCS11Constants.CKR_MECHANISM_INVALID) {
-                    throw e;
-                } else {
-                    mechInfoMap.put(mechanism, INVALID_MECH);
-                }
-            }
-        } else if (result == INVALID_MECH) {
-            result = null;
-        }
-        return result;
-    }
-
-    private synchronized byte[] getTokenId() {
-        if (tokenId == null) {
-            SecureRandom random = JCAUtil.getSecureRandom();
-            tokenId = new byte[20];
-            random.nextBytes(tokenId);
-            serializedTokens.add(new WeakReference<Token>(this));
-        }
-        return tokenId;
-    }
-
-    // list of all tokens that have been serialized within this VM
-    // NOTE that elements are never removed from this list
-    // the assumption is that the number of tokens that are serialized
-    // is relatively small
-    private static final List<Reference<Token>> serializedTokens =
-        new ArrayList<Reference<Token>>();
-
-    private Object writeReplace() throws ObjectStreamException {
-        if (isValid() == false) {
-            throw new NotSerializableException("Token has been removed");
-        }
-        return new TokenRep(this);
-    }
-
-    // serialized representation of a token
-    // tokens can only be de-serialized within the same VM invocation
-    // and if the token has not been removed in the meantime
-    private static class TokenRep implements Serializable {
-
-        private static final long serialVersionUID = 3503721168218219807L;
-
-        private final byte[] tokenId;
-
-        TokenRep(Token token) {
-            tokenId = token.getTokenId();
-        }
-
-        private Object readResolve() throws ObjectStreamException {
-            for (Reference<Token> tokenRef : serializedTokens) {
-                Token token = tokenRef.get();
-                if ((token != null) && token.isValid()) {
-                    if (Arrays.equals(token.getTokenId(), tokenId)) {
-                        return token;
-                    }
-                }
-            }
-            throw new NotSerializableException("Could not find token");
-        }
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2011, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11.wrapper;
-
-/**
- * This class represents the necessary parameters required by
- * the CKM_AES_CTR mechanism as defined in CK_AES_CTR_PARAMS structure.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_AES_CTR_PARAMS {
- *   CK_ULONG ulCounterBits;
- *   CK_BYTE cb[16];
- * } CK_AES_CTR_PARAMS;
- * </PRE>
- *
- * @author Yu-Ching Valerie Peng
- * @since   1.7
- */
-public class CK_AES_CTR_PARAMS {
-
-    private final long ulCounterBits;
-    private final byte[] cb;
-
-    public CK_AES_CTR_PARAMS(byte[] cb) {
-        ulCounterBits = 128;
-        this.cb = cb.clone();
-    }
-
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("ulCounterBits: ");
-        sb.append(ulCounterBits);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("cb: ");
-        sb.append(Functions.toHexString(cb));
-
-        return sb.toString();
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_ATTRIBUTE.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-import java.math.BigInteger;
-
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * class CK_ATTRIBUTE includes the type, value and length of an attribute.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_ATTRIBUTE {&nbsp;&nbsp;
- *   CK_ATTRIBUTE_TYPE type;&nbsp;&nbsp;
- *   CK_VOID_PTR pValue;&nbsp;&nbsp;
- *   CK_ULONG ulValueLen;
- * } CK_ATTRIBUTE;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_ATTRIBUTE {
-
-    // common attributes
-    // NOTE that CK_ATTRIBUTE is a mutable classes but these attributes
-    // *MUST NEVER* be modified, e.g. by using them in a
-    // C_GetAttributeValue() call!
-
-    public final static CK_ATTRIBUTE TOKEN_FALSE =
-                                    new CK_ATTRIBUTE(CKA_TOKEN, false);
-
-    public final static CK_ATTRIBUTE SENSITIVE_FALSE =
-                                    new CK_ATTRIBUTE(CKA_SENSITIVE, false);
-
-    public final static CK_ATTRIBUTE EXTRACTABLE_TRUE =
-                                    new CK_ATTRIBUTE(CKA_EXTRACTABLE, true);
-
-    public final static CK_ATTRIBUTE ENCRYPT_TRUE =
-                                    new CK_ATTRIBUTE(CKA_ENCRYPT, true);
-
-    public final static CK_ATTRIBUTE DECRYPT_TRUE =
-                                    new CK_ATTRIBUTE(CKA_DECRYPT, true);
-
-    public final static CK_ATTRIBUTE WRAP_TRUE =
-                                    new CK_ATTRIBUTE(CKA_WRAP, true);
-
-    public final static CK_ATTRIBUTE UNWRAP_TRUE =
-                                    new CK_ATTRIBUTE(CKA_UNWRAP, true);
-
-    public final static CK_ATTRIBUTE SIGN_TRUE =
-                                    new CK_ATTRIBUTE(CKA_SIGN, true);
-
-    public final static CK_ATTRIBUTE VERIFY_TRUE =
-                                    new CK_ATTRIBUTE(CKA_VERIFY, true);
-
-    public final static CK_ATTRIBUTE SIGN_RECOVER_TRUE =
-                                    new CK_ATTRIBUTE(CKA_SIGN_RECOVER, true);
-
-    public final static CK_ATTRIBUTE VERIFY_RECOVER_TRUE =
-                                    new CK_ATTRIBUTE(CKA_VERIFY_RECOVER, true);
-
-    public final static CK_ATTRIBUTE DERIVE_TRUE =
-                                    new CK_ATTRIBUTE(CKA_DERIVE, true);
-
-    public final static CK_ATTRIBUTE ENCRYPT_NULL =
-                                    new CK_ATTRIBUTE(CKA_ENCRYPT);
-
-    public final static CK_ATTRIBUTE DECRYPT_NULL =
-                                    new CK_ATTRIBUTE(CKA_DECRYPT);
-
-    public final static CK_ATTRIBUTE WRAP_NULL =
-                                    new CK_ATTRIBUTE(CKA_WRAP);
-
-    public final static CK_ATTRIBUTE UNWRAP_NULL =
-                                    new CK_ATTRIBUTE(CKA_UNWRAP);
-
-    public CK_ATTRIBUTE() {
-        // empty
-    }
-
-    public CK_ATTRIBUTE(long type) {
-        this.type = type;
-    }
-
-    public CK_ATTRIBUTE(long type, Object pValue) {
-        this.type = type;
-        this.pValue = pValue;
-    }
-
-    public CK_ATTRIBUTE(long type, boolean value) {
-        this.type = type;
-        this.pValue = Boolean.valueOf(value);
-    }
-
-    public CK_ATTRIBUTE(long type, long value) {
-        this.type = type;
-        this.pValue = Long.valueOf(value);
-    }
-
-    public CK_ATTRIBUTE(long type, BigInteger value) {
-        this.type = type;
-        this.pValue = sun.security.pkcs11.P11Util.getMagnitude(value);
-    }
-
-    public BigInteger getBigInteger() {
-        if (pValue instanceof byte[] == false) {
-            throw new RuntimeException("Not a byte[]");
-        }
-        return new BigInteger(1, (byte[])pValue);
-    }
-
-    public boolean getBoolean() {
-        if (pValue instanceof Boolean == false) {
-            throw new RuntimeException
-                ("Not a Boolean: " + pValue.getClass().getName());
-        }
-        return ((Boolean)pValue).booleanValue();
-    }
-
-    public char[] getCharArray() {
-        if (pValue instanceof char[] == false) {
-            throw new RuntimeException("Not a char[]");
-        }
-        return (char[])pValue;
-    }
-
-    public byte[] getByteArray() {
-        if (pValue instanceof byte[] == false) {
-            throw new RuntimeException("Not a byte[]");
-        }
-        return (byte[])pValue;
-    }
-
-    public long getLong() {
-        if (pValue instanceof Long == false) {
-            throw new RuntimeException
-                ("Not a Long: " + pValue.getClass().getName());
-        }
-        return ((Long)pValue).longValue();
-    }
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ATTRIBUTE_TYPE type;
-     * </PRE>
-     */
-    public long type;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VOID_PTR pValue;
-     *   CK_ULONG ulValueLen;
-     * </PRE>
-     */
-    public Object pValue;
-
-    /**
-     * Returns the string representation of CK_ATTRIBUTE.
-     *
-     * @return the string representation of CK_ATTRIBUTE
-     */
-    public String toString() {
-        String prefix = Functions.getAttributeName(type) + " = ";
-        if (type == CKA_CLASS) {
-            return prefix + Functions.getObjectClassName(getLong());
-        } else if (type == CKA_KEY_TYPE) {
-            return prefix + Functions.getKeyName(getLong());
-        } else {
-            String s;
-            if (pValue instanceof char[]) {
-                s = new String((char[])pValue);
-            } else if (pValue instanceof byte[]) {
-                s = Functions.toHexString((byte[])pValue);
-            } else {
-                s = String.valueOf(pValue);
-            }
-            return prefix + s;
-        }
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_CREATEMUTEX.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * interface CK_CREATEMUTEX.
- *
- * @author Karl Scheibelhofer &lt;Karl.Scheibelhofer@iaik.at&gt;
- * @author Martin Schlaeffer &lt;schlaeff@sbox.tugraz.at&gt;
- */
-public interface CK_CREATEMUTEX {
-
-    /**
-     * Method CK_CREATEMUTEX
-     *
-     * @return The mutex (lock) object.
-     * @exception PKCS11Exception
-     */
-    public Object CK_CREATEMUTEX() throws PKCS11Exception;
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_C_INITIALIZE_ARGS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_C_INITIALIZE_ARGS contains the optional arguments for the
- * C_Initialize function.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_C_INITIALIZE_ARGS {&nbsp;&nbsp;
- *   CK_CREATEMUTEX CreateMutex;&nbsp;&nbsp;
- *   CK_DESTROYMUTEX DestroyMutex;&nbsp;&nbsp;
- *   CK_LOCKMUTEX LockMutex;&nbsp;&nbsp;
- *   CK_UNLOCKMUTEX UnlockMutex;&nbsp;&nbsp;
- *   CK_FLAGS flags;&nbsp;&nbsp;
- *   CK_VOID_PTR pReserved;&nbsp;&nbsp;
- * } CK_C_INITIALIZE_ARGS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_C_INITIALIZE_ARGS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CREATEMUTEX CreateMutex;
-     * </PRE>
-     */
-    public CK_CREATEMUTEX  CreateMutex;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_DESTROYMUTEX DestroyMutex;
-     * </PRE>
-     */
-    public CK_DESTROYMUTEX DestroyMutex;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_LOCKMUTEX LockMutex;
-     * </PRE>
-     */
-    public CK_LOCKMUTEX    LockMutex;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_UNLOCKMUTEX UnlockMutex;
-     * </PRE>
-     */
-    public CK_UNLOCKMUTEX  UnlockMutex;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_FLAGS flags;
-     * </PRE>
-     */
-    public long            flags;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VOID_PTR pReserved;
-     * </PRE>
-     */
-    public Object          pReserved;
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_DATE.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class .<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_DATE {&nbsp;&nbsp;
- *   CK_CHAR year[4];&nbsp;&nbsp;
- *   CK_CHAR month[2];&nbsp;&nbsp;
- *   CK_CHAR day[2];&nbsp;&nbsp;
- * } CK_DATE;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_DATE implements Cloneable {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CHAR year[4];   - the year ("1900" - "9999")
-     * </PRE>
-     */
-    public char[] year;    /* the year ("1900" - "9999") */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CHAR month[2];  - the month ("01" - "12")
-     * </PRE>
-     */
-    public char[] month;   /* the month ("01" - "12") */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CHAR day[2];    - the day ("01" - "31")
-     * </PRE>
-     */
-    public char[] day;     /* the day ("01" - "31") */
-
-    public CK_DATE(char[] year, char[] month, char[] day) {
-        this.year = year;
-        this.month = month;
-        this.day = day;
-    }
-
-    /**
-     * Create a (deep) clone of this object.
-     *
-     * @return A clone of this object.
-     */
-    public Object clone() {
-        CK_DATE copy = null;
-        try {
-            copy = (CK_DATE) super.clone();
-        } catch (CloneNotSupportedException cnse) {
-            // re-throw as RuntimeException
-            throw (RuntimeException)
-                (new RuntimeException("Clone error").initCause(cnse));
-        }
-        copy.year = this.year.clone();
-        copy.month = this.month.clone();
-        copy.day =  this.day.clone();
-
-        return copy;
-    }
-
-    /**
-     * Returns the string representation of CK_DATE.
-     *
-     * @return the string representation of CK_DATE
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(new String(day));
-        sb.append('.');
-        sb.append(new String(month));
-        sb.append('.');
-        sb.append(new String(year));
-        sb.append(" (DD.MM.YYYY)");
-
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_DESTROYMUTEX.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * interface CK_DESTROYMUTEX.<p>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public interface CK_DESTROYMUTEX {
-
-    /**
-     * Method CK_DESTROYMUTEX
-     *
-     * @param pMutex The mutex (lock) object.
-     * @exception PKCS11Exception
-     */
-    public void CK_DESTROYMUTEX(Object pMutex) throws PKCS11Exception;
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_ECDH1_DERIVE_PARAMS provides the parameters to the
- * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_ECDH1_DERIVE_PARAMS {
- *   CK_EC_KDF_TYPE kdf;
- *   CK_ULONG ulSharedDataLen;
- *   CK_BYTE_PTR pSharedData;
- *   CK_ULONG ulPublicDataLen;
- *   CK_BYTE_PTR pPublicData;
- * } CK_ECDH1_DERIVE_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-public class CK_ECDH1_DERIVE_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_EC_KDF_TYPE kdf;
-     * </PRE>
-     */
-    public long kdf;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulSharedDataLen;
-     *   CK_BYTE_PTR pSharedData;
-     * </PRE>
-     */
-    public byte[] pSharedData;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulPublicDataLen;
-     *   CK_BYTE_PTR pPublicData;
-     * </PRE>
-     */
-    public byte[] pPublicData;
-
-    public CK_ECDH1_DERIVE_PARAMS(long kdf, byte[] pSharedData, byte[] pPublicData) {
-        this.kdf = kdf;
-        this.pSharedData = pSharedData;
-        this.pPublicData = pPublicData;
-    }
-
-    /**
-     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
-     *
-     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("kdf: 0x");
-        sb.append(Functions.toFullHexString(kdf));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pSharedDataLen: ");
-        sb.append(pSharedData.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pSharedData: ");
-        sb.append(Functions.toHexString(pSharedData));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicDataLen: ");
-        sb.append(pPublicData.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicData: ");
-        sb.append(Functions.toHexString(pPublicData));
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_ECDH2_DERIVE_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_ECDH2_DERIVE_PARAMS provides the parameters to the
- * CKM_ECMQV_DERIVE mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_ECDH2_DERIVE_PARAMS {
- *   CK_EC_KDF_TYPE kdf;
- *   CK_ULONG ulSharedDataLen;
- *   CK_BYTE_PTR pSharedData;
- *   CK_ULONG ulPublicDataLen;
- *   CK_BYTE_PTR pPublicData;
- *   CK_ULONG ulPrivateDataLen;
- *   CK_OBJECT_HANDLE hPrivateData;
- *   CK_ULONG ulPublicDataLen2;
- *   CK_BYTE_PTR pPublicData2;
- * } CK_ECDH2_DERIVE_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-public class CK_ECDH2_DERIVE_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_EC_KDF_TYPE kdf;
-     * </PRE>
-     */
-    public long kdf;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulSharedDataLen;
-     *   CK_BYTE_PTR pSharedData;
-     * </PRE>
-     */
-    public byte[] pSharedData;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulPublicDataLen;
-     *   CK_BYTE_PTR pPublicData;
-     * </PRE>
-     */
-    public byte[] pPublicData;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulPrivateDataLen;
-     * </PRE>
-     */
-    public long ulPrivateDataLen;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_OBJECT_HANDLE hPrivateData;
-     * </PRE>
-     */
-    public long hPrivateData;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulPublicDataLen2;
-     *   CK_BYTE_PTR pPublicData2;
-     * </PRE>
-     */
-    public byte[] pPublicData2;
-
-    /**
-     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
-     *
-     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("kdf: 0x");
-        sb.append(Functions.toFullHexString(kdf));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pSharedDataLen: ");
-        sb.append(pSharedData.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pSharedData: ");
-        sb.append(Functions.toHexString(pSharedData));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicDataLen: ");
-        sb.append(pPublicData.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicData: ");
-        sb.append(Functions.toHexString(pPublicData));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulPrivateDataLen: ");
-        sb.append(ulPrivateDataLen);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("hPrivateData: ");
-        sb.append(hPrivateData);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicDataLen2: ");
-        sb.append(pPublicData2.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicData2: ");
-        sb.append(Functions.toHexString(pPublicData2));
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_INFO.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class  CK_INFO provides general information about Cryptoki.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- *  typedef struct CK_INFO {&nbsp;&nbsp;
- *    CK_VERSION cryptokiVersion;&nbsp;&nbsp;
- *    CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
- *    CK_FLAGS flags;&nbsp;&nbsp;
- *    CK_UTF8CHAR libraryDescription[32];&nbsp;&nbsp;
- *    CK_VERSION libraryVersion;&nbsp;&nbsp;
- *  } CK_INFO;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_INFO {
-
-    /**
-     * Cryptoki interface version number<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VERSION cryptokiVersion;
-     * </PRE>
-     */
-    public CK_VERSION cryptokiVersion;
-
-    /**
-     * ID of the Cryptoki library manufacturer. must be blank
-     * padded - only the first 32 chars will be used<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_UTF8CHAR manufacturerID[32];
-     * </PRE>
-     */
-    public char[] manufacturerID;
-
-    /**
-     * bit flags reserved for future versions. must be zero<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_FLAGS flags;
-     * </PRE>
-     */
-    public long flags;
-
-
-/* libraryDescription and libraryVersion are new for v2.0 */
-
-    /**
-     * must be blank padded - only the first 32 chars will be used<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_UTF8CHAR libraryDescription[32];
-     * </PRE>
-     */
-    public char[] libraryDescription;
-
-    /**
-     * Cryptoki library version number<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VERSION libraryVersion;
-     * </PRE>
-     */
-    public CK_VERSION libraryVersion;
-
-    public CK_INFO(CK_VERSION cryptoVer, char[] vendor, long flags,
-                   char[] libDesc, CK_VERSION libVer) {
-        this.cryptokiVersion = cryptoVer;
-        this.manufacturerID = vendor;
-        this.flags = flags;
-        this.libraryDescription = libDesc;
-        this.libraryVersion = libVer;
-    }
-
-    /**
-     * Returns the string representation of CK_INFO.
-     *
-     * @return the string representation of CK_INFO
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("cryptokiVersion: ");
-        sb.append(cryptokiVersion.toString());
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("manufacturerID: ");
-        sb.append(new String(manufacturerID));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("flags: ");
-        sb.append(Functions.toBinaryString(flags));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("libraryDescription: ");
-        sb.append(new String(libraryDescription));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("libraryVersion: ");
-        sb.append(libraryVersion.toString());
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString() ;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_LOCKMUTEX.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * interface CK_LOCKMUTEX<p>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public interface CK_LOCKMUTEX {
-
-    /**
-     * Method CK_LOCKMUTEX
-     *
-     * @param pMutex The mutex (lock) object to lock.
-     * @exception PKCS11Exception
-     */
-    public void CK_LOCKMUTEX(Object pMutex) throws PKCS11Exception;
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-import java.math.BigInteger;
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * class CK_MECHANISM specifies a particular mechanism and any parameters it
- * requires.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- *  typedef struct CK_MECHANISM {&nbsp;&nbsp;
- *    CK_MECHANISM_TYPE mechanism;&nbsp;&nbsp;
- *    CK_VOID_PTR pParameter;&nbsp;&nbsp;
- *    CK_ULONG ulParameterLen;&nbsp;&nbsp;
- *  } CK_MECHANISM;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_MECHANISM {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_MECHANISM_TYPE mechanism;
-     * </PRE>
-     */
-    public long mechanism;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VOID_PTR pParameter;
-     *   CK_ULONG ulParameterLen;
-     * </PRE>
-     */
-    public Object pParameter;
-
-    public CK_MECHANISM() {
-        // empty
-    }
-
-    public CK_MECHANISM(long mechanism) {
-        this.mechanism = mechanism;
-    }
-
-    // We don't have a (long,Object) constructor to force type checking.
-    // This makes sure we don't accidentally pass a class that the native
-    // code cannot handle.
-
-    public CK_MECHANISM(long mechanism, byte[] pParameter) {
-        init(mechanism, pParameter);
-    }
-
-    public CK_MECHANISM(long mechanism, BigInteger b) {
-        init(mechanism, sun.security.pkcs11.P11Util.getMagnitude(b));
-    }
-
-    public CK_MECHANISM(long mechanism, CK_VERSION version) {
-        init(mechanism, version);
-    }
-
-    public CK_MECHANISM(long mechanism, CK_SSL3_MASTER_KEY_DERIVE_PARAMS params) {
-        init(mechanism, params);
-    }
-
-    public CK_MECHANISM(long mechanism, CK_SSL3_KEY_MAT_PARAMS params) {
-        init(mechanism, params);
-    }
-
-    public CK_MECHANISM(long mechanism, CK_TLS_PRF_PARAMS params) {
-        init(mechanism, params);
-    }
-
-    public CK_MECHANISM(long mechanism, CK_ECDH1_DERIVE_PARAMS params) {
-        init(mechanism, params);
-    }
-
-    public CK_MECHANISM(long mechanism, Long params) {
-        init(mechanism, params);
-    }
-
-    public CK_MECHANISM(long mechanism, CK_AES_CTR_PARAMS params) {
-        init(mechanism, params);
-    }
-
-    private void init(long mechanism, Object pParameter) {
-        this.mechanism = mechanism;
-        this.pParameter = pParameter;
-    }
-
-    /**
-     * Returns the string representation of CK_MECHANISM.
-     *
-     * @return the string representation of CK_MECHANISM
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("mechanism: ");
-        sb.append(mechanism);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pParameter: ");
-        sb.append(pParameter.toString());
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulParameterLen: ??");
-        //buffer.append(pParameter.length);
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString() ;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_MECHANISM_INFO.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_MECHANISM_INFO provides information about a particular mechanism.
- * <p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_MECHANISM_INFO {&nbsp;&nbsp;
- *   CK_ULONG ulMinKeySize;&nbsp;&nbsp;
- *   CK_ULONG ulMaxKeySize;&nbsp;&nbsp;
- *   CK_FLAGS flags;&nbsp;&nbsp;
- * } CK_MECHANISM_INFO;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_MECHANISM_INFO {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulMinKeySize;
-     * </PRE>
-     */
-    public long ulMinKeySize;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulMaxKeySize;
-     * </PRE>
-     */
-    public long ulMaxKeySize;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_FLAGS flags;
-     * </PRE>
-     */
-    public long flags;
-
-    public CK_MECHANISM_INFO(long minKeySize, long maxKeySize,
-                             long flags) {
-        this.ulMinKeySize = minKeySize;
-        this.ulMaxKeySize = maxKeySize;
-        this.flags = flags;
-    }
-
-    /**
-     * Returns the string representation of CK_MECHANISM_INFO.
-     *
-     * @return the string representation of CK_MECHANISM_INFO
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("ulMinKeySize: ");
-        sb.append(String.valueOf(ulMinKeySize));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulMaxKeySize: ");
-        sb.append(String.valueOf(ulMaxKeySize));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("flags: ");
-        sb.append(String.valueOf(flags));
-        sb.append(" = ");
-        sb.append(Functions.mechanismInfoFlagsToString(flags));
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString() ;
-    }
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_NOTIFY.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * interface CK_NOTIFY.<p>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public interface CK_NOTIFY {
-
-    /**
-     * Method CK_NOTIFY
-     *
-     * @param hSession
-     * @param event
-     * @param pApplication
-     * @exception PKCS11Exception
-     */
-    public void CK_NOTIFY(long hSession, long event, Object pApplication) throws PKCS11Exception;
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_PBE_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_PBE_PARAMS provides all of the necessary information required byte
- * the CKM_PBE mechanisms and the CKM_PBA_SHA1_WITH_SHA1_HMAC mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_PBE_PARAMS {
- *   CK_CHAR_PTR pInitVector;
- *   CK_CHAR_PTR pPassword;
- *   CK_ULONG ulPasswordLen;
- *   CK_CHAR_PTR pSalt;
- *   CK_ULONG ulSaltLen;
- *   CK_ULONG ulIteration;
- * } CK_PBE_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_PBE_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CHAR_PTR pInitVector;
-     * </PRE>
-     */
-    public char[] pInitVector;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CHAR_PTR pPassword;
-     *   CK_ULONG ulPasswordLen;
-     * </PRE>
-     */
-    public char[] pPassword;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CHAR_PTR pSalt
-     *   CK_ULONG ulSaltLen;
-     * </PRE>
-     */
-    public char[] pSalt;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulIteration;
-     * </PRE>
-     */
-    public long ulIteration;
-
-    /**
-     * Returns the string representation of CK_PBE_PARAMS.
-     *
-     * @return the string representation of CK_PBE_PARAMS
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("pInitVector: ");
-        sb.append(pInitVector);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulPasswordLen: ");
-        sb.append(pPassword.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPassword: ");
-        sb.append(pPassword);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulSaltLen: ");
-        sb.append(pSalt.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pSalt: ");
-        sb.append(pSalt);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulIteration: ");
-        sb.append(ulIteration);
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_PKCS5_PBKD2_PARAMS provides the parameters to the CKM_PKCS5_PBKD2
- * mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_PKCS5_PBKD2_PARAMS {
- *   CK_PKCS5_PBKD2_SALT_SOURCE_TYPE saltSource;
- *   CK_VOID_PTR pSaltSourceData;
- *   CK_ULONG ulSaltSourceDataLen;
- *   CK_ULONG iterations;
- *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
- *   CK_VOID_PTR pPrfData;
- *   CK_ULONG ulPrfDataLen;
- * } CK_PKCS5_PBKD2_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_PKCS5_PBKD2_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
-     * </PRE>
-     */
-    public long saltSource;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VOID_PTR pSaltSourceData;
-     *   CK_ULONG ulSaltSourceDataLen;
-     * </PRE>
-     */
-    public byte[] pSaltSourceData;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG iterations;
-     * </PRE>
-     */
-    public long iterations;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-     * </PRE>
-     */
-    public long prf;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VOID_PTR pPrfData;
-     *   CK_ULONG ulPrfDataLen;
-     * </PRE>
-     */
-    public byte[] pPrfData;
-
-    /**
-     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
-     *
-     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("saltSource: ");
-        sb.append(saltSource);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pSaltSourceData: ");
-        sb.append(Functions.toHexString(pSaltSourceData));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulSaltSourceDataLen: ");
-        sb.append(pSaltSourceData.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("iterations: ");
-        sb.append(iterations);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("prf: ");
-        sb.append(prf);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPrfData: ");
-        sb.append(Functions.toHexString(pPrfData));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulPrfDataLen: ");
-        sb.append(pPrfData.length);
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_OAEP_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_OAEP mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_RSA_PKCS_OAEP_PARAMS {
- *   CK_MECHANISM_TYPE hashAlg;
- *   CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
- *   CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
- *   CK_VOID_PTR pSourceData;
- *   CK_ULONG ulSourceDataLen;
- * } CK_RSA_PKCS_OAEP_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_RSA_PKCS_OAEP_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_MECHANISM_TYPE hashAlg;
-     * </PRE>
-     */
-    public long hashAlg;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
-     * </PRE>
-     */
-    public long mgf;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
-     * </PRE>
-     */
-    public long source;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VOID_PTR pSourceData;
-     *   CK_ULONG ulSourceDataLen;
-     * </PRE>
-     */
-    public byte[] pSourceData;
-
-    //CK_ULONG ulSourceDataLen;
-    // ulSourceDataLen == pSourceData.length
-
-    /**
-     * Returns the string representation of CK_RSA_PKCS_OAEP_PARAMS.
-     *
-     * @return the string representation of CK_RSA_PKCS_OAEP_PARAMS
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("hashAlg: ");
-        sb.append(hashAlg);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("mgf: ");
-        sb.append(mgf);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("source: ");
-        sb.append(source);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pSourceData: ");
-        sb.append(pSourceData.toString());
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pSourceDataLen: ");
-        sb.append(Functions.toHexString(pSourceData));
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString() ;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_RSA_PKCS_PSS_PARAMS provides the parameters to the CKM_RSA_PKCS_OAEP
- * mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_RSA_PKCS_PSS_PARAMS {
- *   CK_MECHANISM_TYPE hashAlg;
- *   CK_RSA_PKCS_MGF_TYPE mgf;
- *   CK_ULONG sLen;
- * } CK_RSA_PKCS_PSS_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-public class CK_RSA_PKCS_PSS_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_MECHANISM_TYPE hashAlg;
-     * </PRE>
-     */
-    public long hashAlg;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_RSA_PKCS_MGF_TYPE mgf;
-     * </PRE>
-     */
-    public long mgf;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG sLen;
-     * </PRE>
-     */
-    public long sLen;
-
-    /**
-     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
-     *
-     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("hashAlg: 0x");
-        sb.append(Functions.toFullHexString(hashAlg));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("mgf: 0x");
-        sb.append(Functions.toFullHexString(mgf));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("sLen: ");
-        sb.append(sLen);
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SESSION_INFO.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_SESSION_INFO provides information about a session.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_SESSION_INFO {&nbsp;&nbsp;
- *   CK_SLOT_ID slotID;&nbsp;&nbsp;
- *   CK_STATE state;&nbsp;&nbsp;
- *   CK_FLAGS flags;&nbsp;&nbsp;
- *   CK_ULONG ulDeviceError;&nbsp;&nbsp;
- * } CK_SESSION_INFO;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_SESSION_INFO {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_SLOT_ID slotID;
-     * </PRE>
-     */
-    public long slotID;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_STATE state;
-     * </PRE>
-     */
-    public long state;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_FLAGS flags;
-     * </PRE>
-     */
-    public long flags;          /* see below */
-
-    /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
-     * v2.0 */
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulDeviceError;
-     * </PRE>
-     */
-    public long ulDeviceError;  /* device-dependent error code */
-
-    public CK_SESSION_INFO(long slotID, long state,
-                           long flags, long ulDeviceError) {
-        this.slotID = slotID;
-        this.state = state;
-        this.flags = flags;
-        this.ulDeviceError = ulDeviceError;
-    }
-
-    /**
-     * Returns the string representation of CK_SESSION_INFO.
-     *
-     * @return the string representation of CK_SESSION_INFO
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("slotID: ");
-        sb.append(String.valueOf(slotID));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("state: ");
-        sb.append(Functions.sessionStateToString(state));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("flags: ");
-        sb.append(Functions.sessionInfoFlagsToString(flags));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulDeviceError: ");
-        sb.append(Functions.toHexString(ulDeviceError));
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString() ;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SLOT_INFO.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_SLOT_INFO provides information about a slot.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- *  typedef struct CK_SLOT_INFO {&nbsp;&nbsp;
- *    CK_UTF8CHAR slotDescription[64];&nbsp;&nbsp;
- *    CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
- *    CK_FLAGS flags;&nbsp;&nbsp;
- *    CK_VERSION hardwareVersion;&nbsp;&nbsp;
- *    CK_VERSION firmwareVersion;&nbsp;&nbsp;
- *  } CK_SLOT_INFO;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_SLOT_INFO {
-
-    /* slotDescription and manufacturerID have been changed from
-     * CK_CHAR to CK_UTF8CHAR for v2.11. */
-
-    /**
-     * must be blank padded and only the first 64 chars will be used<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_UTF8CHAR slotDescription[64];
-     * </PRE>
-     */
-    public char[] slotDescription;
-
-    /**
-     * must be blank padded and only the first 32 chars will be used<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_UTF8CHAR manufacturerID[32];
-     * </PRE>
-     */
-    public char[] manufacturerID;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_FLAGS flags;
-     * </PRE>
-     */
-    public long flags;
-
-    /* hardwareVersion and firmwareVersion are new for v2.0 */
-    /**
-     * version of hardware<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VERSION hardwareVersion;
-     * </PRE>
-     */
-    public CK_VERSION hardwareVersion;
-
-    /**
-     * version of firmware<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VERSION firmwareVersion;
-     * </PRE>
-     */
-    public CK_VERSION firmwareVersion;
-
-    public CK_SLOT_INFO(char[] slotDesc, char[] vendor,
-                        long flags, CK_VERSION hwVer, CK_VERSION fwVer) {
-        this.slotDescription = slotDesc;
-        this.manufacturerID = vendor;
-        this.flags = flags;
-        this.hardwareVersion = hwVer;
-        this.firmwareVersion = fwVer;
-    }
-
-    /**
-     * Returns the string representation of CK_SLOT_INFO.
-     *
-     * @return the string representation of CK_SLOT_INFO
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("slotDescription: ");
-        sb.append(new String(slotDescription));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("manufacturerID: ");
-        sb.append(new String(manufacturerID));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("flags: ");
-        sb.append(Functions.slotInfoFlagsToString(flags));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("hardwareVersion: ");
-        sb.append(hardwareVersion.toString());
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("firmwareVersion: ");
-        sb.append(firmwareVersion.toString());
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString() ;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_SSL3_KEY_MAT_OUT contains the resulting key handles and
- * initialization vectors after performing a C_DeriveKey function with the
- * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_SSL3_KEY_MAT_OUT {
- *   CK_OBJECT_HANDLE hClientMacSecret;
- *   CK_OBJECT_HANDLE hServerMacSecret;
- *   CK_OBJECT_HANDLE hClientKey;
- *   CK_OBJECT_HANDLE hServerKey;
- *   CK_BYTE_PTR pIVClient;
- *   CK_BYTE_PTR pIVServer;
- * } CK_SSL3_KEY_MAT_OUT;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_SSL3_KEY_MAT_OUT{
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_OBJECT_HANDLE hClientMacSecret;
-     * </PRE>
-     */
-    public long hClientMacSecret;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_OBJECT_HANDLE hServerMacSecret;
-     * </PRE>
-     */
-    public long hServerMacSecret;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_OBJECT_HANDLE hClientKey;
-     * </PRE>
-     */
-    public long hClientKey;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_OBJECT_HANDLE hServerKey;
-     * </PRE>
-     */
-    public long hServerKey;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_BYTE_PTR pIVClient;
-     * </PRE>
-     */
-    public byte[] pIVClient;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_BYTE_PTR pIVServer;
-     * </PRE>
-     */
-    public byte[] pIVServer;
-
-    /**
-     * Returns the string representation of CK_SSL3_KEY_MAT_OUT.
-     *
-     * @return the string representation of CK_SSL3_KEY_MAT_OUT
-     */
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append(Constants.INDENT);
-        buffer.append("hClientMacSecret: ");
-        buffer.append(hClientMacSecret);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("hServerMacSecret: ");
-        buffer.append(hServerMacSecret);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("hClientKey: ");
-        buffer.append(hClientKey);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("hServerKey: ");
-        buffer.append(hServerKey);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("pIVClient: ");
-        buffer.append(Functions.toHexString(pIVClient));
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("pIVServer: ");
-        buffer.append(Functions.toHexString(pIVServer));
-        //buffer.append(Constants.NEWLINE);
-
-        return buffer.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_SSL3_KEY_MAT_PARAMS provides the parameters to the
- * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_SSL3_KEY_MAT_PARAMS {
- *   CK_ULONG ulMacSizeInBits;
- *   CK_ULONG ulKeySizeInBits;
- *   CK_ULONG ulIVSizeInBits;
- *   CK_BBOOL bIsExport;
- *   CK_SSL3_RANDOM_DATA RandomInfo;
- *   CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
- * } CK_SSL3_KEY_MAT_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_SSL3_KEY_MAT_PARAMS{
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulMacSizeInBits;
-     * </PRE>
-     */
-    public long ulMacSizeInBits;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulKeySizeInBits;
-     * </PRE>
-     */
-    public long ulKeySizeInBits;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulIVSizeInBits;
-     * </PRE>
-     */
-    public long ulIVSizeInBits;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_BBOOL bIsExport;
-     * </PRE>
-     */
-    public boolean bIsExport;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_SSL3_RANDOM_DATA RandomInfo;
-     * </PRE>
-     */
-    public CK_SSL3_RANDOM_DATA RandomInfo;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-     * </PRE>
-     */
-    public CK_SSL3_KEY_MAT_OUT pReturnedKeyMaterial;
-
-    public CK_SSL3_KEY_MAT_PARAMS(int macSize, int keySize, int ivSize, boolean export, CK_SSL3_RANDOM_DATA random) {
-        ulMacSizeInBits = macSize;
-        ulKeySizeInBits = keySize;
-        ulIVSizeInBits = ivSize;
-        bIsExport = export;
-        RandomInfo = random;
-        pReturnedKeyMaterial = new CK_SSL3_KEY_MAT_OUT();
-        if (ivSize != 0) {
-            int n = ivSize >> 3;
-            pReturnedKeyMaterial.pIVClient = new byte[n];
-            pReturnedKeyMaterial.pIVServer = new byte[n];
-        }
-    }
-
-    /**
-     * Returns the string representation of CK_SSL3_KEY_MAT_PARAMS.
-     *
-     * @return the string representation of CK_SSL3_KEY_MAT_PARAMS
-     */
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append(Constants.INDENT);
-        buffer.append("ulMacSizeInBits: ");
-        buffer.append(ulMacSizeInBits);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("ulKeySizeInBits: ");
-        buffer.append(ulKeySizeInBits);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("ulIVSizeInBits: ");
-        buffer.append(ulIVSizeInBits);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("bIsExport: ");
-        buffer.append(bIsExport);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("RandomInfo: ");
-        buffer.append(RandomInfo);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("pReturnedKeyMaterial: ");
-        buffer.append(pReturnedKeyMaterial);
-        //buffer.append(Constants.NEWLINE);
-
-        return buffer.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_MASTER_KEY_DERIVE_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_SSL3_MASTER_KEY_DERIVE_PARAMS provides the parameters to the
- * CKM_SSL3_MASTER_KEY_DERIVE mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
- *   CK_SSL3_RANDOM_DATA RandomInfo;
- *   CK_VERSION_PTR pVersion;
- * } CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_SSL3_RANDOM_DATA RandomInfo;
-     * </PRE>
-     */
-    public CK_SSL3_RANDOM_DATA RandomInfo;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VERSION_PTR pVersion;
-     * </PRE>
-     */
-    public CK_VERSION pVersion;
-
-    public CK_SSL3_MASTER_KEY_DERIVE_PARAMS(CK_SSL3_RANDOM_DATA random, CK_VERSION version) {
-        RandomInfo = random;
-        pVersion = version;
-    }
-
-    /**
-     * Returns the string representation of CK_SSL3_MASTER_KEY_DERIVE_PARAMS.
-     *
-     * @return the string representation of CK_SSL3_MASTER_KEY_DERIVE_PARAMS
-     */
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append(Constants.INDENT);
-        buffer.append("RandomInfo: ");
-        buffer.append(RandomInfo);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("pVersion: ");
-        buffer.append(pVersion);
-        //buffer.append(Constants.NEWLINE);
-
-        return buffer.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_SSL3_RANDOM_DATA provides information about the random data of a
- * client and a server in an SSL context. This class is used by both the
- * CKM_SSL3_MASTER_KEY_DERIVE and the CKM_SSL3_KEY_AND_MAC_DERIVE mechanisms.
- * <p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_SSL3_RANDOM_DATA {
- *   CK_BYTE_PTR pClientRandom;
- *   CK_ULONG ulClientRandomLen;
- *   CK_BYTE_PTR pServerRandom;
- *   CK_ULONG ulServerRandomLen;
- * } CK_SSL3_RANDOM_DATA;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_SSL3_RANDOM_DATA {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_BYTE_PTR pClientRandom;
-     *   CK_ULONG ulClientRandomLen;
-     * </PRE>
-     */
-    public byte[] pClientRandom;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_BYTE_PTR pServerRandom;
-     *   CK_ULONG ulServerRandomLen;
-     * </PRE>
-     */
-    public byte[] pServerRandom;
-
-    public CK_SSL3_RANDOM_DATA(byte[] clientRandom, byte[] serverRandom) {
-        pClientRandom = clientRandom;
-        pServerRandom = serverRandom;
-    }
-
-    /**
-     * Returns the string representation of CK_SSL3_RANDOM_DATA.
-     *
-     * @return the string representation of CK_SSL3_RANDOM_DATA
-     */
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append(Constants.INDENT);
-        buffer.append("pClientRandom: ");
-        buffer.append(Functions.toHexString(pClientRandom));
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("ulClientRandomLen: ");
-        buffer.append(pClientRandom.length);
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("pServerRandom: ");
-        buffer.append(Functions.toHexString(pServerRandom));
-        buffer.append(Constants.NEWLINE);
-
-        buffer.append(Constants.INDENT);
-        buffer.append("ulServerRandomLen: ");
-        buffer.append(pServerRandom.length);
-        //buffer.append(Constants.NEWLINE);
-
-        return buffer.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2005, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package sun.security.pkcs11.wrapper;
-
-/**
- * CK_TLS_PRF_PARAMS from PKCS#11 v2.20.
- *
- * @author  Andreas Sterbenz
- * @since   1.6
- */
-public class CK_TLS_PRF_PARAMS {
-
-    public byte[] pSeed;
-    public byte[] pLabel;
-    public byte[] pOutput;
-
-    public CK_TLS_PRF_PARAMS(byte[] pSeed, byte[] pLabel, byte[] pOutput) {
-        this.pSeed = pSeed;
-        this.pLabel = pLabel;
-        this.pOutput = pOutput;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_TOKEN_INFO.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,389 +0,0 @@
-/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_TOKEN_INFO provides information about a token.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_TOKEN_INFO {&nbsp;&nbsp;
- *   CK_UTF8CHAR label[32];&nbsp;&nbsp;
- *   CK_UTF8CHAR manufacturerID[32];&nbsp;&nbsp;
- *   CK_UTF8CHAR model[16];&nbsp;&nbsp;
- *   CK_CHAR serialNumber[16];&nbsp;&nbsp;
- *   CK_FLAGS flags;&nbsp;&nbsp;
- *   CK_ULONG ulMaxSessionCount;&nbsp;&nbsp;
- *   CK_ULONG ulSessionCount;&nbsp;&nbsp;
- *   CK_ULONG ulMaxRwSessionCount;&nbsp;&nbsp;
- *   CK_ULONG ulRwSessionCount;&nbsp;&nbsp;
- *   CK_ULONG ulMaxPinLen;&nbsp;&nbsp;
- *   CK_ULONG ulMinPinLen;&nbsp;&nbsp;
- *   CK_ULONG ulTotalPublicMemory;&nbsp;&nbsp;
- *   CK_ULONG ulFreePublicMemory;&nbsp;&nbsp;
- *   CK_ULONG ulTotalPrivateMemory;&nbsp;&nbsp;
- *   CK_ULONG ulFreePrivateMemory;&nbsp;&nbsp;
- *   CK_VERSION hardwareVersion;&nbsp;&nbsp;
- *   CK_VERSION firmwareVersion;&nbsp;&nbsp;
- *   CK_CHAR utcTime[16];&nbsp;&nbsp;
- * } CK_TOKEN_INFO;
- * &nbsp;&nbsp;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_TOKEN_INFO {
-
-    /* label, manufacturerID, and model have been changed from
-     * CK_CHAR to CK_UTF8CHAR for v2.11. */
-    /**
-     * must be blank padded and only the first 32 chars will be used<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_UTF8CHAR label[32];
-     * </PRE>
-     */
-    public char[] label;           /* blank padded */
-
-    /**
-     * must be blank padded and only the first 32 chars will be used<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_UTF8CHAR manufacturerID[32];
-     * </PRE>
-     */
-    public char[] manufacturerID;  /* blank padded */
-
-    /**
-     * must be blank padded and only the first 16 chars will be used<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_UTF8CHAR model[16];
-     * </PRE>
-     */
-    public char[] model;           /* blank padded */
-
-    /**
-     * must be blank padded and only the first 16 chars will be used<p>
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CHAR serialNumber[16];
-     * </PRE>
-     */
-    public char[] serialNumber;    /* blank padded */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_FLAGS flags;
-     * </PRE>
-     */
-    public long flags;               /* see below */
-
-    /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
-     * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
-     * changed from CK_USHORT to CK_ULONG for v2.0 */
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulMaxSessionCount;
-     * </PRE>
-     */
-    public long ulMaxSessionCount;     /* max open sessions */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulSessionCount;
-     * </PRE>
-     */
-    public long ulSessionCount;        /* sess. now open */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulMaxRwSessionCount;
-     * </PRE>
-     */
-    public long ulMaxRwSessionCount;   /* max R/W sessions */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulRwSessionCount;
-     * </PRE>
-     */
-    public long ulRwSessionCount;      /* R/W sess. now open */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulMaxPinLen;
-     * </PRE>
-     */
-    public long ulMaxPinLen;           /* in bytes */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulMinPinLen;
-     * </PRE>
-     */
-    public long ulMinPinLen;           /* in bytes */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulTotalPublicMemory;
-     * </PRE>
-     */
-    public long ulTotalPublicMemory;   /* in bytes */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulFreePublicMemory;
-     * </PRE>
-     */
-    public long ulFreePublicMemory;    /* in bytes */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulTotalPrivateMemory;
-     * </PRE>
-     */
-    public long ulTotalPrivateMemory;  /* in bytes */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulFreePrivateMemory;
-     * </PRE>
-     */
-    public long ulFreePrivateMemory;   /* in bytes */
-
-    /* hardwareVersion, firmwareVersion, and time are new for
-     * v2.0 */
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VERSION hardwareVersion;
-     * </PRE>
-     */
-    public CK_VERSION    hardwareVersion;       /* version of hardware */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_VERSION firmwareVersion;
-     * </PRE>
-     */
-    public CK_VERSION    firmwareVersion;       /* version of firmware */
-
-    /**
-     * only the first 16 chars will be used
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_CHAR utcTime[16];
-     * </PRE>
-     */
-    public char[] utcTime;           /* time */
-
-    public CK_TOKEN_INFO(char[] label, char[] vendor, char[] model,
-                         char[] serialNo, long flags,
-                         long sessionMax, long session,
-                         long rwSessionMax, long rwSession,
-                         long pinLenMax, long pinLenMin,
-                         long totalPubMem, long freePubMem,
-                         long totalPrivMem, long freePrivMem,
-                         CK_VERSION hwVer, CK_VERSION fwVer, char[] utcTime) {
-        this.label = label;
-        this.manufacturerID = vendor;
-        this.model = model;
-        this.serialNumber = serialNo;
-        this.flags = flags;
-        this.ulMaxSessionCount = sessionMax;
-        this.ulSessionCount = session;
-        this.ulMaxRwSessionCount = rwSessionMax;
-        this.ulRwSessionCount = rwSession;
-        this.ulMaxPinLen = pinLenMax;
-        this.ulMinPinLen = pinLenMin;
-        this.ulTotalPublicMemory = totalPubMem;
-        this.ulFreePublicMemory = freePubMem;
-        this.ulTotalPrivateMemory = totalPrivMem;
-        this.ulFreePrivateMemory = freePrivMem;
-        this.hardwareVersion = hwVer;
-        this.firmwareVersion = fwVer;
-        this.utcTime = utcTime;
-    }
-
-    /**
-     * Returns the string representation of CK_TOKEN_INFO.
-     *
-     * @return the string representation of CK_TOKEN_INFO
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("label: ");
-        sb.append(new String(label));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("manufacturerID: ");
-        sb.append(new String(manufacturerID));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("model: ");
-        sb.append(new String(model));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("serialNumber: ");
-        sb.append(new String(serialNumber));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("flags: ");
-        sb.append(Functions.tokenInfoFlagsToString(flags));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulMaxSessionCount: ");
-        sb.append((ulMaxSessionCount == PKCS11Constants.CK_EFFECTIVELY_INFINITE)
-                  ? "CK_EFFECTIVELY_INFINITE"
-                  : (ulMaxSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
-                    ? "CK_UNAVAILABLE_INFORMATION"
-                    : String.valueOf(ulMaxSessionCount));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulSessionCount: ");
-        sb.append((ulSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
-                  ? "CK_UNAVAILABLE_INFORMATION"
-                  : String.valueOf(ulSessionCount));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulMaxRwSessionCount: ");
-        sb.append((ulMaxRwSessionCount == PKCS11Constants.CK_EFFECTIVELY_INFINITE)
-                  ? "CK_EFFECTIVELY_INFINITE"
-                  : (ulMaxRwSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
-                    ? "CK_UNAVAILABLE_INFORMATION"
-                    : String.valueOf(ulMaxRwSessionCount));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulRwSessionCount: ");
-        sb.append((ulRwSessionCount == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
-                  ? "CK_UNAVAILABLE_INFORMATION"
-                  : String.valueOf(ulRwSessionCount));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulMaxPinLen: ");
-        sb.append(String.valueOf(ulMaxPinLen));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulMinPinLen: ");
-        sb.append(String.valueOf(ulMinPinLen));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulTotalPublicMemory: ");
-        sb.append((ulTotalPublicMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
-                  ? "CK_UNAVAILABLE_INFORMATION"
-                  : String.valueOf(ulTotalPublicMemory));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulFreePublicMemory: ");
-        sb.append((ulFreePublicMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
-                  ? "CK_UNAVAILABLE_INFORMATION"
-                  : String.valueOf(ulFreePublicMemory));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulTotalPrivateMemory: ");
-        sb.append((ulTotalPrivateMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
-                  ? "CK_UNAVAILABLE_INFORMATION"
-                  : String.valueOf(ulTotalPrivateMemory));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulFreePrivateMemory: ");
-        sb.append((ulFreePrivateMemory == PKCS11Constants.CK_UNAVAILABLE_INFORMATION)
-                  ? "CK_UNAVAILABLE_INFORMATION"
-                  : String.valueOf(ulFreePrivateMemory));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("hardwareVersion: ");
-        sb.append(hardwareVersion.toString());
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("firmwareVersion: ");
-        sb.append(firmwareVersion.toString());
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("utcTime: ");
-        sb.append(new String(utcTime));
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString() ;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_UNLOCKMUTEX.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * interface CK_UNLOCKMUTEX<p>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public interface CK_UNLOCKMUTEX {
-
-    /**
-     * Method CK_UNLOCKMUTEX
-     *
-     * @param pMutex The mutex (lock) object to unlock.
-     * @exception PKCS11Exception
-     */
-    public void CK_UNLOCKMUTEX(Object pMutex) throws PKCS11Exception;
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_VERSION.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_VERSION describes the version of a Cryptoki interface, a Cryptoki
- * library, or an SSL implementation, or the hardware or firmware version of a
- * slot or token.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_VERSION {&nbsp;&nbsp;
- *   CK_BYTE major;&nbsp;&nbsp;
- *   CK_BYTE minor;&nbsp;&nbsp;
- * } CK_VERSION;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class CK_VERSION {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_BYTE major;
-     * </PRE>
-     */
-    public byte major;  /* integer portion of version number */
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_BYTE minor;
-     * </PRE>
-     */
-    public byte minor;  /* 1/100ths portion of version number */
-
-    public CK_VERSION(int major, int minor) {
-        this.major = (byte)major;
-        this.minor = (byte)minor;
-    }
-
-    /**
-     * Returns the string representation of CK_VERSION.
-     *
-     * @return the string representation of CK_VERSION
-     */
-    public String toString() {
-        StringBuilder buffer = new StringBuilder();
-
-        buffer.append(major & 0xff);
-        buffer.append('.');
-        int m = minor & 0xff;
-        if (m < 10) {
-            buffer.append('0');
-        }
-        buffer.append(m);
-
-        return buffer.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_DERIVE mechanism.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
- *   CK_X9_42_DH_KDF_TYPE kdf;
- *   CK_ULONG ulOtherInfoLen;
- *   CK_BYTE_PTR pOtherInfo;
- *   CK_ULONG ulPublicDataLen;
- *   CK_BYTE_PTR pPublicData;
- * } CK_X9_42_DH1_DERIVE_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-public class CK_X9_42_DH1_DERIVE_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-    *   CK_X9_42_DH_KDF_TYPE kdf;
-     * </PRE>
-     */
-    public long kdf;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulOtherInfoLen;
-     *   CK_BYTE_PTR pOtherInfo;
-     * </PRE>
-     */
-    public byte[] pOtherInfo;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulPublicDataLen;
-     *   CK_BYTE_PTR pPublicData;
-     * </PRE>
-     */
-    public byte[] pPublicData;
-
-    /**
-     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
-     *
-     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("kdf: 0x");
-        sb.append(Functions.toFullHexString(kdf));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pOtherInfoLen: ");
-        sb.append(pOtherInfo.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pOtherInfo: ");
-        sb.append(Functions.toHexString(pOtherInfo));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicDataLen: ");
-        sb.append(pPublicData.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicData: ");
-        sb.append(Functions.toHexString(pPublicData));
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/CK_X9_42_DH2_DERIVE_PARAMS.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * class CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE mechanisms.<p>
- * <B>PKCS#11 structure:</B>
- * <PRE>
- * typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
- *   CK_X9_42_DH_KDF_TYPE kdf;
- *   CK_ULONG ulOtherInfoLen;
- *   CK_BYTE_PTR pOtherInfo;
- *   CK_ULONG ulPublicDataLen;
- *   CK_BYTE_PTR pPublicData;
- *   CK_ULONG ulPrivateDataLen;
- *   CK_OBJECT_HANDLE hPrivateData;
- *   CK_ULONG ulPublicDataLen2;
- *   CK_BYTE_PTR pPublicData2;
- * } CK_X9_42_DH2_DERIVE_PARAMS;
- * </PRE>
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-public class CK_X9_42_DH2_DERIVE_PARAMS {
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_X9_42_DH_KDF_TYPE kdf;
-     * </PRE>
-     */
-    public long kdf;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulOtherInfoLen;
-     *   CK_BYTE_PTR pOtherInfo;
-     * </PRE>
-     */
-    public byte[] pOtherInfo;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulPublicDataLen;
-     *   CK_BYTE_PTR pPublicData;
-     * </PRE>
-     */
-    public byte[] pPublicData;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulPrivateDataLen;
-     * </PRE>
-     */
-    public long ulPrivateDataLen;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_OBJECT_HANDLE hPrivateData;
-     * </PRE>
-     */
-    public long hPrivateData;
-
-    /**
-     * <B>PKCS#11:</B>
-     * <PRE>
-     *   CK_ULONG ulPublicDataLen2;
-     *   CK_BYTE_PTR pPublicData2;
-     * </PRE>
-     */
-    public byte[] pPublicData2;
-
-    /**
-     * Returns the string representation of CK_PKCS5_PBKD2_PARAMS.
-     *
-     * @return the string representation of CK_PKCS5_PBKD2_PARAMS
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(Constants.INDENT);
-        sb.append("kdf: 0x");
-        sb.append(Functions.toFullHexString(kdf));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pOtherInfoLen: ");
-        sb.append(pOtherInfo.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pOtherInfo: ");
-        sb.append(Functions.toHexString(pOtherInfo));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicDataLen: ");
-        sb.append(pPublicData.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicData: ");
-        sb.append(Functions.toHexString(pPublicData));
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("ulPrivateDataLen: ");
-        sb.append(ulPrivateDataLen);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("hPrivateData: ");
-        sb.append(hPrivateData);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicDataLen2: ");
-        sb.append(pPublicData2.length);
-        sb.append(Constants.NEWLINE);
-
-        sb.append(Constants.INDENT);
-        sb.append("pPublicData2: ");
-        sb.append(Functions.toHexString(pPublicData2));
-        //buffer.append(Constants.NEWLINE);
-
-        return sb.toString();
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/Constants.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-
-/**
- * This class holds only final static member variables that are constants
- * in this package.
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class Constants {
-
-    public static final String NEWLINE = System.lineSeparator();
-
-    public static final String INDENT = "  ";
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/Functions.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,905 +0,0 @@
-/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-import java.math.BigInteger;
-
-import java.util.*;
-
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * This class contains onyl static methods. It is the place for all functions
- * that are used by several classes in this package.
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-public class Functions {
-
-    // maps between ids and their names, forward and reverse
-    // ids are stored as Integers to save space
-    // since only the lower 32 bits are ever used anyway
-
-    // mechanisms (CKM_*)
-    private static final Map<Integer,String> mechNames =
-        new HashMap<Integer,String>();
-
-    private static final Map<String,Integer> mechIds =
-        new HashMap<String,Integer>();
-
-    // key types (CKK_*)
-    private static final Map<Integer,String> keyNames =
-        new HashMap<Integer,String>();
-
-    private static final Map<String,Integer> keyIds =
-        new HashMap<String,Integer>();
-
-    // attributes (CKA_*)
-    private static final Map<Integer,String> attributeNames =
-        new HashMap<Integer,String>();
-
-    private static final Map<String,Integer> attributeIds =
-        new HashMap<String,Integer>();
-
-    // object classes (CKO_*)
-    private static final Map<Integer,String> objectClassNames =
-        new HashMap<Integer,String>();
-
-    private static final Map<String,Integer> objectClassIds =
-        new HashMap<String,Integer>();
-
-
-    /**
-     * For converting numbers to their hex presentation.
-     */
-    private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
-
-    /**
-     * Converts a long value to a hexadecimal String of length 16. Includes
-     * leading zeros if necessary.
-     *
-     * @param value The long value to be converted.
-     * @return The hexadecimal string representation of the long value.
-     */
-    public static String toFullHexString(long value) {
-        long currentValue = value;
-        StringBuilder sb = new StringBuilder(16);
-        for(int j = 0; j < 16; j++) {
-            int currentDigit = (int) currentValue & 0xf;
-            sb.append(HEX_DIGITS[currentDigit]);
-            currentValue >>>= 4;
-        }
-
-        return sb.reverse().toString();
-    }
-
-    /**
-     * Converts a int value to a hexadecimal String of length 8. Includes
-     * leading zeros if necessary.
-     *
-     * @param value The int value to be converted.
-     * @return The hexadecimal string representation of the int value.
-     */
-    public static String toFullHexString(int value) {
-        int currentValue = value;
-        StringBuilder sb = new StringBuilder(8);
-        for(int i = 0; i < 8; i++) {
-            int currentDigit = currentValue & 0xf;
-            sb.append(HEX_DIGITS[currentDigit]);
-            currentValue >>>= 4;
-        }
-
-        return sb.reverse().toString();
-    }
-
-    /**
-     * converts a long value to a hexadecimal String
-     *
-     * @param value the long value to be converted
-     * @return the hexadecimal string representation of the long value
-     */
-    public static String toHexString(long value) {
-        return Long.toHexString(value);
-    }
-
-    /**
-     * Converts a byte array to a hexadecimal String. Each byte is presented by
-     * its two digit hex-code; 0x0A -> "0a", 0x00 -> "00". No leading "0x" is
-     * included in the result.
-     *
-     * @param value the byte array to be converted
-     * @return the hexadecimal string representation of the byte array
-     */
-    public static String toHexString(byte[] value) {
-        if (value == null) {
-            return null;
-        }
-
-        StringBuilder sb = new StringBuilder(2 * value.length);
-        int          single;
-
-        for (int i = 0; i < value.length; i++) {
-            single = value[i] & 0xFF;
-
-            if (single < 0x10) {
-                sb.append('0');
-            }
-
-            sb.append(Integer.toString(single, 16));
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * converts a long value to a binary String
-     *
-     * @param value the long value to be converted
-     * @return the binary string representation of the long value
-     */
-    public static String toBinaryString(long value) {
-        return Long.toString(value, 2);
-    }
-
-    /**
-     * converts a byte array to a binary String
-     *
-     * @param value the byte array to be converted
-     * @return the binary string representation of the byte array
-     */
-    public static String toBinaryString(byte[] value) {
-        BigInteger helpBigInteger = new BigInteger(1, value);
-
-        return helpBigInteger.toString(2);
-    }
-
-    private static class Flags {
-        private final long[] flagIds;
-        private final String[] flagNames;
-        Flags(long[] flagIds, String[] flagNames) {
-            if (flagIds.length != flagNames.length) {
-                throw new AssertionError("Array lengths do not match");
-            }
-            this.flagIds = flagIds;
-            this.flagNames = flagNames;
-        }
-        String toString(long val) {
-            StringBuilder sb = new StringBuilder();
-            boolean first = true;
-            for (int i = 0; i < flagIds.length; i++) {
-                if ((val & flagIds[i]) != 0) {
-                    if (first == false) {
-                        sb.append(" | ");
-                    }
-                    sb.append(flagNames[i]);
-                    first = false;
-                }
-            }
-            return sb.toString();
-        }
-    }
-
-    private static final Flags slotInfoFlags = new Flags(new long[] {
-        CKF_TOKEN_PRESENT,
-        CKF_REMOVABLE_DEVICE,
-        CKF_HW_SLOT,
-    }, new String[] {
-        "CKF_TOKEN_PRESENT",
-        "CKF_REMOVABLE_DEVICE",
-        "CKF_HW_SLOT",
-    });
-
-    /**
-     * converts the long value flags to a SlotInfoFlag string
-     *
-     * @param flags the flags to be converted
-     * @return the SlotInfoFlag string representation of the flags
-     */
-    public static String slotInfoFlagsToString(long flags) {
-        return slotInfoFlags.toString(flags);
-    }
-
-    private static final Flags tokenInfoFlags = new Flags(new long[] {
-        CKF_RNG,
-        CKF_WRITE_PROTECTED,
-        CKF_LOGIN_REQUIRED,
-        CKF_USER_PIN_INITIALIZED,
-        CKF_RESTORE_KEY_NOT_NEEDED,
-        CKF_CLOCK_ON_TOKEN,
-        CKF_PROTECTED_AUTHENTICATION_PATH,
-        CKF_DUAL_CRYPTO_OPERATIONS,
-        CKF_TOKEN_INITIALIZED,
-        CKF_SECONDARY_AUTHENTICATION,
-        CKF_USER_PIN_COUNT_LOW,
-        CKF_USER_PIN_FINAL_TRY,
-        CKF_USER_PIN_LOCKED,
-        CKF_USER_PIN_TO_BE_CHANGED,
-        CKF_SO_PIN_COUNT_LOW,
-        CKF_SO_PIN_FINAL_TRY,
-        CKF_SO_PIN_LOCKED,
-        CKF_SO_PIN_TO_BE_CHANGED,
-    }, new String[] {
-        "CKF_RNG",
-        "CKF_WRITE_PROTECTED",
-        "CKF_LOGIN_REQUIRED",
-        "CKF_USER_PIN_INITIALIZED",
-        "CKF_RESTORE_KEY_NOT_NEEDED",
-        "CKF_CLOCK_ON_TOKEN",
-        "CKF_PROTECTED_AUTHENTICATION_PATH",
-        "CKF_DUAL_CRYPTO_OPERATIONS",
-        "CKF_TOKEN_INITIALIZED",
-        "CKF_SECONDARY_AUTHENTICATION",
-        "CKF_USER_PIN_COUNT_LOW",
-        "CKF_USER_PIN_FINAL_TRY",
-        "CKF_USER_PIN_LOCKED",
-        "CKF_USER_PIN_TO_BE_CHANGED",
-        "CKF_SO_PIN_COUNT_LOW",
-        "CKF_SO_PIN_FINAL_TRY",
-        "CKF_SO_PIN_LOCKED",
-        "CKF_SO_PIN_TO_BE_CHANGED",
-    });
-
-    /**
-     * converts long value flags to a TokenInfoFlag string
-     *
-     * @param flags the flags to be converted
-     * @return the TokenInfoFlag string representation of the flags
-     */
-    public static String tokenInfoFlagsToString(long flags) {
-        return tokenInfoFlags.toString(flags);
-    }
-
-    private static final Flags sessionInfoFlags = new Flags(new long[] {
-        CKF_RW_SESSION,
-        CKF_SERIAL_SESSION,
-    }, new String[] {
-        "CKF_RW_SESSION",
-        "CKF_SERIAL_SESSION",
-    });
-
-    /**
-     * converts the long value flags to a SessionInfoFlag string
-     *
-     * @param flags the flags to be converted
-     * @return the SessionInfoFlag string representation of the flags
-     */
-    public static String sessionInfoFlagsToString(long flags) {
-        return sessionInfoFlags.toString(flags);
-    }
-
-    /**
-     * converts the long value state to a SessionState string
-     *
-     * @param state the state to be converted
-     * @return the SessionState string representation of the state
-     */
-    public static String sessionStateToString(long state) {
-        String name;
-
-        if (state == CKS_RO_PUBLIC_SESSION) {
-            name = "CKS_RO_PUBLIC_SESSION";
-        } else if (state == CKS_RO_USER_FUNCTIONS) {
-            name = "CKS_RO_USER_FUNCTIONS";
-        } else if (state == CKS_RW_PUBLIC_SESSION) {
-            name = "CKS_RW_PUBLIC_SESSION";
-        } else if (state == CKS_RW_USER_FUNCTIONS) {
-            name = "CKS_RW_USER_FUNCTIONS";
-        } else if (state == CKS_RW_SO_FUNCTIONS) {
-            name = "CKS_RW_SO_FUNCTIONS";
-        } else {
-            name = "ERROR: unknown session state 0x" + toFullHexString(state);
-        }
-
-        return name;
-    }
-
-    private static final Flags mechanismInfoFlags = new Flags(new long[] {
-        CKF_HW,
-        CKF_ENCRYPT,
-        CKF_DECRYPT,
-        CKF_DIGEST,
-        CKF_SIGN,
-        CKF_SIGN_RECOVER,
-        CKF_VERIFY,
-        CKF_VERIFY_RECOVER,
-        CKF_GENERATE,
-        CKF_GENERATE_KEY_PAIR,
-        CKF_WRAP,
-        CKF_UNWRAP,
-        CKF_DERIVE,
-        CKF_EC_F_P,
-        CKF_EC_F_2M,
-        CKF_EC_ECPARAMETERS,
-        CKF_EC_NAMEDCURVE,
-        CKF_EC_UNCOMPRESS,
-        CKF_EC_COMPRESS,
-        CKF_EXTENSION,
-    }, new String[] {
-        "CKF_HW",
-        "CKF_ENCRYPT",
-        "CKF_DECRYPT",
-        "CKF_DIGEST",
-        "CKF_SIGN",
-        "CKF_SIGN_RECOVER",
-        "CKF_VERIFY",
-        "CKF_VERIFY_RECOVER",
-        "CKF_GENERATE",
-        "CKF_GENERATE_KEY_PAIR",
-        "CKF_WRAP",
-        "CKF_UNWRAP",
-        "CKF_DERIVE",
-        "CKF_EC_F_P",
-        "CKF_EC_F_2M",
-        "CKF_EC_ECPARAMETERS",
-        "CKF_EC_NAMEDCURVE",
-        "CKF_EC_UNCOMPRESS",
-        "CKF_EC_COMPRESS",
-        "CKF_EXTENSION",
-    });
-
-    /**
-     * converts the long value flags to a MechanismInfoFlag string
-     *
-     * @param flags the flags to be converted
-     * @return the MechanismInfoFlag string representation of the flags
-     */
-    public static String mechanismInfoFlagsToString(long flags) {
-        return mechanismInfoFlags.toString(flags);
-    }
-
-    private static String getName(Map<Integer,String> nameMap, long id) {
-        String name = null;
-        if ((id >>> 32) == 0) {
-            name = nameMap.get(Integer.valueOf((int)id));
-        }
-        if (name == null) {
-            name = "Unknown 0x" + toFullHexString(id);
-        }
-        return name;
-    }
-
-    public static long getId(Map<String,Integer> idMap, String name) {
-        Integer mech = idMap.get(name);
-        if (mech == null) {
-            throw new IllegalArgumentException("Unknown name " + name);
-        }
-        return mech.intValue() & 0xffffffffL;
-    }
-
-    public static String getMechanismName(long id) {
-        return getName(mechNames, id);
-    }
-
-    public static long getMechanismId(String name) {
-        return getId(mechIds, name);
-    }
-
-    public static String getKeyName(long id) {
-        return getName(keyNames, id);
-    }
-
-    public static long getKeyId(String name) {
-        return getId(keyIds, name);
-    }
-
-    public static String getAttributeName(long id) {
-        return getName(attributeNames, id);
-    }
-
-    public static long getAttributeId(String name) {
-        return getId(attributeIds, name);
-    }
-
-    public static String getObjectClassName(long id) {
-        return getName(objectClassNames, id);
-    }
-
-    public static long getObjectClassId(String name) {
-        return getId(objectClassIds, name);
-    }
-
-    /**
-     * Check the given arrays for equalitiy. This method considers both arrays as
-     * equal, if both are <code>null</code> or both have the same length and
-     * contain exactly the same char values.
-     *
-     * @param array1 The first array.
-     * @param array2 The second array.
-     * @return True, if both arrays are <code>null</code> or both have the same
-     *         length and contain exactly the same char values. False, otherwise.
-     * @preconditions
-     * @postconditions
-     */
-    private static boolean equals(char[] array1, char[] array2) {
-        return Arrays.equals(array1, array2);
-    }
-
-    /**
-     * Check the given dates for equalitiy. This method considers both dates as
-     * equal, if both are <code>null</code> or both contain exactly the same char
-     * values.
-     *
-     * @param date1 The first date.
-     * @param date2 The second date.
-     * @return True, if both dates are <code>null</code> or both contain the same
-     *         char values. False, otherwise.
-     * @preconditions
-     * @postconditions
-     */
-    public static boolean equals(CK_DATE date1, CK_DATE date2) {
-        boolean equal = false;
-
-        if (date1 == date2) {
-            equal = true;
-        } else if ((date1 != null) && (date2 != null)) {
-            equal = equals(date1.year, date2.year)
-              && equals(date1.month, date2.month)
-              && equals(date1.day, date2.day);
-        } else {
-            equal = false;
-        }
-
-        return equal ;
-    }
-
-    /**
-     * Calculate a hash code for the given byte array.
-     *
-     * @param array The byte array.
-     * @return A hash code for the given array.
-     * @preconditions
-     * @postconditions
-     */
-    public static int hashCode(byte[] array) {
-        int hash = 0;
-
-        if (array != null) {
-            for (int i = 0; (i < 4) && (i < array.length); i++) {
-                hash ^= (0xFF & array[i]) << ((i%4) << 3);
-            }
-        }
-
-        return hash ;
-    }
-
-    /**
-     * Calculate a hash code for the given char array.
-     *
-     * @param array The char array.
-     * @return A hash code for the given array.
-     * @preconditions
-     * @postconditions
-     */
-    public static int hashCode(char[] array) {
-        int hash = 0;
-
-        if (array != null) {
-            for (int i = 0; (i < 4) && (i < array.length); i++) {
-                hash ^= (0xFFFF & array[i]) << ((i%2) << 4);
-            }
-        }
-
-        return hash ;
-    }
-
-    /**
-     * Calculate a hash code for the given date object.
-     *
-     * @param date The date object.
-     * @return A hash code for the given date.
-     * @preconditions
-     * @postconditions
-     */
-    public static int hashCode(CK_DATE date) {
-        int hash = 0;
-
-        if (date != null) {
-            if (date.year.length == 4) {
-                hash ^= (0xFFFF & date.year[0]) << 16;
-                hash ^= 0xFFFF & date.year[1];
-                hash ^= (0xFFFF & date.year[2]) << 16;
-                hash ^= 0xFFFF & date.year[3];
-            }
-            if (date.month.length == 2) {
-                hash ^= (0xFFFF & date.month[0]) << 16;
-                hash ^= 0xFFFF & date.month[1];
-            }
-            if (date.day.length == 2) {
-                hash ^= (0xFFFF & date.day[0]) << 16;
-                hash ^= 0xFFFF & date.day[1];
-            }
-        }
-
-        return hash ;
-    }
-
-    private static void addMapping(Map<Integer,String> nameMap,
-            Map<String,Integer> idMap, long id, String name) {
-        if ((id >>> 32) != 0) {
-            throw new AssertionError("Id has high bits set: " + id + ", " + name);
-        }
-        Integer intId = Integer.valueOf((int)id);
-        if (nameMap.put(intId, name) != null) {
-            throw new AssertionError("Duplicate id: " + id + ", " + name);
-        }
-        if (idMap.put(name, intId) != null) {
-            throw new AssertionError("Duplicate name: " + id + ", " + name);
-        }
-    }
-
-    private static void addMech(long id, String name) {
-        addMapping(mechNames, mechIds, id, name);
-    }
-
-    private static void addKeyType(long id, String name) {
-        addMapping(keyNames, keyIds, id, name);
-    }
-
-    private static void addAttribute(long id, String name) {
-        addMapping(attributeNames, attributeIds, id, name);
-    }
-
-    private static void addObjectClass(long id, String name) {
-        addMapping(objectClassNames, objectClassIds, id, name);
-    }
-
-    static {
-        addMech(CKM_RSA_PKCS_KEY_PAIR_GEN,      "CKM_RSA_PKCS_KEY_PAIR_GEN");
-        addMech(CKM_RSA_PKCS,                   "CKM_RSA_PKCS");
-        addMech(CKM_RSA_9796,                   "CKM_RSA_9796");
-        addMech(CKM_RSA_X_509,                  "CKM_RSA_X_509");
-        addMech(CKM_MD2_RSA_PKCS,               "CKM_MD2_RSA_PKCS");
-        addMech(CKM_MD5_RSA_PKCS,               "CKM_MD5_RSA_PKCS");
-        addMech(CKM_SHA1_RSA_PKCS,              "CKM_SHA1_RSA_PKCS");
-        addMech(CKM_RIPEMD128_RSA_PKCS,         "CKM_RIPEMD128_RSA_PKCS");
-        addMech(CKM_RIPEMD160_RSA_PKCS,         "CKM_RIPEMD160_RSA_PKCS");
-        addMech(CKM_RSA_PKCS_OAEP,              "CKM_RSA_PKCS_OAEP");
-        addMech(CKM_RSA_X9_31_KEY_PAIR_GEN,     "CKM_RSA_X9_31_KEY_PAIR_GEN");
-        addMech(CKM_RSA_X9_31,                  "CKM_RSA_X9_31");
-        addMech(CKM_SHA1_RSA_X9_31,             "CKM_SHA1_RSA_X9_31");
-        addMech(CKM_RSA_PKCS_PSS,               "CKM_RSA_PKCS_PSS");
-        addMech(CKM_SHA1_RSA_PKCS_PSS,          "CKM_SHA1_RSA_PKCS_PSS");
-        addMech(CKM_DSA_KEY_PAIR_GEN,           "CKM_DSA_KEY_PAIR_GEN");
-        addMech(CKM_DSA,                        "CKM_DSA");
-        addMech(CKM_DSA_SHA1,                   "CKM_DSA_SHA1");
-        addMech(CKM_DH_PKCS_KEY_PAIR_GEN,       "CKM_DH_PKCS_KEY_PAIR_GEN");
-        addMech(CKM_DH_PKCS_DERIVE,             "CKM_DH_PKCS_DERIVE");
-        addMech(CKM_X9_42_DH_KEY_PAIR_GEN,      "CKM_X9_42_DH_KEY_PAIR_GEN");
-        addMech(CKM_X9_42_DH_DERIVE,            "CKM_X9_42_DH_DERIVE");
-        addMech(CKM_X9_42_DH_HYBRID_DERIVE,     "CKM_X9_42_DH_HYBRID_DERIVE");
-        addMech(CKM_X9_42_MQV_DERIVE,           "CKM_X9_42_MQV_DERIVE");
-        addMech(CKM_SHA224_RSA_PKCS,            "CKM_SHA224_RSA_PKCS");
-        addMech(CKM_SHA256_RSA_PKCS,            "CKM_SHA256_RSA_PKCS");
-        addMech(CKM_SHA384_RSA_PKCS,            "CKM_SHA384_RSA_PKCS");
-        addMech(CKM_SHA512_RSA_PKCS,            "CKM_SHA512_RSA_PKCS");
-        addMech(CKM_RC2_KEY_GEN,                "CKM_RC2_KEY_GEN");
-        addMech(CKM_RC2_ECB,                    "CKM_RC2_ECB");
-        addMech(CKM_RC2_CBC,                    "CKM_RC2_CBC");
-        addMech(CKM_RC2_MAC,                    "CKM_RC2_MAC");
-        addMech(CKM_RC2_MAC_GENERAL,            "CKM_RC2_MAC_GENERAL");
-        addMech(CKM_RC2_CBC_PAD,                "CKM_RC2_CBC_PAD");
-        addMech(CKM_RC4_KEY_GEN,                "CKM_RC4_KEY_GEN");
-        addMech(CKM_RC4,                        "CKM_RC4");
-        addMech(CKM_DES_KEY_GEN,                "CKM_DES_KEY_GEN");
-        addMech(CKM_DES_ECB,                    "CKM_DES_ECB");
-        addMech(CKM_DES_CBC,                    "CKM_DES_CBC");
-        addMech(CKM_DES_MAC,                    "CKM_DES_MAC");
-        addMech(CKM_DES_MAC_GENERAL,            "CKM_DES_MAC_GENERAL");
-        addMech(CKM_DES_CBC_PAD,                "CKM_DES_CBC_PAD");
-        addMech(CKM_DES2_KEY_GEN,               "CKM_DES2_KEY_GEN");
-        addMech(CKM_DES3_KEY_GEN,               "CKM_DES3_KEY_GEN");
-        addMech(CKM_DES3_ECB,                   "CKM_DES3_ECB");
-        addMech(CKM_DES3_CBC,                   "CKM_DES3_CBC");
-        addMech(CKM_DES3_MAC,                   "CKM_DES3_MAC");
-        addMech(CKM_DES3_MAC_GENERAL,           "CKM_DES3_MAC_GENERAL");
-        addMech(CKM_DES3_CBC_PAD,               "CKM_DES3_CBC_PAD");
-        addMech(CKM_CDMF_KEY_GEN,               "CKM_CDMF_KEY_GEN");
-        addMech(CKM_CDMF_ECB,                   "CKM_CDMF_ECB");
-        addMech(CKM_CDMF_CBC,                   "CKM_CDMF_CBC");
-        addMech(CKM_CDMF_MAC,                   "CKM_CDMF_MAC");
-        addMech(CKM_CDMF_MAC_GENERAL,           "CKM_CDMF_MAC_GENERAL");
-        addMech(CKM_CDMF_CBC_PAD,               "CKM_CDMF_CBC_PAD");
-        addMech(CKM_MD2,                        "CKM_MD2");
-        addMech(CKM_MD2_HMAC,                   "CKM_MD2_HMAC");
-        addMech(CKM_MD2_HMAC_GENERAL,           "CKM_MD2_HMAC_GENERAL");
-        addMech(CKM_MD5,                        "CKM_MD5");
-        addMech(CKM_MD5_HMAC,                   "CKM_MD5_HMAC");
-        addMech(CKM_MD5_HMAC_GENERAL,           "CKM_MD5_HMAC_GENERAL");
-        addMech(CKM_SHA_1,                      "CKM_SHA_1");
-        addMech(CKM_SHA_1_HMAC,                 "CKM_SHA_1_HMAC");
-        addMech(CKM_SHA_1_HMAC_GENERAL,         "CKM_SHA_1_HMAC_GENERAL");
-        addMech(CKM_RIPEMD128,                  "CKM_RIPEMD128");
-        addMech(CKM_RIPEMD128_HMAC,             "CKM_RIPEMD128_HMAC");
-        addMech(CKM_RIPEMD128_HMAC_GENERAL,     "CKM_RIPEMD128_HMAC_GENERAL");
-        addMech(CKM_RIPEMD160,                  "CKM_RIPEMD160");
-        addMech(CKM_RIPEMD160_HMAC,             "CKM_RIPEMD160_HMAC");
-        addMech(CKM_RIPEMD160_HMAC_GENERAL,     "CKM_RIPEMD160_HMAC_GENERAL");
-        addMech(CKM_SHA224,                     "CKM_SHA224");
-        addMech(CKM_SHA224_HMAC,                "CKM_SHA224_HMAC");
-        addMech(CKM_SHA224_HMAC_GENERAL,        "CKM_SHA224_HMAC_GENERAL");
-        addMech(CKM_SHA256,                     "CKM_SHA256");
-        addMech(CKM_SHA256_HMAC,                "CKM_SHA256_HMAC");
-        addMech(CKM_SHA256_HMAC_GENERAL,        "CKM_SHA256_HMAC_GENERAL");
-        addMech(CKM_SHA384,                     "CKM_SHA384");
-        addMech(CKM_SHA384_HMAC,                "CKM_SHA384_HMAC");
-        addMech(CKM_SHA384_HMAC_GENERAL,        "CKM_SHA384_HMAC_GENERAL");
-        addMech(CKM_SHA512,                     "CKM_SHA512");
-        addMech(CKM_SHA512_HMAC,                "CKM_SHA512_HMAC");
-        addMech(CKM_SHA512_HMAC_GENERAL,        "CKM_SHA512_HMAC_GENERAL");
-        addMech(CKM_CAST_KEY_GEN,               "CKM_CAST_KEY_GEN");
-        addMech(CKM_CAST_ECB,                   "CKM_CAST_ECB");
-        addMech(CKM_CAST_CBC,                   "CKM_CAST_CBC");
-        addMech(CKM_CAST_MAC,                   "CKM_CAST_MAC");
-        addMech(CKM_CAST_MAC_GENERAL,           "CKM_CAST_MAC_GENERAL");
-        addMech(CKM_CAST_CBC_PAD,               "CKM_CAST_CBC_PAD");
-        addMech(CKM_CAST3_KEY_GEN,              "CKM_CAST3_KEY_GEN");
-        addMech(CKM_CAST3_ECB,                  "CKM_CAST3_ECB");
-        addMech(CKM_CAST3_CBC,                  "CKM_CAST3_CBC");
-        addMech(CKM_CAST3_MAC,                  "CKM_CAST3_MAC");
-        addMech(CKM_CAST3_MAC_GENERAL,          "CKM_CAST3_MAC_GENERAL");
-        addMech(CKM_CAST3_CBC_PAD,              "CKM_CAST3_CBC_PAD");
-        addMech(CKM_CAST128_KEY_GEN,            "CKM_CAST128_KEY_GEN");
-        addMech(CKM_CAST128_ECB,                "CKM_CAST128_ECB");
-        addMech(CKM_CAST128_CBC,                "CKM_CAST128_CBC");
-        addMech(CKM_CAST128_MAC,                "CKM_CAST128_MAC");
-        addMech(CKM_CAST128_MAC_GENERAL,        "CKM_CAST128_MAC_GENERAL");
-        addMech(CKM_CAST128_CBC_PAD,            "CKM_CAST128_CBC_PAD");
-        addMech(CKM_RC5_KEY_GEN,                "CKM_RC5_KEY_GEN");
-        addMech(CKM_RC5_ECB,                    "CKM_RC5_ECB");
-        addMech(CKM_RC5_CBC,                    "CKM_RC5_CBC");
-        addMech(CKM_RC5_MAC,                    "CKM_RC5_MAC");
-        addMech(CKM_RC5_MAC_GENERAL,            "CKM_RC5_MAC_GENERAL");
-        addMech(CKM_RC5_CBC_PAD,                "CKM_RC5_CBC_PAD");
-        addMech(CKM_IDEA_KEY_GEN,               "CKM_IDEA_KEY_GEN");
-        addMech(CKM_IDEA_ECB,                   "CKM_IDEA_ECB");
-        addMech(CKM_IDEA_CBC,                   "CKM_IDEA_CBC");
-        addMech(CKM_IDEA_MAC,                   "CKM_IDEA_MAC");
-        addMech(CKM_IDEA_MAC_GENERAL,           "CKM_IDEA_MAC_GENERAL");
-        addMech(CKM_IDEA_CBC_PAD,               "CKM_IDEA_CBC_PAD");
-        addMech(CKM_GENERIC_SECRET_KEY_GEN,     "CKM_GENERIC_SECRET_KEY_GEN");
-        addMech(CKM_CONCATENATE_BASE_AND_KEY,   "CKM_CONCATENATE_BASE_AND_KEY");
-        addMech(CKM_CONCATENATE_BASE_AND_DATA,  "CKM_CONCATENATE_BASE_AND_DATA");
-        addMech(CKM_CONCATENATE_DATA_AND_BASE,  "CKM_CONCATENATE_DATA_AND_BASE");
-        addMech(CKM_XOR_BASE_AND_DATA,          "CKM_XOR_BASE_AND_DATA");
-        addMech(CKM_EXTRACT_KEY_FROM_KEY,       "CKM_EXTRACT_KEY_FROM_KEY");
-        addMech(CKM_SSL3_PRE_MASTER_KEY_GEN,    "CKM_SSL3_PRE_MASTER_KEY_GEN");
-        addMech(CKM_SSL3_MASTER_KEY_DERIVE,     "CKM_SSL3_MASTER_KEY_DERIVE");
-        addMech(CKM_SSL3_KEY_AND_MAC_DERIVE,    "CKM_SSL3_KEY_AND_MAC_DERIVE");
-        addMech(CKM_SSL3_MASTER_KEY_DERIVE_DH,  "CKM_SSL3_MASTER_KEY_DERIVE_DH");
-        addMech(CKM_TLS_PRE_MASTER_KEY_GEN,     "CKM_TLS_PRE_MASTER_KEY_GEN");
-        addMech(CKM_TLS_MASTER_KEY_DERIVE,      "CKM_TLS_MASTER_KEY_DERIVE");
-        addMech(CKM_TLS_KEY_AND_MAC_DERIVE,     "CKM_TLS_KEY_AND_MAC_DERIVE");
-        addMech(CKM_TLS_MASTER_KEY_DERIVE_DH,   "CKM_TLS_MASTER_KEY_DERIVE_DH");
-        addMech(CKM_TLS_PRF,                    "CKM_TLS_PRF");
-        addMech(CKM_SSL3_MD5_MAC,               "CKM_SSL3_MD5_MAC");
-        addMech(CKM_SSL3_SHA1_MAC,              "CKM_SSL3_SHA1_MAC");
-        addMech(CKM_MD5_KEY_DERIVATION,         "CKM_MD5_KEY_DERIVATION");
-        addMech(CKM_MD2_KEY_DERIVATION,         "CKM_MD2_KEY_DERIVATION");
-        addMech(CKM_SHA1_KEY_DERIVATION,        "CKM_SHA1_KEY_DERIVATION");
-        addMech(CKM_SHA224_KEY_DERIVATION,      "CKM_SHA224_KEY_DERIVATION");
-        addMech(CKM_SHA256_KEY_DERIVATION,      "CKM_SHA256_KEY_DERIVATION");
-        addMech(CKM_SHA384_KEY_DERIVATION,      "CKM_SHA384_KEY_DERIVATION");
-        addMech(CKM_SHA512_KEY_DERIVATION,      "CKM_SHA512_KEY_DERIVATION");
-        addMech(CKM_PBE_MD2_DES_CBC,            "CKM_PBE_MD2_DES_CBC");
-        addMech(CKM_PBE_MD5_DES_CBC,            "CKM_PBE_MD5_DES_CBC");
-        addMech(CKM_PBE_MD5_CAST_CBC,           "CKM_PBE_MD5_CAST_CBC");
-        addMech(CKM_PBE_MD5_CAST3_CBC,          "CKM_PBE_MD5_CAST3_CBC");
-        addMech(CKM_PBE_MD5_CAST128_CBC,        "CKM_PBE_MD5_CAST128_CBC");
-        addMech(CKM_PBE_SHA1_CAST128_CBC,       "CKM_PBE_SHA1_CAST128_CBC");
-        addMech(CKM_PBE_SHA1_RC4_128,           "CKM_PBE_SHA1_RC4_128");
-        addMech(CKM_PBE_SHA1_RC4_40,            "CKM_PBE_SHA1_RC4_40");
-        addMech(CKM_PBE_SHA1_DES3_EDE_CBC,      "CKM_PBE_SHA1_DES3_EDE_CBC");
-        addMech(CKM_PBE_SHA1_DES2_EDE_CBC,      "CKM_PBE_SHA1_DES2_EDE_CBC");
-        addMech(CKM_PBE_SHA1_RC2_128_CBC,       "CKM_PBE_SHA1_RC2_128_CBC");
-        addMech(CKM_PBE_SHA1_RC2_40_CBC,        "CKM_PBE_SHA1_RC2_40_CBC");
-        addMech(CKM_PKCS5_PBKD2,                "CKM_PKCS5_PBKD2");
-        addMech(CKM_PBA_SHA1_WITH_SHA1_HMAC,    "CKM_PBA_SHA1_WITH_SHA1_HMAC");
-        addMech(CKM_KEY_WRAP_LYNKS,             "CKM_KEY_WRAP_LYNKS");
-        addMech(CKM_KEY_WRAP_SET_OAEP,          "CKM_KEY_WRAP_SET_OAEP");
-        addMech(CKM_SKIPJACK_KEY_GEN,           "CKM_SKIPJACK_KEY_GEN");
-        addMech(CKM_SKIPJACK_ECB64,             "CKM_SKIPJACK_ECB64");
-        addMech(CKM_SKIPJACK_CBC64,             "CKM_SKIPJACK_CBC64");
-        addMech(CKM_SKIPJACK_OFB64,             "CKM_SKIPJACK_OFB64");
-        addMech(CKM_SKIPJACK_CFB64,             "CKM_SKIPJACK_CFB64");
-        addMech(CKM_SKIPJACK_CFB32,             "CKM_SKIPJACK_CFB32");
-        addMech(CKM_SKIPJACK_CFB16,             "CKM_SKIPJACK_CFB16");
-        addMech(CKM_SKIPJACK_CFB8,              "CKM_SKIPJACK_CFB8");
-        addMech(CKM_SKIPJACK_WRAP,              "CKM_SKIPJACK_WRAP");
-        addMech(CKM_SKIPJACK_PRIVATE_WRAP,      "CKM_SKIPJACK_PRIVATE_WRAP");
-        addMech(CKM_SKIPJACK_RELAYX,            "CKM_SKIPJACK_RELAYX");
-        addMech(CKM_KEA_KEY_PAIR_GEN,           "CKM_KEA_KEY_PAIR_GEN");
-        addMech(CKM_KEA_KEY_DERIVE,             "CKM_KEA_KEY_DERIVE");
-        addMech(CKM_FORTEZZA_TIMESTAMP,         "CKM_FORTEZZA_TIMESTAMP");
-        addMech(CKM_BATON_KEY_GEN,              "CKM_BATON_KEY_GEN");
-        addMech(CKM_BATON_ECB128,               "CKM_BATON_ECB128");
-        addMech(CKM_BATON_ECB96,                "CKM_BATON_ECB96");
-        addMech(CKM_BATON_CBC128,               "CKM_BATON_CBC128");
-        addMech(CKM_BATON_COUNTER,              "CKM_BATON_COUNTER");
-        addMech(CKM_BATON_SHUFFLE,              "CKM_BATON_SHUFFLE");
-        addMech(CKM_BATON_WRAP,                 "CKM_BATON_WRAP");
-        addMech(CKM_EC_KEY_PAIR_GEN,            "CKM_EC_KEY_PAIR_GEN");
-        addMech(CKM_ECDSA,                      "CKM_ECDSA");
-        addMech(CKM_ECDSA_SHA1,                 "CKM_ECDSA_SHA1");
-        addMech(CKM_ECDH1_DERIVE,               "CKM_ECDH1_DERIVE");
-        addMech(CKM_ECDH1_COFACTOR_DERIVE,      "CKM_ECDH1_COFACTOR_DERIVE");
-        addMech(CKM_ECMQV_DERIVE,               "CKM_ECMQV_DERIVE");
-        addMech(CKM_JUNIPER_KEY_GEN,            "CKM_JUNIPER_KEY_GEN");
-        addMech(CKM_JUNIPER_ECB128,             "CKM_JUNIPER_ECB128");
-        addMech(CKM_JUNIPER_CBC128,             "CKM_JUNIPER_CBC128");
-        addMech(CKM_JUNIPER_COUNTER,            "CKM_JUNIPER_COUNTER");
-        addMech(CKM_JUNIPER_SHUFFLE,            "CKM_JUNIPER_SHUFFLE");
-        addMech(CKM_JUNIPER_WRAP,               "CKM_JUNIPER_WRAP");
-        addMech(CKM_FASTHASH,                   "CKM_FASTHASH");
-        addMech(CKM_AES_KEY_GEN,                "CKM_AES_KEY_GEN");
-        addMech(CKM_AES_ECB,                    "CKM_AES_ECB");
-        addMech(CKM_AES_CBC,                    "CKM_AES_CBC");
-        addMech(CKM_AES_MAC,                    "CKM_AES_MAC");
-        addMech(CKM_AES_MAC_GENERAL,            "CKM_AES_MAC_GENERAL");
-        addMech(CKM_AES_CBC_PAD,                "CKM_AES_CBC_PAD");
-        addMech(CKM_BLOWFISH_KEY_GEN,           "CKM_BLOWFISH_KEY_GEN");
-        addMech(CKM_BLOWFISH_CBC,               "CKM_BLOWFISH_CBC");
-        addMech(CKM_DSA_PARAMETER_GEN,          "CKM_DSA_PARAMETER_GEN");
-        addMech(CKM_DH_PKCS_PARAMETER_GEN,      "CKM_DH_PKCS_PARAMETER_GEN");
-        addMech(CKM_X9_42_DH_PARAMETER_GEN,     "CKM_X9_42_DH_PARAMETER_GEN");
-        addMech(CKM_VENDOR_DEFINED,             "CKM_VENDOR_DEFINED");
-
-        addMech(CKM_NSS_TLS_PRF_GENERAL,        "CKM_NSS_TLS_PRF_GENERAL");
-
-        addMech(PCKM_SECURERANDOM,              "SecureRandom");
-        addMech(PCKM_KEYSTORE,                  "KeyStore");
-
-        addKeyType(CKK_RSA,                     "CKK_RSA");
-        addKeyType(CKK_DSA,                     "CKK_DSA");
-        addKeyType(CKK_DH,                      "CKK_DH");
-        addKeyType(CKK_EC,                      "CKK_EC");
-        addKeyType(CKK_X9_42_DH,                "CKK_X9_42_DH");
-        addKeyType(CKK_KEA,                     "CKK_KEA");
-        addKeyType(CKK_GENERIC_SECRET,          "CKK_GENERIC_SECRET");
-        addKeyType(CKK_RC2,                     "CKK_RC2");
-        addKeyType(CKK_RC4,                     "CKK_RC4");
-        addKeyType(CKK_DES,                     "CKK_DES");
-        addKeyType(CKK_DES2,                    "CKK_DES2");
-        addKeyType(CKK_DES3,                    "CKK_DES3");
-        addKeyType(CKK_CAST,                    "CKK_CAST");
-        addKeyType(CKK_CAST3,                   "CKK_CAST3");
-        addKeyType(CKK_CAST128,                 "CKK_CAST128");
-        addKeyType(CKK_RC5,                     "CKK_RC5");
-        addKeyType(CKK_IDEA,                    "CKK_IDEA");
-        addKeyType(CKK_SKIPJACK,                "CKK_SKIPJACK");
-        addKeyType(CKK_BATON,                   "CKK_BATON");
-        addKeyType(CKK_JUNIPER,                 "CKK_JUNIPER");
-        addKeyType(CKK_CDMF,                    "CKK_CDMF");
-        addKeyType(CKK_AES,                     "CKK_AES");
-        addKeyType(CKK_BLOWFISH,                "CKK_BLOWFISH");
-        addKeyType(CKK_VENDOR_DEFINED,          "CKK_VENDOR_DEFINED");
-
-        addKeyType(PCKK_ANY,                    "*");
-
-        addAttribute(CKA_CLASS,                 "CKA_CLASS");
-        addAttribute(CKA_TOKEN,                 "CKA_TOKEN");
-        addAttribute(CKA_PRIVATE,               "CKA_PRIVATE");
-        addAttribute(CKA_LABEL,                 "CKA_LABEL");
-        addAttribute(CKA_APPLICATION,           "CKA_APPLICATION");
-        addAttribute(CKA_VALUE,                 "CKA_VALUE");
-        addAttribute(CKA_OBJECT_ID,             "CKA_OBJECT_ID");
-        addAttribute(CKA_CERTIFICATE_TYPE,      "CKA_CERTIFICATE_TYPE");
-        addAttribute(CKA_ISSUER,                "CKA_ISSUER");
-        addAttribute(CKA_SERIAL_NUMBER,         "CKA_SERIAL_NUMBER");
-        addAttribute(CKA_AC_ISSUER,             "CKA_AC_ISSUER");
-        addAttribute(CKA_OWNER,                 "CKA_OWNER");
-        addAttribute(CKA_ATTR_TYPES,            "CKA_ATTR_TYPES");
-        addAttribute(CKA_TRUSTED,               "CKA_TRUSTED");
-        addAttribute(CKA_KEY_TYPE,              "CKA_KEY_TYPE");
-        addAttribute(CKA_SUBJECT,               "CKA_SUBJECT");
-        addAttribute(CKA_ID,                    "CKA_ID");
-        addAttribute(CKA_SENSITIVE,             "CKA_SENSITIVE");
-        addAttribute(CKA_ENCRYPT,               "CKA_ENCRYPT");
-        addAttribute(CKA_DECRYPT,               "CKA_DECRYPT");
-        addAttribute(CKA_WRAP,                  "CKA_WRAP");
-        addAttribute(CKA_UNWRAP,                "CKA_UNWRAP");
-        addAttribute(CKA_SIGN,                  "CKA_SIGN");
-        addAttribute(CKA_SIGN_RECOVER,          "CKA_SIGN_RECOVER");
-        addAttribute(CKA_VERIFY,                "CKA_VERIFY");
-        addAttribute(CKA_VERIFY_RECOVER,        "CKA_VERIFY_RECOVER");
-        addAttribute(CKA_DERIVE,                "CKA_DERIVE");
-        addAttribute(CKA_START_DATE,            "CKA_START_DATE");
-        addAttribute(CKA_END_DATE,              "CKA_END_DATE");
-        addAttribute(CKA_MODULUS,               "CKA_MODULUS");
-        addAttribute(CKA_MODULUS_BITS,          "CKA_MODULUS_BITS");
-        addAttribute(CKA_PUBLIC_EXPONENT,       "CKA_PUBLIC_EXPONENT");
-        addAttribute(CKA_PRIVATE_EXPONENT,      "CKA_PRIVATE_EXPONENT");
-        addAttribute(CKA_PRIME_1,               "CKA_PRIME_1");
-        addAttribute(CKA_PRIME_2,               "CKA_PRIME_2");
-        addAttribute(CKA_EXPONENT_1,            "CKA_EXPONENT_1");
-        addAttribute(CKA_EXPONENT_2,            "CKA_EXPONENT_2");
-        addAttribute(CKA_COEFFICIENT,           "CKA_COEFFICIENT");
-        addAttribute(CKA_PRIME,                 "CKA_PRIME");
-        addAttribute(CKA_SUBPRIME,              "CKA_SUBPRIME");
-        addAttribute(CKA_BASE,                  "CKA_BASE");
-        addAttribute(CKA_PRIME_BITS,            "CKA_PRIME_BITS");
-        addAttribute(CKA_SUB_PRIME_BITS,        "CKA_SUB_PRIME_BITS");
-        addAttribute(CKA_VALUE_BITS,            "CKA_VALUE_BITS");
-        addAttribute(CKA_VALUE_LEN,             "CKA_VALUE_LEN");
-        addAttribute(CKA_EXTRACTABLE,           "CKA_EXTRACTABLE");
-        addAttribute(CKA_LOCAL,                 "CKA_LOCAL");
-        addAttribute(CKA_NEVER_EXTRACTABLE,     "CKA_NEVER_EXTRACTABLE");
-        addAttribute(CKA_ALWAYS_SENSITIVE,      "CKA_ALWAYS_SENSITIVE");
-        addAttribute(CKA_KEY_GEN_MECHANISM,     "CKA_KEY_GEN_MECHANISM");
-        addAttribute(CKA_MODIFIABLE,            "CKA_MODIFIABLE");
-        addAttribute(CKA_EC_PARAMS,             "CKA_EC_PARAMS");
-        addAttribute(CKA_EC_POINT,              "CKA_EC_POINT");
-        addAttribute(CKA_SECONDARY_AUTH,        "CKA_SECONDARY_AUTH");
-        addAttribute(CKA_AUTH_PIN_FLAGS,        "CKA_AUTH_PIN_FLAGS");
-        addAttribute(CKA_HW_FEATURE_TYPE,       "CKA_HW_FEATURE_TYPE");
-        addAttribute(CKA_RESET_ON_INIT,         "CKA_RESET_ON_INIT");
-        addAttribute(CKA_HAS_RESET,             "CKA_HAS_RESET");
-        addAttribute(CKA_VENDOR_DEFINED,        "CKA_VENDOR_DEFINED");
-        addAttribute(CKA_NETSCAPE_DB,           "CKA_NETSCAPE_DB");
-
-        addAttribute(CKA_NETSCAPE_TRUST_SERVER_AUTH,      "CKA_NETSCAPE_TRUST_SERVER_AUTH");
-        addAttribute(CKA_NETSCAPE_TRUST_CLIENT_AUTH,      "CKA_NETSCAPE_TRUST_CLIENT_AUTH");
-        addAttribute(CKA_NETSCAPE_TRUST_CODE_SIGNING,     "CKA_NETSCAPE_TRUST_CODE_SIGNING");
-        addAttribute(CKA_NETSCAPE_TRUST_EMAIL_PROTECTION, "CKA_NETSCAPE_TRUST_EMAIL_PROTECTION");
-        addAttribute(CKA_NETSCAPE_CERT_SHA1_HASH,         "CKA_NETSCAPE_CERT_SHA1_HASH");
-        addAttribute(CKA_NETSCAPE_CERT_MD5_HASH,          "CKA_NETSCAPE_CERT_MD5_HASH");
-
-        addObjectClass(CKO_DATA,                "CKO_DATA");
-        addObjectClass(CKO_CERTIFICATE,         "CKO_CERTIFICATE");
-        addObjectClass(CKO_PUBLIC_KEY,          "CKO_PUBLIC_KEY");
-        addObjectClass(CKO_PRIVATE_KEY,         "CKO_PRIVATE_KEY");
-        addObjectClass(CKO_SECRET_KEY,          "CKO_SECRET_KEY");
-        addObjectClass(CKO_HW_FEATURE,          "CKO_HW_FEATURE");
-        addObjectClass(CKO_DOMAIN_PARAMETERS,   "CKO_DOMAIN_PARAMETERS");
-        addObjectClass(CKO_VENDOR_DEFINED,      "CKO_VENDOR_DEFINED");
-
-        addObjectClass(PCKO_ANY,                "*");
-
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/PKCS11.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1827 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import sun.security.util.Debug;
-
-import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
-
-/**
- * This is the default implementation of the PKCS11 interface. IT connects to
- * the pkcs11wrapper.dll file, which is the native part of this library.
- * The strange and awkward looking initialization was chosen to avoid calling
- * loadLibrary from a static initialization block, because this would complicate
- * the use in applets.
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- * @invariants (pkcs11ModulePath_ <> null)
- */
-public class PKCS11 {
-
-    /**
-     * The name of the native part of the wrapper; i.e. the filename without
-     * the extension (e.g. ".DLL" or ".so").
-     */
-    private static final String PKCS11_WRAPPER = "j2pkcs11";
-
-    static {
-        // cannot use LoadLibraryAction because that would make the native
-        // library available to the bootclassloader, but we run in the
-        // extension classloader.
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            public Object run() {
-                System.loadLibrary(PKCS11_WRAPPER);
-                return null;
-            }
-        });
-        boolean enableDebug = Debug.getInstance("sunpkcs11") != null;
-        initializeLibrary(enableDebug);
-    }
-
-    public static void loadNative() {
-        // dummy method that can be called to make sure the native
-        // portion has been loaded. actual loading happens in the
-        // static initializer, hence this method is empty.
-    }
-
-    /**
-     * The PKCS#11 module to connect to. This is the PKCS#11 driver of the token;
-     * e.g. pk2priv.dll.
-     */
-    private final String pkcs11ModulePath;
-
-    private long pNativeData;
-
-    /**
-     * This method does the initialization of the native library. It is called
-     * exactly once for this class.
-     *
-     * @preconditions
-     * @postconditions
-     */
-    private static native void initializeLibrary(boolean debug);
-
-    // XXX
-    /**
-     * This method does the finalization of the native library. It is called
-     * exactly once for this class. The library uses this method for a clean-up
-     * of any resources.
-     *
-     * @preconditions
-     * @postconditions
-     */
-    private static native void finalizeLibrary();
-
-    private static final Map<String,PKCS11> moduleMap =
-        new HashMap<String,PKCS11>();
-
-    /**
-     * Connects to the PKCS#11 driver given. The filename must contain the
-     * path, if the driver is not in the system's search path.
-     *
-     * @param pkcs11ModulePath the PKCS#11 library path
-     * @preconditions (pkcs11ModulePath <> null)
-     * @postconditions
-     */
-    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 {
-        // 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);
-        if (pkcs11 == null) {
-            if ((pInitArgs != null)
-                    && ((pInitArgs.flags & CKF_OS_LOCKING_OK) != 0)) {
-                pkcs11 = new PKCS11(pkcs11ModulePath, functionList);
-            } else {
-                pkcs11 = new SynchronizedPKCS11(pkcs11ModulePath, functionList);
-            }
-            if (omitInitialize == false) {
-                try {
-                    pkcs11.C_Initialize(pInitArgs);
-                } catch (PKCS11Exception e) {
-                    // ignore already-initialized error code
-                    // rethrow all other errors
-                    if (e.getErrorCode() != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
-                        throw e;
-                    }
-                }
-            }
-            moduleMap.put(pkcs11ModulePath, pkcs11);
-        }
-        return pkcs11;
-    }
-
-    /**
-     * Connects this object to the specified PKCS#11 library. This method is for
-     * internal use only.
-     * Declared private, because incorrect handling may result in errors in the
-     * native part.
-     *
-     * @param pkcs11ModulePath The PKCS#11 library path.
-     * @preconditions (pkcs11ModulePath <> null)
-     * @postconditions
-     */
-    private native void connect(String pkcs11ModulePath, String functionListName)
-            throws IOException;
-
-    /**
-     * Disconnects the PKCS#11 library from this object. After calling this
-     * method, this object is no longer connected to a native PKCS#11 module
-     * and any subsequent calls to C_ methods will fail. This method is for
-     * internal use only.
-     * Declared private, because incorrect handling may result in errors in the
-     * native part.
-     *
-     * @preconditions
-     * @postconditions
-     */
-    private native void disconnect();
-
-
-    // Implementation of PKCS11 methods delegated to native pkcs11wrapper library
-
-/* *****************************************************************************
- * General-purpose
- ******************************************************************************/
-
-    /**
-     * C_Initialize initializes the Cryptoki library.
-     * (General-purpose)
-     *
-     * @param pInitArgs if pInitArgs is not NULL it gets casted to
-     *         CK_C_INITIALIZE_ARGS_PTR and dereferenced
-     *         (PKCS#11 param: CK_VOID_PTR pInitArgs)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    native void C_Initialize(Object pInitArgs) throws PKCS11Exception;
-
-    /**
-     * C_Finalize indicates that an application is done with the
-     * Cryptoki library
-     * (General-purpose)
-     *
-     * @param pReserved is reserved. Should be NULL_PTR
-     *         (PKCS#11 param: CK_VOID_PTR pReserved)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pReserved == null)
-     * @postconditions
-     */
-    public native void C_Finalize(Object pReserved) throws PKCS11Exception;
-
-
-    /**
-     * C_GetInfo returns general information about Cryptoki.
-     * (General-purpose)
-     *
-     * @return the information.
-     *         (PKCS#11 param: CK_INFO_PTR pInfo)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native CK_INFO C_GetInfo() throws PKCS11Exception;
-
-
-/* *****************************************************************************
- * Slot and token management
- ******************************************************************************/
-
-    /**
-     * C_GetSlotList obtains a list of slots in the system.
-     * (Slot and token management)
-     *
-     * @param tokenPresent if true only Slot IDs with a token are returned
-     *         (PKCS#11 param: CK_BBOOL tokenPresent)
-     * @return a long array of slot IDs and number of Slot IDs
-     *         (PKCS#11 param: CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native long[] C_GetSlotList(boolean tokenPresent)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_GetSlotInfo obtains information about a particular slot in
-     * the system.
-     * (Slot and token management)
-     *
-     * @param slotID the ID of the slot
-     *         (PKCS#11 param: CK_SLOT_ID slotID)
-     * @return the slot information
-     *         (PKCS#11 param: CK_SLOT_INFO_PTR pInfo)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native CK_SLOT_INFO C_GetSlotInfo(long slotID) throws PKCS11Exception;
-
-
-    /**
-     * C_GetTokenInfo obtains information about a particular token
-     * in the system.
-     * (Slot and token management)
-     *
-     * @param slotID ID of the token's slot
-     *         (PKCS#11 param: CK_SLOT_ID slotID)
-     * @return the token information
-     *         (PKCS#11 param: CK_TOKEN_INFO_PTR pInfo)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native CK_TOKEN_INFO C_GetTokenInfo(long slotID)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_GetMechanismList obtains a list of mechanism types
-     * supported by a token.
-     * (Slot and token management)
-     *
-     * @param slotID ID of the token's slot
-     *         (PKCS#11 param: CK_SLOT_ID slotID)
-     * @return a long array of mechanism types and number of mechanism types
-     *         (PKCS#11 param: CK_MECHANISM_TYPE_PTR pMechanismList,
-     *                         CK_ULONG_PTR pulCount)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native long[] C_GetMechanismList(long slotID) throws PKCS11Exception;
-
-
-    /**
-     * C_GetMechanismInfo obtains information about a particular
-     * mechanism possibly supported by a token.
-     * (Slot and token management)
-     *
-     * @param slotID ID of the token's slot
-     *         (PKCS#11 param: CK_SLOT_ID slotID)
-     * @param type type of mechanism
-     *         (PKCS#11 param: CK_MECHANISM_TYPE type)
-     * @return the mechanism info
-     *         (PKCS#11 param: CK_MECHANISM_INFO_PTR pInfo)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native CK_MECHANISM_INFO C_GetMechanismInfo(long slotID, long type)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_InitToken initializes a token.
-     * (Slot and token management)
-     *
-     * @param slotID ID of the token's slot
-     *         (PKCS#11 param: CK_SLOT_ID slotID)
-     * @param pPin the SO's initial PIN and the length in bytes of the PIN
-     *         (PKCS#11 param: CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
-     * @param pLabel 32-byte token label (blank padded)
-     *         (PKCS#11 param: CK_UTF8CHAR_PTR pLabel)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-//    public native void C_InitToken(long slotID, char[] pPin, char[] pLabel)
-//            throws PKCS11Exception;
-
-
-    /**
-     * C_InitPIN initializes the normal user's PIN.
-     * (Slot and token management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pPin the normal user's PIN and the length in bytes of the PIN
-     *         (PKCS#11 param: CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-//    public native void C_InitPIN(long hSession, char[] pPin)
-//            throws PKCS11Exception;
-
-
-    /**
-     * C_SetPIN modifies the PIN of the user who is logged in.
-     * (Slot and token management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pOldPin the old PIN and the length of the old PIN
-     *         (PKCS#11 param: CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen)
-     * @param pNewPin the new PIN and the length of the new PIN
-     *         (PKCS#11 param: CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-//    public native void C_SetPIN(long hSession, char[] pOldPin, char[] pNewPin)
-//            throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Session management
- ******************************************************************************/
-
-    /**
-     * C_OpenSession opens a session between an application and a
-     * token.
-     * (Session management)
-     *
-     * @param slotID the slot's ID
-     *         (PKCS#11 param: CK_SLOT_ID slotID)
-     * @param flags of CK_SESSION_INFO
-     *         (PKCS#11 param: CK_FLAGS flags)
-     * @param pApplication passed to callback
-     *         (PKCS#11 param: CK_VOID_PTR pApplication)
-     * @param Notify the callback function
-     *         (PKCS#11 param: CK_NOTIFY Notify)
-     * @return the session handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE_PTR phSession)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native long C_OpenSession(long slotID, long flags,
-            Object pApplication, CK_NOTIFY Notify) throws PKCS11Exception;
-
-
-    /**
-     * C_CloseSession closes a session between an application and a
-     * token.
-     * (Session management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_CloseSession(long hSession) throws PKCS11Exception;
-
-
-    /**
-     * C_CloseAllSessions closes all sessions with a token.
-     * (Session management)
-     *
-     * @param slotID the ID of the token's slot
-     *         (PKCS#11 param: CK_SLOT_ID slotID)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-//    public native void C_CloseAllSessions(long slotID) throws PKCS11Exception;
-
-
-    /**
-     * C_GetSessionInfo obtains information about the session.
-     * (Session management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @return the session info
-     *         (PKCS#11 param: CK_SESSION_INFO_PTR pInfo)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native CK_SESSION_INFO C_GetSessionInfo(long hSession)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_GetOperationState obtains the state of the cryptographic operation
-     * in a session.
-     * (Session management)
-     *
-     * @param hSession session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @return the state and the state length
-     *         (PKCS#11 param: CK_BYTE_PTR pOperationState,
-     *                         CK_ULONG_PTR pulOperationStateLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native byte[] C_GetOperationState(long hSession)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_SetOperationState restores the state of the cryptographic
-     * operation in a session.
-     * (Session management)
-     *
-     * @param hSession session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pOperationState the state and the state length
-     *         (PKCS#11 param: CK_BYTE_PTR pOperationState,
-     *                         CK_ULONG ulOperationStateLen)
-     * @param hEncryptionKey en/decryption key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hEncryptionKey)
-     * @param hAuthenticationKey sign/verify key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hAuthenticationKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_SetOperationState(long hSession, byte[] pOperationState,
-            long hEncryptionKey, long hAuthenticationKey) throws PKCS11Exception;
-
-
-    /**
-     * C_Login logs a user into a token.
-     * (Session management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param userType the user type
-     *         (PKCS#11 param: CK_USER_TYPE userType)
-     * @param pPin the user's PIN and the length of the PIN
-     *         (PKCS#11 param: CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_Login(long hSession, long userType, char[] pPin)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_Logout logs a user out from a token.
-     * (Session management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_Logout(long hSession) throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Object management
- ******************************************************************************/
-
-    /**
-     * C_CreateObject creates a new object.
-     * (Object management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pTemplate the object's template and number of attributes in
-     *         template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
-     * @return the object's handle
-     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phObject)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native long C_CreateObject(long hSession, CK_ATTRIBUTE[] pTemplate)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_CopyObject copies an object, creating a new object for the
-     * copy.
-     * (Object management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param hObject the object's handle
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
-     * @param pTemplate the template for the new object and number of attributes
-     *         in template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
-     * @return the handle of the copy
-     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phNewObject)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native long C_CopyObject(long hSession, long hObject,
-            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
-
-
-    /**
-     * C_DestroyObject destroys an object.
-     * (Object management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param hObject the object's handle
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_DestroyObject(long hSession, long hObject)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_GetObjectSize gets the size of an object in bytes.
-     * (Object management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param hObject the object's handle
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
-     * @return the size of the object
-     *         (PKCS#11 param: CK_ULONG_PTR pulSize)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-//    public native long C_GetObjectSize(long hSession, long hObject)
-//            throws PKCS11Exception;
-
-
-    /**
-     * C_GetAttributeValue obtains the value of one or more object
-     * attributes. The template attributes also receive the values.
-     * (Object management)
-     * note: in PKCS#11 pTemplate and the result template are the same
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param hObject the object's handle
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
-     * @param pTemplate specifies the attributes and number of attributes to get
-     *                  The template attributes also receive the values.
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pTemplate <> null)
-     * @postconditions (result <> null)
-     */
-    public native void C_GetAttributeValue(long hSession, long hObject,
-            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
-
-
-    /**
-     * C_SetAttributeValue modifies the value of one or more object
-     * attributes
-     * (Object management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param hObject the object's handle
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hObject)
-     * @param pTemplate specifies the attributes and values to get; number of
-     *         attributes in the template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pTemplate <> null)
-     * @postconditions
-     */
-    public native void C_SetAttributeValue(long hSession, long hObject,
-            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
-
-
-    /**
-     * C_FindObjectsInit initializes a search for token and session
-     * objects that match a template.
-     * (Object management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pTemplate the object's attribute values to match and the number of
-     *         attributes in search template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_FindObjectsInit(long hSession, CK_ATTRIBUTE[] pTemplate)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_FindObjects continues a search for token and session
-     * objects that match a template, obtaining additional object
-     * handles.
-     * (Object management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param ulMaxObjectCount the max. object handles to get
-     *         (PKCS#11 param: CK_ULONG ulMaxObjectCount)
-     * @return the object's handles and the actual number of objects returned
-     *         (PKCS#11 param: CK_ULONG_PTR pulObjectCount)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native long[] C_FindObjects(long hSession, long ulMaxObjectCount)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_FindObjectsFinal finishes a search for token and session
-     * objects.
-     * (Object management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_FindObjectsFinal(long hSession) throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Encryption and decryption
- ******************************************************************************/
-
-    /**
-     * C_EncryptInit initializes an encryption operation.
-     * (Encryption and decryption)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the encryption mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hKey the handle of the encryption key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_EncryptInit(long hSession, CK_MECHANISM pMechanism,
-            long hKey) throws PKCS11Exception;
-
-
-    /**
-     * C_Encrypt encrypts single-part data.
-     * (Encryption and decryption)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pData the data to get encrypted and the data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
-     * @return the encrypted data and the encrypted data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedData,
-     *                         CK_ULONG_PTR pulEncryptedDataLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @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;
-
-
-    /**
-     * C_EncryptUpdate continues a multiple-part encryption
-     * operation.
-     * (Encryption and decryption)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pPart the data part to get encrypted and the data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
-     * @return the encrypted data part and the encrypted data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
-                             CK_ULONG_PTR pulEncryptedPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @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;
-
-
-    /**
-     * C_EncryptFinal finishes a multiple-part encryption
-     * operation.
-     * (Encryption and decryption)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @return the last encrypted data part and the last data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pLastEncryptedPart,
-                             CK_ULONG_PTR pulLastEncryptedPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native int C_EncryptFinal(long hSession, long directOut, byte[] out,
-            int outOfs, int outLen) throws PKCS11Exception;
-
-
-    /**
-     * C_DecryptInit initializes a decryption operation.
-     * (Encryption and decryption)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the decryption mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hKey the handle of the decryption key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_DecryptInit(long hSession, CK_MECHANISM pMechanism,
-            long hKey) throws PKCS11Exception;
-
-
-    /**
-     * C_Decrypt decrypts encrypted data in a single part.
-     * (Encryption and decryption)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pEncryptedData the encrypted data to get decrypted and the
-     *         encrypted data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedData,
-     *                         CK_ULONG ulEncryptedDataLen)
-     * @return the decrypted data and the data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @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;
-
-
-    /**
-     * C_DecryptUpdate continues a multiple-part decryption
-     * operation.
-     * (Encryption and decryption)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pEncryptedPart the encrypted data part to get decrypted and the
-     *         encrypted data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
-     *                         CK_ULONG ulEncryptedPartLen)
-     * @return the decrypted data part and the data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @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;
-
-
-    /**
-     * C_DecryptFinal finishes a multiple-part decryption
-     * operation.
-     * (Encryption and decryption)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @return the last decrypted data part and the last data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pLastPart,
-     *                         CK_ULONG_PTR pulLastPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native int C_DecryptFinal(long hSession, long directOut, byte[] out,
-            int outOfs, int outLen) throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Message digesting
- ******************************************************************************/
-
-    /**
-     * C_DigestInit initializes a message-digesting operation.
-     * (Message digesting)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the digesting mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_DigestInit(long hSession, CK_MECHANISM pMechanism)
-            throws PKCS11Exception;
-
-
-    // note that C_DigestSingle does not exist in PKCS#11
-    // we combined the C_DigestInit and C_Digest into a single function
-    // to save on Java<->C transitions and save 5-10% on small digests
-    // this made the C_Digest method redundant, it has been removed
-    /**
-     * C_Digest digests data in a single part.
-     * (Message digesting)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param data the data to get digested and the data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
-     * @return the message digest and the length of the message digest
-     *         (PKCS#11 param: CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @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;
-
-
-    /**
-     * C_DigestUpdate continues a multiple-part message-digesting
-     * operation.
-     * (Message digesting)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pPart the data to get digested and the data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pPart <> null)
-     * @postconditions
-     */
-    public native void C_DigestUpdate(long hSession, long directIn, byte[] in,
-            int inOfs, int inLen) throws PKCS11Exception;
-
-
-    /**
-     * C_DigestKey continues a multi-part message-digesting
-     * operation, by digesting the value of a secret key as part of
-     * the data already digested.
-     * (Message digesting)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param hKey the handle of the secret key to be digested
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_DigestKey(long hSession, long hKey)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_DigestFinal finishes a multiple-part message-digesting
-     * operation.
-     * (Message digesting)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @return the message digest and the length of the message digest
-     *         (PKCS#11 param: CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native int C_DigestFinal(long hSession, byte[] pDigest, int digestOfs,
-            int digestLen) throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Signing and MACing
- ******************************************************************************/
-
-    /**
-     * C_SignInit initializes a signature (private key encryption)
-     * operation, where the signature is (will be) an appendix to
-     * the data, and plaintext cannot be recovered from the
-     * signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the signature mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hKey the handle of the signature key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_SignInit(long hSession, CK_MECHANISM pMechanism,
-            long hKey) throws PKCS11Exception;
-
-
-    /**
-     * C_Sign signs (encrypts with private key) data in a single
-     * part, where the signature is (will be) an appendix to the
-     * data, and plaintext cannot be recovered from the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pData the data to sign and the data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
-     * @return the signature and the signature's length
-     *         (PKCS#11 param: CK_BYTE_PTR pSignature,
-     *                         CK_ULONG_PTR pulSignatureLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pData <> null)
-     * @postconditions (result <> null)
-     */
-    public native byte[] C_Sign(long hSession, byte[] pData)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_SignUpdate continues a multiple-part signature operation,
-     * where the signature is (will be) an appendix to the data,
-     * and plaintext cannot be recovered from the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pPart the data part to sign and the data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pPart <> null)
-     * @postconditions
-     */
-    public native void C_SignUpdate(long hSession, long directIn, byte[] in,
-            int inOfs, int inLen) throws PKCS11Exception;
-
-
-    /**
-     * C_SignFinal finishes a multiple-part signature operation,
-     * returning the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @return the signature and the signature's length
-     *         (PKCS#11 param: CK_BYTE_PTR pSignature,
-     *                         CK_ULONG_PTR pulSignatureLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native byte[] C_SignFinal(long hSession, int expectedLen)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_SignRecoverInit initializes a signature operation, where
-     * the data can be recovered from the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the signature mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hKey the handle of the signature key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_SignRecoverInit(long hSession, CK_MECHANISM pMechanism,
-            long hKey) throws PKCS11Exception;
-
-
-    /**
-     * C_SignRecover signs data in a single operation, where the
-     * data can be recovered from the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pData the data to sign and the data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
-     * @return the signature and the signature's length
-     *         (PKCS#11 param: CK_BYTE_PTR pSignature,
-     *                         CK_ULONG_PTR pulSignatureLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @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;
-
-
-
-/* *****************************************************************************
- * Verifying signatures and MACs
- ******************************************************************************/
-
-    /**
-     * C_VerifyInit initializes a verification operation, where the
-     * signature is an appendix to the data, and plaintext cannot
-     * cannot be recovered from the signature (e.g. DSA).
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the verification mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hKey the handle of the verification key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_VerifyInit(long hSession, CK_MECHANISM pMechanism,
-            long hKey) throws PKCS11Exception;
-
-
-    /**
-     * C_Verify verifies a signature in a single-part operation,
-     * where the signature is an appendix to the data, and plaintext
-     * cannot be recovered from the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pData the signed data and the signed data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG ulDataLen)
-     * @param pSignature the signature to verify and the signature's length
-     *         (PKCS#11 param: CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pData <> null) and (pSignature <> null)
-     * @postconditions
-     */
-    public native void C_Verify(long hSession, byte[] pData, byte[] pSignature)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_VerifyUpdate continues a multiple-part verification
-     * operation, where the signature is an appendix to the data,
-     * and plaintext cannot be recovered from the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pPart the signed data part and the signed data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pPart <> null)
-     * @postconditions
-     */
-    public native void C_VerifyUpdate(long hSession, long directIn, byte[] in,
-            int inOfs, int inLen) throws PKCS11Exception;
-
-
-    /**
-     * C_VerifyFinal finishes a multiple-part verification
-     * operation, checking the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pSignature the signature to verify and the signature's length
-     *         (PKCS#11 param: CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pSignature <> null)
-     * @postconditions
-     */
-    public native void C_VerifyFinal(long hSession, byte[] pSignature)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_VerifyRecoverInit initializes a signature verification
-     * operation, where the data is recovered from the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the verification mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hKey the handle of the verification key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native void C_VerifyRecoverInit(long hSession,
-            CK_MECHANISM pMechanism, long hKey) throws PKCS11Exception;
-
-
-    /**
-     * C_VerifyRecover verifies a signature in a single-part
-     * operation, where the data is recovered from the signature.
-     * (Signing and MACing)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pSignature the signature to verify and the signature's length
-     *         (PKCS#11 param: CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
-     * @return the recovered data and the recovered data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @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;
-
-
-
-/* *****************************************************************************
- * Dual-function cryptographic operations
- ******************************************************************************/
-
-    /**
-     * C_DigestEncryptUpdate continues a multiple-part digesting
-     * and encryption operation.
-     * (Dual-function cryptographic operations)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pPart the data part to digest and to encrypt and the data's length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
-     * @return the digested and encrypted data part and the data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
-     *                         CK_ULONG_PTR pulEncryptedPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pPart <> null)
-     * @postconditions
-     */
-//    public native byte[] C_DigestEncryptUpdate(long hSession, byte[] pPart)
-//            throws PKCS11Exception;
-
-
-    /**
-     * C_DecryptDigestUpdate continues a multiple-part decryption and
-     * digesting operation.
-     * (Dual-function cryptographic operations)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pEncryptedPart the encrypted data part to decrypt and to digest
-     *         and encrypted data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
-     *                         CK_ULONG ulEncryptedPartLen)
-     * @return the decrypted and digested data part and the data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pEncryptedPart <> null)
-     * @postconditions
-     */
-//    public native byte[] C_DecryptDigestUpdate(long hSession,
-//            byte[] pEncryptedPart) throws PKCS11Exception;
-
-
-    /**
-     * C_SignEncryptUpdate continues a multiple-part signing and
-     * encryption operation.
-     * (Dual-function cryptographic operations)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pPart the data part to sign and to encrypt and the data part's
-     *         length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
-     * @return the signed and encrypted data part and the data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
-     *                         CK_ULONG_PTR pulEncryptedPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pPart <> null)
-     * @postconditions
-     */
-//    public native byte[] C_SignEncryptUpdate(long hSession, byte[] pPart)
-//            throws PKCS11Exception;
-
-
-    /**
-     * C_DecryptVerifyUpdate continues a multiple-part decryption and
-     * verify operation.
-     * (Dual-function cryptographic operations)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pEncryptedPart the encrypted data part to decrypt and to verify
-     *         and the data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pEncryptedPart,
-     *                         CK_ULONG ulEncryptedPartLen)
-     * @return the decrypted and verified data part and the data part's length
-     *         (PKCS#11 param: CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pEncryptedPart <> null)
-     * @postconditions
-     */
-//    public native byte[] C_DecryptVerifyUpdate(long hSession,
-//            byte[] pEncryptedPart) throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Key management
- ******************************************************************************/
-
-    /**
-     * C_GenerateKey generates a secret key, creating a new key
-     * object.
-     * (Key management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the key generation mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param pTemplate the template for the new key and the number of
-     *         attributes in the template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
-     * @return the handle of the new key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native long C_GenerateKey(long hSession, CK_MECHANISM pMechanism,
-            CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
-
-
-    /**
-     * C_GenerateKeyPair generates a public-key/private-key pair,
-     * creating new key objects.
-     * (Key management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the key generation mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param pPublicKeyTemplate the template for the new public key and the
-     *         number of attributes in the template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pPublicKeyTemplate,
-     *                         CK_ULONG ulPublicKeyAttributeCount)
-     * @param pPrivateKeyTemplate the template for the new private key and the
-     *         number of attributes in the template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pPrivateKeyTemplate
-     *                         CK_ULONG ulPrivateKeyAttributeCount)
-     * @return a long array with exactly two elements and the public key handle
-     *         as the first element and the private key handle as the second
-     *         element
-     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phPublicKey,
-     *                         CK_OBJECT_HANDLE_PTR phPrivateKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pMechanism <> null)
-     * @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;
-
-
-
-    /**
-     * C_WrapKey wraps (i.e., encrypts) a key.
-     * (Key management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the wrapping mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hWrappingKey the handle of the wrapping key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hWrappingKey)
-     * @param hKey the handle of the key to be wrapped
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hKey)
-     * @return the wrapped key and the length of the wrapped key
-     *         (PKCS#11 param: CK_BYTE_PTR pWrappedKey,
-     *                         CK_ULONG_PTR pulWrappedKeyLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public native byte[] C_WrapKey(long hSession, CK_MECHANISM pMechanism,
-            long hWrappingKey, long hKey) throws PKCS11Exception;
-
-
-    /**
-     * C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
-     * key object.
-     * (Key management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the unwrapping mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hUnwrappingKey the handle of the unwrapping key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hUnwrappingKey)
-     * @param pWrappedKey the wrapped key to unwrap and the wrapped key's length
-     *         (PKCS#11 param: CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen)
-     * @param pTemplate the template for the new key and the number of
-     *         attributes in the template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
-     * @return the handle of the unwrapped key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pWrappedKey <> null)
-     * @postconditions
-     */
-    public native long C_UnwrapKey(long hSession, CK_MECHANISM pMechanism,
-            long hUnwrappingKey, byte[] pWrappedKey, CK_ATTRIBUTE[] pTemplate)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_DeriveKey derives a key from a base key, creating a new key
-     * object.
-     * (Key management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pMechanism the key derivation mechanism
-     *         (PKCS#11 param: CK_MECHANISM_PTR pMechanism)
-     * @param hBaseKey the handle of the base key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE hBaseKey)
-     * @param pTemplate the template for the new key and the number of
-     *         attributes in the template
-     *         (PKCS#11 param: CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
-     * @return the handle of the derived key
-     *         (PKCS#11 param: CK_OBJECT_HANDLE_PTR phKey)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-    public native long C_DeriveKey(long hSession, CK_MECHANISM pMechanism,
-            long hBaseKey, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Random number generation
- ******************************************************************************/
-
-    /**
-     * C_SeedRandom mixes additional seed material into the token's
-     * random number generator.
-     * (Random number generation)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param pSeed the seed material and the seed material's length
-     *         (PKCS#11 param: CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pSeed <> null)
-     * @postconditions
-     */
-    public native void C_SeedRandom(long hSession, byte[] pSeed)
-            throws PKCS11Exception;
-
-
-    /**
-     * C_GenerateRandom generates random data.
-     * (Random number generation)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @param RandomData receives the random data and the length of RandomData
-     *         is the length of random data to be generated
-     *         (PKCS#11 param: CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (randomData <> null)
-     * @postconditions
-     */
-    public native void C_GenerateRandom(long hSession, byte[] randomData)
-            throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Parallel function management
- ******************************************************************************/
-
-    /**
-     * C_GetFunctionStatus is a legacy function; it obtains an
-     * updated status of a function running in parallel with an
-     * application.
-     * (Parallel function management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-//    public native void C_GetFunctionStatus(long hSession)
-//            throws PKCS11Exception;
-
-
-    /**
-     * C_CancelFunction is a legacy function; it cancels a function
-     * running in parallel.
-     * (Parallel function management)
-     *
-     * @param hSession the session's handle
-     *         (PKCS#11 param: CK_SESSION_HANDLE hSession)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions
-     * @postconditions
-     */
-//    public native void C_CancelFunction(long hSession) throws PKCS11Exception;
-
-
-
-/* *****************************************************************************
- * Functions added in for Cryptoki Version 2.01 or later
- ******************************************************************************/
-
-    /**
-     * C_WaitForSlotEvent waits for a slot event (token insertion,
-     * removal, etc.) to occur.
-     * (General-purpose)
-     *
-     * @param flags blocking/nonblocking flag
-     *         (PKCS#11 param: CK_FLAGS flags)
-     * @param pReserved reserved. Should be null
-     *         (PKCS#11 param: CK_VOID_PTR pReserved)
-     * @return the slot ID where the event occurred
-     *         (PKCS#11 param: CK_SLOT_ID_PTR pSlot)
-     * @exception PKCS11Exception If function returns other value than CKR_OK.
-     * @preconditions (pRserved == null)
-     * @postconditions
-     */
-//    public native long C_WaitForSlotEvent(long flags, Object pRserved)
-//            throws PKCS11Exception;
-
-    /**
-     * Returns the string representation of this object.
-     *
-     * @return The string representation of object
-     */
-    public String toString() {
-        return "Module name: " + pkcs11ModulePath;
-    }
-
-    /**
-     * Calls disconnect() to cleanup the native part of the wrapper. Once this
-     * method is called, this object cannot be used any longer. Any subsequent
-     * call to a C_* method will result in a runtime exception.
-     *
-     * @exception Throwable If finalization fails.
-     */
-    protected void finalize() throws Throwable {
-        disconnect();
-    }
-
-// PKCS11 subclass that has all methods synchronized and delegating to the
-// parent. Used for tokens that only support single threaded access
-static class SynchronizedPKCS11 extends PKCS11 {
-
-    SynchronizedPKCS11(String pkcs11ModulePath, String functionListName)
-            throws IOException {
-        super(pkcs11ModulePath, functionListName);
-    }
-
-    synchronized void C_Initialize(Object pInitArgs) throws PKCS11Exception {
-        super.C_Initialize(pInitArgs);
-    }
-
-    public synchronized void C_Finalize(Object pReserved)
-            throws PKCS11Exception {
-        super.C_Finalize(pReserved);
-    }
-
-    public synchronized CK_INFO C_GetInfo() throws PKCS11Exception {
-        return super.C_GetInfo();
-    }
-
-    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 {
-        return super.C_GetSlotInfo(slotID);
-    }
-
-    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 {
-        return super.C_GetMechanismList(slotID);
-    }
-
-    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 {
-        return super.C_OpenSession(slotID, flags, pApplication, Notify);
-    }
-
-    public synchronized void C_CloseSession(long hSession)
-            throws PKCS11Exception {
-        super.C_CloseSession(hSession);
-    }
-
-    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 {
-        super.C_Login(hSession, userType, pPin);
-    }
-
-    public synchronized void C_Logout(long hSession) throws PKCS11Exception {
-        super.C_Logout(hSession);
-    }
-
-    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 {
-        return super.C_CopyObject(hSession, hObject, pTemplate);
-    }
-
-    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 {
-        super.C_GetAttributeValue(hSession, hObject, pTemplate);
-    }
-
-    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 {
-        super.C_FindObjectsInit(hSession, pTemplate);
-    }
-
-    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 {
-        super.C_FindObjectsFinal(hSession);
-    }
-
-    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 {
-        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_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 {
-        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 {
-        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_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 {
-        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 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 {
-        super.C_DigestKey(hSession, hKey);
-    }
-
-    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 {
-        super.C_SignInit(hSession, pMechanism, hKey);
-    }
-
-    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 {
-        super.C_SignUpdate(hSession, directIn, in, inOfs, inLen);
-    }
-
-    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 {
-        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 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 {
-        super.C_Verify(hSession, pData, pSignature);
-    }
-
-    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 {
-        super.C_VerifyFinal(hSession, pSignature);
-    }
-
-    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 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);
-    }
-
-    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);
-    }
-
-    public synchronized long C_DeriveKey(long hSession, CK_MECHANISM pMechanism,
-    long hBaseKey, CK_ATTRIBUTE[] pTemplate) throws PKCS11Exception {
-        return super.C_DeriveKey(hSession, pMechanism, hBaseKey, pTemplate);
-    }
-
-    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 {
-        super.C_GenerateRandom(hSession, randomData);
-    }
-}
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,966 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-/**
- * This interface holds constants of the PKCS#11 v2.11 standard.
- * This is mainly the content of the 'pkcs11t.h' header file.
- *
- * Mapping of primitiv data types to Java types:
- * <pre>
- *   TRUE .......................................... true
- *   FALSE ......................................... false
- *   CK_BYTE ....................................... byte
- *   CK_CHAR ....................................... char
- *   CK_UTF8CHAR ................................... char
- *   CK_BBOOL ...................................... boolean
- *   CK_ULONG ...................................... long
- *   CK_LONG ....................................... long
- *   CK_FLAGS ...................................... long
- *   CK_NOTIFICATION ............................... long
- *   CK_SLOT_ID .................................... long
- *   CK_SESSION_HANDLE ............................. long
- *   CK_USER_TYPE .................................. long
- *   CK_SESSION_HANDLE ............................. long
- *   CK_STATE ...................................... long
- *   CK_OBJECT_HANDLE .............................. long
- *   CK_OBJECT_CLASS ............................... long
- *   CK_HW_FEATURE_TYPE ............................ long
- *   CK_KEY_TYPE ................................... long
- *   CK_CERTIFICATE_TYPE ........................... long
- *   CK_ATTRIBUTE_TYPE ............................. long
- *   CK_VOID_PTR ................................... Object[]
- *   CK_BYTE_PTR ................................... byte[]
- *   CK_CHAR_PTR ................................... char[]
- *   CK_UTF8CHAR_PTR ............................... char[]
- *   CK_MECHANISM_TYPE ............................. long
- *   CK_RV ......................................... long
- *   CK_RSA_PKCS_OAEP_MGF_TYPE ..................... long
- *   CK_RSA_PKCS_OAEP_SOURCE_TYPE .................. long
- *   CK_RC2_PARAMS ................................. long
- *   CK_MAC_GENERAL_PARAMS ......................... long
- *   CK_EXTRACT_PARAMS ............................. long
- *   CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE .... long
- *   CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE .............. long
- *   CK_EC_KDF_TYPE ................................ long
- *   CK_X9_42_DH_KDF_TYPE .......................... long
- * </pre>
- *
- * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
- * @invariants
- */
-public interface PKCS11Constants {
-
-    public static final boolean TRUE = true;
-
-    public static final boolean FALSE = false;
-
-    public static final Object NULL_PTR = null;
-
-    /* some special values for certain CK_ULONG variables */
-
-    // Cryptoki defines CK_UNAVAILABLE_INFORMATION as (~0UL)
-    // This means it is 0xffffffff in ILP32/LLP64 but 0xffffffffffffffff in LP64.
-    // To avoid these differences on the Java side, the native code treats
-    // CK_UNAVAILABLE_INFORMATION specially and always returns (long)-1 for it.
-    // See ckULongSpecialToJLong() in pkcs11wrapper.h
-    public static final long CK_UNAVAILABLE_INFORMATION = -1;
-    public static final long CK_EFFECTIVELY_INFINITE = 0L;
-
-    /* The following value is always invalid if used as a session */
-    /* handle or object handle */
-    public static final long CK_INVALID_HANDLE = 0L;
-
-    /* CK_NOTIFICATION enumerates the types of notifications that
-     * Cryptoki provides to an application */
-    /* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
-     * for v2.0 */
-    public static final long CKN_SURRENDER = 0L;
-
-    /* flags: bit flags that provide capabilities of the slot
-     *      Bit Flag              Mask        Meaning
-     */
-    public static final long CKF_TOKEN_PRESENT = 0x00000001L;
-    public static final long CKF_REMOVABLE_DEVICE = 0x00000002L;
-    public static final long CKF_HW_SLOT = 0x00000004L;
-
-    /* The flags parameter is defined as follows:
-     *      Bit Flag                    Mask        Meaning
-     */
-    /* has random # generator */
-    public static final long  CKF_RNG                     = 0x00000001L;
-
-    /* token is write-protected */
-    public static final long  CKF_WRITE_PROTECTED         = 0x00000002L;
-
-    /* user must login */
-    public static final long  CKF_LOGIN_REQUIRED          = 0x00000004L;
-
-    /* normal user's PIN is set */
-    public static final long  CKF_USER_PIN_INITIALIZED    = 0x00000008L;
-
-    /* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
-     * that means that *every* time the state of cryptographic
-     * operations of a session is successfully saved, all keys
-     * needed to continue those operations are stored in the state */
-    public static final long  CKF_RESTORE_KEY_NOT_NEEDED  = 0x00000020L;
-
-    /* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
-     * that the token has some sort of clock.  The time on that
-     * clock is returned in the token info structure */
-    public static final long  CKF_CLOCK_ON_TOKEN          = 0x00000040L;
-
-    /* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
-     * set, that means that there is some way for the user to login
-     * without sending a PIN through the Cryptoki library itself */
-    public static final long  CKF_PROTECTED_AUTHENTICATION_PATH = 0x00000100L;
-
-    /* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
-     * that means that a single session with the token can perform
-     * dual simultaneous cryptographic operations (digest and
-     * encrypt; decrypt and digest; sign and encrypt; and decrypt
-     * and sign) */
-    public static final long  CKF_DUAL_CRYPTO_OPERATIONS  = 0x00000200L;
-
-    /* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
-     * token has been initialized using C_InitializeToken or an
-     * equivalent mechanism outside the scope of PKCS #11.
-     * Calling C_InitializeToken when this flag is set will cause
-     * the token to be reinitialized. */
-    public static final long  CKF_TOKEN_INITIALIZED       = 0x00000400L;
-
-    /* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
-     * true, the token supports secondary authentication for
-     * private key objects. */
-    public static final long  CKF_SECONDARY_AUTHENTICATION  = 0x00000800L;
-
-    /* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
-     * incorrect user login PIN has been entered at least once
-     * since the last successful authentication. */
-    public static final long  CKF_USER_PIN_COUNT_LOW       = 0x00010000L;
-
-    /* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
-     * supplying an incorrect user PIN will it to become locked. */
-    public static final long  CKF_USER_PIN_FINAL_TRY       = 0x00020000L;
-
-    /* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
-     * user PIN has been locked. User login to the token is not
-     * possible. */
-    public static final long  CKF_USER_PIN_LOCKED          = 0x00040000L;
-
-    /* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
-     * the user PIN value is the default value set by token
-     * initialization or manufacturing. */
-    public static final long  CKF_USER_PIN_TO_BE_CHANGED   = 0x00080000L;
-
-    /* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
-     * incorrect SO login PIN has been entered at least once since
-     * the last successful authentication. */
-    public static final long  CKF_SO_PIN_COUNT_LOW         = 0x00100000L;
-
-    /* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
-     * supplying an incorrect SO PIN will it to become locked. */
-    public static final long  CKF_SO_PIN_FINAL_TRY         = 0x00200000L;
-
-    /* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
-     * PIN has been locked. SO login to the token is not possible.
-     */
-    public static final long  CKF_SO_PIN_LOCKED            = 0x00400000L;
-
-    /* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
-     * the SO PIN value is the default value set by token
-     * initialization or manufacturing. */
-    public static final long  CKF_SO_PIN_TO_BE_CHANGED     = 0x00800000L;
-
-
-    /* CK_USER_TYPE enumerates the types of Cryptoki users */
-    /* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
-     * v2.0 */
-    /* Security Officer */
-    public static final long CKU_SO = 0L;
-    /* Normal user */
-    public static final long CKU_USER = 1L;
-
-    /* CK_STATE enumerates the session states */
-    /* CK_STATE has been changed from an enum to a CK_ULONG for
-     * v2.0 */
-    public static final long  CKS_RO_PUBLIC_SESSION = 0L;
-    public static final long  CKS_RO_USER_FUNCTIONS = 1L;
-    public static final long  CKS_RW_PUBLIC_SESSION = 2L;
-    public static final long  CKS_RW_USER_FUNCTIONS = 3L;
-    public static final long  CKS_RW_SO_FUNCTIONS   = 4L;
-
-
-    /* The flags are defined in the following table:
-     *      Bit Flag                Mask        Meaning
-     */
-    /* session is r/w */
-    public static final long  CKF_RW_SESSION        = 0x00000002L;
-    /* no parallel */
-    public static final long  CKF_SERIAL_SESSION    = 0x00000004L;
-
-
-    /* The following classes of objects are defined: */
-    /* CKO_HW_FEATURE is new for v2.10 */
-    /* CKO_DOMAIN_PARAMETERS is new for v2.11 */
-    public static final long  CKO_DATA              = 0x00000000L;
-    public static final long  CKO_CERTIFICATE       = 0x00000001L;
-    public static final long  CKO_PUBLIC_KEY        = 0x00000002L;
-    public static final long  CKO_PRIVATE_KEY       = 0x00000003L;
-    public static final long  CKO_SECRET_KEY        = 0x00000004L;
-    public static final long  CKO_HW_FEATURE        = 0x00000005L;
-    public static final long  CKO_DOMAIN_PARAMETERS = 0x00000006L;
-    public static final long  CKO_VENDOR_DEFINED    = 0x80000000L;
-
-    // pseudo object class ANY (for template manager)
-    public static final long  PCKO_ANY              = 0x7FFFFF23L;
-
-
-    /* The following hardware feature types are defined */
-    public static final long  CKH_MONOTONIC_COUNTER = 0x00000001L;
-    public static final long  CKH_CLOCK             = 0x00000002L;
-    public static final long  CKH_VENDOR_DEFINED    = 0x80000000L;
-
-    /* the following key types are defined: */
-    public static final long  CKK_RSA             = 0x00000000L;
-    public static final long  CKK_DSA             = 0x00000001L;
-    public static final long  CKK_DH              = 0x00000002L;
-
-    /* CKK_ECDSA and CKK_KEA are new for v2.0 */
-    /* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
-    public static final long  CKK_ECDSA           = 0x00000003L;
-    public static final long  CKK_EC              = 0x00000003L;
-    public static final long  CKK_X9_42_DH        = 0x00000004L;
-    public static final long  CKK_KEA             = 0x00000005L;
-
-    public static final long  CKK_GENERIC_SECRET  = 0x00000010L;
-    public static final long  CKK_RC2             = 0x00000011L;
-    public static final long  CKK_RC4             = 0x00000012L;
-    public static final long  CKK_DES             = 0x00000013L;
-    public static final long  CKK_DES2            = 0x00000014L;
-    public static final long  CKK_DES3            = 0x00000015L;
-
-    /* all these key types are new for v2.0 */
-    public static final long  CKK_CAST            = 0x00000016L;
-    public static final long  CKK_CAST3           = 0x00000017L;
-    /* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
-    public static final long  CKK_CAST5           = 0x00000018L;
-    /* CAST128=CAST5 */
-    public static final long  CKK_CAST128         = 0x00000018L;
-    public static final long  CKK_RC5             = 0x00000019L;
-    public static final long  CKK_IDEA            = 0x0000001AL;
-    public static final long  CKK_SKIPJACK        = 0x0000001BL;
-    public static final long  CKK_BATON           = 0x0000001CL;
-    public static final long  CKK_JUNIPER         = 0x0000001DL;
-    public static final long  CKK_CDMF            = 0x0000001EL;
-    public static final long  CKK_AES             = 0x0000001FL;
-    // v2.20
-    public static final long  CKK_BLOWFISH        = 0x00000020L;
-
-    public static final long  CKK_VENDOR_DEFINED  = 0x80000000L;
-
-    // new for v2.20 amendment 3
-    //public static final long  CKK_CAMELLIA          = 0x00000025L;
-    //public static final long  CKK_ARIA              = 0x00000026L;
-
-    // pseudo key type ANY (for template manager)
-    public static final long  PCKK_ANY            = 0x7FFFFF22L;
-
-    public static final long  PCKK_HMAC            = 0x7FFFFF23L;
-    public static final long  PCKK_SSLMAC          = 0x7FFFFF24L;
-    public static final long  PCKK_TLSPREMASTER    = 0x7FFFFF25L;
-    public static final long  PCKK_TLSRSAPREMASTER = 0x7FFFFF26L;
-    public static final long  PCKK_TLSMASTER       = 0x7FFFFF27L;
-
-    /* The following certificate types are defined: */
-    /* CKC_X_509_ATTR_CERT is new for v2.10 */
-    public static final long  CKC_X_509           = 0x00000000L;
-    public static final long  CKC_X_509_ATTR_CERT = 0x00000001L;
-    public static final long  CKC_VENDOR_DEFINED  = 0x80000000L;
-
-
-    /* The following attribute types are defined: */
-    public static final long  CKA_CLASS              = 0x00000000L;
-    public static final long  CKA_TOKEN              = 0x00000001L;
-    public static final long  CKA_PRIVATE            = 0x00000002L;
-    public static final long  CKA_LABEL              = 0x00000003L;
-    public static final long  CKA_APPLICATION        = 0x00000010L;
-    public static final long  CKA_VALUE              = 0x00000011L;
-
-    /* CKA_OBJECT_ID is new for v2.10 */
-    public static final long  CKA_OBJECT_ID          = 0x00000012L;
-
-    public static final long  CKA_CERTIFICATE_TYPE   = 0x00000080L;
-    public static final long  CKA_ISSUER             = 0x00000081L;
-    public static final long  CKA_SERIAL_NUMBER      = 0x00000082L;
-
-    /* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new L;
-     * for v2.10 */
-    public static final long  CKA_AC_ISSUER          = 0x00000083L;
-    public static final long  CKA_OWNER              = 0x00000084L;
-    public static final long  CKA_ATTR_TYPES         = 0x00000085L;
-
-    /* CKA_TRUSTED is new for v2.11 */
-    public static final long  CKA_TRUSTED            = 0x00000086L;
-
-    public static final long  CKA_KEY_TYPE           = 0x00000100L;
-    public static final long  CKA_SUBJECT            = 0x00000101L;
-    public static final long  CKA_ID                 = 0x00000102L;
-    public static final long  CKA_SENSITIVE          = 0x00000103L;
-    public static final long  CKA_ENCRYPT            = 0x00000104L;
-    public static final long  CKA_DECRYPT            = 0x00000105L;
-    public static final long  CKA_WRAP               = 0x00000106L;
-    public static final long  CKA_UNWRAP             = 0x00000107L;
-    public static final long  CKA_SIGN               = 0x00000108L;
-    public static final long  CKA_SIGN_RECOVER       = 0x00000109L;
-    public static final long  CKA_VERIFY             = 0x0000010AL;
-    public static final long  CKA_VERIFY_RECOVER     = 0x0000010BL;
-    public static final long  CKA_DERIVE             = 0x0000010CL;
-    public static final long  CKA_START_DATE         = 0x00000110L;
-    public static final long  CKA_END_DATE           = 0x00000111L;
-    public static final long  CKA_MODULUS            = 0x00000120L;
-    public static final long  CKA_MODULUS_BITS       = 0x00000121L;
-    public static final long  CKA_PUBLIC_EXPONENT    = 0x00000122L;
-    public static final long  CKA_PRIVATE_EXPONENT   = 0x00000123L;
-    public static final long  CKA_PRIME_1            = 0x00000124L;
-    public static final long  CKA_PRIME_2            = 0x00000125L;
-    public static final long  CKA_EXPONENT_1         = 0x00000126L;
-    public static final long  CKA_EXPONENT_2         = 0x00000127L;
-    public static final long  CKA_COEFFICIENT        = 0x00000128L;
-    public static final long  CKA_PRIME              = 0x00000130L;
-    public static final long  CKA_SUBPRIME           = 0x00000131L;
-    public static final long  CKA_BASE               = 0x00000132L;
-
-    /* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
-    public static final long  CKA_PRIME_BITS         = 0x00000133L;
-    public static final long  CKA_SUB_PRIME_BITS     = 0x00000134L;
-
-    public static final long  CKA_VALUE_BITS         = 0x00000160L;
-    public static final long  CKA_VALUE_LEN          = 0x00000161L;
-
-    /* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
-     * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
-     * and CKA_EC_POINT are new for v2.0 */
-    public static final long  CKA_EXTRACTABLE        = 0x00000162L;
-    public static final long  CKA_LOCAL              = 0x00000163L;
-    public static final long  CKA_NEVER_EXTRACTABLE  = 0x00000164L;
-    public static final long  CKA_ALWAYS_SENSITIVE   = 0x00000165L;
-
-    /* CKA_KEY_GEN_MECHANISM is new for v2.11 */
-    public static final long  CKA_KEY_GEN_MECHANISM  = 0x00000166L;
-
-    public static final long  CKA_MODIFIABLE         = 0x00000170L;
-
-    /* CKA_ECDSA_PARAMS is deprecated in v2.11,
-     * CKA_EC_PARAMS is preferred. */
-    public static final long  CKA_ECDSA_PARAMS       = 0x00000180L;
-    public static final long  CKA_EC_PARAMS          = 0x00000180L;
-    public static final long  CKA_EC_POINT           = 0x00000181L;
-
-    /* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
-     * CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
-     * are new for v2.10 */
-    public static final long  CKA_SECONDARY_AUTH     = 0x00000200L;
-    public static final long  CKA_AUTH_PIN_FLAGS     = 0x00000201L;
-    public static final long  CKA_HW_FEATURE_TYPE    = 0x00000300L;
-    public static final long  CKA_RESET_ON_INIT      = 0x00000301L;
-    public static final long  CKA_HAS_RESET          = 0x00000302L;
-
-    public static final long  CKA_VENDOR_DEFINED     = 0x80000000L;
-
-    /* the following mechanism types are defined: */
-    public static final long  CKM_RSA_PKCS_KEY_PAIR_GEN      = 0x00000000L;
-    public static final long  CKM_RSA_PKCS                   = 0x00000001L;
-    public static final long  CKM_RSA_9796                   = 0x00000002L;
-    public static final long  CKM_RSA_X_509                  = 0x00000003L;
-
-    /* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
-     * are new for v2.0.  They are mechanisms which hash and sign */
-    public static final long  CKM_MD2_RSA_PKCS               = 0x00000004L;
-    public static final long  CKM_MD5_RSA_PKCS               = 0x00000005L;
-    public static final long  CKM_SHA1_RSA_PKCS              = 0x00000006L;
-
-    /* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
-     * CKM_RSA_PKCS_OAEP are new for v2.10 */
-    public static final long  CKM_RIPEMD128_RSA_PKCS         = 0x00000007L;
-    public static final long  CKM_RIPEMD160_RSA_PKCS         = 0x00000008L;
-    public static final long  CKM_RSA_PKCS_OAEP              = 0x00000009L;
-
-    /* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
-     * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
-    public static final long  CKM_RSA_X9_31_KEY_PAIR_GEN     = 0x0000000AL;
-    public static final long  CKM_RSA_X9_31                  = 0x0000000BL;
-    public static final long  CKM_SHA1_RSA_X9_31             = 0x0000000CL;
-    public static final long  CKM_RSA_PKCS_PSS               = 0x0000000DL;
-    public static final long  CKM_SHA1_RSA_PKCS_PSS          = 0x0000000EL;
-
-    public static final long  CKM_DSA_KEY_PAIR_GEN           = 0x00000010L;
-    public static final long  CKM_DSA                        = 0x00000011L;
-    public static final long  CKM_DSA_SHA1                   = 0x00000012L;
-    public static final long  CKM_DH_PKCS_KEY_PAIR_GEN       = 0x00000020L;
-    public static final long  CKM_DH_PKCS_DERIVE             = 0x00000021L;
-
-    /* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
-     * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
-     * v2.11 */
-    public static final long  CKM_X9_42_DH_KEY_PAIR_GEN      = 0x00000030L;
-    public static final long  CKM_X9_42_DH_DERIVE            = 0x00000031L;
-    public static final long  CKM_X9_42_DH_HYBRID_DERIVE     = 0x00000032L;
-    public static final long  CKM_X9_42_MQV_DERIVE           = 0x00000033L;
-
-    // v2.20
-    public static final long  CKM_SHA256_RSA_PKCS            = 0x00000040L;
-    public static final long  CKM_SHA384_RSA_PKCS            = 0x00000041L;
-    public static final long  CKM_SHA512_RSA_PKCS            = 0x00000042L;
-
-    public static final long  CKM_RC2_KEY_GEN                = 0x00000100L;
-    public static final long  CKM_RC2_ECB                    = 0x00000101L;
-    public static final long  CKM_RC2_CBC                    = 0x00000102L;
-    public static final long  CKM_RC2_MAC                    = 0x00000103L;
-
-    /* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-    public static final long  CKM_RC2_MAC_GENERAL            = 0x00000104L;
-    public static final long  CKM_RC2_CBC_PAD                = 0x00000105L;
-
-    public static final long  CKM_RC4_KEY_GEN                = 0x00000110L;
-    public static final long  CKM_RC4                        = 0x00000111L;
-    public static final long  CKM_DES_KEY_GEN                = 0x00000120L;
-    public static final long  CKM_DES_ECB                    = 0x00000121L;
-    public static final long  CKM_DES_CBC                    = 0x00000122L;
-    public static final long  CKM_DES_MAC                    = 0x00000123L;
-
-    /* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-    public static final long  CKM_DES_MAC_GENERAL            = 0x00000124L;
-    public static final long  CKM_DES_CBC_PAD                = 0x00000125L;
-
-    public static final long  CKM_DES2_KEY_GEN               = 0x00000130L;
-    public static final long  CKM_DES3_KEY_GEN               = 0x00000131L;
-    public static final long  CKM_DES3_ECB                   = 0x00000132L;
-    public static final long  CKM_DES3_CBC                   = 0x00000133L;
-    public static final long  CKM_DES3_MAC                   = 0x00000134L;
-
-    /* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
-     * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
-     * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-    public static final long  CKM_DES3_MAC_GENERAL           = 0x00000135L;
-    public static final long  CKM_DES3_CBC_PAD               = 0x00000136L;
-    public static final long  CKM_CDMF_KEY_GEN               = 0x00000140L;
-    public static final long  CKM_CDMF_ECB                   = 0x00000141L;
-    public static final long  CKM_CDMF_CBC                   = 0x00000142L;
-    public static final long  CKM_CDMF_MAC                   = 0x00000143L;
-    public static final long  CKM_CDMF_MAC_GENERAL           = 0x00000144L;
-    public static final long  CKM_CDMF_CBC_PAD               = 0x00000145L;
-
-    public static final long  CKM_MD2                        = 0x00000200L;
-
-    /* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-    public static final long  CKM_MD2_HMAC                   = 0x00000201L;
-    public static final long  CKM_MD2_HMAC_GENERAL           = 0x00000202L;
-
-    public static final long  CKM_MD5                        = 0x00000210L;
-
-    /* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-    public static final long  CKM_MD5_HMAC                   = 0x00000211L;
-    public static final long  CKM_MD5_HMAC_GENERAL           = 0x00000212L;
-
-    public static final long  CKM_SHA_1                      = 0x00000220L;
-
-    /* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-    public static final long  CKM_SHA_1_HMAC                 = 0x00000221L;
-    public static final long  CKM_SHA_1_HMAC_GENERAL         = 0x00000222L;
-
-    /* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
-     * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
-     * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
-    public static final long  CKM_RIPEMD128                  = 0x00000230L;
-    public static final long  CKM_RIPEMD128_HMAC             = 0x00000231L;
-    public static final long  CKM_RIPEMD128_HMAC_GENERAL     = 0x00000232L;
-    public static final long  CKM_RIPEMD160                  = 0x00000240L;
-    public static final long  CKM_RIPEMD160_HMAC             = 0x00000241L;
-    public static final long  CKM_RIPEMD160_HMAC_GENERAL     = 0x00000242L;
-
-    // v2.20
-    public static final long  CKM_SHA256                     = 0x00000250L;
-    public static final long  CKM_SHA256_HMAC                = 0x00000251L;
-    public static final long  CKM_SHA256_HMAC_GENERAL        = 0x00000252L;
-
-    public static final long  CKM_SHA384                     = 0x00000260L;
-    public static final long  CKM_SHA384_HMAC                = 0x00000261L;
-    public static final long  CKM_SHA384_HMAC_GENERAL        = 0x00000262L;
-
-    public static final long  CKM_SHA512                     = 0x00000270L;
-    public static final long  CKM_SHA512_HMAC                = 0x00000271L;
-    public static final long  CKM_SHA512_HMAC_GENERAL        = 0x00000272L;
-
-    /* All of the following mechanisms are new for v2.0 */
-    /* Note that CAST128 and CAST5 are the same algorithm */
-    public static final long  CKM_CAST_KEY_GEN               = 0x00000300L;
-    public static final long  CKM_CAST_ECB                   = 0x00000301L;
-    public static final long  CKM_CAST_CBC                   = 0x00000302L;
-    public static final long  CKM_CAST_MAC                   = 0x00000303L;
-    public static final long  CKM_CAST_MAC_GENERAL           = 0x00000304L;
-    public static final long  CKM_CAST_CBC_PAD               = 0x00000305L;
-    public static final long  CKM_CAST3_KEY_GEN              = 0x00000310L;
-    public static final long  CKM_CAST3_ECB                  = 0x00000311L;
-    public static final long  CKM_CAST3_CBC                  = 0x00000312L;
-    public static final long  CKM_CAST3_MAC                  = 0x00000313L;
-    public static final long  CKM_CAST3_MAC_GENERAL          = 0x00000314L;
-    public static final long  CKM_CAST3_CBC_PAD              = 0x00000315L;
-    public static final long  CKM_CAST5_KEY_GEN              = 0x00000320L;
-    public static final long  CKM_CAST128_KEY_GEN            = 0x00000320L;
-    public static final long  CKM_CAST5_ECB                  = 0x00000321L;
-    public static final long  CKM_CAST128_ECB                = 0x00000321L;
-    public static final long  CKM_CAST5_CBC                  = 0x00000322L;
-    public static final long  CKM_CAST128_CBC                = 0x00000322L;
-    public static final long  CKM_CAST5_MAC                  = 0x00000323L;
-    public static final long  CKM_CAST128_MAC                = 0x00000323L;
-    public static final long  CKM_CAST5_MAC_GENERAL          = 0x00000324L;
-    public static final long  CKM_CAST128_MAC_GENERAL        = 0x00000324L;
-    public static final long  CKM_CAST5_CBC_PAD              = 0x00000325L;
-    public static final long  CKM_CAST128_CBC_PAD            = 0x00000325L;
-    public static final long  CKM_RC5_KEY_GEN                = 0x00000330L;
-    public static final long  CKM_RC5_ECB                    = 0x00000331L;
-    public static final long  CKM_RC5_CBC                    = 0x00000332L;
-    public static final long  CKM_RC5_MAC                    = 0x00000333L;
-    public static final long  CKM_RC5_MAC_GENERAL            = 0x00000334L;
-    public static final long  CKM_RC5_CBC_PAD                = 0x00000335L;
-    public static final long  CKM_IDEA_KEY_GEN               = 0x00000340L;
-    public static final long  CKM_IDEA_ECB                   = 0x00000341L;
-    public static final long  CKM_IDEA_CBC                   = 0x00000342L;
-    public static final long  CKM_IDEA_MAC                   = 0x00000343L;
-    public static final long  CKM_IDEA_MAC_GENERAL           = 0x00000344L;
-    public static final long  CKM_IDEA_CBC_PAD               = 0x00000345L;
-    public static final long  CKM_GENERIC_SECRET_KEY_GEN     = 0x00000350L;
-    public static final long  CKM_CONCATENATE_BASE_AND_KEY   = 0x00000360L;
-    public static final long  CKM_CONCATENATE_BASE_AND_DATA  = 0x00000362L;
-    public static final long  CKM_CONCATENATE_DATA_AND_BASE  = 0x00000363L;
-    public static final long  CKM_XOR_BASE_AND_DATA          = 0x00000364L;
-    public static final long  CKM_EXTRACT_KEY_FROM_KEY       = 0x00000365L;
-    public static final long  CKM_SSL3_PRE_MASTER_KEY_GEN    = 0x00000370L;
-    public static final long  CKM_SSL3_MASTER_KEY_DERIVE     = 0x00000371L;
-    public static final long  CKM_SSL3_KEY_AND_MAC_DERIVE    = 0x00000372L;
-
-    /* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
-     * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
-     * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
-    public static final long  CKM_SSL3_MASTER_KEY_DERIVE_DH  = 0x00000373L;
-    public static final long  CKM_TLS_PRE_MASTER_KEY_GEN     = 0x00000374L;
-    public static final long  CKM_TLS_MASTER_KEY_DERIVE      = 0x00000375L;
-    public static final long  CKM_TLS_KEY_AND_MAC_DERIVE     = 0x00000376L;
-    public static final long  CKM_TLS_MASTER_KEY_DERIVE_DH   = 0x00000377L;
-    public static final long  CKM_TLS_PRF                    = 0x00000378L;
-
-    public static final long  CKM_SSL3_MD5_MAC               = 0x00000380L;
-    public static final long  CKM_SSL3_SHA1_MAC              = 0x00000381L;
-    public static final long  CKM_MD5_KEY_DERIVATION         = 0x00000390L;
-    public static final long  CKM_MD2_KEY_DERIVATION         = 0x00000391L;
-    public static final long  CKM_SHA1_KEY_DERIVATION        = 0x00000392L;
-
-    // v2.20
-    public static final long  CKM_SHA256_KEY_DERIVATION      = 0x00000393L;
-    public static final long  CKM_SHA384_KEY_DERIVATION      = 0x00000394L;
-    public static final long  CKM_SHA512_KEY_DERIVATION      = 0x00000395L;
-
-    public static final long  CKM_PBE_MD2_DES_CBC            = 0x000003A0L;
-    public static final long  CKM_PBE_MD5_DES_CBC            = 0x000003A1L;
-    public static final long  CKM_PBE_MD5_CAST_CBC           = 0x000003A2L;
-    public static final long  CKM_PBE_MD5_CAST3_CBC          = 0x000003A3L;
-    public static final long  CKM_PBE_MD5_CAST5_CBC          = 0x000003A4L;
-    public static final long  CKM_PBE_MD5_CAST128_CBC        = 0x000003A4L;
-    public static final long  CKM_PBE_SHA1_CAST5_CBC         = 0x000003A5L;
-    public static final long  CKM_PBE_SHA1_CAST128_CBC       = 0x000003A5L;
-    public static final long  CKM_PBE_SHA1_RC4_128           = 0x000003A6L;
-    public static final long  CKM_PBE_SHA1_RC4_40            = 0x000003A7L;
-    public static final long  CKM_PBE_SHA1_DES3_EDE_CBC      = 0x000003A8L;
-    public static final long  CKM_PBE_SHA1_DES2_EDE_CBC      = 0x000003A9L;
-    public static final long  CKM_PBE_SHA1_RC2_128_CBC       = 0x000003AAL;
-    public static final long  CKM_PBE_SHA1_RC2_40_CBC        = 0x000003ABL;
-
-    /* CKM_PKCS5_PBKD2 is new for v2.10 */
-    public static final long  CKM_PKCS5_PBKD2                = 0x000003B0L;
-
-    public static final long  CKM_PBA_SHA1_WITH_SHA1_HMAC    = 0x000003C0L;
-    public static final long  CKM_KEY_WRAP_LYNKS             = 0x00000400L;
-    public static final long  CKM_KEY_WRAP_SET_OAEP          = 0x00000401L;
-
-    /* Fortezza mechanisms */
-    public static final long  CKM_SKIPJACK_KEY_GEN           = 0x00001000L;
-    public static final long  CKM_SKIPJACK_ECB64             = 0x00001001L;
-    public static final long  CKM_SKIPJACK_CBC64             = 0x00001002L;
-    public static final long  CKM_SKIPJACK_OFB64             = 0x00001003L;
-    public static final long  CKM_SKIPJACK_CFB64             = 0x00001004L;
-    public static final long  CKM_SKIPJACK_CFB32             = 0x00001005L;
-    public static final long  CKM_SKIPJACK_CFB16             = 0x00001006L;
-    public static final long  CKM_SKIPJACK_CFB8              = 0x00001007L;
-    public static final long  CKM_SKIPJACK_WRAP              = 0x00001008L;
-    public static final long  CKM_SKIPJACK_PRIVATE_WRAP      = 0x00001009L;
-    public static final long  CKM_SKIPJACK_RELAYX            = 0x0000100AL;
-    public static final long  CKM_KEA_KEY_PAIR_GEN           = 0x00001010L;
-    public static final long  CKM_KEA_KEY_DERIVE             = 0x00001011L;
-    public static final long  CKM_FORTEZZA_TIMESTAMP         = 0x00001020L;
-    public static final long  CKM_BATON_KEY_GEN              = 0x00001030L;
-    public static final long  CKM_BATON_ECB128               = 0x00001031L;
-    public static final long  CKM_BATON_ECB96                = 0x00001032L;
-    public static final long  CKM_BATON_CBC128               = 0x00001033L;
-    public static final long  CKM_BATON_COUNTER              = 0x00001034L;
-    public static final long  CKM_BATON_SHUFFLE              = 0x00001035L;
-    public static final long  CKM_BATON_WRAP                 = 0x00001036L;
-
-    /* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
-     * CKM_EC_KEY_PAIR_GEN is preferred */
-    public static final long  CKM_ECDSA_KEY_PAIR_GEN         = 0x00001040L;
-    public static final long  CKM_EC_KEY_PAIR_GEN            = 0x00001040L;
-
-    public static final long  CKM_ECDSA                      = 0x00001041L;
-    public static final long  CKM_ECDSA_SHA1                 = 0x00001042L;
-
-    /* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
-     * are new for v2.11 */
-    public static final long  CKM_ECDH1_DERIVE               = 0x00001050L;
-    public static final long  CKM_ECDH1_COFACTOR_DERIVE      = 0x00001051L;
-    public static final long  CKM_ECMQV_DERIVE               = 0x00001052L;
-
-    public static final long  CKM_JUNIPER_KEY_GEN            = 0x00001060L;
-    public static final long  CKM_JUNIPER_ECB128             = 0x00001061L;
-    public static final long  CKM_JUNIPER_CBC128             = 0x00001062L;
-    public static final long  CKM_JUNIPER_COUNTER            = 0x00001063L;
-    public static final long  CKM_JUNIPER_SHUFFLE            = 0x00001064L;
-    public static final long  CKM_JUNIPER_WRAP               = 0x00001065L;
-    public static final long  CKM_FASTHASH                   = 0x00001070L;
-
-    /* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
-     * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
-     * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
-     * new for v2.11 */
-    public static final long  CKM_AES_KEY_GEN                = 0x00001080L;
-    public static final long  CKM_AES_ECB                    = 0x00001081L;
-    public static final long  CKM_AES_CBC                    = 0x00001082L;
-    public static final long  CKM_AES_MAC                    = 0x00001083L;
-    public static final long  CKM_AES_MAC_GENERAL            = 0x00001084L;
-    public static final long  CKM_AES_CBC_PAD                = 0x00001085L;
-    // v2.20
-    public static final long  CKM_BLOWFISH_KEY_GEN           = 0x00001090L;
-    public static final long  CKM_BLOWFISH_CBC               = 0x00001091L;
-    public static final long  CKM_DSA_PARAMETER_GEN          = 0x00002000L;
-    public static final long  CKM_DH_PKCS_PARAMETER_GEN      = 0x00002001L;
-    public static final long  CKM_X9_42_DH_PARAMETER_GEN     = 0x00002002L;
-
-    public static final long  CKM_VENDOR_DEFINED             = 0x80000000L;
-
-    // new for v2.20 amendment 3
-    public static final long  CKM_SHA224                     = 0x00000255L;
-    public static final long  CKM_SHA224_HMAC                = 0x00000256L;
-    public static final long  CKM_SHA224_HMAC_GENERAL        = 0x00000257L;
-    public static final long  CKM_SHA224_KEY_DERIVATION      = 0x00000396L;
-    public static final long  CKM_SHA224_RSA_PKCS            = 0x00000046L;
-    public static final long  CKM_SHA224_RSA_PKCS_PSS        = 0x00000047L;
-    public static final long  CKM_AES_CTR                    = 0x00001086L;
-    /*
-    public static final long  CKM_CAMELLIA_KEY_GEN           = 0x00000550L;
-    public static final long  CKM_CAMELLIA_ECB               = 0x00000551L;
-    public static final long  CKM_CAMELLIA_CBC               = 0x00000552L;
-    public static final long  CKM_CAMELLIA_MAC               = 0x00000553L;
-    public static final long  CKM_CAMELLIA_MAC_GENERAL       = 0x00000554L;
-    public static final long  CKM_CAMELLIA_CBC_PAD           = 0x00000555L;
-    public static final long  CKM_CAMELLIA_ECB_ENCRYPT_DATA  = 0x00000556L;
-    public static final long  CKM_CAMELLIA_CBC_ENCRYPT_DATA  = 0x00000557L;
-    public static final long  CKM_CAMELLIA_CTR               = 0x00000558L;
-    public static final long  CKM_ARIA_KEY_GEN               = 0x00000560L;
-    public static final long  CKM_ARIA_ECB                   = 0x00000561L;
-    public static final long  CKM_ARIA_CBC                   = 0x00000562L;
-    public static final long  CKM_ARIA_MAC                   = 0x00000563L;
-    public static final long  CKM_ARIA_MAC_GENERAL           = 0x00000564L;
-    public static final long  CKM_ARIA_CBC_PAD               = 0x00000565L;
-    public static final long  CKM_ARIA_ECB_ENCRYPT_DATA      = 0x00000566L;
-    public static final long  CKM_ARIA_CBC_ENCRYPT_DATA      = 0x00000567L;
-    */
-
-    // NSS private
-    public static final long  CKM_NSS_TLS_PRF_GENERAL        = 0x80000373L;
-
-    // ids for our pseudo mechanisms SecureRandom and KeyStore
-    public static final long  PCKM_SECURERANDOM              = 0x7FFFFF20L;
-    public static final long  PCKM_KEYSTORE                  = 0x7FFFFF21L;
-
-    /* The flags are defined as follows:
-     *      Bit Flag               Mask        Meaning */
-    /* performed by HW */
-    public static final long  CKF_HW                 = 0x00000001L;
-
-    /* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
-     * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
-     * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
-     * and CKF_DERIVE are new for v2.0.  They specify whether or not
-     * a mechanism can be used for a particular task */
-    public static final long  CKF_ENCRYPT            = 0x00000100L;
-    public static final long  CKF_DECRYPT            = 0x00000200L;
-    public static final long  CKF_DIGEST             = 0x00000400L;
-    public static final long  CKF_SIGN               = 0x00000800L;
-    public static final long  CKF_SIGN_RECOVER       = 0x00001000L;
-    public static final long  CKF_VERIFY             = 0x00002000L;
-    public static final long  CKF_VERIFY_RECOVER     = 0x00004000L;
-    public static final long  CKF_GENERATE           = 0x00008000L;
-    public static final long  CKF_GENERATE_KEY_PAIR  = 0x00010000L;
-    public static final long  CKF_WRAP               = 0x00020000L;
-    public static final long  CKF_UNWRAP             = 0x00040000L;
-    public static final long  CKF_DERIVE             = 0x00080000L;
-
-    /* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
-     * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
-     * describe a token's EC capabilities not available in mechanism
-     * information. */
-    public static final long  CKF_EC_F_P              = 0x00100000L;
-    public static final long  CKF_EC_F_2M           = 0x00200000L;
-    public static final long  CKF_EC_ECPARAMETERS   = 0x00400000L;
-    public static final long  CKF_EC_NAMEDCURVE     = 0x00800000L;
-    public static final long  CKF_EC_UNCOMPRESS     = 0x01000000L;
-    public static final long  CKF_EC_COMPRESS       = 0x02000000L;
-
-    /* FALSE for 2.01 */
-    public static final long  CKF_EXTENSION          = 0x80000000L;
-
-
-    /* CK_RV is a value that identifies the return value of a
-     * Cryptoki function */
-    /* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-    public static final long  CKR_OK                                = 0x00000000L;
-    public static final long  CKR_CANCEL                            = 0x00000001L;
-    public static final long  CKR_HOST_MEMORY                       = 0x00000002L;
-    public static final long  CKR_SLOT_ID_INVALID                   = 0x00000003L;
-
-    /* CKR_FLAGS_INVALID was removed for v2.0 */
-
-    /* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-    public static final long  CKR_GENERAL_ERROR                     = 0x00000005L;
-    public static final long  CKR_FUNCTION_FAILED                   = 0x00000006L;
-
-    /* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
-     * and CKR_CANT_LOCK are new for v2.01 */
-    public static final long  CKR_ARGUMENTS_BAD                     = 0x00000007L;
-    public static final long  CKR_NO_EVENT                          = 0x00000008L;
-    public static final long  CKR_NEED_TO_CREATE_THREADS            = 0x00000009L;
-    public static final long  CKR_CANT_LOCK                         = 0x0000000AL;
-
-    public static final long  CKR_ATTRIBUTE_READ_ONLY               = 0x00000010L;
-    public static final long  CKR_ATTRIBUTE_SENSITIVE               = 0x00000011L;
-    public static final long  CKR_ATTRIBUTE_TYPE_INVALID            = 0x00000012L;
-    public static final long  CKR_ATTRIBUTE_VALUE_INVALID           = 0x00000013L;
-    public static final long  CKR_DATA_INVALID                      = 0x00000020L;
-    public static final long  CKR_DATA_LEN_RANGE                    = 0x00000021L;
-    public static final long  CKR_DEVICE_ERROR                      = 0x00000030L;
-    public static final long  CKR_DEVICE_MEMORY                     = 0x00000031L;
-    public static final long  CKR_DEVICE_REMOVED                    = 0x00000032L;
-    public static final long  CKR_ENCRYPTED_DATA_INVALID            = 0x00000040L;
-    public static final long  CKR_ENCRYPTED_DATA_LEN_RANGE          = 0x00000041L;
-    public static final long  CKR_FUNCTION_CANCELED                 = 0x00000050L;
-    public static final long  CKR_FUNCTION_NOT_PARALLEL             = 0x00000051L;
-
-    /* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-    public static final long  CKR_FUNCTION_NOT_SUPPORTED            = 0x00000054L;
-
-    public static final long  CKR_KEY_HANDLE_INVALID                = 0x00000060L;
-
-    /* CKR_KEY_SENSITIVE was removed for v2.0 */
-
-    public static final long  CKR_KEY_SIZE_RANGE                    = 0x00000062L;
-    public static final long  CKR_KEY_TYPE_INCONSISTENT             = 0x00000063L;
-
-    /* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
-     * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
-     * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
-     * v2.0 */
-    public static final long  CKR_KEY_NOT_NEEDED                    = 0x00000064L;
-    public static final long  CKR_KEY_CHANGED                       = 0x00000065L;
-    public static final long  CKR_KEY_NEEDED                        = 0x00000066L;
-    public static final long  CKR_KEY_INDIGESTIBLE                  = 0x00000067L;
-    public static final long  CKR_KEY_FUNCTION_NOT_PERMITTED        = 0x00000068L;
-    public static final long  CKR_KEY_NOT_WRAPPABLE                 = 0x00000069L;
-    public static final long  CKR_KEY_UNEXTRACTABLE                 = 0x0000006AL;
-
-    public static final long  CKR_MECHANISM_INVALID                 = 0x00000070L;
-    public static final long  CKR_MECHANISM_PARAM_INVALID           = 0x00000071L;
-
-    /* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
-     * were removed for v2.0 */
-    public static final long  CKR_OBJECT_HANDLE_INVALID             = 0x00000082L;
-    public static final long  CKR_OPERATION_ACTIVE                  = 0x00000090L;
-    public static final long  CKR_OPERATION_NOT_INITIALIZED         = 0x00000091L;
-    public static final long  CKR_PIN_INCORRECT                     = 0x000000A0L;
-    public static final long  CKR_PIN_INVALID                       = 0x000000A1L;
-    public static final long  CKR_PIN_LEN_RANGE                     = 0x000000A2L;
-
-    /* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-    public static final long  CKR_PIN_EXPIRED                       = 0x000000A3L;
-    public static final long  CKR_PIN_LOCKED                        = 0x000000A4L;
-
-    public static final long  CKR_SESSION_CLOSED                    = 0x000000B0L;
-    public static final long  CKR_SESSION_COUNT                     = 0x000000B1L;
-    public static final long  CKR_SESSION_HANDLE_INVALID            = 0x000000B3L;
-    public static final long  CKR_SESSION_PARALLEL_NOT_SUPPORTED    = 0x000000B4L;
-    public static final long  CKR_SESSION_READ_ONLY                 = 0x000000B5L;
-    public static final long  CKR_SESSION_EXISTS                    = 0x000000B6L;
-
-    /* CKR_SESSION_READ_ONLY_EXISTS and
-     * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-    public static final long  CKR_SESSION_READ_ONLY_EXISTS          = 0x000000B7L;
-    public static final long  CKR_SESSION_READ_WRITE_SO_EXISTS      = 0x000000B8L;
-
-    public static final long  CKR_SIGNATURE_INVALID                 = 0x000000C0L;
-    public static final long  CKR_SIGNATURE_LEN_RANGE               = 0x000000C1L;
-    public static final long  CKR_TEMPLATE_INCOMPLETE               = 0x000000D0L;
-    public static final long  CKR_TEMPLATE_INCONSISTENT             = 0x000000D1L;
-    public static final long  CKR_TOKEN_NOT_PRESENT                 = 0x000000E0L;
-    public static final long  CKR_TOKEN_NOT_RECOGNIZED              = 0x000000E1L;
-    public static final long  CKR_TOKEN_WRITE_PROTECTED             = 0x000000E2L;
-    public static final long  CKR_UNWRAPPING_KEY_HANDLE_INVALID     = 0x000000F0L;
-    public static final long  CKR_UNWRAPPING_KEY_SIZE_RANGE         = 0x000000F1L;
-    public static final long  CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  = 0x000000F2L;
-    public static final long  CKR_USER_ALREADY_LOGGED_IN            = 0x00000100L;
-    public static final long  CKR_USER_NOT_LOGGED_IN                = 0x00000101L;
-    public static final long  CKR_USER_PIN_NOT_INITIALIZED          = 0x00000102L;
-    public static final long  CKR_USER_TYPE_INVALID                 = 0x00000103L;
-
-    /* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
-     * are new to v2.01 */
-    public static final long  CKR_USER_ANOTHER_ALREADY_LOGGED_IN    = 0x00000104L;
-    public static final long  CKR_USER_TOO_MANY_TYPES               = 0x00000105L;
-
-    public static final long  CKR_WRAPPED_KEY_INVALID               = 0x00000110L;
-    public static final long  CKR_WRAPPED_KEY_LEN_RANGE             = 0x00000112L;
-    public static final long  CKR_WRAPPING_KEY_HANDLE_INVALID       = 0x00000113L;
-    public static final long  CKR_WRAPPING_KEY_SIZE_RANGE           = 0x00000114L;
-    public static final long  CKR_WRAPPING_KEY_TYPE_INCONSISTENT    = 0x00000115L;
-    public static final long  CKR_RANDOM_SEED_NOT_SUPPORTED         = 0x00000120L;
-
-    /* These are new to v2.0 */
-    public static final long  CKR_RANDOM_NO_RNG                     = 0x00000121L;
-
-    /* These are new to v2.11 */
-    public static final long  CKR_DOMAIN_PARAMS_INVALID             = 0x00000130L;
-
-    /* These are new to v2.0 */
-    public static final long  CKR_BUFFER_TOO_SMALL                  = 0x00000150L;
-    public static final long  CKR_SAVED_STATE_INVALID               = 0x00000160L;
-    public static final long  CKR_INFORMATION_SENSITIVE             = 0x00000170L;
-    public static final long  CKR_STATE_UNSAVEABLE                  = 0x00000180L;
-
-    /* These are new to v2.01 */
-    public static final long  CKR_CRYPTOKI_NOT_INITIALIZED          = 0x00000190L;
-    public static final long  CKR_CRYPTOKI_ALREADY_INITIALIZED      = 0x00000191L;
-    public static final long  CKR_MUTEX_BAD                         = 0x000001A0L;
-    public static final long  CKR_MUTEX_NOT_LOCKED                  = 0x000001A1L;
-
-    public static final long  CKR_VENDOR_DEFINED                    = 0x80000000L;
-
-
-    /* flags: bit flags that provide capabilities of the slot
-     *        Bit Flag = Mask
-     */
-    public static final long  CKF_LIBRARY_CANT_CREATE_OS_THREADS = 0x00000001L;
-    public static final long  CKF_OS_LOCKING_OK                  = 0x00000002L;
-
-
-    /* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-    public static final long  CKF_DONT_BLOCK =    1L;
-
-
-    /* The following MGFs are defined */
-    public static final long  CKG_MGF1_SHA1       =  0x00000001L;
-    // new for v2.20 amendment 3
-    public static final long  CKG_MGF1_SHA224     = 0x00000005L;
-
-    /* The following encoding parameter sources are defined */
-    public static final long  CKZ_DATA_SPECIFIED   = 0x00000001L;
-
-
-    /* The following PRFs are defined in PKCS #5 v2.0. */
-    public static final long  CKP_PKCS5_PBKD2_HMAC_SHA1 = 0x00000001L;
-
-
-    /* The following salt value sources are defined in PKCS #5 v2.0. */
-    public static final long CKZ_SALT_SPECIFIED        = 0x00000001L;
-
-    /* the following EC Key Derivation Functions are defined */
-    public static final long CKD_NULL                 = 0x00000001L;
-    public static final long CKD_SHA1_KDF             = 0x00000002L;
-
-    /* the following X9.42 Diffie-Hellman Key Derivation Functions are defined */
-    public static final long CKD_SHA1_KDF_ASN1        = 0x00000003L;
-    public static final long CKD_SHA1_KDF_CONCATENATE = 0x00000004L;
-
-
-    // private NSS attribute (for DSA and DH private keys)
-    public static final long  CKA_NETSCAPE_DB         = 0xD5A0DB00L;
-
-    // base number of NSS private attributes
-    public static final long  CKA_NETSCAPE_BASE       = 0x80000000L + 0x4E534350L;
-
-    // object type for NSS trust
-    public static final long  CKO_NETSCAPE_TRUST      = CKA_NETSCAPE_BASE + 3;
-
-    // base number for NSS trust attributes
-    public static final long  CKA_NETSCAPE_TRUST_BASE = CKA_NETSCAPE_BASE + 0x2000;
-
-    // attributes for NSS trust
-    public static final long  CKA_NETSCAPE_TRUST_SERVER_AUTH      = CKA_NETSCAPE_TRUST_BASE +   8;
-    public static final long  CKA_NETSCAPE_TRUST_CLIENT_AUTH      = CKA_NETSCAPE_TRUST_BASE +   9;
-    public static final long  CKA_NETSCAPE_TRUST_CODE_SIGNING     = CKA_NETSCAPE_TRUST_BASE +  10;
-    public static final long  CKA_NETSCAPE_TRUST_EMAIL_PROTECTION = CKA_NETSCAPE_TRUST_BASE +  11;
-    public static final long  CKA_NETSCAPE_CERT_SHA1_HASH         = CKA_NETSCAPE_TRUST_BASE + 100;
-    public static final long  CKA_NETSCAPE_CERT_MD5_HASH          = CKA_NETSCAPE_TRUST_BASE + 101;
-
-    // trust values for each of the NSS trust attributes
-    public static final long  CKT_NETSCAPE_TRUSTED           = CKA_NETSCAPE_BASE + 1;
-    public static final long  CKT_NETSCAPE_TRUSTED_DELEGATOR = CKA_NETSCAPE_BASE + 2;
-    public static final long  CKT_NETSCAPE_UNTRUSTED         = CKA_NETSCAPE_BASE + 3;
-    public static final long  CKT_NETSCAPE_MUST_VERIFY       = CKA_NETSCAPE_BASE + 4;
-    public static final long  CKT_NETSCAPE_TRUST_UNKNOWN     = CKA_NETSCAPE_BASE + 5; /* default */
-    public static final long  CKT_NETSCAPE_VALID             = CKA_NETSCAPE_BASE + 10;
-    public static final long  CKT_NETSCAPE_VALID_DELEGATOR   = CKA_NETSCAPE_BASE + 11;
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-import java.util.*;
-
-
-/**
- * This is the superclass of all checked exceptions used by this package. An
- * exception of this class indicates that a function call to the underlying
- * PKCS#11 module returned a value not equal to CKR_OK. The application can get
- * the returned value by calling getErrorCode(). A return value not equal to
- * CKR_OK is the only reason for such an exception to be thrown.
- * PKCS#11 defines the meaning of an error-code, which may depend on the
- * context in which the error occurs.
- *
- * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
- * @invariants
- */
-public class PKCS11Exception extends Exception {
-    private static final long serialVersionUID = 4877072363729195L;
-
-    /**
-     * The code of the error which was the reason for this exception.
-     */
-    protected long errorCode_;
-
-    private static final Map<Long,String> errorMap;
-
-    static {
-        int[] errorCodes = new int[] {
-            0x00000000,
-            0x00000001,
-            0x00000002,
-            0x00000003,
-            0x00000005,
-            0x00000006,
-            0x00000007,
-            0x00000008,
-            0x00000009,
-            0x0000000A,
-            0x00000010,
-            0x00000011,
-            0x00000012,
-            0x00000013,
-            0x00000020,
-            0x00000021,
-            0x00000030,
-            0x00000031,
-            0x00000032,
-            0x00000040,
-            0x00000041,
-            0x00000050,
-            0x00000051,
-            0x00000054,
-            0x00000060,
-            0x00000062,
-            0x00000063,
-            0x00000064,
-            0x00000065,
-            0x00000066,
-            0x00000067,
-            0x00000068,
-            0x00000069,
-            0x0000006A,
-            0x00000070,
-            0x00000071,
-            0x00000082,
-            0x00000090,
-            0x00000091,
-            0x000000A0,
-            0x000000A1,
-            0x000000A2,
-            0x000000A3,
-            0x000000A4,
-            0x000000B0,
-            0x000000B1,
-            0x000000B3,
-            0x000000B4,
-            0x000000B5,
-            0x000000B6,
-            0x000000B7,
-            0x000000B8,
-            0x000000C0,
-            0x000000C1,
-            0x000000D0,
-            0x000000D1,
-            0x000000E0,
-            0x000000E1,
-            0x000000E2,
-            0x000000F0,
-            0x000000F1,
-            0x000000F2,
-            0x00000100,
-            0x00000101,
-            0x00000102,
-            0x00000103,
-            0x00000104,
-            0x00000105,
-            0x00000110,
-            0x00000112,
-            0x00000113,
-            0x00000114,
-            0x00000115,
-            0x00000120,
-            0x00000121,
-            0x00000130,
-            0x00000150,
-            0x00000160,
-            0x00000170,
-            0x00000180,
-            0x00000190,
-            0x00000191,
-            0x000001A0,
-            0x000001A1,
-            0x00000200,
-            0x80000000,
-        };
-        String[] errorMessages = new String[] {
-            "CKR_OK",
-            "CKR_CANCEL",
-            "CKR_HOST_MEMORY",
-            "CKR_SLOT_ID_INVALID",
-            "CKR_GENERAL_ERROR",
-            "CKR_FUNCTION_FAILED",
-            "CKR_ARGUMENTS_BAD",
-            "CKR_NO_EVENT",
-            "CKR_NEED_TO_CREATE_THREADS",
-            "CKR_CANT_LOCK",
-            "CKR_ATTRIBUTE_READ_ONLY",
-            "CKR_ATTRIBUTE_SENSITIVE",
-            "CKR_ATTRIBUTE_TYPE_INVALID",
-            "CKR_ATTRIBUTE_VALUE_INVALID",
-            "CKR_DATA_INVALID",
-            "CKR_DATA_LEN_RANGE",
-            "CKR_DEVICE_ERROR",
-            "CKR_DEVICE_MEMORY",
-            "CKR_DEVICE_REMOVED",
-            "CKR_ENCRYPTED_DATA_INVALID",
-            "CKR_ENCRYPTED_DATA_LEN_RANGE",
-            "CKR_FUNCTION_CANCELED",
-            "CKR_FUNCTION_NOT_PARALLEL",
-            "CKR_FUNCTION_NOT_SUPPORTED",
-            "CKR_KEY_HANDLE_INVALID",
-            "CKR_KEY_SIZE_RANGE",
-            "CKR_KEY_TYPE_INCONSISTENT",
-            "CKR_KEY_NOT_NEEDED",
-            "CKR_KEY_CHANGED",
-            "CKR_KEY_NEEDED",
-            "CKR_KEY_INDIGESTIBLE",
-            "CKR_KEY_FUNCTION_NOT_PERMITTED",
-            "CKR_KEY_NOT_WRAPPABLE",
-            "CKR_KEY_UNEXTRACTABLE",
-            "CKR_MECHANISM_INVALID",
-            "CKR_MECHANISM_PARAM_INVALID",
-            "CKR_OBJECT_HANDLE_INVALID",
-            "CKR_OPERATION_ACTIVE",
-            "CKR_OPERATION_NOT_INITIALIZED",
-            "CKR_PIN_INCORRECT",
-            "CKR_PIN_INVALID",
-            "CKR_PIN_LEN_RANGE",
-            "CKR_PIN_EXPIRED",
-            "CKR_PIN_LOCKED",
-            "CKR_SESSION_CLOSED",
-            "CKR_SESSION_COUNT",
-            "CKR_SESSION_HANDLE_INVALID",
-            "CKR_SESSION_PARALLEL_NOT_SUPPORTED",
-            "CKR_SESSION_READ_ONLY",
-            "CKR_SESSION_EXISTS",
-            "CKR_SESSION_READ_ONLY_EXISTS",
-            "CKR_SESSION_READ_WRITE_SO_EXISTS",
-            "CKR_SIGNATURE_INVALID",
-            "CKR_SIGNATURE_LEN_RANGE",
-            "CKR_TEMPLATE_INCOMPLETE",
-            "CKR_TEMPLATE_INCONSISTENT",
-            "CKR_TOKEN_NOT_PRESENT",
-            "CKR_TOKEN_NOT_RECOGNIZED",
-            "CKR_TOKEN_WRITE_PROTECTED",
-            "CKR_UNWRAPPING_KEY_HANDLE_INVALID",
-            "CKR_UNWRAPPING_KEY_SIZE_RANGE",
-            "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT",
-            "CKR_USER_ALREADY_LOGGED_IN",
-            "CKR_USER_NOT_LOGGED_IN",
-            "CKR_USER_PIN_NOT_INITIALIZED",
-            "CKR_USER_TYPE_INVALID",
-            "CKR_USER_ANOTHER_ALREADY_LOGGED_IN",
-            "CKR_USER_TOO_MANY_TYPES",
-            "CKR_WRAPPED_KEY_INVALID",
-            "CKR_WRAPPED_KEY_LEN_RANGE",
-            "CKR_WRAPPING_KEY_HANDLE_INVALID",
-            "CKR_WRAPPING_KEY_SIZE_RANGE",
-            "CKR_WRAPPING_KEY_TYPE_INCONSISTENT",
-            "CKR_RANDOM_SEED_NOT_SUPPORTED",
-            "CKR_RANDOM_NO_RNG",
-            "CKR_DOMAIN_PARAMS_INVALID",
-            "CKR_BUFFER_TOO_SMALL",
-            "CKR_SAVED_STATE_INVALID",
-            "CKR_INFORMATION_SENSITIVE",
-            "CKR_STATE_UNSAVEABLE",
-            "CKR_CRYPTOKI_NOT_INITIALIZED",
-            "CKR_CRYPTOKI_ALREADY_INITIALIZED",
-            "CKR_MUTEX_BAD",
-            "CKR_MUTEX_NOT_LOCKED",
-            "CKR_FUNCTION_REJECTED",
-            "CKR_VENDOR_DEFINED",
-        };
-        errorMap = new HashMap<Long,String>();
-        for (int i = 0; i < errorCodes.length; i++) {
-            errorMap.put(Long.valueOf(errorCodes[i]), errorMessages[i]);
-        }
-    }
-
-
-    /**
-     * Constructor taking the error code as defined for the CKR_* constants
-     * in PKCS#11.
-     */
-    public PKCS11Exception(long errorCode) {
-        errorCode_ = errorCode;
-    }
-
-    /**
-     * This method gets the corresponding text error message from
-     * a property file. If this file is not available, it returns the error
-     * code as a hex-string.
-     *
-     * @return The message or the error code; e.g. "CKR_DEVICE_ERROR" or
-     *         "0x00000030".
-     * @preconditions
-     * @postconditions (result <> null)
-     */
-    public String getMessage() {
-        String message = errorMap.get(Long.valueOf(errorCode_));
-        if (message == null) {
-            message = "0x" + Functions.toFullHexString((int)errorCode_);
-        }
-        return message;
-    }
-
-    /**
-     * Returns the PKCS#11 error code.
-     *
-     * @return The error code; e.g. 0x00000030.
-     * @preconditions
-     * @postconditions
-     */
-    public long getErrorCode() {
-        return errorCode_ ;
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11/wrapper/PKCS11RuntimeException.java	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-package sun.security.pkcs11.wrapper;
-
-
-/**
- * This is the superclass of all runtime exception used by this library.
- * For instance, Runtime exceptions occur, if an internal error in the native
- * part of the wrapper occurs.
- *
- * @author <a href="mailto:Karl.Scheibelhofer@iaik.at"> Karl Scheibelhofer </a>
- * @invariants
- */
-public class PKCS11RuntimeException extends RuntimeException {
-    private static final long serialVersionUID = 7889842162743590564L;
-
-    /**
-     * Empty constructor.
-     *
-     * @preconditions
-     * @postconditions
-     */
-    public PKCS11RuntimeException() {
-        super();
-    }
-
-    /**
-     * Constructor taking a string that describes the reason of the exception
-     * in more detail.
-     *
-     * @param message A descrption of the reason for this exception.
-     * @preconditions
-     * @postconditions
-     */
-    public PKCS11RuntimeException(String message) {
-        super(message);
-    }
-
-    /**
-     * Constructor taking an other exception to wrap.
-     *
-     * @param encapsulatedException The other exception the wrap into this.
-     * @preconditions
-     * @postconditions
-     */
-    public PKCS11RuntimeException(Exception encapsulatedException) {
-        super(encapsulatedException);
-    }
-
-    /**
-     * Constructor taking a message for this exception and an other exception to
-     * wrap.
-     *
-     * @param message The message giving details about the exception to ease
-     *                debugging.
-     * @param encapsulatedException The other exception the wrap into this.
-     * @preconditions
-     * @postconditions
-     */
-    public PKCS11RuntimeException(String message, Exception encapsulatedException) {
-        super(message, encapsulatedException);
-    }
-
-}
--- a/jdk/src/jdk.crypto.token/share/legal/pkcs11cryptotoken.md	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-## PKCS #11 Cryptographic Token Interface, v2.20 amendment 3 Header Files
-
-### PKCS #11 Cryptographic Token Interface License
-<pre>
-
-License to copy and use this software is granted provided that it is
-identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
-(Cryptoki)" in all material mentioning or referencing this software.
-
-License is also granted to make and use derivative works provided that
-such works are identified as "derived from the RSA Security Inc. PKCS #11
-Cryptographic Token Interface (Cryptoki)" in all material mentioning or
-referencing the derived work.
-
-RSA Security Inc. makes no representations concerning either the
-merchantability of this software or the suitability of this software for
-any particular purpose. It is provided "as is" without express or implied
-warranty of any kind.
-
-</pre>
--- a/jdk/src/jdk.crypto.token/share/legal/pkcs11wrapper.md	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-## IAIK (Institute for Applied Information Processing and Communication) PKCS#11 wrapper files v1
-
-### IAIK License
-<pre>
-
-Copyright (c) 2002 Graz University of Technology. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-3. The end-user documentation included with the redistribution, if any, must
-   include the following acknowledgment:
-
-   "This product includes software developed by IAIK of Graz University of
-    Technology."
-
-   Alternately, this acknowledgment may appear in the software itself, if and
-   wherever such third-party acknowledgments normally appear.
-
-4. The names "Graz University of Technology" and "IAIK of Graz University of
-   Technology" must not be used to endorse or promote products derived from this
-   software without prior written permission.
-
-5. Products derived from this software may not be called "IAIK PKCS Wrapper",
-   nor may "IAIK" appear in their name, without prior written permission of
-   Graz University of Technology.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-LICENSOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-</pre>
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2005, 2014, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// #define SECMOD_DEBUG
-
-#include "j2secmod.h"
-#include "jni_util.h"
-
-
-JNIEXPORT jboolean JNICALL Java_sun_security_pkcs11_Secmod_nssVersionCheck
-  (JNIEnv *env, jclass thisClass, jlong jHandle, jstring jVersion)
-{
-    int res = 0;
-    FPTR_VersionCheck versionCheck;
-    const char *requiredVersion;
-
-    versionCheck = (FPTR_VersionCheck)findFunction(env, jHandle,
-        "NSS_VersionCheck");
-    if (versionCheck == NULL) {
-        return JNI_FALSE;
-    }
-
-    requiredVersion = (*env)->GetStringUTFChars(env, jVersion, NULL);
-    if (requiredVersion == NULL)  {
-        return JNI_FALSE;
-    }
-
-    res = versionCheck(requiredVersion);
-    dprintf2("-version >=%s: %d\n", requiredVersion, res);
-    (*env)->ReleaseStringUTFChars(env, jVersion, requiredVersion);
-
-    return (res == 0) ? JNI_FALSE : JNI_TRUE;
-}
-
-/*
- * Initializes NSS.
- * The NSS_INIT_OPTIMIZESPACE flag is supplied by the caller.
- * The NSS_Init* functions are mapped to the NSS_Initialize function.
- */
-JNIEXPORT jboolean JNICALL Java_sun_security_pkcs11_Secmod_nssInitialize
-  (JNIEnv *env, jclass thisClass, jstring jFunctionName, jlong jHandle, jstring jConfigDir, jboolean jNssOptimizeSpace)
-{
-    int res = 0;
-    FPTR_Initialize initialize =
-        (FPTR_Initialize)findFunction(env, jHandle, "NSS_Initialize");
-    unsigned int flags = 0x00;
-    const char *configDir = NULL;
-    const char *functionName = NULL;
-
-    /* If we cannot initialize, exit now */
-    if (initialize == NULL) {
-        res = 1;
-        goto cleanup;
-    }
-
-    functionName = (*env)->GetStringUTFChars(env, jFunctionName, NULL);
-    if (functionName == NULL) {
-        res = 1;
-        goto cleanup;
-    }
-
-    if (jConfigDir != NULL) {
-        configDir = (*env)->GetStringUTFChars(env, jConfigDir, NULL);
-        if (!configDir) {
-            res = 1;
-            goto cleanup;
-        }
-    }
-
-    if (jNssOptimizeSpace == JNI_TRUE) {
-        flags = 0x20; // NSS_INIT_OPTIMIZESPACE flag
-    }
-
-    /*
-     * If the NSS_Init function is requested then call NSS_Initialize to
-     * open the Cert, Key and Security Module databases, read only.
-     */
-    if (strcmp("NSS_Init", functionName) == 0) {
-        flags = flags | 0x01; // NSS_INIT_READONLY flag
-        res = initialize(configDir, "", "", "secmod.db", flags);
-
-    /*
-     * If the NSS_InitReadWrite function is requested then call
-     * NSS_Initialize to open the Cert, Key and Security Module databases,
-     * read/write.
-     */
-    } else if (strcmp("NSS_InitReadWrite", functionName) == 0) {
-        res = initialize(configDir, "", "", "secmod.db", flags);
-
-    /*
-     * If the NSS_NoDB_Init function is requested then call
-     * NSS_Initialize without creating Cert, Key or Security Module
-     * databases.
-     */
-    } else if (strcmp("NSS_NoDB_Init", functionName) == 0) {
-        flags = flags | 0x02  // NSS_INIT_NOCERTDB flag
-                      | 0x04  // NSS_INIT_NOMODDB flag
-                      | 0x08  // NSS_INIT_FORCEOPEN flag
-                      | 0x10; // NSS_INIT_NOROOTINIT flag
-        res = initialize("", "", "", "", flags);
-
-    } else {
-        res = 2;
-    }
-
-cleanup:
-    if (functionName != NULL) {
-        (*env)->ReleaseStringUTFChars(env, jFunctionName, functionName);
-    }
-    if (configDir != NULL) {
-        (*env)->ReleaseStringUTFChars(env, jConfigDir, configDir);
-    }
-    dprintf1("-res: %d\n", res);
-
-    return (res == 0) ? JNI_TRUE : JNI_FALSE;
-}
-
-JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_Secmod_nssGetModuleList
-  (JNIEnv *env, jclass thisClass, jlong jHandle, jstring jLibDir)
-{
-    FPTR_GetDBModuleList getModuleList =
-        (FPTR_GetDBModuleList)findFunction(env, jHandle, "SECMOD_GetDefaultModuleList");
-
-    SECMODModuleList *list;
-    SECMODModule *module;
-    jclass jListClass, jModuleClass;
-    jobject jList, jModule;
-    jmethodID jListConstructor, jAdd, jModuleConstructor;
-    jstring jCommonName, jDllName;
-    jboolean jFIPS;
-    jint i;
-
-    if (getModuleList == NULL) {
-        dprintf("-getmodulelist function not found\n");
-        return NULL;
-    }
-    list = getModuleList();
-    if (list == NULL) {
-        dprintf("-module list is null\n");
-        return NULL;
-    }
-
-    jListClass = (*env)->FindClass(env, "java/util/ArrayList");
-    if (jListClass == NULL) {
-        return NULL;
-    }
-    jListConstructor = (*env)->GetMethodID(env, jListClass, "<init>", "()V");
-    if (jListConstructor == NULL) {
-        return NULL;
-    }
-    jAdd = (*env)->GetMethodID(env, jListClass, "add", "(Ljava/lang/Object;)Z");
-    if (jAdd == NULL) {
-        return NULL;
-    }
-    jList = (*env)->NewObject(env, jListClass, jListConstructor);
-    if (jList == NULL) {
-        return NULL;
-    }
-    jModuleClass = (*env)->FindClass(env, "sun/security/pkcs11/Secmod$Module");
-    if (jModuleClass == NULL) {
-        return NULL;
-    }
-    jModuleConstructor = (*env)->GetMethodID(env, jModuleClass, "<init>",
-        "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V");
-    if (jModuleConstructor == NULL) {
-        return NULL;
-    }
-
-    while (list != NULL) {
-        module = list->module;
-        // assert module != null
-        dprintf1("-commonname: %s\n", module->commonName);
-        dprintf1("-dllname: %s\n", (module->dllName != NULL) ? module->dllName : "NULL");
-        dprintf1("-slots: %d\n", module->slotCount);
-        dprintf1("-loaded: %d\n", module->loaded);
-        dprintf1("-internal: %d\n", module->internal);
-        dprintf1("-fips: %d\n", module->isFIPS);
-        jCommonName = (*env)->NewStringUTF(env, module->commonName);
-        if (jCommonName == NULL) {
-            return NULL;
-        }
-        if (module->dllName == NULL) {
-            jDllName = NULL;
-        } else {
-            jDllName = (*env)->NewStringUTF(env, module->dllName);
-            if (jDllName == NULL) {
-                return NULL;
-            }
-        }
-        jFIPS = module->isFIPS;
-        for (i = 0; i < module->slotCount; i++ ) {
-            jModule = (*env)->NewObject(env, jModuleClass, jModuleConstructor,
-                jLibDir, jDllName, jCommonName, jFIPS, i);
-            if (jModule == NULL) {
-                return NULL;
-            }
-            (*env)->CallVoidMethod(env, jList, jAdd, jModule);
-            if ((*env)->ExceptionCheck(env)) {
-                return NULL;
-            }
-        }
-        list = list->next;
-    }
-    dprintf("-ok\n");
-
-    return jList;
-}
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2005, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#include <jni.h>
-
-#include "sun_security_pkcs11_Secmod.h"
-
-// #define SECMOD_DEBUG
-
-#include "j2secmod_md.h"
-
-#include "p11_md.h"
-
-
-void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName);
-
-#ifdef SECMOD_DEBUG
-#define dprintf(s) printf(s)
-#define dprintf1(s, p1) printf(s, p1)
-#define dprintf2(s, p1, p2) printf(s, p1, p2)
-#define dprintf3(s, p1, p2, p3) printf(s, p1, p2, p3)
-#else
-#define dprintf(s)
-#define dprintf1(s, p1)
-#define dprintf2(s, p1, p2)
-#define dprintf3(s, p1, p2, p3)
-#endif
-
-// NSS types
-
-typedef int PRBool;
-
-typedef struct SECMODModuleStr SECMODModule;
-typedef struct SECMODModuleListStr SECMODModuleList;
-
-struct SECMODModuleStr {
-    void        *v1;
-    PRBool      internal;       /* true of internally linked modules, false
-                                 * for the loaded modules */
-    PRBool      loaded;         /* Set to true if module has been loaded */
-    PRBool      isFIPS;         /* Set to true if module is finst internal */
-    char        *dllName;       /* name of the shared library which implements
-                                 * this module */
-    char        *commonName;    /* name of the module to display to the user */
-    void        *library;       /* pointer to the library. opaque. used only by
-                                 * pk11load.c */
-
-    void        *functionList; /* The PKCS #11 function table */
-    void        *refLock;       /* only used pk11db.c */
-    int         refCount;       /* Module reference count */
-    void        **slots;        /* array of slot points attached to this mod*/
-    int         slotCount;      /* count of slot in above array */
-    void        *slotInfo;      /* special info about slots default settings */
-    int         slotInfoCount;  /* count */
-    // incomplete, sizeof() is wrong
-};
-
-struct SECMODModuleListStr {
-    SECMODModuleList    *next;
-    SECMODModule        *module;
-};
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1842 +0,0 @@
-/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-/*
- * pkcs11wrapper.c
- * 18.05.2001
- *
- * This is the implementation of the native functions of the Java to PKCS#11 interface.
- * All function use some helper functions to convert the JNI types to PKCS#11 types.
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-/* declare file private functions */
-
-void jMechanismParameterToCKMechanismParameterSlow(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength);
-
-
-/*
- * converts a pointer to a CK_DATE structure into a Java CK_DATE Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpValue - the pointer to the CK_DATE structure
- * @return - the new Java CK_DATE object
- */
-jobject ckDatePtrToJDateObject(JNIEnv *env, const CK_DATE *ckpDate)
-{
-    jclass jDateClass;
-    jmethodID jCtrId;
-    jobject jDateObject;
-    jcharArray jYear;
-    jcharArray jMonth;
-    jcharArray jDay;
-
-    /* load CK_DATE class */
-    jDateClass = (*env)->FindClass(env, CLASS_DATE);
-    if (jDateClass == NULL) { return NULL; }
-
-    /* load CK_DATE constructor */
-    jCtrId = (*env)->GetMethodID(env, jDateClass, "<init>", "([C[C[C)V");
-    if (jCtrId == NULL) { return NULL; }
-
-    /* prep all fields */
-    jYear = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpDate->year), 4);
-    if (jYear == NULL) { return NULL; }
-    jMonth = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpDate->month), 2);
-    if (jMonth == NULL) { return NULL; }
-    jDay = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpDate->day), 2);
-    if (jDay == NULL) { return NULL; }
-
-    /* create new CK_DATE object */
-    jDateObject =
-      (*env)->NewObject(env, jDateClass, jCtrId, jYear, jMonth, jDay);
-    if (jDateObject == NULL) { return NULL; }
-
-    /* free local references */
-    (*env)->DeleteLocalRef(env, jDateClass);
-    (*env)->DeleteLocalRef(env, jYear);
-    (*env)->DeleteLocalRef(env, jMonth);
-    (*env)->DeleteLocalRef(env, jDay);
-
-    return jDateObject ;
-}
-
-/*
- * converts a pointer to a CK_VERSION structure into a Java CK_VERSION Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpVersion - the pointer to the CK_VERSION structure
- * @return - the new Java CK_VERSION object
- */
-jobject ckVersionPtrToJVersion(JNIEnv *env, const CK_VERSION_PTR ckpVersion)
-{
-    jclass jVersionClass;
-    jmethodID jCtrId;
-    jobject jVersionObject;
-    jint jMajor;
-    jint jMinor;
-
-    /* load CK_VERSION class */
-    jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
-    if (jVersionClass == NULL) { return NULL; }
-
-    /* load CK_VERSION constructor */
-    jCtrId = (*env)->GetMethodID(env, jVersionClass, "<init>", "(II)V");
-    if (jCtrId == NULL) { return NULL; }
-
-    /* prep both fields */
-    jMajor = ckpVersion->major;
-    jMinor = ckpVersion->minor;
-
-    /* create new CK_VERSION object */
-    jVersionObject =
-      (*env)->NewObject(env, jVersionClass, jCtrId, jMajor, jMinor);
-    if (jVersionObject == NULL) { return NULL; }
-
-    /* free local references */
-    (*env)->DeleteLocalRef(env, jVersionClass);
-
-    return jVersionObject ;
-}
-
-/*
- * converts a pointer to a CK_SESSION_INFO structure into a Java CK_SESSION_INFO Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpSessionInfo - the pointer to the CK_SESSION_INFO structure
- * @return - the new Java CK_SESSION_INFO object
- */
-jobject ckSessionInfoPtrToJSessionInfo(JNIEnv *env, const CK_SESSION_INFO_PTR ckpSessionInfo)
-{
-    jclass jSessionInfoClass;
-    jmethodID jCtrId;
-    jobject jSessionInfoObject;
-    jlong jSlotID;
-    jlong jState;
-    jlong jFlags;
-    jlong jDeviceError;
-
-    /* load CK_SESSION_INFO class */
-    jSessionInfoClass = (*env)->FindClass(env, CLASS_SESSION_INFO);
-    if (jSessionInfoClass == NULL) { return NULL; }
-
-    /* load CK_SESSION_INFO constructor */
-    jCtrId = (*env)->GetMethodID(env, jSessionInfoClass, "<init>", "(JJJJ)V");
-    if (jCtrId == NULL) { return NULL; }
-
-    /* prep all fields */
-    jSlotID = ckULongToJLong(ckpSessionInfo->slotID);
-    jState = ckULongToJLong(ckpSessionInfo->state);
-    jFlags = ckULongToJLong(ckpSessionInfo->flags);
-    jDeviceError = ckULongToJLong(ckpSessionInfo->ulDeviceError);
-
-    /* create new CK_SESSION_INFO object */
-    jSessionInfoObject =
-      (*env)->NewObject(env, jSessionInfoClass, jCtrId, jSlotID, jState,
-                        jFlags, jDeviceError);
-    if (jSessionInfoObject == NULL) { return NULL; }
-
-    /* free local references */
-    (*env)->DeleteLocalRef(env, jSessionInfoClass);
-
-    return jSessionInfoObject ;
-}
-
-/*
- * converts a pointer to a CK_ATTRIBUTE structure into a Java CK_ATTRIBUTE Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpAttribute - the pointer to the CK_ATTRIBUTE structure
- * @return - the new Java CK_ATTRIBUTE object
- */
-jobject ckAttributePtrToJAttribute(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute)
-{
-    jclass jAttributeClass;
-    jmethodID jCtrId;
-    jobject jAttributeObject;
-    jlong jType;
-    jobject jPValue = NULL;
-
-    jAttributeClass = (*env)->FindClass(env, CLASS_ATTRIBUTE);
-    if (jAttributeClass == NULL) { return NULL; }
-
-    /* load CK_INFO constructor */
-    jCtrId = (*env)->GetMethodID(env, jAttributeClass, "<init>", "(JLjava/lang/Object;)V");
-    if (jCtrId == NULL) { return NULL; }
-
-    /* prep both fields */
-    jType = ckULongToJLong(ckpAttribute->type);
-    jPValue = ckAttributeValueToJObject(env, ckpAttribute);
-    if ((*env)->ExceptionCheck(env)) { return NULL; }
-
-    /* create new CK_ATTRIBUTE object */
-    jAttributeObject =
-      (*env)->NewObject(env, jAttributeClass, jCtrId, jType, jPValue);
-    if (jAttributeObject == NULL) { return NULL; }
-
-    /* free local references */
-    (*env)->DeleteLocalRef(env, jAttributeClass);
-    (*env)->DeleteLocalRef(env, jPValue);
-
-    return jAttributeObject;
-}
-
-
-/*
- * converts a Java CK_VERSION object into a pointer to a CK_VERSION structure
- *
- * @param env - used to call JNI funktions to get the values out of the Java object
- * @param jVersion - the Java CK_VERSION object to convert
- * @return - the pointer to the new CK_VERSION structure
- */
-CK_VERSION_PTR jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion)
-{
-    CK_VERSION_PTR ckpVersion;
-    jclass jVersionClass;
-    jfieldID jFieldID;
-    jbyte jMajor, jMinor;
-
-    if (jVersion == NULL) {
-        return NULL;
-    }
-
-    /* get CK_VERSION class */
-    jVersionClass = (*env)->GetObjectClass(env, jVersion);
-    if (jVersionClass == NULL) { return NULL; }
-
-    /* get Major */
-    jFieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
-    if (jFieldID == NULL) { return NULL; }
-    jMajor = (*env)->GetByteField(env, jVersion, jFieldID);
-
-    /* get Minor */
-    jFieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
-    if (jFieldID == NULL) { return NULL; }
-    jMinor = (*env)->GetByteField(env, jVersion, jFieldID);
-
-    /* allocate memory for CK_VERSION pointer */
-    ckpVersion = (CK_VERSION_PTR) malloc(sizeof(CK_VERSION));
-    if (ckpVersion == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    ckpVersion->major = jByteToCKByte(jMajor);
-    ckpVersion->minor = jByteToCKByte(jMinor);
-
-    return ckpVersion ;
-}
-
-
-/*
- * converts a Java CK_DATE object into a pointer to a CK_DATE structure
- *
- * @param env - used to call JNI funktions to get the values out of the Java object
- * @param jVersion - the Java CK_DATE object to convert
- * @return - the pointer to the new CK_DATE structure
- */
-CK_DATE * jDateObjectPtrToCKDatePtr(JNIEnv *env, jobject jDate)
-{
-    CK_DATE * ckpDate;
-    CK_ULONG ckLength;
-    jclass jDateClass;
-    jfieldID jFieldID;
-    jobject jYear, jMonth, jDay;
-    jchar *jTempChars;
-    CK_ULONG i;
-
-    if (jDate == NULL) {
-        return NULL;
-    }
-
-    /* get CK_DATE class */
-    jDateClass = (*env)->FindClass(env, CLASS_DATE);
-    if (jDateClass == NULL) { return NULL; }
-
-    /* get Year */
-    jFieldID = (*env)->GetFieldID(env, jDateClass, "year", "[C");
-    if (jFieldID == NULL) { return NULL; }
-    jYear = (*env)->GetObjectField(env, jDate, jFieldID);
-
-    /* get Month */
-    jFieldID = (*env)->GetFieldID(env, jDateClass, "month", "[C");
-    if (jFieldID == NULL) { return NULL; }
-    jMonth = (*env)->GetObjectField(env, jDate, jFieldID);
-
-    /* get Day */
-    jFieldID = (*env)->GetFieldID(env, jDateClass, "day", "[C");
-    if (jFieldID == NULL) { return NULL; }
-    jDay = (*env)->GetObjectField(env, jDate, jFieldID);
-
-    /* allocate memory for CK_DATE pointer */
-    ckpDate = (CK_DATE *) malloc(sizeof(CK_DATE));
-    if (ckpDate == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    if (jYear == NULL) {
-        ckpDate->year[0] = 0;
-        ckpDate->year[1] = 0;
-        ckpDate->year[2] = 0;
-        ckpDate->year[3] = 0;
-    } else {
-        ckLength = (*env)->GetArrayLength(env, jYear);
-        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
-        if (jTempChars == NULL) {
-            free(ckpDate);
-            throwOutOfMemoryError(env, 0);
-            return NULL;
-        }
-        (*env)->GetCharArrayRegion(env, jYear, 0, ckLength, jTempChars);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpDate);
-            free(jTempChars);
-            return NULL;
-        }
-
-        for (i = 0; (i < ckLength) && (i < 4) ; i++) {
-            ckpDate->year[i] = jCharToCKChar(jTempChars[i]);
-        }
-        free(jTempChars);
-    }
-
-    if (jMonth == NULL) {
-        ckpDate->month[0] = 0;
-        ckpDate->month[1] = 0;
-    } else {
-        ckLength = (*env)->GetArrayLength(env, jMonth);
-        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
-        if (jTempChars == NULL) {
-            free(ckpDate);
-            throwOutOfMemoryError(env, 0);
-            return NULL;
-        }
-        (*env)->GetCharArrayRegion(env, jMonth, 0, ckLength, jTempChars);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpDate);
-            free(jTempChars);
-            return NULL;
-        }
-
-        for (i = 0; (i < ckLength) && (i < 2) ; i++) {
-            ckpDate->month[i] = jCharToCKChar(jTempChars[i]);
-        }
-        free(jTempChars);
-    }
-
-    if (jDay == NULL) {
-        ckpDate->day[0] = 0;
-        ckpDate->day[1] = 0;
-    } else {
-        ckLength = (*env)->GetArrayLength(env, jDay);
-        jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
-        if (jTempChars == NULL) {
-            free(ckpDate);
-            throwOutOfMemoryError(env, 0);
-            return NULL;
-        }
-        (*env)->GetCharArrayRegion(env, jDay, 0, ckLength, jTempChars);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpDate);
-            free(jTempChars);
-            return NULL;
-        }
-
-        for (i = 0; (i < ckLength) && (i < 2) ; i++) {
-            ckpDate->day[i] = jCharToCKChar(jTempChars[i]);
-        }
-        free(jTempChars);
-    }
-
-    return ckpDate ;
-}
-
-
-/*
- * converts a Java CK_ATTRIBUTE object into a CK_ATTRIBUTE structure
- *
- * @param env - used to call JNI funktions to get the values out of the Java object
- * @param jAttribute - the Java CK_ATTRIBUTE object to convert
- * @return - the new CK_ATTRIBUTE structure
- */
-CK_ATTRIBUTE jAttributeToCKAttribute(JNIEnv *env, jobject jAttribute)
-{
-    CK_ATTRIBUTE ckAttribute;
-    jclass jAttributeClass;
-    jfieldID jFieldID;
-    jlong jType;
-    jobject jPValue;
-    memset(&ckAttribute, 0, sizeof(CK_ATTRIBUTE));
-
-    // TBD: what if jAttribute == NULL?!
-
-    TRACE0("\nDEBUG: jAttributeToCKAttribute");
-    /* get CK_ATTRIBUTE class */
-    TRACE0(", getting attribute object class");
-    jAttributeClass = (*env)->GetObjectClass(env, jAttribute);
-    if (jAttributeClass == NULL) { return ckAttribute; }
-
-    /* get type */
-    TRACE0(", getting type field");
-    jFieldID = (*env)->GetFieldID(env, jAttributeClass, "type", "J");
-    if (jFieldID == NULL) { return ckAttribute; }
-    jType = (*env)->GetLongField(env, jAttribute, jFieldID);
-    TRACE1(", type=0x%X", jType);
-
-    /* get pValue */
-    TRACE0(", getting pValue field");
-    jFieldID = (*env)->GetFieldID(env, jAttributeClass, "pValue", "Ljava/lang/Object;");
-    if (jFieldID == NULL) { return ckAttribute; }
-    jPValue = (*env)->GetObjectField(env, jAttribute, jFieldID);
-    TRACE1(", pValue=%p", jPValue);
-
-    ckAttribute.type = jLongToCKULong(jType);
-    TRACE0(", converting pValue to primitive object");
-
-    /* convert the Java pValue object to a CK-type pValue pointer */
-    jObjectToPrimitiveCKObjectPtrPtr(env, jPValue, &(ckAttribute.pValue), &(ckAttribute.ulValueLen));
-
-    TRACE0("\nFINISHED\n");
-
-    return ckAttribute ;
-}
-
-/*
- * converts the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to a
- * CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to convert
- * @return - the new CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
- */
-CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam)
-{
-    // XXX don't return structs
-    // XXX prefetch class and field ids
-    jclass jSsl3MasterKeyDeriveParamsClass;
-    CK_SSL3_MASTER_KEY_DERIVE_PARAMS ckParam;
-    jfieldID fieldID;
-    jclass jSsl3RandomDataClass;
-    jobject jRandomInfo, jRIClientRandom, jRIServerRandom, jVersion;
-    memset(&ckParam, 0, sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
-
-    /* get RandomInfo */
-    jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
-    if (jSsl3MasterKeyDeriveParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jSsl3MasterKeyDeriveParamsClass, "RandomInfo", "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;");
-    if (fieldID == NULL) { return ckParam; }
-    jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pClientRandom and ulClientRandomLength out of RandomInfo */
-    jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA);
-    if (jSsl3RandomDataClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jRIClientRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
-
-    /* get pServerRandom and ulServerRandomLength out of RandomInfo */
-    fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jRIServerRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
-
-    /* get pVersion */
-    fieldID = (*env)->GetFieldID(env, jSsl3MasterKeyDeriveParamsClass, "pVersion",  "Lsun/security/pkcs11/wrapper/CK_VERSION;");
-    if (fieldID == NULL) { return ckParam; }
-    jVersion = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.pVersion = jVersionToCKVersionPtr(env, jVersion);
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    jByteArrayToCKByteArray(env, jRIClientRandom, &(ckParam.RandomInfo.pClientRandom), &(ckParam.RandomInfo.ulClientRandomLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pVersion);
-        return ckParam;
-    }
-    jByteArrayToCKByteArray(env, jRIServerRandom, &(ckParam.RandomInfo.pServerRandom), &(ckParam.RandomInfo.ulServerRandomLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pVersion);
-        free(ckParam.RandomInfo.pClientRandom);
-        return ckParam;
-    }
-
-    return ckParam ;
-}
-
-
-/*
- * converts the Java CK_TLS_PRF_PARAMS object to a CK_TLS_PRF_PARAMS structure
- */
-CK_TLS_PRF_PARAMS jTlsPrfParamsToCKTlsPrfParam(JNIEnv *env, jobject jParam)
-{
-    jclass jTlsPrfParamsClass;
-    CK_TLS_PRF_PARAMS ckParam;
-    jfieldID fieldID;
-    jobject jSeed, jLabel, jOutput;
-    memset(&ckParam, 0, sizeof(CK_TLS_PRF_PARAMS));
-
-    // TBD: what if jParam == NULL?!
-
-    /* get pSeed */
-    jTlsPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
-    if (jTlsPrfParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pSeed", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jSeed = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pLabel */
-    fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pLabel", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jLabel = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pOutput */
-    fieldID = (*env)->GetFieldID(env, jTlsPrfParamsClass, "pOutput", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jOutput = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    jByteArrayToCKByteArray(env, jSeed, &(ckParam.pSeed), &(ckParam.ulSeedLen));
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    jByteArrayToCKByteArray(env, jLabel, &(ckParam.pLabel), &(ckParam.ulLabelLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pSeed);
-        return ckParam;
-    }
-    ckParam.pulOutputLen = malloc(sizeof(CK_ULONG));
-    if (ckParam.pulOutputLen == NULL) {
-        free(ckParam.pSeed);
-        free(ckParam.pLabel);
-        throwOutOfMemoryError(env, 0);
-        return ckParam;
-    }
-    jByteArrayToCKByteArray(env, jOutput, &(ckParam.pOutput), ckParam.pulOutputLen);
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pSeed);
-        free(ckParam.pLabel);
-        free(ckParam.pulOutputLen);
-        return ckParam;
-    }
-
-    return ckParam ;
-}
-
-/*
- * converts the Java CK_SSL3_KEY_MAT_PARAMS object to a CK_SSL3_KEY_MAT_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_SSL3_KEY_MAT_PARAMS object to convert
- * @return - the new CK_SSL3_KEY_MAT_PARAMS structure
- */
-CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam)
-{
-    // XXX don't return structs
-    // XXX prefetch class and field ids
-    jclass jSsl3KeyMatParamsClass, jSsl3RandomDataClass, jSsl3KeyMatOutClass;
-    CK_SSL3_KEY_MAT_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jMacSizeInBits, jKeySizeInBits, jIVSizeInBits;
-    jboolean jIsExport;
-    jobject jRandomInfo, jRIClientRandom, jRIServerRandom;
-    jobject jReturnedKeyMaterial, jRMIvClient, jRMIvServer;
-    CK_ULONG ckTemp;
-    memset(&ckParam, 0, sizeof(CK_SSL3_KEY_MAT_PARAMS));
-
-    /* get ulMacSizeInBits */
-    jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
-    if (jSsl3KeyMatParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulMacSizeInBits", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jMacSizeInBits = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get ulKeySizeInBits */
-    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulKeySizeInBits", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jKeySizeInBits = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get ulIVSizeInBits */
-    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulIVSizeInBits", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jIVSizeInBits = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get bIsExport */
-    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "bIsExport", "Z");
-    if (fieldID == NULL) { return ckParam; }
-    jIsExport = (*env)->GetBooleanField(env, jParam, fieldID);
-
-    /* get RandomInfo */
-    jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA);
-    if (jSsl3RandomDataClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "RandomInfo",  "Lsun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA;");
-    if (fieldID == NULL) { return ckParam; }
-    jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pClientRandom and ulClientRandomLength out of RandomInfo */
-    fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jRIClientRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
-
-    /* get pServerRandom and ulServerRandomLength out of RandomInfo */
-    fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jRIServerRandom = (*env)->GetObjectField(env, jRandomInfo, fieldID);
-
-    /* get pReturnedKeyMaterial */
-    jSsl3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
-    if (jSsl3KeyMatOutClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "pReturnedKeyMaterial",  "Lsun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT;");
-    if (fieldID == NULL) { return ckParam; }
-    jReturnedKeyMaterial = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pIVClient out of pReturnedKeyMaterial */
-    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVClient", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jRMIvClient = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID);
-
-    /* get pIVServer out of pReturnedKeyMaterial */
-    fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVServer", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jRMIvServer = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID);
-
-    /* populate java values */
-    ckParam.ulMacSizeInBits = jLongToCKULong(jMacSizeInBits);
-    ckParam.ulKeySizeInBits = jLongToCKULong(jKeySizeInBits);
-    ckParam.ulIVSizeInBits = jLongToCKULong(jIVSizeInBits);
-    ckParam.bIsExport = jBooleanToCKBBool(jIsExport);
-    jByteArrayToCKByteArray(env, jRIClientRandom, &(ckParam.RandomInfo.pClientRandom), &(ckParam.RandomInfo.ulClientRandomLen));
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    jByteArrayToCKByteArray(env, jRIServerRandom, &(ckParam.RandomInfo.pServerRandom), &(ckParam.RandomInfo.ulServerRandomLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.RandomInfo.pClientRandom);
-        return ckParam;
-    }
-    /* allocate memory for pRetrunedKeyMaterial */
-    ckParam.pReturnedKeyMaterial = (CK_SSL3_KEY_MAT_OUT_PTR) malloc(sizeof(CK_SSL3_KEY_MAT_OUT));
-    if (ckParam.pReturnedKeyMaterial == NULL) {
-        free(ckParam.RandomInfo.pClientRandom);
-        free(ckParam.RandomInfo.pServerRandom);
-        throwOutOfMemoryError(env, 0);
-        return ckParam;
-    }
-
-    // the handles are output params only, no need to fetch them from Java
-    ckParam.pReturnedKeyMaterial->hClientMacSecret = 0;
-    ckParam.pReturnedKeyMaterial->hServerMacSecret = 0;
-    ckParam.pReturnedKeyMaterial->hClientKey = 0;
-    ckParam.pReturnedKeyMaterial->hServerKey = 0;
-
-    jByteArrayToCKByteArray(env, jRMIvClient, &(ckParam.pReturnedKeyMaterial->pIVClient), &ckTemp);
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.RandomInfo.pClientRandom);
-        free(ckParam.RandomInfo.pServerRandom);
-        free(ckParam.pReturnedKeyMaterial);
-        return ckParam;
-    }
-    jByteArrayToCKByteArray(env, jRMIvServer, &(ckParam.pReturnedKeyMaterial->pIVServer), &ckTemp);
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.RandomInfo.pClientRandom);
-        free(ckParam.RandomInfo.pServerRandom);
-        free(ckParam.pReturnedKeyMaterial->pIVClient);
-        free(ckParam.pReturnedKeyMaterial);
-        return ckParam;
-    }
-
-    return ckParam ;
-}
-
-/*
- * converts the Java CK_AES_CTR_PARAMS object to a CK_AES_CTR_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_AES_CTR_PARAMS object to convert
- * @param ckpParam - pointer to the new CK_AES_CTR_PARAMS structure
- */
-void jAesCtrParamsToCKAesCtrParam(JNIEnv *env, jobject jParam,
-                                  CK_AES_CTR_PARAMS_PTR ckpParam) {
-    jclass jAesCtrParamsClass;
-    jfieldID fieldID;
-    jlong jCounterBits;
-    jobject jCb;
-    CK_BYTE_PTR ckBytes;
-    CK_ULONG ckTemp;
-
-    /* get ulCounterBits */
-    jAesCtrParamsClass = (*env)->FindClass(env, CLASS_AES_CTR_PARAMS);
-    if (jAesCtrParamsClass == NULL) { return; }
-    fieldID = (*env)->GetFieldID(env, jAesCtrParamsClass, "ulCounterBits", "J");
-    if (fieldID == NULL) { return; }
-    jCounterBits = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get cb */
-    fieldID = (*env)->GetFieldID(env, jAesCtrParamsClass, "cb", "[B");
-    if (fieldID == NULL) { return; }
-    jCb = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckpParam->ulCounterBits = jLongToCKULong(jCounterBits);
-    jByteArrayToCKByteArray(env, jCb, &ckBytes, &ckTemp);
-    if ((*env)->ExceptionCheck(env)) { return; }
-    if (ckTemp != 16) {
-        TRACE1("ERROR: WRONG CTR IV LENGTH %d", ckTemp);
-    } else {
-        memcpy(ckpParam->cb, ckBytes, ckTemp);
-        free(ckBytes);
-    }
-}
-
-/*
- * converts a Java CK_MECHANISM object into a CK_MECHANISM structure
- *
- * @param env - used to call JNI funktions to get the values out of the Java object
- * @param jMechanism - the Java CK_MECHANISM object to convert
- * @return - the new CK_MECHANISM structure
- */
-void jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism, CK_MECHANISM_PTR ckMechanismPtr)
-{
-    jlong jMechanismType = (*env)->GetLongField(env, jMechanism, mech_mechanismID);
-    jobject jParameter = (*env)->GetObjectField(env, jMechanism, mech_pParameterID);
-
-    (*ckMechanismPtr).mechanism = jLongToCKULong(jMechanismType);
-
-    /* convert the specific Java mechanism parameter object to a pointer to a CK-type mechanism
-     * structure
-     */
-    if (jParameter == NULL) {
-        (*ckMechanismPtr).pParameter = NULL;
-        (*ckMechanismPtr).ulParameterLen = 0;
-    } else {
-        jMechanismParameterToCKMechanismParameter(env, jParameter, &(*ckMechanismPtr).pParameter, &(*ckMechanismPtr).ulParameterLen);
-    }
-}
-
-/*
- * the following functions convert Attribute and Mechanism value pointers
- *
- * jobject ckAttributeValueToJObject(JNIEnv *env,
- *                                   const CK_ATTRIBUTE_PTR ckpAttribute);
- *
- * void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env,
- *                                       jobject jObject,
- *                                       CK_VOID_PTR *ckpObjectPtr,
- *                                       CK_ULONG *pLength);
- *
- * void jMechanismParameterToCKMechanismParameter(JNIEnv *env,
- *                                                jobject jParam,
- *                                                CK_VOID_PTR *ckpParamPtr,
- *                                                CK_ULONG *ckpLength);
- *
- * These functions are used if a PKCS#11 mechanism or attribute structure gets
- * convertet to a Java attribute or mechanism object or vice versa.
- *
- * ckAttributeValueToJObject converts a PKCS#11 attribute value pointer to a Java
- * object depending on the type of the Attribute. A PKCS#11 attribute value can
- * be a CK_ULONG, CK_BYTE[], CK_CHAR[], big integer, CK_BBOOL, CK_UTF8CHAR[],
- * CK_DATE or CK_FLAGS that gets converted to a corresponding Java object.
- *
- * jObjectToPrimitiveCKObjectPtrPtr is used by jAttributeToCKAttributePtr for
- * converting the Java attribute value to a PKCS#11 attribute value pointer.
- * For now only primitive datatypes and arrays of primitive datatypes can get
- * converted. Otherwise this function throws a PKCS#11Exception with the
- * errorcode CKR_VENDOR_DEFINED.
- *
- * jMechanismParameterToCKMechanismParameter converts a Java mechanism parameter
- * to a PKCS#11 mechanism parameter. First this function determines what mechanism
- * parameter the Java object is, then it allocates the memory for the new PKCS#11
- * structure and calls the corresponding function to convert the Java object to
- * a PKCS#11 mechanism parameter structure.
- */
-
-/*
- * converts the pValue of a CK_ATTRIBUTE structure into a Java Object by checking the type
- * of the attribute.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpAttribute - the pointer to the CK_ATTRIBUTE structure that contains the type
- *                       and the pValue to convert
- * @return - the new Java object of the CK-type pValue
- */
-jobject ckAttributeValueToJObject(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute)
-{
-    jint jValueLength;
-    jobject jValueObject = NULL;
-
-    jValueLength = ckULongToJInt(ckpAttribute->ulValueLen);
-
-    if ((jValueLength <= 0) || (ckpAttribute->pValue == NULL)) {
-        return NULL ;
-    }
-
-    switch(ckpAttribute->type) {
-        case CKA_CLASS:
-            /* value CK_OBJECT_CLASS, defacto a CK_ULONG */
-        case CKA_KEY_TYPE:
-            /* value CK_KEY_TYPE, defacto a CK_ULONG */
-        case CKA_CERTIFICATE_TYPE:
-            /* value CK_CERTIFICATE_TYPE, defacto a CK_ULONG */
-        case CKA_HW_FEATURE_TYPE:
-            /* value CK_HW_FEATURE_TYPE, defacto a CK_ULONG */
-        case CKA_MODULUS_BITS:
-        case CKA_VALUE_BITS:
-        case CKA_VALUE_LEN:
-        case CKA_KEY_GEN_MECHANISM:
-        case CKA_PRIME_BITS:
-        case CKA_SUB_PRIME_BITS:
-            /* value CK_ULONG */
-            jValueObject = ckULongPtrToJLongObject(env, (CK_ULONG*) ckpAttribute->pValue);
-            break;
-
-            /* can be CK_BYTE[],CK_CHAR[] or big integer; defacto always CK_BYTE[] */
-        case CKA_VALUE:
-        case CKA_OBJECT_ID:
-        case CKA_SUBJECT:
-        case CKA_ID:
-        case CKA_ISSUER:
-        case CKA_SERIAL_NUMBER:
-        case CKA_OWNER:
-        case CKA_AC_ISSUER:
-        case CKA_ATTR_TYPES:
-        case CKA_ECDSA_PARAMS:
-            /* CKA_EC_PARAMS is the same, these two are equivalent */
-        case CKA_EC_POINT:
-        case CKA_PRIVATE_EXPONENT:
-        case CKA_PRIME_1:
-        case CKA_PRIME_2:
-        case CKA_EXPONENT_1:
-        case CKA_EXPONENT_2:
-        case CKA_COEFFICIENT:
-            /* value CK_BYTE[] */
-            jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
-            break;
-
-        case CKA_RESET_ON_INIT:
-        case CKA_HAS_RESET:
-        case CKA_TOKEN:
-        case CKA_PRIVATE:
-        case CKA_MODIFIABLE:
-        case CKA_DERIVE:
-        case CKA_LOCAL:
-        case CKA_ENCRYPT:
-        case CKA_VERIFY:
-        case CKA_VERIFY_RECOVER:
-        case CKA_WRAP:
-        case CKA_SENSITIVE:
-        case CKA_SECONDARY_AUTH:
-        case CKA_DECRYPT:
-        case CKA_SIGN:
-        case CKA_SIGN_RECOVER:
-        case CKA_UNWRAP:
-        case CKA_EXTRACTABLE:
-        case CKA_ALWAYS_SENSITIVE:
-        case CKA_NEVER_EXTRACTABLE:
-        case CKA_TRUSTED:
-            /* value CK_BBOOL */
-            jValueObject = ckBBoolPtrToJBooleanObject(env, (CK_BBOOL*) ckpAttribute->pValue);
-            break;
-
-        case CKA_LABEL:
-        case CKA_APPLICATION:
-            /* value RFC 2279 (UTF-8) string */
-            jValueObject = ckUTF8CharArrayToJCharArray(env, (CK_UTF8CHAR*) ckpAttribute->pValue, jValueLength);
-            break;
-
-        case CKA_START_DATE:
-        case CKA_END_DATE:
-            /* value CK_DATE */
-            jValueObject = ckDatePtrToJDateObject(env, (CK_DATE*) ckpAttribute->pValue);
-            break;
-
-        case CKA_MODULUS:
-        case CKA_PUBLIC_EXPONENT:
-        case CKA_PRIME:
-        case CKA_SUBPRIME:
-        case CKA_BASE:
-            /* value big integer, i.e. CK_BYTE[] */
-            jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
-            break;
-
-        case CKA_AUTH_PIN_FLAGS:
-            jValueObject = ckULongPtrToJLongObject(env, (CK_ULONG*) ckpAttribute->pValue);
-            /* value FLAGS, defacto a CK_ULONG */
-            break;
-
-        case CKA_VENDOR_DEFINED:
-            /* we make a CK_BYTE[] out of this */
-            jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
-            break;
-
-        // Netscape trust attributes
-        case CKA_NETSCAPE_TRUST_SERVER_AUTH:
-        case CKA_NETSCAPE_TRUST_CLIENT_AUTH:
-        case CKA_NETSCAPE_TRUST_CODE_SIGNING:
-        case CKA_NETSCAPE_TRUST_EMAIL_PROTECTION:
-            /* value CK_ULONG */
-            jValueObject = ckULongPtrToJLongObject(env, (CK_ULONG*) ckpAttribute->pValue);
-            break;
-
-        default:
-            /* we make a CK_BYTE[] out of this */
-            jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
-            break;
-    }
-
-    return jValueObject ;
-}
-
-/*
- * the following functions convert a Java mechanism parameter object to a PKCS#11
- * mechanism parameter structure
- *
- * CK_<Param>_PARAMS j<Param>ParamToCK<Param>Param(JNIEnv *env,
- *                                                 jobject jParam);
- *
- * These functions get a Java object, that must be the right Java mechanism
- * object and they return the new PKCS#11 mechanism parameter structure.
- * Every field of the Java object is retrieved, gets converted to a corresponding
- * PKCS#11 type and is set in the new PKCS#11 structure.
- */
-
-/*
- * converts the given Java mechanism parameter to a CK mechanism parameter structure
- * and store the length in bytes in the length variable.
- * The memory of *ckpParamPtr has to be freed after use!
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java mechanism parameter object to convert
- * @param ckpParamPtr - the reference of the new pointer to the new CK mechanism parameter
- *                      structure
- * @param ckpLength - the reference of the length in bytes of the new CK mechanism parameter
- *                    structure
- */
-void jMechanismParameterToCKMechanismParameter(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength)
-{
-    if (jParam == NULL) {
-        *ckpParamPtr = NULL;
-        *ckpLength = 0;
-    } else if ((*env)->IsInstanceOf(env, jParam, jByteArrayClass)) {
-        jByteArrayToCKByteArray(env, jParam, (CK_BYTE_PTR *)ckpParamPtr, ckpLength);
-    } else if ((*env)->IsInstanceOf(env, jParam, jLongClass)) {
-        *ckpParamPtr = jLongObjectToCKULongPtr(env, jParam);
-        *ckpLength = sizeof(CK_ULONG);
-    } else {
-        TRACE0("\nSLOW PATH jMechanismParameterToCKMechanismParameter\n");
-        jMechanismParameterToCKMechanismParameterSlow(env, jParam, ckpParamPtr, ckpLength);
-    }
-}
-
-void jMechanismParameterToCKMechanismParameterSlow(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength)
-{
-    /* get all Java mechanism parameter classes */
-    jclass jVersionClass, jSsl3MasterKeyDeriveParamsClass, jSsl3KeyMatParamsClass;
-    jclass jTlsPrfParamsClass, jAesCtrParamsClass, jRsaPkcsOaepParamsClass;
-    jclass jPbeParamsClass, jPkcs5Pbkd2ParamsClass, jRsaPkcsPssParamsClass;
-    jclass jEcdh1DeriveParamsClass, jEcdh2DeriveParamsClass;
-    jclass jX942Dh1DeriveParamsClass, jX942Dh2DeriveParamsClass;
-    TRACE0("\nDEBUG: jMechanismParameterToCKMechanismParameter");
-
-    /* most common cases, i.e. NULL/byte[]/long, are already handled by
-     * jMechanismParameterToCKMechanismParameter before calling this method.
-     */
-    jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
-    if (jVersionClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jVersionClass)) {
-        /*
-         * CK_VERSION used by CKM_SSL3_PRE_MASTER_KEY_GEN
-         */
-        CK_VERSION_PTR ckpParam;
-
-        /* convert jParameter to CKParameter */
-        ckpParam = jVersionToCKVersionPtr(env, jParam);
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_VERSION);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
-    if (jSsl3MasterKeyDeriveParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jSsl3MasterKeyDeriveParamsClass)) {
-        /*
-         * CK_SSL3_MASTER_KEY_DERIVE_PARAMS
-         */
-        CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR) malloc(sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
-    if (jSsl3KeyMatParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jSsl3KeyMatParamsClass)) {
-        /*
-         * CK_SSL3_KEY_MAT_PARAMS
-         */
-        CK_SSL3_KEY_MAT_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_SSL3_KEY_MAT_PARAMS_PTR) malloc(sizeof(CK_SSL3_KEY_MAT_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jSsl3KeyMatParamToCKSsl3KeyMatParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_SSL3_KEY_MAT_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jTlsPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
-    if (jTlsPrfParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jTlsPrfParamsClass)) {
-        /*
-         * CK_TLS_PRF_PARAMS
-         */
-        CK_TLS_PRF_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_TLS_PRF_PARAMS_PTR) malloc(sizeof(CK_TLS_PRF_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jTlsPrfParamsToCKTlsPrfParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_TLS_PRF_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jAesCtrParamsClass = (*env)->FindClass(env, CLASS_AES_CTR_PARAMS);
-    if (jAesCtrParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jAesCtrParamsClass)) {
-        /*
-         * CK_AES_CTR_PARAMS
-         */
-        CK_AES_CTR_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_AES_CTR_PARAMS_PTR) malloc(sizeof(CK_AES_CTR_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        jAesCtrParamsToCKAesCtrParam(env, jParam, ckpParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_AES_CTR_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS);
-    if (jRsaPkcsOaepParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jRsaPkcsOaepParamsClass)) {
-        /*
-         * CK_RSA_PKCS_OAEP_PARAMS
-         */
-        CK_RSA_PKCS_OAEP_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_RSA_PKCS_OAEP_PARAMS_PTR) malloc(sizeof(CK_RSA_PKCS_OAEP_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jRsaPkcsOaepParamToCKRsaPkcsOaepParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
-    if (jPbeParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jPbeParamsClass)) {
-        /*
-         * CK_PBE_PARAMS
-         */
-        CK_PBE_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_PBE_PARAMS_PTR) malloc(sizeof(CK_PBE_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jPbeParamToCKPbeParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_PBE_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS);
-    if (jPkcs5Pbkd2ParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jPkcs5Pbkd2ParamsClass)) {
-        /*
-         * CK_PKCS5_PBKD2_PARAMS
-         */
-        CK_PKCS5_PBKD2_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_PKCS5_PBKD2_PARAMS_PTR) malloc(sizeof(CK_PKCS5_PBKD2_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_PKCS5_PBKD2_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jRsaPkcsPssParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_PSS_PARAMS);
-    if (jRsaPkcsPssParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jRsaPkcsPssParamsClass)) {
-        /*
-         * CK_RSA_PKCS_PSS_PARAMS
-         */
-        CK_RSA_PKCS_PSS_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_RSA_PKCS_PSS_PARAMS_PTR) malloc(sizeof(CK_RSA_PKCS_PSS_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jRsaPkcsPssParamToCKRsaPkcsPssParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_RSA_PKCS_PSS_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jEcdh1DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH1_DERIVE_PARAMS);
-    if (jEcdh1DeriveParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jEcdh1DeriveParamsClass)) {
-        /*
-         * CK_ECDH1_DERIVE_PARAMS
-         */
-        CK_ECDH1_DERIVE_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_ECDH1_DERIVE_PARAMS_PTR) malloc(sizeof(CK_ECDH1_DERIVE_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jEcdh1DeriveParamToCKEcdh1DeriveParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_ECDH1_DERIVE_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jEcdh2DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH2_DERIVE_PARAMS);
-    if (jEcdh2DeriveParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jEcdh2DeriveParamsClass)) {
-        /*
-         * CK_ECDH2_DERIVE_PARAMS
-         */
-        CK_ECDH2_DERIVE_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_ECDH2_DERIVE_PARAMS_PTR) malloc(sizeof(CK_ECDH2_DERIVE_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jEcdh2DeriveParamToCKEcdh2DeriveParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_ECDH2_DERIVE_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS);
-    if (jX942Dh1DeriveParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jX942Dh1DeriveParamsClass)) {
-        /*
-         * CK_X9_42_DH1_DERIVE_PARAMS
-         */
-        CK_X9_42_DH1_DERIVE_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_X9_42_DH1_DERIVE_PARAMS_PTR) malloc(sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jX942Dh1DeriveParamToCKX942Dh1DeriveParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_X9_42_DH1_DERIVE_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS);
-    if (jX942Dh2DeriveParamsClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jParam, jX942Dh2DeriveParamsClass)) {
-        /*
-         * CK_X9_42_DH2_DERIVE_PARAMS
-         */
-        CK_X9_42_DH2_DERIVE_PARAMS_PTR ckpParam;
-
-        ckpParam = (CK_X9_42_DH2_DERIVE_PARAMS_PTR) malloc(sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
-        if (ckpParam == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-
-        /* convert jParameter to CKParameter */
-        *ckpParam = jX942Dh2DeriveParamToCKX942Dh2DeriveParam(env, jParam);
-        if ((*env)->ExceptionCheck(env)) {
-            free(ckpParam);
-            return;
-        }
-
-        /* get length and pointer of parameter */
-        *ckpLength = sizeof(CK_X9_42_DH2_DERIVE_PARAMS);
-        *ckpParamPtr = ckpParam;
-        return;
-    }
-
-    /* if everything faild up to here */
-    /* try if the parameter is a primitive Java type */
-    jObjectToPrimitiveCKObjectPtrPtr(env, jParam, ckpParamPtr, ckpLength);
-    /* *ckpParamPtr = jObjectToCKVoidPtr(jParam); */
-    /* *ckpLength = 1; */
-
-    TRACE0("FINISHED\n");
-}
-
-
-/* the mechanism parameter convertion functions: */
-
-/*
- * converts the Java CK_RSA_PKCS_OAEP_PARAMS object to a CK_RSA_PKCS_OAEP_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_RSA_PKCS_OAEP_PARAMS object to convert
- * @return - the new CK_RSA_PKCS_OAEP_PARAMS structure
- */
-CK_RSA_PKCS_OAEP_PARAMS jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobject jParam)
-{
-    jclass jRsaPkcsOaepParamsClass;
-    CK_RSA_PKCS_OAEP_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jHashAlg, jMgf, jSource;
-    jobject jSourceData;
-    CK_BYTE_PTR ckpByte;
-    memset(&ckParam, 0, sizeof(CK_RSA_PKCS_OAEP_PARAMS));
-
-    /* get hashAlg */
-    jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS);
-    if (jRsaPkcsOaepParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "hashAlg", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jHashAlg = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get mgf */
-    fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "mgf", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jMgf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get source */
-    fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "source", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jSource = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get sourceData and sourceDataLength */
-    fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "pSourceData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jSourceData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.hashAlg = jLongToCKULong(jHashAlg);
-    ckParam.mgf = jLongToCKULong(jMgf);
-    ckParam.source = jLongToCKULong(jSource);
-    jByteArrayToCKByteArray(env, jSourceData, & ckpByte, &(ckParam.ulSourceDataLen));
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    ckParam.pSourceData = (CK_VOID_PTR) ckpByte;
-
-    return ckParam ;
-}
-
-/*
- * converts the Java CK_PBE_PARAMS object to a CK_PBE_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_PBE_PARAMS object to convert
- * @return - the new CK_PBE_PARAMS structure
- */
-CK_PBE_PARAMS jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam)
-{
-    jclass jPbeParamsClass;
-    CK_PBE_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jIteration;
-    jobject jInitVector, jPassword, jSalt;
-    CK_ULONG ckTemp;
-    memset(&ckParam, 0, sizeof(CK_PBE_PARAMS));
-
-    /* get pInitVector */
-    jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
-    if (jPbeParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVector", "[C");
-    if (fieldID == NULL) { return ckParam; }
-    jInitVector = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPassword and ulPasswordLength */
-    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pPassword", "[C");
-    if (fieldID == NULL) { return ckParam; }
-    jPassword = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pSalt and ulSaltLength */
-    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pSalt", "[C");
-    if (fieldID == NULL) { return ckParam; }
-    jSalt = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get ulIteration */
-    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "ulIteration", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jIteration = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.ulIteration = jLongToCKULong(jIteration);
-    jCharArrayToCKCharArray(env, jInitVector, &(ckParam.pInitVector), &ckTemp);
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    jCharArrayToCKCharArray(env, jPassword, &(ckParam.pPassword), &(ckParam.ulPasswordLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pInitVector);
-        return ckParam;
-    }
-    jCharArrayToCKCharArray(env, jSalt, &(ckParam.pSalt), &(ckParam.ulSaltLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pInitVector);
-        free(ckParam.pPassword);
-        return ckParam;
-    }
-
-    return ckParam ;
-}
-
-/*
- * Copy back the initialization vector from the native structure to the
- * Java object. This is only used for CKM_PBE_* mechanisms and their
- * CK_PBE_PARAMS parameters.
- *
- */
-void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
-{
-    jclass jMechanismClass, jPbeParamsClass;
-    CK_PBE_PARAMS *ckParam;
-    jfieldID fieldID;
-    CK_MECHANISM_TYPE ckMechanismType;
-    jlong jMechanismType;
-    jobject jParameter;
-    jobject jInitVector;
-    jint jInitVectorLength;
-    CK_CHAR_PTR initVector;
-    int i;
-    jchar* jInitVectorChars;
-
-    /* get mechanism */
-    jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
-    if (jMechanismClass == NULL) { return; }
-    fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
-    if (fieldID == NULL) { return; }
-    jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
-    ckMechanismType = jLongToCKULong(jMechanismType);
-    if (ckMechanismType != ckMechanism->mechanism) {
-        /* we do not have maching types, this should not occur */
-        return;
-    }
-
-    jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
-    if (jPbeParamsClass == NULL) { return; }
-    ckParam = (CK_PBE_PARAMS *) ckMechanism->pParameter;
-    if (ckParam != NULL_PTR) {
-        initVector = ckParam->pInitVector;
-        if (initVector != NULL_PTR) {
-            /* get pParameter */
-            fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
-            if (fieldID == NULL) { return; }
-            jParameter = (*env)->GetObjectField(env, jMechanism, fieldID);
-            fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVektor", "[C");
-            if (fieldID == NULL) { return; }
-            jInitVector = (*env)->GetObjectField(env, jParameter, fieldID);
-
-            if (jInitVector != NULL) {
-                jInitVectorLength = (*env)->GetArrayLength(env, jInitVector);
-                jInitVectorChars = (*env)->GetCharArrayElements(env, jInitVector, NULL);
-                if (jInitVectorChars == NULL) { return; }
-
-                /* copy the chars to the Java buffer */
-                for (i=0; i < jInitVectorLength; i++) {
-                    jInitVectorChars[i] = ckCharToJChar(initVector[i]);
-                }
-                /* copy back the Java buffer to the object */
-                (*env)->ReleaseCharArrayElements(env, jInitVector, jInitVectorChars, 0);
-            }
-        }
-    }
-}
-
-/*
- * converts the Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_PKCS5_PBKD2_PARAMS object to convert
- * @return - the new CK_PKCS5_PBKD2_PARAMS structure
- */
-CK_PKCS5_PBKD2_PARAMS jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject jParam)
-{
-    jclass jPkcs5Pbkd2ParamsClass;
-    CK_PKCS5_PBKD2_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jSaltSource, jIteration, jPrf;
-    jobject jSaltSourceData, jPrfData;
-    memset(&ckParam, 0, sizeof(CK_PKCS5_PBKD2_PARAMS));
-
-    /* get saltSource */
-    jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS);
-    if (jPkcs5Pbkd2ParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "saltSource", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jSaltSource = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pSaltSourceData */
-    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pSaltSourceData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jSaltSourceData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get iterations */
-    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "iterations", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jIteration = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get prf */
-    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "prf", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jPrf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pPrfData and ulPrfDataLength in byte */
-    fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pPrfData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jPrfData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.saltSource = jLongToCKULong(jSaltSource);
-    jByteArrayToCKByteArray(env, jSaltSourceData, (CK_BYTE_PTR *) &(ckParam.pSaltSourceData), &(ckParam.ulSaltSourceDataLen));
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    ckParam.iterations = jLongToCKULong(jIteration);
-    ckParam.prf = jLongToCKULong(jPrf);
-    jByteArrayToCKByteArray(env, jPrfData, (CK_BYTE_PTR *) &(ckParam.pPrfData), &(ckParam.ulPrfDataLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pSaltSourceData);
-        return ckParam;
-    }
-
-    return ckParam ;
-}
-
-/*
- * converts the Java CK_RSA_PKCS_PSS_PARAMS object to a CK_RSA_PKCS_PSS_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_RSA_PKCS_PSS_PARAMS object to convert
- * @return - the new CK_RSA_PKCS_PSS_PARAMS structure
- */
-CK_RSA_PKCS_PSS_PARAMS jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam)
-{
-    jclass jRsaPkcsPssParamsClass;
-    CK_RSA_PKCS_PSS_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jHashAlg, jMgf, jSLen;
-    memset(&ckParam, 0, sizeof(CK_RSA_PKCS_PSS_PARAMS));
-
-    /* get hashAlg */
-    jRsaPkcsPssParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_PSS_PARAMS);
-    if (jRsaPkcsPssParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "hashAlg", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jHashAlg = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get mgf */
-    fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "mgf", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jMgf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get sLen */
-    fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "sLen", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jSLen = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.hashAlg = jLongToCKULong(jHashAlg);
-    ckParam.mgf = jLongToCKULong(jMgf);
-    ckParam.sLen = jLongToCKULong(jSLen);
-
-    return ckParam ;
-}
-
-/*
- * converts the Java CK_ECDH1_DERIVE_PARAMS object to a CK_ECDH1_DERIVE_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_ECDH1_DERIVE_PARAMS object to convert
- * @return - the new CK_ECDH1_DERIVE_PARAMS structure
- */
-CK_ECDH1_DERIVE_PARAMS jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam)
-{
-    jclass jEcdh1DeriveParamsClass;
-    CK_ECDH1_DERIVE_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jLong;
-    jobject jSharedData, jPublicData;
-    memset(&ckParam, 0, sizeof(CK_ECDH1_DERIVE_PARAMS));
-
-    /* get kdf */
-    jEcdh1DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH1_DERIVE_PARAMS);
-    if (jEcdh1DeriveParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "kdf", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jLong = (*env)->GetLongField(env, jParam, fieldID);
-    ckParam.kdf = jLongToCKULong(jLong);
-
-    /* get pSharedData and ulSharedDataLen */
-    fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "pSharedData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jSharedData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPublicData and ulPublicDataLen */
-    fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "pPublicData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.kdf = jLongToCKULong(jLong);
-    jByteArrayToCKByteArray(env, jSharedData, &(ckParam.pSharedData), &(ckParam.ulSharedDataLen));
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    jByteArrayToCKByteArray(env, jPublicData, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pSharedData);
-        return ckParam;
-    }
-
-    return ckParam ;
-}
-
-/*
- * converts the Java CK_ECDH2_DERIVE_PARAMS object to a CK_ECDH2_DERIVE_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_ECDH2_DERIVE_PARAMS object to convert
- * @return - the new CK_ECDH2_DERIVE_PARAMS structure
- */
-CK_ECDH2_DERIVE_PARAMS jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv *env, jobject jParam)
-{
-    jclass jEcdh2DeriveParamsClass;
-    CK_ECDH2_DERIVE_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jKdf, jPrivateDataLen, jPrivateData;
-    jobject jSharedData, jPublicData, jPublicData2;
-    memset(&ckParam, 0, sizeof(CK_ECDH2_DERIVE_PARAMS));
-
-    /* get kdf */
-    jEcdh2DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH2_DERIVE_PARAMS);
-    if (jEcdh2DeriveParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "kdf", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jKdf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pSharedData and ulSharedDataLen */
-    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pSharedData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jSharedData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPublicData and ulPublicDataLen */
-    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pPublicData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get ulPrivateDataLen */
-    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "ulPrivateDataLen", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jPrivateDataLen = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get hPrivateData */
-    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "hPrivateData", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jPrivateData = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pPublicData2 and ulPublicDataLen2 */
-    fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pPublicData2", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jPublicData2 = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.kdf = jLongToCKULong(jKdf);
-    jByteArrayToCKByteArray(env, jSharedData, &(ckParam.pSharedData), &(ckParam.ulSharedDataLen));
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    jByteArrayToCKByteArray(env, jPublicData, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pSharedData);
-        return ckParam;
-    }
-    ckParam.ulPrivateDataLen = jLongToCKULong(jPrivateDataLen);
-    ckParam.hPrivateData = jLongToCKULong(jPrivateData);
-    jByteArrayToCKByteArray(env, jPublicData2, &(ckParam.pPublicData2), &(ckParam.ulPublicDataLen2));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pSharedData);
-        free(ckParam.pPublicData);
-        return ckParam;
-    }
-    return ckParam ;
-}
-
-/*
- * converts the Java CK_X9_42_DH1_DERIVE_PARAMS object to a CK_X9_42_DH1_DERIVE_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_X9_42_DH1_DERIVE_PARAMS object to convert
- * @return - the new CK_X9_42_DH1_DERIVE_PARAMS structure
- */
-CK_X9_42_DH1_DERIVE_PARAMS jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env, jobject jParam)
-{
-    jclass jX942Dh1DeriveParamsClass;
-    CK_X9_42_DH1_DERIVE_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jKdf;
-    jobject jOtherInfo, jPublicData;
-    memset(&ckParam, 0, sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
-
-    /* get kdf */
-    jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS);
-    if (jX942Dh1DeriveParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "kdf", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jKdf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pOtherInfo and ulOtherInfoLen */
-    fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "pOtherInfo", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jOtherInfo = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPublicData and ulPublicDataLen */
-    fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "pPublicData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.kdf = jLongToCKULong(jKdf);
-    jByteArrayToCKByteArray(env, jOtherInfo, &(ckParam.pOtherInfo), &(ckParam.ulOtherInfoLen));
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    jByteArrayToCKByteArray(env, jPublicData, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pOtherInfo);
-        return ckParam;
-    }
-
-    return ckParam ;
-}
-
-/*
- * converts the Java CK_X9_42_DH2_DERIVE_PARAMS object to a CK_X9_42_DH2_DERIVE_PARAMS structure
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jParam - the Java CK_X9_42_DH2_DERIVE_PARAMS object to convert
- * @return - the new CK_X9_42_DH2_DERIVE_PARAMS structure
- */
-CK_X9_42_DH2_DERIVE_PARAMS jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env, jobject jParam)
-{
-    jclass jX942Dh2DeriveParamsClass;
-    CK_X9_42_DH2_DERIVE_PARAMS ckParam;
-    jfieldID fieldID;
-    jlong jKdf, jPrivateDataLen, jPrivateData;
-    jobject jOtherInfo, jPublicData, jPublicData2;
-    memset(&ckParam, 0, sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
-
-    /* get kdf */
-    jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS);
-    if (jX942Dh2DeriveParamsClass == NULL) { return ckParam; }
-    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "kdf", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jKdf = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pOtherInfo and ulOtherInfoLen */
-    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pOtherInfo", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jOtherInfo = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get pPublicData and ulPublicDataLen */
-    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pPublicData", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jPublicData = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* get ulPrivateDataLen */
-    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "ulPrivateDataLen", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jPrivateDataLen = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get hPrivateData */
-    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "hPrivateData", "J");
-    if (fieldID == NULL) { return ckParam; }
-    jPrivateData = (*env)->GetLongField(env, jParam, fieldID);
-
-    /* get pPublicData2 and ulPublicDataLen2 */
-    fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pPublicData2", "[B");
-    if (fieldID == NULL) { return ckParam; }
-    jPublicData2 = (*env)->GetObjectField(env, jParam, fieldID);
-
-    /* populate java values */
-    ckParam.kdf = jLongToCKULong(jKdf);
-    jByteArrayToCKByteArray(env, jOtherInfo, &(ckParam.pOtherInfo), &(ckParam.ulOtherInfoLen));
-    if ((*env)->ExceptionCheck(env)) { return ckParam; }
-    jByteArrayToCKByteArray(env, jPublicData, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pOtherInfo);
-        return ckParam;
-    }
-    ckParam.ulPrivateDataLen = jLongToCKULong(jPrivateDataLen);
-    ckParam.hPrivateData = jLongToCKULong(jPrivateData);
-    jByteArrayToCKByteArray(env, jPublicData2, &(ckParam.pPublicData2), &(ckParam.ulPublicDataLen2));
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckParam.pOtherInfo);
-        free(ckParam.pPublicData);
-        return ckParam;
-    }
-
-    return ckParam ;
-}
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,489 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- * ===========================================================================
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-#ifdef P11_ENABLE_C_ENCRYPTINIT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_EncryptInit
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptInit
-(JNIEnv *env, jobject obj, jlong jSessionHandle,
- jobject jMechanism, jlong jKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckKeyHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckKeyHandle = jLongToCKULong(jKeyHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, &ckMechanism,
-                                        ckKeyHandle);
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_ENCRYPT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Encrypt
- * Signature: (J[BII[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jData            CK_BYTE_PTR pData
- *                                      CK_ULONG ulDataLen
- * @return  jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
- *                                      CK_ULONG_PTR pulEncryptedDataLen
- */
-JNIEXPORT jint JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1Encrypt
-(JNIEnv *env, jobject obj, jlong jSessionHandle,
- jbyteArray jIn, jint jInOfs, jint jInLen,
- jbyteArray jOut, jint jOutOfs, jint jOutLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-
-    CK_BYTE_PTR inBufP;
-    CK_BYTE_PTR outBufP;
-    CK_ULONG ckEncryptedPartLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
-    if (inBufP == NULL) { return 0; }
-
-    outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
-    if (outBufP == NULL) {
-        // Make sure to release inBufP
-        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-        return 0;
-    }
-
-    ckEncryptedPartLen = jOutLen;
-
-    rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle,
-                                    (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
-                                    (CK_BYTE_PTR)(outBufP + jOutOfs),
-                                    &ckEncryptedPartLen);
-
-    (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-    (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
-
-    ckAssertReturnValueOK(env, rv);
-    return ckEncryptedPartLen;
-}
-#endif
-
-#ifdef P11_ENABLE_C_ENCRYPTUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_EncryptUpdate
- * Signature: (J[BII[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jPart            CK_BYTE_PTR pPart
- *                                      CK_ULONG ulPartLen
- * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
- *                                      CK_ULONG_PTR pulEncryptedPartLen
- */
-JNIEXPORT jint JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptUpdate
-(JNIEnv *env, jobject obj, jlong jSessionHandle,
- jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
- jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-
-    CK_BYTE_PTR inBufP;
-    CK_BYTE_PTR outBufP;
-    CK_ULONG ckEncryptedPartLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (directIn != 0) {
-      inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
-    } else {
-      inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
-      if (inBufP == NULL) { return 0; }
-    }
-
-    if (directOut != 0) {
-      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
-    } else {
-      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
-      if (outBufP == NULL) {
-          // Make sure to release inBufP
-          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-          return 0;
-      }
-    }
-
-    ckEncryptedPartLen = jOutLen;
-
-    //printf("EU: inBufP=%i, jInOfs=%i, jInLen=%i, outBufP=%i\n",
-    //       inBufP, jInOfs, jInLen, outBufP);
-
-    rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle,
-                                          (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
-                                          (CK_BYTE_PTR)(outBufP + jOutOfs),
-                                          &ckEncryptedPartLen);
-
-    //printf("EU: ckEncryptedPartLen=%i\n", ckEncryptedPartLen);
-
-    if (directIn == 0) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-    }
-
-    if (directOut == 0) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
-    }
-
-    ckAssertReturnValueOK(env, rv);
-
-    return ckEncryptedPartLen;
-}
-#endif
-
-#ifdef P11_ENABLE_C_ENCRYPTFINAL
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_EncryptFinal
- * Signature: (J[BII)I
- * Parametermapping:                        *PKCS11*
- * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
- * @return  jbyteArray jLastEncryptedPart   CK_BYTE_PTR pLastEncryptedDataPart
- *                                          CK_ULONG_PTR pulLastEncryptedDataPartLen
- */
-JNIEXPORT jint JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal
-(JNIEnv *env, jobject obj, jlong jSessionHandle,
- jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE_PTR outBufP;
-    CK_ULONG ckLastEncryptedPartLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (directOut != 0) {
-      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
-    } else {
-      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
-      if (outBufP == NULL) { return 0; }
-    }
-
-    ckLastEncryptedPartLen = jOutLen;
-
-    //printf("EF: outBufP=%i\n", outBufP);
-
-    rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle,
-                                         (CK_BYTE_PTR)(outBufP + jOutOfs),
-                                         &ckLastEncryptedPartLen);
-
-    //printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen);
-
-    if (directOut == 0) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
-    }
-
-    ckAssertReturnValueOK(env, rv);
-
-    return ckLastEncryptedPartLen;
-}
-#endif
-
-#ifdef P11_ENABLE_C_DECRYPTINIT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DecryptInit
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptInit
-(JNIEnv *env, jobject obj, jlong jSessionHandle,
- jobject jMechanism, jlong jKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckKeyHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckKeyHandle = jLongToCKULong(jKeyHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, &ckMechanism,
-                                        ckKeyHandle);
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_DECRYPT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Decrypt
- * Signature: (J[BII[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
- *                                      CK_ULONG ulEncryptedDataLen
- * @return  jbyteArray jData            CK_BYTE_PTR pData
- *                                      CK_ULONG_PTR pulDataLen
- */
-JNIEXPORT jint JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt
-(JNIEnv *env, jobject obj, jlong jSessionHandle,
- jbyteArray jIn, jint jInOfs, jint jInLen,
- jbyteArray jOut, jint jOutOfs, jint jOutLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-
-    CK_BYTE_PTR inBufP;
-    CK_BYTE_PTR outBufP;
-    CK_ULONG ckPartLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
-    if (inBufP == NULL) { return 0; }
-
-    outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
-    if (outBufP == NULL) {
-        // Make sure to release inBufP
-        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-        return 0;
-    }
-
-    ckPartLen = jOutLen;
-
-    rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle,
-                                    (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
-                                    (CK_BYTE_PTR)(outBufP + jOutOfs),
-                                    &ckPartLen);
-
-    (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-    (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
-
-    ckAssertReturnValueOK(env, rv);
-
-    return ckPartLen;
-}
-#endif
-
-#ifdef P11_ENABLE_C_DECRYPTUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DecryptUpdate
- * Signature: (J[BII[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
- *                                      CK_ULONG ulEncryptedPartLen
- * @return  jbyteArray jPart            CK_BYTE_PTR pPart
- *                                      CK_ULONG_PTR pulPartLen
- */
-JNIEXPORT jint JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptUpdate
-(JNIEnv *env, jobject obj, jlong jSessionHandle,
- jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen,
- jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-
-    CK_BYTE_PTR inBufP;
-    CK_BYTE_PTR outBufP;
-    CK_ULONG ckDecryptedPartLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (directIn != 0) {
-      inBufP = (CK_BYTE_PTR) jlong_to_ptr(directIn);
-    } else {
-      inBufP = (*env)->GetPrimitiveArrayCritical(env, jIn, NULL);
-      if (inBufP == NULL) { return 0; }
-    }
-
-    if (directOut != 0) {
-      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
-    } else {
-      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
-      if (outBufP == NULL) {
-          // Make sure to release inBufP
-          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-          return 0;
-      }
-    }
-
-    ckDecryptedPartLen = jOutLen;
-
-    rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle,
-                                          (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
-                                          (CK_BYTE_PTR)(outBufP + jOutOfs),
-                                          &ckDecryptedPartLen);
-    if (directIn == 0) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
-    }
-
-    if (directOut == 0) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
-    }
-
-    ckAssertReturnValueOK(env, rv);
-
-    return ckDecryptedPartLen;
-}
-
-#endif
-
-#ifdef P11_ENABLE_C_DECRYPTFINAL
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DecryptFinal
- * Signature: (J[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @return  jbyteArray jLastPart        CK_BYTE_PTR pLastPart
- *                                      CK_ULONG_PTR pulLastPartLen
- */
-JNIEXPORT jint JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptFinal
-(JNIEnv *env, jobject obj, jlong jSessionHandle,
- jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE_PTR outBufP;
-    CK_ULONG ckLastPartLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (directOut != 0) {
-      outBufP = (CK_BYTE_PTR) jlong_to_ptr(directOut);
-    } else {
-      outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
-      if (outBufP == NULL) { return 0; }
-    }
-
-    ckLastPartLen = jOutLen;
-
-    rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle,
-                                         (CK_BYTE_PTR)(outBufP + jOutOfs),
-                                         &ckLastPartLen);
-
-    if (directOut == 0) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, JNI_COMMIT);
-
-    }
-
-    ckAssertReturnValueOK(env, rv);
-
-    return ckLastPartLen;
-}
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include "jlong.h"
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-#ifdef P11_ENABLE_C_DIGESTINIT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DigestInit
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestInit
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, &ckMechanism);
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_DIGEST
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Digest
- * Signature: (J[BII[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jData            CK_BYTE_PTR pData
- *                                      CK_ULONG ulDataLen
- * @return  jbyteArray jDigest          CK_BYTE_PTR pDigest
- *                                      CK_ULONG_PTR pulDigestLen
- */
-JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestSingle
-  (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jDigest, jint jDigestOfs, jint jDigestLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE_PTR bufP;
-    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
-    CK_BYTE DIGESTBUF[MAX_DIGEST_LEN];
-    CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen);
-    CK_MECHANISM ckMechanism;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return 0; }
-
-    rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, &ckMechanism);
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0; }
-
-    if (jInLen <= MAX_STACK_BUFFER_LEN) {
-        bufP = BUF;
-    } else {
-        /* always use single part op, even for large data */
-        bufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
-        if (bufP == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return 0;
-        }
-    }
-
-    (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)bufP);
-    if ((*env)->ExceptionCheck(env)) {
-        if (bufP != BUF) { free(bufP); }
-        return 0;
-    }
-
-    rv = (*ckpFunctions->C_Digest)(ckSessionHandle, bufP, jInLen, DIGESTBUF, &ckDigestLength);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        (*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)DIGESTBUF);
-    }
-
-    if (bufP != BUF) { free(bufP); }
-
-    return ckDigestLength;
-}
-#endif
-
-#ifdef P11_ENABLE_C_DIGESTUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DigestUpdate
- * Signature: (J[B)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jData            CK_BYTE_PTR pData
- *                                      CK_ULONG ulDataLen
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestUpdate
-  (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE_PTR bufP;
-    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
-    jsize bufLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (directIn != 0) {
-        rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen);
-        ckAssertReturnValueOK(env, rv);
-        return;
-    }
-
-    if (jInLen <= MAX_STACK_BUFFER_LEN) {
-        bufLen = MAX_STACK_BUFFER_LEN;
-        bufP = BUF;
-    } else {
-        bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
-        bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
-        if (bufP == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-    }
-
-    while (jInLen > 0) {
-        jsize chunkLen = min(bufLen, jInLen);
-        (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
-        if ((*env)->ExceptionCheck(env)) {
-            if (bufP != BUF) { free(bufP); }
-            return;
-        }
-        rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, bufP, chunkLen);
-        if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-            if (bufP != BUF) { free(bufP); }
-            return;
-        }
-        jInOfs += chunkLen;
-        jInLen -= chunkLen;
-    }
-
-    if (bufP != BUF) {
-        free(bufP);
-    }
-}
-#endif
-
-#ifdef P11_ENABLE_C_DIGESTKEY
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DigestKey
- * Signature: (JJ)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestKey
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_ULONG ckKeyHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckKeyHandle = jLongToCKULong(jKeyHandle);
-
-    rv = (*ckpFunctions->C_DigestKey)(ckSessionHandle, ckKeyHandle);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_DIGESTFINAL
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DigestFinal
- * Signature: (J[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @return  jbyteArray jDigest          CK_BYTE_PTR pDigest
- *                                      CK_ULONG_PTR pulDigestLen
- */
-JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestFinal
-  (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jDigest, jint jDigestOfs, jint jDigestLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE BUF[MAX_DIGEST_LEN];
-    CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen);
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    rv = (*ckpFunctions->C_DigestFinal)(ckSessionHandle, BUF, &ckDigestLength);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        (*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)BUF);
-    }
-    return ckDigestLength;
-}
-#endif
-
-#ifdef P11_ENABLE_C_SEEDRANDOM
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SeedRandom
- * Signature: (J[B)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jSeed            CK_BYTE_PTR pSeed
- *                                      CK_ULONG ulSeedLen
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SeedRandom
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSeed)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpSeed = NULL_PTR;
-    CK_ULONG ckSeedLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jSeed, &ckpSeed, &ckSeedLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    rv = (*ckpFunctions->C_SeedRandom)(ckSessionHandle, ckpSeed, ckSeedLength);
-
-    free(ckpSeed);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_GENERATERANDOM
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GenerateRandom
- * Signature: (J[B)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jRandomData      CK_BYTE_PTR pRandomData
- *                                      CK_ULONG ulRandomDataLen
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateRandom
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jRandomData)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    jbyte *jRandomBuffer;
-    jlong jRandomBufferLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    jRandomBufferLength = (*env)->GetArrayLength(env, jRandomData);
-    jRandomBuffer = (*env)->GetByteArrayElements(env, jRandomData, NULL);
-    if (jRandomBuffer == NULL) { return; }
-
-    rv = (*ckpFunctions->C_GenerateRandom)(ckSessionHandle,
-                                         (CK_BYTE_PTR) jRandomBuffer,
-                                         jLongToCKULong(jRandomBufferLength));
-
-    /* copy back generated bytes */
-    (*env)->ReleaseByteArrayElements(env, jRandomData, jRandomBuffer, 0);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- * ===========================================================================
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-#ifdef P11_ENABLE_C_DIGESTENCRYPTUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DigestEncryptUpdate
- * Signature: (J[B)[B
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jPart            CK_BYTE_PTR pPart
- *                                      CK_ULONG ulPartLen
- * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
- *                                      CK_ULONG_PTR pulEncryptedPartLen
- */
-JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestEncryptUpdate
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
-    CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
-    jbyteArray jEncryptedPart = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength);
-    if ((*env)->ExceptionCheck(env)) { return NULL; }
-
-    rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-        free(ckpPart);
-        return NULL;
-    }
-
-    ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
-    if (ckpEncryptedPart == NULL) {
-        free(ckpPart);
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
-    }
-    free(ckpPart);
-    free(ckpEncryptedPart);
-
-    return jEncryptedPart ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_DECRYPTDIGESTUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DecryptDigestUpdate
- * Signature: (J[B)[B
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
- *                                      CK_ULONG ulEncryptedPartLen
- * @return  jbyteArray jPart            CK_BYTE_PTR pPart
- *                                      CK_ULONG_PTR pulPartLen
- */
-JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptDigestUpdate
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
-    CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
-    jbyteArray jPart = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength);
-    if ((*env)->ExceptionCheck(env)) { return NULL; }
-
-    rv = (*ckpFunctions->C_DecryptDigestUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-        free(ckpEncryptedPart);
-        return NULL;
-    }
-
-    ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
-    if (ckpPart == NULL) {
-        free(ckpEncryptedPart);
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    rv = (*ckpFunctions->C_DecryptDigestUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
-    }
-    free(ckpEncryptedPart);
-    free(ckpPart);
-
-    return jPart ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_SIGNENCRYPTUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SignEncryptUpdate
- * Signature: (J[B)[B
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jPart            CK_BYTE_PTR pPart
- *                                      CK_ULONG ulPartLen
- * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
- *                                      CK_ULONG_PTR pulEncryptedPartLen
- */
-JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignEncryptUpdate
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
-    CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
-    jbyteArray jEncryptedPart = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength);
-    if ((*env)->ExceptionCheck(env)) { return NULL; }
-
-    rv = (*ckpFunctions->C_SignEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-        free(ckpPart);
-        return NULL;
-    }
-
-    ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
-    if (ckpEncryptedPart == NULL) {
-        free(ckpPart);
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    rv = (*ckpFunctions->C_SignEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
-    }
-    free(ckpPart);
-    free(ckpEncryptedPart);
-
-    return jEncryptedPart ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_DECRYPTVERIFYUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DecryptVerifyUpdate
- * Signature: (J[B)[B
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
- *                                      CK_ULONG ulEncryptedPartLen
- * @return  jbyteArray jPart            CK_BYTE_PTR pPart
- *                                      CK_ULONG_PTR pulPartLen
- */
-JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DecryptVerifyUpdate
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
-    CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
-    jbyteArray jPart = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength);
-    if ((*env)->ExceptionCheck(env)) { return NULL; }
-
-    rv = (*ckpFunctions->C_DecryptVerifyUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-        free(ckpEncryptedPart);
-        return NULL;
-    }
-
-    ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
-    if (ckpPart == NULL) {
-        free(ckpEncryptedPart);
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    rv = (*ckpFunctions->C_DecryptVerifyUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
-
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
-    }
-    free(ckpEncryptedPart);
-    free(ckpPart);
-
-    return jPart ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETFUNCTIONSTATUS
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetFunctionStatus
- * Signature: (J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetFunctionStatus
-    (JNIEnv *env, jobject obj, jlong jSessionHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    /* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */
-    rv = (*ckpFunctions->C_GetFunctionStatus)(ckSessionHandle);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_CANCELFUNCTION
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_CancelFunction
- * Signature: (J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CancelFunction
-    (JNIEnv *env, jobject obj, jlong jSessionHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    /* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */
-    rv = (*ckpFunctions->C_CancelFunction)(ckSessionHandle);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,881 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-/* declare file private functions */
-
-void prefetchFields(JNIEnv *env, jclass thisClass);
-jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo);
-jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo);
-jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo);
-jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo);
-
-/* define variables */
-
-jfieldID pNativeDataID;
-jfieldID mech_mechanismID;
-jfieldID mech_pParameterID;
-
-jclass jByteArrayClass;
-jclass jLongClass;
-
-JavaVM* jvm = NULL;
-
-jboolean debug = 0;
-
-JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
-    jvm = vm;
-    return JNI_VERSION_1_4;
-}
-
-/* ************************************************************************** */
-/* The native implementation of the methods of the PKCS11Implementation class */
-/* ************************************************************************** */
-
-/*
- * This method is used to do static initialization. This method is static and
- * synchronized. Summary: use this method like a static initialization block.
- *
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    initializeLibrary
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_initializeLibrary
-(JNIEnv *env, jclass thisClass, jboolean enableDebug)
-{
-#ifndef NO_CALLBACKS
-    if (notifyListLock == NULL) {
-        notifyListLock = createLockObject(env);
-    }
-#endif
-
-    prefetchFields(env, thisClass);
-    debug = enableDebug;
-}
-
-jclass fetchClass(JNIEnv *env, const char *name) {
-    jclass tmpClass = (*env)->FindClass(env, name);
-    if (tmpClass == NULL) { return NULL; }
-    return (*env)->NewGlobalRef(env, tmpClass);
-}
-
-void prefetchFields(JNIEnv *env, jclass thisClass) {
-    jclass tmpClass;
-
-    /* PKCS11 */
-    pNativeDataID = (*env)->GetFieldID(env, thisClass, "pNativeData", "J");
-    if (pNativeDataID == NULL) { return; }
-
-    /* CK_MECHANISM */
-    tmpClass = (*env)->FindClass(env, CLASS_MECHANISM);
-    if (tmpClass == NULL) { return; }
-    mech_mechanismID = (*env)->GetFieldID(env, tmpClass, "mechanism", "J");
-    if (mech_mechanismID == NULL) { return; }
-    mech_pParameterID = (*env)->GetFieldID(env, tmpClass, "pParameter",
-                                           "Ljava/lang/Object;");
-    if (mech_pParameterID == NULL) { return; }
-    jByteArrayClass = fetchClass(env, "[B");
-    if (jByteArrayClass == NULL) { return; }
-    jLongClass = fetchClass(env, "java/lang/Long");
-}
-
-/* This method is designed to do a clean-up. It releases all global resources
- * of this library. By now, this function is not called. Calling from
- * JNI_OnUnload would be an option, but some VMs do not support JNI_OnUnload.
- *
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    finalizeLibrary
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_finalizeLibrary
-(JNIEnv *env, jclass thisClass)
-{
-/* XXX
-    * remove all left lists and release the resources and the lock
-     * objects that synchroniz access to these lists.
-     *
-    removeAllModuleEntries(env);
-    if (moduleListHead == NULL) { * check, if we removed the last active module *
-        * remove also the moduleListLock, it is no longer used *
-        if (moduleListLock != NULL) {
-            destroyLockObject(env, moduleListLock);
-            moduleListLock = NULL;
-        }
-#ifndef NO_CALLBACKS
-        * remove all left notify callback entries *
-        while (removeFirstNotifyEntry(env));
-        * remove also the notifyListLock, it is no longer used *
-        if (notifyListLock != NULL) {
-            destroyLockObject(env, notifyListLock);
-            notifyListLock = NULL;
-        }
-        if (jInitArgsObject != NULL) {
-            (*env)->DeleteGlobalRef(env, jInitArgsObject);
-        }
-        if (ckpGlobalInitArgs != NULL_PTR) {
-            free(ckpGlobalInitArgs);
-        }
-#endif * NO_CALLBACKS *
-    }
-*/
-}
-
-#ifdef P11_ENABLE_C_INITIALIZE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Initialize
- * Signature: (Ljava/lang/Object;)V
- * Parametermapping:                    *PKCS11*
- * @param   jobject jInitArgs           CK_VOID_PTR pInitArgs
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1Initialize
-(JNIEnv *env, jobject obj, jobject jInitArgs)
-{
-    /*
-     * Initalize Cryptoki
-     */
-    CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
-    CK_RV rv;
-    CK_FUNCTION_LIST_PTR ckpFunctions;
-
-    TRACE0("DEBUG: initializing module... ");
-
-    ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) {
-        TRACE0("failed getting module entry");
-        return;
-    }
-
-    ckpInitArgs = (jInitArgs != NULL)
-                ? makeCKInitArgsAdapter(env, jInitArgs)
-                : NULL_PTR;
-
-    rv = (*ckpFunctions->C_Initialize)(ckpInitArgs);
-
-    free(ckpInitArgs);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-
-    TRACE0("FINISHED\n");
-}
-#endif
-
-#ifdef P11_ENABLE_C_FINALIZE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Finalize
- * Signature: (Ljava/lang/Object;)V
- * Parametermapping:                    *PKCS11*
- * @param   jobject jReserved           CK_VOID_PTR pReserved
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize
-(JNIEnv *env, jobject obj, jobject jReserved)
-{
-    /*
-     * Finalize Cryptoki
-     */
-    CK_VOID_PTR ckpReserved;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckpReserved = jObjectToCKVoidPtr(jReserved);
-
-    rv = (*ckpFunctions->C_Finalize)(ckpReserved);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETINFO
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetInfo
- * Signature: ()Lsun/security/pkcs11/wrapper/CK_INFO;
- * Parametermapping:                    *PKCS11*
- * @return  jobject jInfoObject         CK_INFO_PTR pInfo
- */
-JNIEXPORT jobject JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo
-(JNIEnv *env, jobject obj)
-{
-    CK_INFO ckLibInfo;
-    jobject jInfoObject=NULL;
-    CK_RV rv;
-    CK_FUNCTION_LIST_PTR ckpFunctions;
-    memset(&ckLibInfo, 0, sizeof(CK_INFO));
-
-    ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo);
-    }
-    return jInfoObject ;
-}
-
-/*
- * converts a pointer to a CK_INFO structure into a Java CK_INFO Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpInfo - the pointer to the CK_INFO structure
- * @return - the new Java CK_INFO object
- */
-jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo)
-{
-    jclass jInfoClass;
-    jmethodID jCtrId;
-    jobject jInfoObject;
-    jobject jCryptokiVer;
-    jcharArray jVendor;
-    jlong jFlags;
-    jcharArray jLibraryDesc;
-    jobject jLibraryVer;
-
-    /* load CK_INFO class */
-    jInfoClass = (*env)->FindClass(env, CLASS_INFO);
-    if (jInfoClass == NULL) { return NULL; };
-
-    /* load CK_INFO constructor */
-    jCtrId = (*env)->GetMethodID
-      (env, jInfoClass, "<init>",
-       "(Lsun/security/pkcs11/wrapper/CK_VERSION;[CJ[CLsun/security/pkcs11/wrapper/CK_VERSION;)V");
-    if (jCtrId == NULL) { return NULL; }
-
-    /* prep all fields */
-    jCryptokiVer = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion));
-    if (jCryptokiVer == NULL) { return NULL; }
-    jVendor =
-      ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32);
-    if (jVendor == NULL) { return NULL; }
-    jFlags = ckULongToJLong(ckpInfo->flags);
-    jLibraryDesc =
-      ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]), 32);
-    if (jLibraryDesc == NULL) { return NULL; }
-    jLibraryVer = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion));
-    if (jLibraryVer == NULL) { return NULL; }
-
-    /* create new CK_INFO object */
-    jInfoObject = (*env)->NewObject(env, jInfoClass, jCtrId, jCryptokiVer,
-                                    jVendor, jFlags, jLibraryDesc, jLibraryVer);
-    if (jInfoObject == NULL) { return NULL; }
-
-    /* free local references */
-    (*env)->DeleteLocalRef(env, jInfoClass);
-    (*env)->DeleteLocalRef(env, jCryptokiVer);
-    (*env)->DeleteLocalRef(env, jVendor);
-    (*env)->DeleteLocalRef(env, jLibraryDesc);
-    (*env)->DeleteLocalRef(env, jLibraryVer);
-
-    return jInfoObject ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETSLOTLIST
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetSlotList
- * Signature: (Z)[J
- * Parametermapping:                    *PKCS11*
- * @param   jboolean jTokenPresent      CK_BBOOL tokenPresent
- * @return  jlongArray jSlotList        CK_SLOT_ID_PTR pSlotList
- *                                      CK_ULONG_PTR pulCount
- */
-JNIEXPORT jlongArray JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList
-(JNIEnv *env, jobject obj, jboolean jTokenPresent)
-{
-    CK_ULONG ckTokenNumber;
-    CK_SLOT_ID_PTR ckpSlotList;
-    CK_BBOOL ckTokenPresent;
-    jlongArray jSlotList = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckTokenPresent = jBooleanToCKBBool(jTokenPresent);
-
-    rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR,
-                                        &ckTokenNumber);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
-
-    ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID));
-    if (ckpSlotList == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList,
-                                        &ckTokenNumber);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber);
-    }
-    free(ckpSlotList);
-
-    return jSlotList ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETSLOTINFO
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetSlotInfo
- * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SLOT_INFO;
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSlotID               CK_SLOT_ID slotID
- * @return  jobject jSlotInfoObject     CK_SLOT_INFO_PTR pInfo
- */
-JNIEXPORT jobject JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo
-(JNIEnv *env, jobject obj, jlong jSlotID)
-{
-    CK_SLOT_ID ckSlotID;
-    CK_SLOT_INFO ckSlotInfo;
-    jobject jSlotInfoObject=NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSlotID = jLongToCKULong(jSlotID);
-
-    rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo);
-    }
-    return jSlotInfoObject;
-}
-
-/*
- * converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO
- * Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure
- * @return - the new Java CK_SLOT_INFO object
- */
-jobject
-ckSlotInfoPtrToJSlotInfo
-(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo)
-{
-    jclass jSlotInfoClass;
-    jmethodID jCtrId;
-    jobject jSlotInfoObject;
-    jcharArray jSlotDesc;
-    jcharArray jVendor;
-    jlong jFlags;
-    jobject jHardwareVer;
-    jobject jFirmwareVer;
-
-    /* load CK_SLOT_INFO class */
-    jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO);
-    if (jSlotInfoClass == NULL) { return NULL; };
-
-    /* load CK_SLOT_INFO constructor */
-    jCtrId = (*env)->GetMethodID
-      (env, jSlotInfoClass, "<init>",
-       "([C[CJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;)V");
-    if (jCtrId == NULL) { return NULL; }
-
-    /* prep all fields */
-    jSlotDesc =
-      ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]), 64);
-    if (jSlotDesc == NULL) { return NULL; }
-    jVendor =
-      ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]), 32);
-    if (jVendor == NULL) { return NULL; }
-    jFlags = ckULongToJLong(ckpSlotInfo->flags);
-    jHardwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion));
-    if (jHardwareVer == NULL) { return NULL; }
-    jFirmwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion));
-    if (jFirmwareVer == NULL) { return NULL; }
-
-    /* create new CK_SLOT_INFO object */
-    jSlotInfoObject = (*env)->NewObject
-      (env, jSlotInfoClass, jCtrId, jSlotDesc, jVendor, jFlags,
-       jHardwareVer, jFirmwareVer);
-    if (jSlotInfoObject == NULL) { return NULL; }
-
-    /* free local references */
-    (*env)->DeleteLocalRef(env, jSlotInfoClass);
-    (*env)->DeleteLocalRef(env, jSlotDesc);
-    (*env)->DeleteLocalRef(env, jVendor);
-    (*env)->DeleteLocalRef(env, jHardwareVer);
-    (*env)->DeleteLocalRef(env, jFirmwareVer);
-
-    return jSlotInfoObject ;
-}
-
-#endif
-
-#ifdef P11_ENABLE_C_GETTOKENINFO
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetTokenInfo
- * Signature: (J)Lsun/security/pkcs11/wrapper/CK_TOKEN_INFO;
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSlotID               CK_SLOT_ID slotID
- * @return  jobject jInfoTokenObject    CK_TOKEN_INFO_PTR pInfo
- */
-JNIEXPORT jobject JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo
-(JNIEnv *env, jobject obj, jlong jSlotID)
-{
-    CK_SLOT_ID ckSlotID;
-    CK_TOKEN_INFO ckTokenInfo;
-    jobject jInfoTokenObject = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSlotID = jLongToCKULong(jSlotID);
-
-    rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo);
-    }
-    return jInfoTokenObject ;
-}
-
-/*
- * converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO
- * Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure
- * @return - the new Java CK_TOKEN_INFO object
- */
-jobject
-ckTokenInfoPtrToJTokenInfo
-(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo)
-{
-    jclass jTokenInfoClass;
-    jmethodID jCtrId;
-    jobject jTokenInfoObject;
-    jcharArray jLabel;
-    jcharArray jVendor;
-    jcharArray jModel;
-    jcharArray jSerialNo;
-    jlong jFlags;
-    jlong jMaxSnCnt;
-    jlong jSnCnt;
-    jlong jMaxRwSnCnt;
-    jlong jRwSnCnt;
-    jlong jMaxPinLen;
-    jlong jMinPinLen;
-    jlong jTotalPubMem;
-    jlong jFreePubMem;
-    jlong jTotalPrivMem;
-    jlong jFreePrivMem;
-    jobject jHardwareVer;
-    jobject jFirmwareVer;
-    jcharArray jUtcTime;
-
-    /* load CK_TOKEN_INFO class */
-    jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO);
-    if (jTokenInfoClass == NULL)  { return NULL; };
-
-    /* load CK_TOKEN_INFO constructor */
-    jCtrId = (*env)->GetMethodID
-      (env, jTokenInfoClass, "<init>",
-       "([C[C[C[CJJJJJJJJJJJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;[C)V");
-    if (jCtrId == NULL)  { return NULL; };
-
-    /* prep all fields */
-    jLabel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]), 32);
-    if (jLabel == NULL)  { return NULL; };
-    jVendor =
-      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]), 32);
-    if (jVendor == NULL)  { return NULL; };
-    jModel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]), 16);
-    if (jModel == NULL)  { return NULL; };
-    jSerialNo =
-      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]), 16);
-    if (jSerialNo == NULL)  { return NULL; };
-    jFlags = ckULongToJLong(ckpTokenInfo->flags);
-    jMaxSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxSessionCount);
-    jSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulSessionCount);
-    jMaxRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxRwSessionCount);
-    jRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulRwSessionCount);
-    jMaxPinLen = ckULongToJLong(ckpTokenInfo->ulMaxPinLen);
-    jMinPinLen = ckULongToJLong(ckpTokenInfo->ulMinPinLen);
-    jTotalPubMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPublicMemory);
-    jFreePubMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePublicMemory);
-    jTotalPrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPrivateMemory);
-    jFreePrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePrivateMemory);
-    jHardwareVer =
-      ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion));
-    if (jHardwareVer == NULL) { return NULL; }
-    jFirmwareVer =
-      ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion));
-    if (jFirmwareVer == NULL) { return NULL; }
-    jUtcTime =
-      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]), 16);
-    if (jUtcTime == NULL) { return NULL; }
-
-    /* create new CK_TOKEN_INFO object */
-    jTokenInfoObject =
-      (*env)->NewObject(env, jTokenInfoClass, jCtrId, jLabel, jVendor, jModel,
-                        jSerialNo, jFlags,
-                        jMaxSnCnt, jSnCnt, jMaxRwSnCnt, jRwSnCnt,
-                        jMaxPinLen, jMinPinLen,
-                        jTotalPubMem, jFreePubMem, jTotalPrivMem, jFreePrivMem,
-                        jHardwareVer, jFirmwareVer, jUtcTime);
-    if (jTokenInfoObject == NULL) { return NULL; }
-
-    /* free local references */
-    (*env)->DeleteLocalRef(env, jTokenInfoClass);
-    (*env)->DeleteLocalRef(env, jLabel);
-    (*env)->DeleteLocalRef(env, jVendor);
-    (*env)->DeleteLocalRef(env, jModel);
-    (*env)->DeleteLocalRef(env, jSerialNo);
-    (*env)->DeleteLocalRef(env, jHardwareVer);
-    (*env)->DeleteLocalRef(env, jFirmwareVer);
-
-    return jTokenInfoObject ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_WAITFORSLOTEVENT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_WaitForSlotEvent
- * Signature: (JLjava/lang/Object;)J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jFlags                CK_FLAGS flags
- * @param   jobject jReserved           CK_VOID_PTR pReserved
- * @return  jlong jSlotID               CK_SLOT_ID_PTR pSlot
- */
-JNIEXPORT jlong JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent
-(JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved)
-{
-    CK_FLAGS ckFlags;
-    CK_SLOT_ID ckSlotID;
-    jlong jSlotID = 0L;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0L; }
-
-    ckFlags = jLongToCKULong(jFlags);
-
-    rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jSlotID = ckULongToJLong(ckSlotID);
-    }
-
-    return jSlotID ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETMECHANISMLIST
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetMechanismList
- * Signature: (J)[J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSlotID               CK_SLOT_ID slotID
- * @return  jlongArray jMechanismList   CK_MECHANISM_TYPE_PTR pMechanismList
- *                                      CK_ULONG_PTR pulCount
- */
-JNIEXPORT jlongArray JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList
-(JNIEnv *env, jobject obj, jlong jSlotID)
-{
-    CK_SLOT_ID ckSlotID;
-    CK_ULONG ckMechanismNumber;
-    CK_MECHANISM_TYPE_PTR ckpMechanismList;
-    jlongArray jMechanismList = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSlotID = jLongToCKULong(jSlotID);
-
-    rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR,
-                                             &ckMechanismNumber);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
-
-    ckpMechanismList = (CK_MECHANISM_TYPE_PTR)
-      malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE));
-    if (ckpMechanismList == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList,
-                                             &ckMechanismNumber);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList,
-                                                  ckMechanismNumber);
-    }
-    free(ckpMechanismList);
-
-    return jMechanismList ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETMECHANISMINFO
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetMechanismInfo
- * Signature: (JJ)Lsun/security/pkcs11/wrapper/CK_MECHANISM_INFO;
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSlotID               CK_SLOT_ID slotID
- * @param   jlong jType                 CK_MECHANISM_TYPE type
- * @return  jobject jMechanismInfo      CK_MECHANISM_INFO_PTR pInfo
- */
-JNIEXPORT jobject JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo
-(JNIEnv *env, jobject obj, jlong jSlotID, jlong jType)
-{
-    CK_SLOT_ID ckSlotID;
-    CK_MECHANISM_TYPE ckMechanismType;
-    CK_MECHANISM_INFO ckMechanismInfo;
-    jobject jMechanismInfo = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSlotID = jLongToCKULong(jSlotID);
-    ckMechanismType = jLongToCKULong(jType);
-
-    rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType,
-                                             &ckMechanismInfo);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo);
-    }
-    return jMechanismInfo ;
-}
-
-/*
- * converts a pointer to a CK_MECHANISM_INFO structure into a Java
- * CK_MECHANISM_INFO Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure
- * @return - the new Java CK_MECHANISM_INFO object
- */
-jobject
-ckMechanismInfoPtrToJMechanismInfo
-(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo)
-{
-
-    jclass jMechanismInfoClass;
-    jmethodID jCtrId;
-    jobject jMechanismInfoObject;
-    jlong jMinKeySize;
-    jlong jMaxKeySize;
-    jlong jFlags;
-
-    /* load CK_MECHANISM_INFO class */
-    jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO);
-    if (jMechanismInfoClass == NULL) { return NULL; };
-
-    /* load CK_MECHANISM_INFO constructor */
-    jCtrId = (*env)->GetMethodID(env, jMechanismInfoClass, "<init>", "(JJJ)V");
-    if (jCtrId == NULL) { return NULL; };
-
-    /* prep all fields */
-    jMinKeySize = ckULongToJLong(ckpMechanismInfo->ulMinKeySize);
-    jMaxKeySize = ckULongToJLong(ckpMechanismInfo->ulMaxKeySize);
-    jFlags = ckULongToJLong(ckpMechanismInfo->flags);
-
-    /* create new CK_MECHANISM_INFO object */
-    jMechanismInfoObject = (*env)->NewObject(env, jMechanismInfoClass, jCtrId,
-                                             jMinKeySize, jMaxKeySize, jFlags);
-    if (jMechanismInfoObject == NULL) { return NULL; };
-
-    /* free local references */
-    (*env)->DeleteLocalRef(env, jMechanismInfoClass);
-
-    return jMechanismInfoObject ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_INITTOKEN
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_InitToken
- * Signature: (J[C[C)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSlotID               CK_SLOT_ID slotID
- * @param   jcharArray jPin             CK_CHAR_PTR pPin
- *                                      CK_ULONG ulPinLen
- * @param   jcharArray jLabel           CK_UTF8CHAR_PTR pLabel
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken
-(JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel)
-{
-    CK_SLOT_ID ckSlotID;
-    CK_CHAR_PTR ckpPin = NULL_PTR;
-    CK_UTF8CHAR_PTR ckpLabel = NULL_PTR;
-    CK_ULONG ckPinLength;
-    CK_ULONG ckLabelLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSlotID = jLongToCKULong(jSlotID);
-    jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-    /* ckLabelLength <= 32 !!! */
-    jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength);
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckpPin);
-        return;
-    }
-
-    rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel);
-    TRACE1("InitToken return code: %d", rv);
-
-    free(ckpPin);
-    free(ckpLabel);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_INITPIN
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_InitPIN
- * Signature: (J[C)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE
- * @param   jcharArray jPin             CK_CHAR_PTR pPin
- *                                      CK_ULONG ulPinLen
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN
-(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_CHAR_PTR ckpPin = NULL_PTR;
-    CK_ULONG ckPinLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength);
-
-    free(ckpPin);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_SETPIN
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SetPIN
- * Signature: (J[C[C)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jcharArray jOldPin          CK_CHAR_PTR pOldPin
- *                                      CK_ULONG ulOldLen
- * @param   jcharArray jNewPin          CK_CHAR_PTR pNewPin
- *                                      CK_ULONG ulNewLen
- */
-JNIEXPORT void JNICALL
-Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN
-(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin,
-jcharArray jNewPin)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_CHAR_PTR ckpOldPin = NULL_PTR;
-    CK_CHAR_PTR ckpNewPin = NULL_PTR;
-    CK_ULONG ckOldPinLength;
-    CK_ULONG ckNewPinLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-    jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength);
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckpOldPin);
-        return;
-    }
-
-    rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength,
-                                   ckpNewPin, ckNewPinLength);
-
-    free(ckpOldPin);
-    free(ckpNewPin);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,773 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-#ifdef P11_ENABLE_C_GENERATEKEY
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GenerateKey
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
- *                                      CK_ULONG ulCount
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
- */
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKey
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jobjectArray jTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
-    CK_ULONG ckAttributesLength;
-    CK_OBJECT_HANDLE ckKeyHandle = 0;
-    jlong jKeyHandle = 0L;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0L; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return 0L ; }
-
-    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
-    if ((*env)->ExceptionCheck(env)) {
-        if (ckMechanism.pParameter != NULL_PTR) {
-            free(ckMechanism.pParameter);
-        }
-        return 0L;
-    }
-
-    rv = (*ckpFunctions->C_GenerateKey)(ckSessionHandle, &ckMechanism, ckpAttributes, ckAttributesLength, &ckKeyHandle);
-
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jKeyHandle = ckULongToJLong(ckKeyHandle);
-
-        /* cheack, if we must give a initialization vector back to Java */
-        switch (ckMechanism.mechanism) {
-        case CKM_PBE_MD2_DES_CBC:
-        case CKM_PBE_MD5_DES_CBC:
-        case CKM_PBE_MD5_CAST_CBC:
-        case CKM_PBE_MD5_CAST3_CBC:
-        case CKM_PBE_MD5_CAST128_CBC:
-        /* case CKM_PBE_MD5_CAST5_CBC:  the same as CKM_PBE_MD5_CAST128_CBC */
-        case CKM_PBE_SHA1_CAST128_CBC:
-        /* case CKM_PBE_SHA1_CAST5_CBC: the same as CKM_PBE_SHA1_CAST128_CBC */
-            /* we must copy back the initialization vector to the jMechanism object */
-            copyBackPBEInitializationVector(env, &ckMechanism, jMechanism);
-            break;
-        }
-    }
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-
-    return jKeyHandle ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_GENERATEKEYPAIR
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GenerateKeyPair
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[J
- * Parametermapping:                          *PKCS11*
- * @param   jlong jSessionHandle              CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism                CK_MECHANISM_PTR pMechanism
- * @param   jobjectArray jPublicKeyTemplate   CK_ATTRIBUTE_PTR pPublicKeyTemplate
- *                                            CK_ULONG ulPublicKeyAttributeCount
- * @param   jobjectArray jPrivateKeyTemplate  CK_ATTRIBUTE_PTR pPrivateKeyTemplate
- *                                            CK_ULONG ulPrivateKeyAttributeCount
- * @return  jlongArray jKeyHandles            CK_OBJECT_HANDLE_PTR phPublicKey
- *                                            CK_OBJECT_HANDLE_PTR phPublicKey
- */
-JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKeyPair
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism,
-     jobjectArray jPublicKeyTemplate, jobjectArray jPrivateKeyTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_ATTRIBUTE_PTR ckpPublicKeyAttributes = NULL_PTR;
-    CK_ATTRIBUTE_PTR ckpPrivateKeyAttributes = NULL_PTR;
-    CK_ULONG ckPublicKeyAttributesLength;
-    CK_ULONG ckPrivateKeyAttributesLength;
-    CK_OBJECT_HANDLE_PTR ckpPublicKeyHandle;  /* pointer to Public Key */
-    CK_OBJECT_HANDLE_PTR ckpPrivateKeyHandle; /* pointer to Private Key */
-    CK_OBJECT_HANDLE_PTR ckpKeyHandles;     /* pointer to array with Public and Private Key */
-    jlongArray jKeyHandles = NULL;
-    CK_RV rv;
-    int attempts;
-    const int MAX_ATTEMPTS = 3;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return NULL; }
-
-    ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) malloc(2 * sizeof(CK_OBJECT_HANDLE));
-    if (ckpKeyHandles == NULL) {
-        if (ckMechanism.pParameter != NULL_PTR) {
-            free(ckMechanism.pParameter);
-        }
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    ckpPublicKeyHandle = ckpKeyHandles;   /* first element of array is Public Key */
-    ckpPrivateKeyHandle = (ckpKeyHandles + 1);  /* second element of array is Private Key */
-
-    jAttributeArrayToCKAttributeArray(env, jPublicKeyTemplate, &ckpPublicKeyAttributes, &ckPublicKeyAttributesLength);
-    if ((*env)->ExceptionCheck(env)) {
-        if (ckMechanism.pParameter != NULL_PTR) {
-            free(ckMechanism.pParameter);
-        }
-        free(ckpKeyHandles);
-        return NULL;
-    }
-
-    jAttributeArrayToCKAttributeArray(env, jPrivateKeyTemplate, &ckpPrivateKeyAttributes, &ckPrivateKeyAttributesLength);
-    if ((*env)->ExceptionCheck(env)) {
-        if (ckMechanism.pParameter != NULL_PTR) {
-            free(ckMechanism.pParameter);
-        }
-        free(ckpKeyHandles);
-        freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
-        return NULL;
-    }
-
-    /*
-     * Workaround for NSS bug 1012786:
-     *
-     * Key generation may fail with CKR_FUNCTION_FAILED error
-     * if there is insufficient entropy to generate a random key.
-     *
-     * PKCS11 spec says the following about CKR_FUNCTION_FAILED error
-     * (see section 11.1.1):
-     *
-     *      ... In any event, although the function call failed, the situation
-     *      is not necessarily totally hopeless, as it is likely to be
-     *      when CKR_GENERAL_ERROR is returned. Depending on what the root cause of
-     *      the error actually was, it is possible that an attempt
-     *      to make the exact same function call again would succeed.
-     *
-     * Call C_GenerateKeyPair() several times if CKR_FUNCTION_FAILED occurs.
-     */
-    for (attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {
-        rv = (*ckpFunctions->C_GenerateKeyPair)(ckSessionHandle, &ckMechanism,
-                        ckpPublicKeyAttributes, ckPublicKeyAttributesLength,
-                        ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength,
-                        ckpPublicKeyHandle, ckpPrivateKeyHandle);
-        if (rv == CKR_FUNCTION_FAILED) {
-            printDebug("C_1GenerateKeyPair(): C_GenerateKeyPair() failed \
-                    with CKR_FUNCTION_FAILED error, try again\n");
-        } else {
-            break;
-        }
-    }
-
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jKeyHandles = ckULongArrayToJLongArray(env, ckpKeyHandles, 2);
-    }
-
-    if(ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-    free(ckpKeyHandles);
-    freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
-    freeCKAttributeArray(ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength);
-
-    return jKeyHandles ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_WRAPKEY
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_WrapKey
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;JJ)[B
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @param   jlong jWrappingKeyHandle    CK_OBJECT_HANDLE hWrappingKey
- * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
- * @return  jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
- *                                      CK_ULONG_PTR pulWrappedKeyLen
- */
-JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1WrapKey
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jWrappingKeyHandle, jlong jKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckWrappingKeyHandle;
-    CK_OBJECT_HANDLE ckKeyHandle;
-    jbyteArray jWrappedKey = NULL;
-    CK_RV rv;
-    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
-    CK_BYTE_PTR ckpWrappedKey = BUF;
-    CK_ULONG ckWrappedKeyLength = MAX_STACK_BUFFER_LEN;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return NULL; }
-
-    ckWrappingKeyHandle = jLongToCKULong(jWrappingKeyHandle);
-    ckKeyHandle = jLongToCKULong(jKeyHandle);
-
-    rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
-    if (rv == CKR_BUFFER_TOO_SMALL) {
-        ckpWrappedKey = (CK_BYTE_PTR) malloc(ckWrappedKeyLength);
-        if (ckpWrappedKey == NULL) {
-            if (ckMechanism.pParameter != NULL_PTR) {
-                free(ckMechanism.pParameter);
-            }
-            throwOutOfMemoryError(env, 0);
-            return NULL;
-        }
-
-        rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
-    }
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jWrappedKey = ckByteArrayToJByteArray(env, ckpWrappedKey, ckWrappedKeyLength);
-    }
-
-    if (ckpWrappedKey != BUF) { free(ckpWrappedKey); }
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-    return jWrappedKey ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_UNWRAPKEY
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_UnwrapKey
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[B[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @param   jlong jUnwrappingKeyHandle  CK_OBJECT_HANDLE hUnwrappingKey
- * @param   jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
- *                                      CK_ULONG_PTR pulWrappedKeyLen
- * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
- *                                      CK_ULONG ulCount
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
- */
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1UnwrapKey
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jUnwrappingKeyHandle,
-     jbyteArray jWrappedKey, jobjectArray jTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckUnwrappingKeyHandle;
-    CK_BYTE_PTR ckpWrappedKey = NULL_PTR;
-    CK_ULONG ckWrappedKeyLength;
-    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
-    CK_ULONG ckAttributesLength;
-    CK_OBJECT_HANDLE ckKeyHandle = 0;
-    jlong jKeyHandle = 0L;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0L; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return 0L; }
-
-    ckUnwrappingKeyHandle = jLongToCKULong(jUnwrappingKeyHandle);
-    jByteArrayToCKByteArray(env, jWrappedKey, &ckpWrappedKey, &ckWrappedKeyLength);
-    if ((*env)->ExceptionCheck(env)) {
-        if (ckMechanism.pParameter != NULL_PTR) {
-            free(ckMechanism.pParameter);
-        }
-        return 0L;
-    }
-
-    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
-    if ((*env)->ExceptionCheck(env)) {
-        if (ckMechanism.pParameter != NULL_PTR) {
-            free(ckMechanism.pParameter);
-        }
-        free(ckpWrappedKey);
-        return 0L;
-    }
-
-
-    rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism, ckUnwrappingKeyHandle,
-                 ckpWrappedKey, ckWrappedKeyLength,
-                 ckpAttributes, ckAttributesLength, &ckKeyHandle);
-
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jKeyHandle = ckLongToJLong(ckKeyHandle);
-
-#if 0
-        /* cheack, if we must give a initialization vector back to Java */
-        if (ckMechanism.mechanism == CKM_KEY_WRAP_SET_OAEP) {
-            /* we must copy back the unwrapped key info to the jMechanism object */
-            copyBackSetUnwrappedKey(env, &ckMechanism, jMechanism);
-        }
-#endif
-    }
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-    free(ckpWrappedKey);
-
-    return jKeyHandle ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_DERIVEKEY
-
-void freeMasterKeyDeriveParams(CK_MECHANISM_PTR ckMechanism) {
-    CK_SSL3_MASTER_KEY_DERIVE_PARAMS *params = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
-    if (params == NULL) {
-        return;
-    }
-
-    if (params->RandomInfo.pClientRandom != NULL) {
-        free(params->RandomInfo.pClientRandom);
-    }
-    if (params->RandomInfo.pServerRandom != NULL) {
-        free(params->RandomInfo.pServerRandom);
-    }
-    if (params->pVersion != NULL) {
-        free(params->pVersion);
-    }
-}
-
-void freeEcdh1DeriveParams(CK_MECHANISM_PTR ckMechanism) {
-    CK_ECDH1_DERIVE_PARAMS *params = (CK_ECDH1_DERIVE_PARAMS *) ckMechanism->pParameter;
-    if (params == NULL) {
-        return;
-    }
-
-    if (params->pSharedData != NULL) {
-        free(params->pSharedData);
-    }
-    if (params->pPublicData != NULL) {
-        free(params->pPublicData);
-    }
-}
-
-/*
- * Copy back the PRF output to Java.
- */
-void copyBackTLSPrfParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
-{
-    jclass jMechanismClass, jTLSPrfParamsClass;
-    CK_TLS_PRF_PARAMS *ckTLSPrfParams;
-    jobject jTLSPrfParams;
-    jfieldID fieldID;
-    CK_MECHANISM_TYPE ckMechanismType;
-    jlong jMechanismType;
-    CK_BYTE_PTR output;
-    jobject jOutput;
-    jint jLength;
-    jbyte* jBytes;
-    int i;
-
-    /* get mechanism */
-    jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
-    if (jMechanismClass == NULL) { return; }
-    fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
-    if (fieldID == NULL) { return; }
-    jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
-    ckMechanismType = jLongToCKULong(jMechanismType);
-    if (ckMechanismType != ckMechanism->mechanism) {
-        /* we do not have maching types, this should not occur */
-        return;
-    }
-
-    /* get the native CK_TLS_PRF_PARAMS */
-    ckTLSPrfParams = (CK_TLS_PRF_PARAMS *) ckMechanism->pParameter;
-    if (ckTLSPrfParams != NULL_PTR) {
-        /* get the Java CK_TLS_PRF_PARAMS object (pParameter) */
-        fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
-        if (fieldID == NULL) { return; }
-        jTLSPrfParams = (*env)->GetObjectField(env, jMechanism, fieldID);
-
-        /* copy back the client IV */
-        jTLSPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
-        if (jTLSPrfParamsClass == NULL) { return; }
-        fieldID = (*env)->GetFieldID(env, jTLSPrfParamsClass, "pOutput", "[B");
-        if (fieldID == NULL) { return; }
-        jOutput = (*env)->GetObjectField(env, jTLSPrfParams, fieldID);
-        output = ckTLSPrfParams->pOutput;
-
-        // Note: we assume that the token returned exactly as many bytes as we
-        // requested. Anything else would not make sense.
-        if (jOutput != NULL) {
-            jLength = (*env)->GetArrayLength(env, jOutput);
-            jBytes = (*env)->GetByteArrayElements(env, jOutput, NULL);
-            if (jBytes == NULL) { return; }
-
-            /* copy the bytes to the Java buffer */
-            for (i=0; i < jLength; i++) {
-                jBytes[i] = ckByteToJByte(output[i]);
-            }
-            /* copy back the Java buffer to the object */
-            (*env)->ReleaseByteArrayElements(env, jOutput, jBytes, 0);
-        }
-
-        // free malloc'd data
-        free(ckTLSPrfParams->pSeed);
-        free(ckTLSPrfParams->pLabel);
-        free(ckTLSPrfParams->pulOutputLen);
-        free(ckTLSPrfParams->pOutput);
-    }
-}
-
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DeriveKey
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @param   jlong jBaseKeyHandle        CK_OBJECT_HANDLE hBaseKey
- * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
- *                                      CK_ULONG ulCount
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
- */
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DeriveKey
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jBaseKeyHandle, jobjectArray jTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckBaseKeyHandle;
-    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
-    CK_ULONG ckAttributesLength;
-    CK_OBJECT_HANDLE ckKeyHandle = 0;
-    jlong jKeyHandle = 0L;
-    CK_RV rv;
-    CK_OBJECT_HANDLE_PTR phKey = &ckKeyHandle;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0L; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return 0L; }
-
-    ckBaseKeyHandle = jLongToCKULong(jBaseKeyHandle);
-    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
-    if ((*env)->ExceptionCheck(env)) {
-        if (ckMechanism.pParameter != NULL_PTR) {
-            free(ckMechanism.pParameter);
-        }
-        return 0L;
-    }
-
-    switch (ckMechanism.mechanism) {
-    case CKM_SSL3_KEY_AND_MAC_DERIVE:
-    case CKM_TLS_KEY_AND_MAC_DERIVE:
-    case CKM_TLS_PRF:
-        // these mechanism do not return a key handle via phKey
-        // set to NULL in case pedantic implementations check for it
-        phKey = NULL;
-        break;
-    default:
-        // empty
-        break;
-    }
-
-    rv = (*ckpFunctions->C_DeriveKey)(ckSessionHandle, &ckMechanism, ckBaseKeyHandle,
-                 ckpAttributes, ckAttributesLength, phKey);
-
-    jKeyHandle = ckLongToJLong(ckKeyHandle);
-
-    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-
-    switch (ckMechanism.mechanism) {
-    case CKM_SSL3_MASTER_KEY_DERIVE:
-    case CKM_TLS_MASTER_KEY_DERIVE:
-        /* we must copy back the client version */
-        copyBackClientVersion(env, &ckMechanism, jMechanism);
-        freeMasterKeyDeriveParams(&ckMechanism);
-        break;
-    case CKM_SSL3_MASTER_KEY_DERIVE_DH:
-    case CKM_TLS_MASTER_KEY_DERIVE_DH:
-        freeMasterKeyDeriveParams(&ckMechanism);
-        break;
-    case CKM_SSL3_KEY_AND_MAC_DERIVE:
-    case CKM_TLS_KEY_AND_MAC_DERIVE:
-        /* we must copy back the unwrapped key info to the jMechanism object */
-        copyBackSSLKeyMatParams(env, &ckMechanism, jMechanism);
-        break;
-    case CKM_TLS_PRF:
-        copyBackTLSPrfParams(env, &ckMechanism, jMechanism);
-        break;
-    case CKM_ECDH1_DERIVE:
-        freeEcdh1DeriveParams(&ckMechanism);
-        break;
-    default:
-        // empty
-        break;
-    }
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
-
-    return jKeyHandle ;
-}
-
-/*
- * Copy back the client version information from the native
- * structure to the Java object. This is only used for the
- * CKM_SSL3_MASTER_KEY_DERIVE mechanism when used for deriving a key.
- *
- */
-void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
-{
-  jclass jMechanismClass, jSSL3MasterKeyDeriveParamsClass, jVersionClass;
-  CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams;
-  CK_VERSION *ckVersion;
-  jfieldID fieldID;
-  CK_MECHANISM_TYPE ckMechanismType;
-  jlong jMechanismType;
-  jobject jSSL3MasterKeyDeriveParams;
-  jobject jVersion;
-
-  /* get mechanism */
-  jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
-  if (jMechanismClass == NULL) { return; }
-  fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
-  if (fieldID == NULL) { return; }
-  jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
-  ckMechanismType = jLongToCKULong(jMechanismType);
-  if (ckMechanismType != ckMechanism->mechanism) {
-    /* we do not have maching types, this should not occur */
-    return;
-  }
-
-  /* get the native CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
-  ckSSL3MasterKeyDeriveParams = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
-  if (ckSSL3MasterKeyDeriveParams != NULL_PTR) {
-    /* get the native CK_VERSION */
-    ckVersion = ckSSL3MasterKeyDeriveParams->pVersion;
-    if (ckVersion != NULL_PTR) {
-      /* get the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS (pParameter) */
-      fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
-      if (fieldID == NULL) { return; }
-
-      jSSL3MasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID);
-
-      /* get the Java CK_VERSION */
-      jSSL3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
-      if (jSSL3MasterKeyDeriveParamsClass == NULL) { return; }
-      fieldID = (*env)->GetFieldID(env, jSSL3MasterKeyDeriveParamsClass, "pVersion", "L"CLASS_VERSION";");
-      if (fieldID == NULL) { return; }
-      jVersion = (*env)->GetObjectField(env, jSSL3MasterKeyDeriveParams, fieldID);
-
-      /* now copy back the version from the native structure to the Java structure */
-
-      /* copy back the major version */
-      jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
-      if (jVersionClass == NULL) { return; }
-      fieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
-      if (fieldID == NULL) { return; }
-      (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->major));
-
-      /* copy back the minor version */
-      fieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
-      if (fieldID == NULL) { return; }
-      (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->minor));
-    }
-  }
-}
-
-
-/*
- * Copy back the derived keys and initialization vectors from the native
- * structure to the Java object. This is only used for the
- * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key.
- *
- */
-void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
-{
-  jclass jMechanismClass, jSSL3KeyMatParamsClass, jSSL3KeyMatOutClass;
-  CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam;
-  CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut;
-  jfieldID fieldID;
-  CK_MECHANISM_TYPE ckMechanismType;
-  jlong jMechanismType;
-  CK_BYTE_PTR iv;
-  jobject jSSL3KeyMatParam;
-  jobject jSSL3KeyMatOut;
-  jobject jIV;
-  jint jLength;
-  jbyte* jBytes;
-  int i;
-
-  /* get mechanism */
-  jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
-  if (jMechanismClass == NULL) { return; }
-  fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
-  if (fieldID == NULL) { return; }
-  jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
-  ckMechanismType = jLongToCKULong(jMechanismType);
-  if (ckMechanismType != ckMechanism->mechanism) {
-    /* we do not have maching types, this should not occur */
-    return;
-  }
-
-  /* get the native CK_SSL3_KEY_MAT_PARAMS */
-  ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter;
-  if (ckSSL3KeyMatParam != NULL_PTR) {
-    // free malloc'd data
-    if (ckSSL3KeyMatParam->RandomInfo.pClientRandom != NULL) {
-        free(ckSSL3KeyMatParam->RandomInfo.pClientRandom);
-    }
-    if (ckSSL3KeyMatParam->RandomInfo.pServerRandom != NULL) {
-        free(ckSSL3KeyMatParam->RandomInfo.pServerRandom);
-    }
-
-    /* get the native CK_SSL3_KEY_MAT_OUT */
-    ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial;
-    if (ckSSL3KeyMatOut != NULL_PTR) {
-      /* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */
-      fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
-      if (fieldID == NULL) { return; }
-      jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID);
-
-      /* get the Java CK_SSL3_KEY_MAT_OUT */
-      jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
-      if (jSSL3KeyMatParamsClass == NULL) { return; }
-      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";");
-      if (fieldID == NULL) { return; }
-      jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID);
-
-      /* now copy back all the key handles and the initialization vectors */
-      /* copy back client MAC secret handle */
-      jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
-      if (jSSL3KeyMatOutClass == NULL) { return; }
-      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J");
-      if (fieldID == NULL) { return; }
-      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret));
-
-      /* copy back server MAC secret handle */
-      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J");
-      if (fieldID == NULL) { return; }
-      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret));
-
-      /* copy back client secret key handle */
-      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J");
-      if (fieldID == NULL) { return; }
-      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey));
-
-      /* copy back server secret key handle */
-      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J");
-      if (fieldID == NULL) { return; }
-      (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey));
-
-      /* copy back the client IV */
-      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B");
-      if (fieldID == NULL) { return; }
-      jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
-      iv = ckSSL3KeyMatOut->pIVClient;
-
-      if (jIV != NULL) {
-        jLength = (*env)->GetArrayLength(env, jIV);
-        jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
-        if (jBytes == NULL) { return; }
-        /* copy the bytes to the Java buffer */
-        for (i=0; i < jLength; i++) {
-          jBytes[i] = ckByteToJByte(iv[i]);
-        }
-        /* copy back the Java buffer to the object */
-        (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
-      }
-      // free malloc'd data
-      free(ckSSL3KeyMatOut->pIVClient);
-
-      /* copy back the server IV */
-      fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B");
-      if (fieldID == NULL) { return; }
-      jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
-      iv = ckSSL3KeyMatOut->pIVServer;
-
-      if (jIV != NULL) {
-        jLength = (*env)->GetArrayLength(env, jIV);
-        jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
-        if (jBytes == NULL) { return; }
-        /* copy the bytes to the Java buffer */
-        for (i=0; i < jLength; i++) {
-          jBytes[i] = ckByteToJByte(iv[i]);
-        }
-        /* copy back the Java buffer to the object */
-        (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
-      }
-      // free malloc'd data
-      free(ckSSL3KeyMatOut->pIVServer);
-      free(ckSSL3KeyMatOut);
-    }
-  }
-}
-
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,552 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-/* The initArgs that enable the application to do custom mutex-handling */
-#ifndef NO_CALLBACKS
-jobject jInitArgsObject;
-CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs;
-#endif /* NO_CALLBACKS */
-
-/* ************************************************************************** */
-/* Now come the functions for mutex handling and notification callbacks       */
-/* ************************************************************************** */
-
-/*
- * converts the InitArgs object to a CK_C_INITIALIZE_ARGS structure and sets the functions
- * that will call the right Java mutex functions
- *
- * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
- * @param pInitArgs - the InitArgs object with the Java mutex functions to call
- * @return - the pointer to the CK_C_INITIALIZE_ARGS structure with the functions that will call
- *           the corresponding Java functions
- */
-CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject jInitArgs)
-{
-    CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
-    jclass jInitArgsClass;
-    jfieldID fieldID;
-    jlong jFlags;
-    jobject jReserved;
-    CK_ULONG ckReservedLength;
-#ifndef NO_CALLBACKS
-    jobject jMutexHandler;
-#endif /* NO_CALLBACKS */
-
-    if(jInitArgs == NULL) {
-        return NULL_PTR;
-    }
-
-    /* convert the Java InitArgs object to a pointer to a CK_C_INITIALIZE_ARGS structure */
-    ckpInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS));
-    if (ckpInitArgs == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL_PTR;
-    }
-    ckpInitArgs->flags = (CK_FLAGS)0;
-    ckpInitArgs->pReserved = (CK_VOID_PTR)NULL;
-
-    /* Set the mutex functions that will call the Java mutex functions, but
-     * only set it, if the field is not null.
-     */
-    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
-    if (jInitArgsClass == NULL) {
-        free(ckpInitArgs);
-        return NULL;
-    }
-
-#ifdef NO_CALLBACKS
-    ckpInitArgs->CreateMutex = NULL_PTR;
-    ckpInitArgs->DestroyMutex = NULL_PTR;
-    ckpInitArgs->LockMutex = NULL_PTR;
-    ckpInitArgs->UnlockMutex = NULL_PTR;
-#else
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;");
-    if (fieldID == NULL) {
-        free(ckpInitArgs);
-        return NULL;
-    }
-    jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
-    ckpInitArgs->CreateMutex = (jMutexHandler != NULL) ? &callJCreateMutex : NULL_PTR;
-
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;");
-    if (fieldID == NULL) {
-        free(ckpInitArgs);
-        return NULL;
-    }
-    jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
-    ckpInitArgs->DestroyMutex = (jMutexHandler != NULL) ? &callJDestroyMutex : NULL_PTR;
-
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;");
-    if (fieldID == NULL) {
-        free(ckpInitArgs);
-        return NULL;
-    }
-    jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
-    ckpInitArgs->LockMutex = (jMutexHandler != NULL) ? &callJLockMutex : NULL_PTR;
-
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;");
-    if (fieldID == NULL) {
-        free(ckpInitArgs);
-        return NULL;
-    }
-    jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
-    ckpInitArgs->UnlockMutex = (jMutexHandler != NULL) ? &callJUnlockMutex : NULL_PTR;
-
-    if ((ckpInitArgs->CreateMutex != NULL_PTR)
-            || (ckpInitArgs->DestroyMutex != NULL_PTR)
-            || (ckpInitArgs->LockMutex != NULL_PTR)
-            || (ckpInitArgs->UnlockMutex != NULL_PTR)) {
-        /* we only need to keep a global copy, if we need callbacks */
-        /* set the global object jInitArgs so that the right Java mutex functions will be called */
-        jInitArgsObject = (*env)->NewGlobalRef(env, jInitArgs);
-        ckpGlobalInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS));
-        if (ckpGlobalInitArgs == NULL) {
-            free(ckpInitArgs);
-            throwOutOfMemoryError(env, 0);
-            return NULL_PTR;
-        }
-
-        memcpy(ckpGlobalInitArgs, ckpInitArgs, sizeof(CK_C_INITIALIZE_ARGS));
-    }
-#endif /* NO_CALLBACKS */
-
-    /* convert and set the flags field */
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "flags", "J");
-    if (fieldID == NULL) {
-        free(ckpInitArgs);
-        return NULL;
-    }
-    jFlags = (*env)->GetLongField(env, jInitArgs, fieldID);
-    ckpInitArgs->flags = jLongToCKULong(jFlags);
-
-    /* pReserved should be NULL_PTR in this version */
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "pReserved", "Ljava/lang/Object;");
-    if (fieldID == NULL) {
-        free(ckpInitArgs);
-        return NULL;
-    }
-    jReserved = (*env)->GetObjectField(env, jInitArgs, fieldID);
-
-    /* we try to convert the reserved parameter also */
-    jObjectToPrimitiveCKObjectPtrPtr(env, jReserved, &(ckpInitArgs->pReserved), &ckReservedLength);
-
-    return ckpInitArgs ;
-}
-
-#ifndef NO_CALLBACKS
-
-/*
- * is the function that gets called by PKCS#11 to create a mutex and calls the Java
- * CreateMutex function
- *
- * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
- * @param ppMutex - the new created mutex
- * @return - should return CKR_OK if the mutex creation was ok
- */
-CK_RV callJCreateMutex(CK_VOID_PTR_PTR ppMutex)
-{
-    extern JavaVM *jvm;
-    JNIEnv *env;
-    jint returnValue;
-    jthrowable pkcs11Exception;
-    jclass pkcs11ExceptionClass;
-    jlong errorCode;
-    CK_RV rv = CKR_OK;
-    int wasAttached = 1;
-    jclass jCreateMutexClass;
-    jclass jInitArgsClass;
-    jmethodID methodID;
-    jfieldID fieldID;
-    jobject jCreateMutex;
-    jobject jMutex;
-
-
-    /* Get the currently running Java VM */
-    if (jvm == NULL) { return rv ;} /* there is no VM running */
-
-    /* Determine, if current thread is already attached */
-    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
-    if (returnValue == JNI_EDETACHED) {
-        /* thread detached, so attach it */
-        wasAttached = 0;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else if (returnValue == JNI_EVERSION) {
-        /* this version of JNI is not supported, so just try to attach */
-        /* we assume it was attached to ensure that this thread is not detached
-         * afterwards even though it should not
-         */
-        wasAttached = 1;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else {
-        /* attached */
-        wasAttached = 1;
-    }
-
-    jCreateMutexClass = (*env)->FindClass(env, CLASS_CREATEMUTEX);
-    if (jCreateMutexClass == NULL) { return rv; }
-    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
-    if (jInitArgsClass == NULL) { return rv; }
-
-    /* get the CreateMutex object out of the jInitArgs object */
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;");
-    if (fieldID == NULL) { return rv; }
-    jCreateMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
-    assert(jCreateMutex != 0);
-
-    /* call the CK_CREATEMUTEX function of the CreateMutex object */
-    /* and get the new Java mutex object */
-    methodID = (*env)->GetMethodID(env, jCreateMutexClass, "CK_CREATEMUTEX", "()Ljava/lang/Object;");
-    if (methodID == NULL) { return rv; }
-    jMutex = (*env)->CallObjectMethod(env, jCreateMutex, methodID);
-
-    /* set a global reference on the Java mutex */
-    jMutex = (*env)->NewGlobalRef(env, jMutex);
-    /* convert the Java mutex to a CK mutex */
-    *ppMutex = jObjectToCKVoidPtr(jMutex);
-
-
-    /* check, if callback threw an exception */
-    pkcs11Exception = (*env)->ExceptionOccurred(env);
-
-    if (pkcs11Exception != NULL) {
-        /* TBD: clear the pending exception with ExceptionClear? */
-        /* The was an exception thrown, now we get the error-code from it */
-        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
-        if (pkcs11ExceptionClass == NULL) { return rv; }
-        methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
-        if (methodID == NULL) { return rv; }
-
-        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
-        rv = jLongToCKULong(errorCode);
-    }
-
-    /* if we attached this thread to the VM just for callback, we detach it now */
-    if (wasAttached) {
-        returnValue = (*jvm)->DetachCurrentThread(jvm);
-    }
-
-    return rv ;
-}
-
-/*
- * is the function that gets called by PKCS#11 to destroy a mutex and calls the Java
- * DestroyMutex function
- *
- * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
- * @param pMutex - the mutex to destroy
- * @return - should return CKR_OK if the mutex was destroyed
- */
-CK_RV callJDestroyMutex(CK_VOID_PTR pMutex)
-{
-    extern JavaVM *jvm;
-    JNIEnv *env;
-    jint returnValue;
-    jthrowable pkcs11Exception;
-    jclass pkcs11ExceptionClass;
-    jlong errorCode;
-    CK_RV rv = CKR_OK;
-    int wasAttached = 1;
-    jclass jDestroyMutexClass;
-    jclass jInitArgsClass;
-    jmethodID methodID;
-    jfieldID fieldID;
-    jobject jDestroyMutex;
-    jobject jMutex;
-
-
-    /* Get the currently running Java VM */
-    if (jvm == NULL) { return rv ; } /* there is no VM running */
-
-    /* Determine, if current thread is already attached */
-    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
-    if (returnValue == JNI_EDETACHED) {
-        /* thread detached, so attach it */
-        wasAttached = 0;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else if (returnValue == JNI_EVERSION) {
-        /* this version of JNI is not supported, so just try to attach */
-        /* we assume it was attached to ensure that this thread is not detached
-         * afterwards even though it should not
-         */
-        wasAttached = 1;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else {
-        /* attached */
-        wasAttached = 1;
-    }
-
-    jDestroyMutexClass = (*env)->FindClass(env, CLASS_DESTROYMUTEX);
-    if (jDestroyMutexClass == NULL) { return rv; }
-    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
-    if (jInitArgsClass == NULL) { return rv; }
-
-    /* convert the CK mutex to a Java mutex */
-    jMutex = ckVoidPtrToJObject(pMutex);
-
-    /* get the DestroyMutex object out of the jInitArgs object */
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;");
-    if (fieldID == NULL) { return rv; }
-    jDestroyMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
-    assert(jDestroyMutex != 0);
-
-    /* call the CK_DESTROYMUTEX method of the DestroyMutex object */
-    methodID = (*env)->GetMethodID(env, jDestroyMutexClass, "CK_DESTROYMUTEX", "(Ljava/lang/Object;)V");
-    if (methodID == NULL) { return rv; }
-    (*env)->CallVoidMethod(env, jDestroyMutex, methodID, jMutex);
-
-    /* delete the global reference on the Java mutex */
-    (*env)->DeleteGlobalRef(env, jMutex);
-
-
-    /* check, if callback threw an exception */
-    pkcs11Exception = (*env)->ExceptionOccurred(env);
-
-    if (pkcs11Exception != NULL) {
-        /* TBD: clear the pending exception with ExceptionClear? */
-        /* The was an exception thrown, now we get the error-code from it */
-        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
-        if (pkcs11ExceptionClass == NULL) { return rv; }
-        methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
-        if (methodID == NULL) { return rv; }
-        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
-        rv = jLongToCKULong(errorCode);
-    }
-
-    /* if we attached this thread to the VM just for callback, we detach it now */
-    if (wasAttached) {
-        returnValue = (*jvm)->DetachCurrentThread(jvm);
-    }
-
-    return rv ;
-}
-
-/*
- * is the function that gets called by PKCS#11 to lock a mutex and calls the Java
- * LockMutex function
- *
- * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
- * @param pMutex - the mutex to lock
- * @return - should return CKR_OK if the mutex was not locked already
- */
-CK_RV callJLockMutex(CK_VOID_PTR pMutex)
-{
-    extern JavaVM *jvm;
-    JNIEnv *env;
-    jint returnValue;
-    jthrowable pkcs11Exception;
-    jclass pkcs11ExceptionClass;
-    jlong errorCode;
-    CK_RV rv = CKR_OK;
-    int wasAttached = 1;
-    jclass jLockMutexClass;
-    jclass jInitArgsClass;
-    jmethodID methodID;
-    jfieldID fieldID;
-    jobject jLockMutex;
-    jobject jMutex;
-
-
-    /* Get the currently running Java VM */
-    if (jvm == NULL) { return rv ; } /* there is no VM running */
-
-    /* Determine, if current thread is already attached */
-    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
-    if (returnValue == JNI_EDETACHED) {
-        /* thread detached, so attach it */
-        wasAttached = 0;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else if (returnValue == JNI_EVERSION) {
-        /* this version of JNI is not supported, so just try to attach */
-        /* we assume it was attached to ensure that this thread is not detached
-         * afterwards even though it should not
-         */
-        wasAttached = 1;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else {
-        /* attached */
-        wasAttached = 1;
-    }
-
-    jLockMutexClass = (*env)->FindClass(env, CLASS_LOCKMUTEX);
-    if (jLockMutexClass == NULL) { return rv; }
-    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
-    if (jInitArgsClass == NULL) { return rv; }
-
-    /* convert the CK mutex to a Java mutex */
-    jMutex = ckVoidPtrToJObject(pMutex);
-
-    /* get the LockMutex object out of the jInitArgs object */
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;");
-    if (fieldID == NULL) { return rv; }
-    jLockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
-    assert(jLockMutex != 0);
-
-    /* call the CK_LOCKMUTEX method of the LockMutex object */
-    methodID = (*env)->GetMethodID(env, jLockMutexClass, "CK_LOCKMUTEX", "(Ljava/lang/Object;)V");
-    if (methodID == NULL) { return rv; }
-    (*env)->CallVoidMethod(env, jLockMutex, methodID, jMutex);
-
-    /* check, if callback threw an exception */
-    pkcs11Exception = (*env)->ExceptionOccurred(env);
-
-    if (pkcs11Exception != NULL) {
-        /* TBD: clear the pending exception with ExceptionClear? */
-        /* The was an exception thrown, now we get the error-code from it */
-        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
-        if (pkcs11ExceptionClass == NULL) { return rv; }
-        methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
-        if (methodID == NULL) { return rv; }
-        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
-        rv = jLongToCKULong(errorCode);
-    }
-
-    /* if we attached this thread to the VM just for callback, we detach it now */
-    if (wasAttached) {
-        returnValue = (*jvm)->DetachCurrentThread(jvm);
-    }
-
-    return rv ;
-}
-
-/*
- * is the function that gets called by PKCS#11 to unlock a mutex and calls the Java
- * UnlockMutex function
- *
- * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
- * @param pMutex - the mutex to unlock
- * @return - should return CKR_OK if the mutex was not unlocked already
- */
-CK_RV callJUnlockMutex(CK_VOID_PTR pMutex)
-{
-    extern JavaVM *jvm;
-    JNIEnv *env;
-    jint returnValue;
-    jthrowable pkcs11Exception;
-    jclass pkcs11ExceptionClass;
-    jlong errorCode;
-    CK_RV rv = CKR_OK;
-    int wasAttached = 1;
-    jclass jUnlockMutexClass;
-    jclass jInitArgsClass;
-    jmethodID methodID;
-    jfieldID fieldID;
-    jobject jUnlockMutex;
-    jobject jMutex;
-
-
-    /* Get the currently running Java VM */
-    if (jvm == NULL) { return rv ; } /* there is no VM running */
-
-    /* Determine, if current thread is already attached */
-    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
-    if (returnValue == JNI_EDETACHED) {
-        /* thread detached, so attach it */
-        wasAttached = 0;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else if (returnValue == JNI_EVERSION) {
-        /* this version of JNI is not supported, so just try to attach */
-        /* we assume it was attached to ensure that this thread is not detached
-         * afterwards even though it should not
-         */
-        wasAttached = 1;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else {
-        /* attached */
-        wasAttached = 1;
-    }
-
-    jUnlockMutexClass = (*env)->FindClass(env, CLASS_UNLOCKMUTEX);
-    if (jUnlockMutexClass == NULL) { return rv; }
-    jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
-    if (jInitArgsClass == NULL) { return rv; }
-
-    /* convert the CK-type mutex to a Java mutex */
-    jMutex = ckVoidPtrToJObject(pMutex);
-
-    /* get the UnlockMutex object out of the jInitArgs object */
-    fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;");
-    if (fieldID == NULL) { return rv; }
-    jUnlockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
-    assert(jUnlockMutex != 0);
-
-    /* call the CK_UNLOCKMUTEX method of the UnLockMutex object */
-    methodID = (*env)->GetMethodID(env, jUnlockMutexClass, "CK_UNLOCKMUTEX", "(Ljava/lang/Object;)V");
-    if (methodID == NULL) { return rv; }
-    (*env)->CallVoidMethod(env, jUnlockMutex, methodID, jMutex);
-
-    /* check, if callback threw an exception */
-    pkcs11Exception = (*env)->ExceptionOccurred(env);
-
-    if (pkcs11Exception != NULL) {
-        /* TBD: clear the pending exception with ExceptionClear? */
-        /* The was an exception thrown, now we get the error-code from it */
-        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
-        if (pkcs11ExceptionClass == NULL) { return rv; }
-        methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
-        if (methodID == NULL) { return rv; }
-        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
-        rv = jLongToCKULong(errorCode);
-    }
-
-    /* if we attached this thread to the VM just for callback, we detach it now */
-    if (wasAttached) {
-        returnValue = (*jvm)->DetachCurrentThread(jvm);
-    }
-
-    return rv ;
-}
-
-#endif /* NO_CALLBACKS */
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,429 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-#ifdef P11_ENABLE_C_CREATEOBJECT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_CreateObject
- * Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
- *                                      CK_ULONG ulCount
- * @return  jlong jObjectHandle         CK_OBJECT_HANDLE_PTR phObject
- */
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CreateObject
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_OBJECT_HANDLE ckObjectHandle;
-    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
-    CK_ULONG ckAttributesLength;
-    jlong jObjectHandle = 0L;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0L; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
-    if ((*env)->ExceptionCheck(env)) { return 0L; }
-
-    rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle, ckpAttributes, ckAttributesLength, &ckObjectHandle);
-
-    jObjectHandle = ckULongToJLong(ckObjectHandle);
-    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
-
-    return jObjectHandle ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_COPYOBJECT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_CopyObject
- * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
- * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
- *                                      CK_ULONG ulCount
- * @return  jlong jNewObjectHandle      CK_OBJECT_HANDLE_PTR phNewObject
- */
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CopyObject
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_OBJECT_HANDLE ckObjectHandle;
-    CK_OBJECT_HANDLE ckNewObjectHandle;
-    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
-    CK_ULONG ckAttributesLength;
-    jlong jNewObjectHandle = 0L;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0L; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckObjectHandle = jLongToCKULong(jObjectHandle);
-    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
-    if ((*env)->ExceptionCheck(env)) { return 0L; }
-
-    rv = (*ckpFunctions->C_CopyObject)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength, &ckNewObjectHandle);
-
-    jNewObjectHandle = ckULongToJLong(ckNewObjectHandle);
-    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-
-    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
-
-    return jNewObjectHandle ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_DESTROYOBJECT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_DestroyObject
- * Signature: (JJ)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DestroyObject
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_OBJECT_HANDLE ckObjectHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckObjectHandle = jLongToCKULong(jObjectHandle);
-
-    rv = (*ckpFunctions->C_DestroyObject)(ckSessionHandle, ckObjectHandle);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETOBJECTSIZE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetObjectSize
- * Signature: (JJ)J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
- * @return  jlong jObjectSize           CK_ULONG_PTR pulSize
- */
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetObjectSize
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_OBJECT_HANDLE ckObjectHandle;
-    CK_ULONG ckObjectSize;
-    jlong jObjectSize = 0L;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0L; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckObjectHandle = jLongToCKULong(jObjectHandle);
-
-    rv = (*ckpFunctions->C_GetObjectSize)(ckSessionHandle, ckObjectHandle, &ckObjectSize);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
-
-    jObjectSize = ckULongToJLong(ckObjectSize);
-
-    return jObjectSize ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETATTRIBUTEVALUE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetAttributeValue
- * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
- * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
- *                                      CK_ULONG ulCount
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetAttributeValue
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_OBJECT_HANDLE ckObjectHandle;
-    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
-    CK_ULONG ckAttributesLength;
-    CK_ULONG ckBufferLength;
-    CK_ULONG i;
-    jobject jAttribute;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    TRACE0("DEBUG: C_GetAttributeValue");
-    TRACE1(", hSession=%u", jSessionHandle);
-    TRACE1(", hObject=%u", jObjectHandle);
-    TRACE1(", pTemplate=%p", jTemplate);
-    TRACE0(" ... ");
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckObjectHandle = jLongToCKULong(jObjectHandle);
-    TRACE1("jAttributeArrayToCKAttributeArray now with jTemplate = %d", jTemplate);
-    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    TRACE2("DEBUG: jAttributeArrayToCKAttributeArray finished with ckpAttribute = %d, Length = %d\n", ckpAttributes, ckAttributesLength);
-
-    /* first set all pValue to NULL, to get the needed buffer length */
-    for(i = 0; i < ckAttributesLength; i++) {
-        if (ckpAttributes[i].pValue != NULL_PTR) {
-            free(ckpAttributes[i].pValue);
-            ckpAttributes[i].pValue = NULL_PTR;
-        }
-    }
-
-    rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-        free(ckpAttributes);
-        return ;
-    }
-
-    /* now, the ulValueLength field of each attribute should hold the exact buffer length needed
-     * allocate the needed buffers accordingly
-     */
-    for (i = 0; i < ckAttributesLength; i++) {
-        ckBufferLength = sizeof(CK_BYTE) * ckpAttributes[i].ulValueLen;
-        ckpAttributes[i].pValue = (void *) malloc(ckBufferLength);
-        if (ckpAttributes[i].pValue == NULL) {
-            freeCKAttributeArray(ckpAttributes, i);
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-        ckpAttributes[i].ulValueLen = ckBufferLength;
-    }
-
-    /* now get the attributes with all values */
-    rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
-
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        /* copy back the values to the Java attributes */
-        for (i = 0; i < ckAttributesLength; i++) {
-            jAttribute = ckAttributePtrToJAttribute(env, &(ckpAttributes[i]));
-            if (jAttribute == NULL) {
-                freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-                return;
-            }
-            (*env)->SetObjectArrayElement(env, jTemplate, i, jAttribute);
-            if ((*env)->ExceptionCheck(env)) {
-                freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-                return;
-            }
-        }
-    }
-    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-    TRACE0("FINISHED\n");
-}
-#endif
-
-#ifdef P11_ENABLE_C_SETATTRIBUTEVALUE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SetAttributeValue
- * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
- * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
- *                                      CK_ULONG ulCount
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetAttributeValue
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_OBJECT_HANDLE ckObjectHandle;
-    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
-    CK_ULONG ckAttributesLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckObjectHandle = jLongToCKULong(jObjectHandle);
-    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    rv = (*ckpFunctions->C_SetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
-
-    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-
-    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_FINDOBJECTSINIT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_FindObjectsInit
- * Signature: (J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
- *                                      CK_ULONG ulCount
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsInit
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
-    CK_ULONG ckAttributesLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    TRACE0("DEBUG: C_FindObjectsInit");
-    TRACE1(", hSession=%u", jSessionHandle);
-    TRACE1(", pTemplate=%p", jTemplate);
-    TRACE0(" ... ");
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    rv = (*ckpFunctions->C_FindObjectsInit)(ckSessionHandle, ckpAttributes, ckAttributesLength);
-
-    freeCKAttributeArray(ckpAttributes, ckAttributesLength);
-    TRACE0("FINISHED\n");
-
-    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_FINDOBJECTS
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_FindObjects
- * Signature: (JJ)[J
- * Parametermapping:                        *PKCS11*
- * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
- * @param   jlong jMaxObjectCount           CK_ULONG ulMaxObjectCount
- * @return  jlongArray jObjectHandleArray   CK_OBJECT_HANDLE_PTR phObject
- *                                          CK_ULONG_PTR pulObjectCount
- */
-JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjects
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jMaxObjectCount)
-{
-    CK_RV rv;
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_ULONG ckMaxObjectLength;
-    CK_OBJECT_HANDLE_PTR ckpObjectHandleArray;
-    CK_ULONG ckActualObjectCount;
-    jlongArray jObjectHandleArray = NULL;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckMaxObjectLength = jLongToCKULong(jMaxObjectCount);
-    ckpObjectHandleArray = (CK_OBJECT_HANDLE_PTR) malloc(sizeof(CK_OBJECT_HANDLE) * ckMaxObjectLength);
-    if (ckpObjectHandleArray == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    rv = (*ckpFunctions->C_FindObjects)(ckSessionHandle, ckpObjectHandleArray, ckMaxObjectLength, &ckActualObjectCount);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jObjectHandleArray = ckULongArrayToJLongArray(env, ckpObjectHandleArray, ckActualObjectCount);
-    }
-
-    free(ckpObjectHandleArray);
-
-    return jObjectHandleArray ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_FINDOBJECTSFINAL
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_FindObjectsFinal
- * Signature: (J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsFinal
-    (JNIEnv *env, jobject obj, jlong jSessionHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    rv = (*ckpFunctions->C_FindObjectsFinal)(ckSessionHandle);
-    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,634 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-/* The list of notify callback handles that are currently active and waiting
- * for callbacks from their sessions.
- */
-#ifndef NO_CALLBACKS
-NotifyListNode *notifyListHead = NULL;
-jobject notifyListLock = NULL;
-#endif /* NO_CALLBACKS */
-
-#ifdef P11_ENABLE_C_OPENSESSION
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_OpenSession
- * Signature: (JJLjava/lang/Object;Lsun/security/pkcs11/wrapper/CK_NOTIFY;)J
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSlotID               CK_SLOT_ID slotID
- * @param   jlong jFlags                CK_FLAGS flags
- * @param   jobject jApplication        CK_VOID_PTR pApplication
- * @param   jobject jNotify             CK_NOTIFY Notify
- * @return  jlong jSessionHandle        CK_SESSION_HANDLE_PTR phSession
- */
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1OpenSession
-    (JNIEnv *env, jobject obj, jlong jSlotID, jlong jFlags, jobject jApplication, jobject jNotify)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_SLOT_ID ckSlotID;
-    CK_FLAGS ckFlags;
-    CK_VOID_PTR ckpApplication;
-    CK_NOTIFY ckNotify;
-    jlong jSessionHandle;
-    CK_RV rv;
-#ifndef NO_CALLBACKS
-    NotifyEncapsulation *notifyEncapsulation = NULL;
-#endif /* NO_CALLBACKS */
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0L; }
-
-    ckSlotID = jLongToCKULong(jSlotID);
-    ckFlags = jLongToCKULong(jFlags);
-
-#ifndef NO_CALLBACKS
-    if (jNotify != NULL) {
-        notifyEncapsulation = (NotifyEncapsulation *) malloc(sizeof(NotifyEncapsulation));
-        if (notifyEncapsulation == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return 0L;
-        }
-        notifyEncapsulation->jApplicationData = (jApplication != NULL)
-                ? (*env)->NewGlobalRef(env, jApplication)
-                : NULL;
-        notifyEncapsulation->jNotifyObject = (*env)->NewGlobalRef(env, jNotify);
-        ckpApplication = notifyEncapsulation;
-        ckNotify = (CK_NOTIFY) &notifyCallback;
-    } else {
-        ckpApplication = NULL_PTR;
-        ckNotify = NULL_PTR;
-    }
-#else
-        ckpApplication = NULL_PTR;
-        ckNotify = NULL_PTR;
-#endif /* NO_CALLBACKS */
-
-    TRACE0("DEBUG: C_OpenSession");
-    TRACE1(", slotID=%u", ckSlotID);
-    TRACE1(", flags=%x", ckFlags);
-    TRACE0(" ... ");
-
-    rv = (*ckpFunctions->C_OpenSession)(ckSlotID, ckFlags, ckpApplication, ckNotify, &ckSessionHandle);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-#ifndef NO_CALLBACKS
-        if (notifyEncapsulation != NULL) {
-            if (notifyEncapsulation->jApplicationData != NULL) {
-                (*env)->DeleteGlobalRef(env, jApplication);
-            }
-            (*env)->DeleteGlobalRef(env, jNotify);
-            free(notifyEncapsulation);
-        }
-#endif /* NO_CALLBACKS */
-        return 0L;
-    }
-
-    TRACE0("got session");
-    TRACE1(", SessionHandle=%u", ckSessionHandle);
-    TRACE0(" ... ");
-
-    jSessionHandle = ckULongToJLong(ckSessionHandle);
-
-#ifndef NO_CALLBACKS
-    if (notifyEncapsulation != NULL) {
-        /* store the notifyEncapsulation to enable later cleanup */
-        putNotifyEntry(env, ckSessionHandle, notifyEncapsulation);
-    }
-#endif /* NO_CALLBACKS */
-
-    TRACE0("FINISHED\n");
-
-    return jSessionHandle ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_CLOSESESSION
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_CloseSession
- * Signature: (J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseSession
-    (JNIEnv *env, jobject obj, jlong jSessionHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-#ifndef NO_CALLBACKS
-    NotifyEncapsulation *notifyEncapsulation;
-    jobject jApplicationData;
-#endif /* NO_CALLBACKS */
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    rv = (*ckpFunctions->C_CloseSession)(ckSessionHandle);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-
-#ifndef NO_CALLBACKS
-    notifyEncapsulation = removeNotifyEntry(env, ckSessionHandle);
-
-    if (notifyEncapsulation != NULL) {
-        /* there was a notify object used with this session, now dump the
-         * encapsulation object
-         */
-        (*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject);
-        jApplicationData = notifyEncapsulation->jApplicationData;
-        if (jApplicationData != NULL) {
-            (*env)->DeleteGlobalRef(env, jApplicationData);
-        }
-        free(notifyEncapsulation);
-    }
-#endif /* NO_CALLBACKS */
-
-}
-#endif
-
-#ifdef P11_ENABLE_C_CLOSEALLSESSIONS
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_CloseAllSessions
- * Signature: (J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSlotID               CK_SLOT_ID slotID
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseAllSessions
-    (JNIEnv *env, jobject obj, jlong jSlotID)
-{
-    CK_SLOT_ID ckSlotID;
-    CK_RV rv;
-#ifndef NO_CALLBACKS
-    NotifyEncapsulation *notifyEncapsulation;
-    jobject jApplicationData;
-#endif /* NO_CALLBACKS */
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSlotID = jLongToCKULong(jSlotID);
-
-    rv = (*ckpFunctions->C_CloseAllSessions)(ckSlotID);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-
-#ifndef NO_CALLBACKS
-    /* Remove all notify callback helper objects. */
-    while ((notifyEncapsulation = removeFirstNotifyEntry(env)) != NULL) {
-        /* there was a notify object used with this session, now dump the
-         * encapsulation object
-         */
-        (*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject);
-        jApplicationData = notifyEncapsulation->jApplicationData;
-        if (jApplicationData != NULL) {
-            (*env)->DeleteGlobalRef(env, jApplicationData);
-        }
-        free(notifyEncapsulation);
-    }
-#endif /* NO_CALLBACKS */
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETSESSIONINFO
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetSessionInfo
- * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SESSION_INFO;
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @return  jobject jSessionInfo        CK_SESSION_INFO_PTR pInfo
- */
-JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionInfo
-    (JNIEnv *env, jobject obj, jlong jSessionHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_SESSION_INFO ckSessionInfo;
-    jobject jSessionInfo=NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    rv = (*ckpFunctions->C_GetSessionInfo)(ckSessionHandle, &ckSessionInfo);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jSessionInfo = ckSessionInfoPtrToJSessionInfo(env, &ckSessionInfo);
-    }
-    return jSessionInfo ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_GETOPERATIONSTATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_GetOperationState
- * Signature: (J)[B
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @return  jbyteArray jState           CK_BYTE_PTR pOperationState
- *                                      CK_ULONG_PTR pulOperationStateLen
- */
-JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState
-    (JNIEnv *env, jobject obj, jlong jSessionHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpState;
-    CK_ULONG ckStateLength;
-    jbyteArray jState = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, NULL_PTR, &ckStateLength);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
-
-    ckpState = (CK_BYTE_PTR) malloc(ckStateLength);
-    if (ckpState == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, ckpState, &ckStateLength);
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jState = ckByteArrayToJByteArray(env, ckpState, ckStateLength);
-    }
-    free(ckpState);
-
-    return jState ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_SETOPERATIONSTATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SetOperationState
- * Signature: (J[BJJ)V
- * Parametermapping:                        *PKCS11*
- * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
- * @param   jbyteArray jOperationState      CK_BYTE_PTR pOperationState
- *                                          CK_ULONG ulOperationStateLen
- * @param   jlong jEncryptionKeyHandle      CK_OBJECT_HANDLE hEncryptionKey
- * @param   jlong jAuthenticationKeyHandle  CK_OBJECT_HANDLE hAuthenticationKey
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jOperationState, jlong jEncryptionKeyHandle, jlong jAuthenticationKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpState = NULL_PTR;
-    CK_ULONG ckStateLength;
-    CK_OBJECT_HANDLE ckEncryptionKeyHandle;
-    CK_OBJECT_HANDLE ckAuthenticationKeyHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jOperationState, &ckpState, &ckStateLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    ckEncryptionKeyHandle = jLongToCKULong(jEncryptionKeyHandle);
-    ckAuthenticationKeyHandle = jLongToCKULong(jAuthenticationKeyHandle);
-
-    rv = (*ckpFunctions->C_SetOperationState)(ckSessionHandle, ckpState, ckStateLength, ckEncryptionKeyHandle, ckAuthenticationKeyHandle);
-
-    free(ckpState);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_LOGIN
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Login
- * Signature: (JJ[C)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jlong jUserType             CK_USER_TYPE userType
- * @param   jcharArray jPin             CK_CHAR_PTR pPin
- *                                      CK_ULONG ulPinLen
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, jcharArray jPin)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_USER_TYPE ckUserType;
-    CK_CHAR_PTR ckpPinArray = NULL_PTR;
-    CK_ULONG ckPinLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    ckUserType = jLongToCKULong(jUserType);
-    jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray, ckPinLength);
-
-    free(ckpPinArray);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_LOGOUT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Logout
- * Signature: (J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout
-    (JNIEnv *env, jobject obj, jlong jSessionHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    rv = (*ckpFunctions->C_Logout)(ckSessionHandle);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-/* ************************************************************************** */
-/* Functions for keeping track of notify callbacks                            */
-/* ************************************************************************** */
-
-#ifndef NO_CALLBACKS
-
-/*
- * Add the given notify encapsulation object to the list of active notify
- * objects.
- * If notifyEncapsulation is NULL, this function does nothing.
- */
-void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation *notifyEncapsulation) {
-    NotifyListNode *currentNode, *newNode;
-
-    if (notifyEncapsulation == NULL) {
-        return;
-    }
-
-    newNode = (NotifyListNode *) malloc(sizeof(NotifyListNode));
-    if (newNode == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    newNode->hSession = hSession;
-    newNode->notifyEncapsulation = notifyEncapsulation;
-    newNode->next = NULL;
-
-    (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
-
-    if (notifyListHead == NULL) {
-        /* this is the first entry */
-        notifyListHead = newNode;
-    } else {
-        /* go to the last entry; i.e. the first node which's 'next' is NULL.
-         */
-        currentNode = notifyListHead;
-        while (currentNode->next != NULL) {
-            currentNode = currentNode->next;
-        }
-        currentNode->next = newNode;
-    }
-
-    (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
-}
-
-/*
- * Removes the active notifyEncapsulation object used with the given session and
- * returns it. If there is no notifyEncapsulation active for this session, this
- * function returns NULL.
- */
-NotifyEncapsulation * removeNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession) {
-    NotifyEncapsulation *notifyEncapsulation;
-    NotifyListNode *currentNode, *previousNode;
-
-    (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
-
-    if (notifyListHead == NULL) {
-        /* this is the first entry */
-        notifyEncapsulation = NULL;
-    } else {
-        /* Find the node with the wanted session handle. Also stop, when we reach
-         * the last entry; i.e. the first node which's 'next' is NULL.
-         */
-        currentNode = notifyListHead;
-        previousNode = NULL;
-
-        while ((currentNode->hSession != hSession) && (currentNode->next != NULL)) {
-            previousNode = currentNode;
-            currentNode = currentNode->next;
-        }
-
-        if (currentNode->hSession == hSession) {
-            /* We found a entry for the wanted session, now remove it. */
-            if (previousNode == NULL) {
-                /* it's the first node */
-                notifyListHead = currentNode->next;
-            } else {
-                previousNode->next = currentNode->next;
-            }
-            notifyEncapsulation = currentNode->notifyEncapsulation;
-            free(currentNode);
-        } else {
-            /* We did not find a entry for this session */
-            notifyEncapsulation = NULL;
-        }
-    }
-
-    (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
-
-    return notifyEncapsulation ;
-}
-
-/*
-
- * Removes the first notifyEncapsulation object. If there is no notifyEncapsulation,
- * this function returns NULL.
- */
-NotifyEncapsulation * removeFirstNotifyEntry(JNIEnv *env) {
-    NotifyEncapsulation *notifyEncapsulation;
-    NotifyListNode *currentNode;
-
-    (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
-
-    if (notifyListHead == NULL) {
-        /* this is the first entry */
-        notifyEncapsulation = NULL;
-    } else {
-        /* Remove the first entry. */
-        currentNode = notifyListHead;
-        notifyListHead = notifyListHead->next;
-        notifyEncapsulation = currentNode->notifyEncapsulation;
-        free(currentNode);
-    }
-
-    (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
-
-    return notifyEncapsulation ;
-}
-
-#endif /* NO_CALLBACKS */
-
-#ifndef NO_CALLBACKS
-
-/*
- * The function handling notify callbacks. It casts the pApplication parameter
- * back to a NotifyEncapsulation structure and retrieves the Notify object and
- * the application data from it.
- *
- * @param hSession The session, this callback is comming from.
- * @param event The type of event that occurred.
- * @param pApplication The application data as passed in upon OpenSession. In
-                       this wrapper we always pass in a NotifyEncapsulation
-                       object, which holds necessary information for delegating
-                       the callback to the Java VM.
- * @return
- */
-CK_RV notifyCallback(
-    CK_SESSION_HANDLE hSession,     /* the session's handle */
-    CK_NOTIFICATION   event,
-    CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
-)
-{
-    NotifyEncapsulation *notifyEncapsulation;
-    extern JavaVM *jvm;
-    JNIEnv *env;
-    jint returnValue;
-    jlong jSessionHandle;
-    jlong jEvent;
-    jclass ckNotifyClass;
-    jmethodID jmethod;
-    jthrowable pkcs11Exception;
-    jclass pkcs11ExceptionClass;
-    jlong errorCode;
-    CK_RV rv = CKR_OK;
-    int wasAttached = 1;
-
-    if (pApplication == NULL) { return rv ; } /* This should not occur in this wrapper. */
-
-    notifyEncapsulation = (NotifyEncapsulation *) pApplication;
-
-    /* Get the currently running Java VM */
-    if (jvm == NULL) { return rv ; } /* there is no VM running */
-
-    /* Determine, if current thread is already attached */
-    returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
-    if (returnValue == JNI_EDETACHED) {
-        /* thread detached, so attach it */
-        wasAttached = 0;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else if (returnValue == JNI_EVERSION) {
-        /* this version of JNI is not supported, so just try to attach */
-        /* we assume it was attached to ensure that this thread is not detached
-         * afterwards even though it should not
-         */
-        wasAttached = 1;
-        returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
-    } else {
-        /* attached */
-        wasAttached = 1;
-    }
-
-    jSessionHandle = ckULongToJLong(hSession);
-    jEvent = ckULongToJLong(event);
-
-    ckNotifyClass = (*env)->FindClass(env, CLASS_NOTIFY);
-    if (ckNotifyClass == NULL) { return rv; }
-    jmethod = (*env)->GetMethodID(env, ckNotifyClass, "CK_NOTIFY", "(JJLjava/lang/Object;)V");
-    if (jmethod == NULL) { return rv; }
-
-    (*env)->CallVoidMethod(env, notifyEncapsulation->jNotifyObject, jmethod,
-                         jSessionHandle, jEvent, notifyEncapsulation->jApplicationData);
-
-    /* check, if callback threw an exception */
-    pkcs11Exception = (*env)->ExceptionOccurred(env);
-
-    if (pkcs11Exception != NULL) {
-        /* TBD: clear the pending exception with ExceptionClear? */
-        /* The was an exception thrown, now we get the error-code from it */
-        pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
-        if (pkcs11ExceptionClass == NULL) { return rv; }
-
-        jmethod = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
-        if (jmethod == NULL) { return rv; }
-
-        errorCode = (*env)->CallLongMethod(env, pkcs11Exception, jmethod);
-        rv = jLongToCKULong(errorCode);
-    }
-
-    /* if we attached this thread to the VM just for callback, we detach it now */
-    if (wasAttached) {
-        returnValue = (*jvm)->DetachCurrentThread(jvm);
-    }
-
-    return rv ;
-}
-
-#endif /* NO_CALLBACKS */
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,674 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include "jlong.h"
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-#ifdef P11_ENABLE_C_SIGNINIT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SignInit
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignInit
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckKeyHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return; }
-    ckKeyHandle = jLongToCKULong(jKeyHandle);
-
-    rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_SIGN
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Sign
- * Signature: (J[B)[B
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jData            CK_BYTE_PTR pData
- *                                      CK_ULONG ulDataLen
- * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
- *                                      CK_ULONG_PTR pulSignatureLen
- */
-JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Sign
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpData = NULL_PTR;
-    CK_BYTE_PTR ckpSignature;
-    CK_ULONG ckDataLength;
-    CK_ULONG ckSignatureLength = 0;
-    jbyteArray jSignature = NULL;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
-    if ((*env)->ExceptionCheck(env)) { return NULL; }
-
-    /* START standard code */
-
-    /* first determine the length of the signature */
-    rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckSignatureLength);
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-        free(ckpData);
-        return NULL;
-    }
-
-    ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
-    if (ckpSignature == NULL) {
-        free(ckpData);
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-
-    /* now get the signature */
-    rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
- /* END standard code */
-
-
-    /* START workaround code for operation abort bug in pkcs#11 of Datakey and iButton */
-/*
-    ckpSignature = (CK_BYTE_PTR) malloc(256 * sizeof(CK_BYTE));
-    if (ckpSignature == NULL) {
-        free(ckpData);
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
-
-    if (rv == CKR_BUFFER_TOO_SMALL) {
-        free(ckpSignature);
-        ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
-        if (ckpSignature == NULL) {
-            free(ckpData);
-            throwOutOfMemoryError(env, 0);
-            return NULL;
-        }
-        rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
-    }
- */
-    /* END workaround code */
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength);
-    }
-    free(ckpData);
-    free(ckpSignature);
-
-    return jSignature ;
-}
-#endif
-
-#ifdef P11_ENABLE_C_SIGNUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SignUpdate
- * Signature: (J[BII)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jPart            CK_BYTE_PTR pPart
- *                                      CK_ULONG ulPartLen
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignUpdate
-  (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE_PTR bufP;
-    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
-    jsize bufLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (directIn != 0) {
-        rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, (CK_BYTE_PTR) jlong_to_ptr(directIn), jInLen);
-        ckAssertReturnValueOK(env, rv);
-        return;
-    }
-
-    if (jInLen <= MAX_STACK_BUFFER_LEN) {
-        bufLen = MAX_STACK_BUFFER_LEN;
-        bufP = BUF;
-    } else {
-        bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
-        bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
-        if (bufP == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-    }
-
-    while (jInLen > 0) {
-        jsize chunkLen = min(bufLen, jInLen);
-        (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
-        if ((*env)->ExceptionCheck(env)) {
-            if (bufP != BUF) { free(bufP); }
-            return;
-        }
-        rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, bufP, chunkLen);
-        if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-            if (bufP != BUF) {
-                free(bufP);
-            }
-            return;
-        }
-        jInOfs += chunkLen;
-        jInLen -= chunkLen;
-    }
-
-    if (bufP != BUF) { free(bufP); }
-}
-#endif
-
-#ifdef P11_ENABLE_C_SIGNFINAL
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SignFinal
- * Signature: (J)[B
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
- *                                      CK_ULONG_PTR pulSignatureLen
- */
-JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignFinal
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jint jExpectedLength)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    jbyteArray jSignature = NULL;
-    CK_RV rv;
-    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
-    CK_BYTE_PTR bufP = BUF;
-    CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return NULL; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if ((jExpectedLength > 0) && ((CK_ULONG)jExpectedLength < ckSignatureLength)) {
-        ckSignatureLength = jExpectedLength;
-    }
-
-    rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
-    if (rv == CKR_BUFFER_TOO_SMALL) {
-        bufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
-        if (bufP == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return NULL;
-        }
-        rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
-    }
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength);
-    }
-
-    if (bufP != BUF) { free(bufP); }
-
-    return jSignature;
-}
-#endif
-
-#ifdef P11_ENABLE_C_SIGNRECOVERINIT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SignRecoverInit
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecoverInit
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckKeyHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    ckKeyHandle = jLongToCKULong(jKeyHandle);
-
-    rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-
-    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_SIGNRECOVER
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_SignRecover
- * Signature: (J[BII[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jData            CK_BYTE_PTR pData
- *                                      CK_ULONG ulDataLen
- * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
- *                                      CK_ULONG_PTR pulSignatureLen
- */
-JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecover
-  (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
-    CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
-    CK_BYTE_PTR inBufP;
-    CK_BYTE_PTR outBufP = OUTBUF;
-    CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (jInLen <= MAX_STACK_BUFFER_LEN) {
-        inBufP = INBUF;
-    } else {
-        inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
-        if (inBufP == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return 0;
-        }
-    }
-
-    (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
-    if ((*env)->ExceptionCheck(env)) {
-        if (inBufP != INBUF) { free(inBufP); }
-        return 0;
-    }
-    rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
-    /* re-alloc larger buffer if it fits into our Java buffer */
-    if ((rv == CKR_BUFFER_TOO_SMALL) && (ckSignatureLength <= jIntToCKULong(jOutLen))) {
-        outBufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
-        if (outBufP == NULL) {
-            if (inBufP != INBUF) {
-                free(inBufP);
-            }
-            throwOutOfMemoryError(env, 0);
-            return 0;
-        }
-        rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
-    }
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckSignatureLength, (jbyte *)outBufP);
-    }
-
-    if (inBufP != INBUF) { free(inBufP); }
-    if (outBufP != OUTBUF) { free(outBufP); }
-
-    return ckSignatureLength;
-}
-#endif
-
-#ifdef P11_ENABLE_C_VERIFYINIT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_VerifyInit
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyInit
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckKeyHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    ckKeyHandle = jLongToCKULong(jKeyHandle);
-
-    rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
-
-    if(ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_VERIFY
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_Verify
- * Signature: (J[B[B)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jData            CK_BYTE_PTR pData
- *                                      CK_ULONG ulDataLen
- * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
- *                                      CK_ULONG_PTR pulSignatureLen
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Verify
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData, jbyteArray jSignature)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpData = NULL_PTR;
-    CK_BYTE_PTR ckpSignature = NULL_PTR;
-    CK_ULONG ckDataLength;
-    CK_ULONG ckSignatureLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
-    if ((*env)->ExceptionCheck(env)) {
-        free(ckpData);
-        return;
-    }
-
-    /* verify the signature */
-    rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength);
-
-    free(ckpData);
-    free(ckpSignature);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_VERIFYUPDATE
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_VerifyUpdate
- * Signature: (J[BII)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jPart            CK_BYTE_PTR pPart
- *                                      CK_ULONG ulPartLen
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyUpdate
-  (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE_PTR bufP;
-    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
-    jsize bufLen;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (directIn != 0) {
-        rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen);
-        ckAssertReturnValueOK(env, rv);
-        return;
-    }
-
-    if (jInLen <= MAX_STACK_BUFFER_LEN) {
-        bufLen = MAX_STACK_BUFFER_LEN;
-        bufP = BUF;
-    } else {
-        bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
-        bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
-        if (bufP == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-    }
-
-    while (jInLen > 0) {
-        jsize chunkLen = min(bufLen, jInLen);
-        (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
-        if ((*env)->ExceptionCheck(env)) {
-            if (bufP != BUF) { free(bufP); }
-            return;
-        }
-
-        rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, bufP, chunkLen);
-        if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-            if (bufP != BUF) { free(bufP); }
-            return;
-        }
-        jInOfs += chunkLen;
-        jInLen -= chunkLen;
-    }
-
-    if (bufP != BUF) { free(bufP); }
-}
-#endif
-
-#ifdef P11_ENABLE_C_VERIFYFINAL
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_VerifyFinal
- * Signature: (J[B)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
- *                                      CK_ULONG ulSignatureLen
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyFinal
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_BYTE_PTR ckpSignature = NULL_PTR;
-    CK_ULONG ckSignatureLength;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    /* verify the signature */
-    rv = (*ckpFunctions->C_VerifyFinal)(ckSessionHandle, ckpSignature, ckSignatureLength);
-
-    free(ckpSignature);
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_VERIFYRECOVERINIT
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_VerifyRecoverInit
- * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecoverInit
-    (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
-    CK_OBJECT_HANDLE ckKeyHandle;
-    CK_RV rv;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return; }
-
-    ckKeyHandle = jLongToCKULong(jKeyHandle);
-
-    rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
-
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
-    }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-#endif
-
-#ifdef P11_ENABLE_C_VERIFYRECOVER
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    C_VerifyRecover
- * Signature: (J[BII[BII)I
- * Parametermapping:                    *PKCS11*
- * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
- * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
- *                                      CK_ULONG ulSignatureLen
- * @return  jbyteArray jData            CK_BYTE_PTR pData
- *                                      CK_ULONG_PTR pulDataLen
- */
-JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover
-  (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
-{
-    CK_SESSION_HANDLE ckSessionHandle;
-    CK_RV rv;
-    CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
-    CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
-    CK_BYTE_PTR inBufP;
-    CK_BYTE_PTR outBufP = OUTBUF;
-    CK_ULONG ckDataLength = MAX_STACK_BUFFER_LEN;
-
-    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
-    if (ckpFunctions == NULL) { return 0; }
-
-    ckSessionHandle = jLongToCKULong(jSessionHandle);
-
-    if (jInLen <= MAX_STACK_BUFFER_LEN) {
-        inBufP = INBUF;
-    } else {
-        inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
-        if (inBufP == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return 0;
-        }
-    }
-
-    (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
-    if ((*env)->ExceptionCheck(env)) {
-        if (inBufP != INBUF) { free(inBufP); }
-        return 0;
-    }
-
-    rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
-
-    /* re-alloc larger buffer if it fits into our Java buffer */
-    if ((rv == CKR_BUFFER_TOO_SMALL) && (ckDataLength <= jIntToCKULong(jOutLen))) {
-        outBufP = (CK_BYTE_PTR) malloc(ckDataLength);
-        if (outBufP == NULL) {
-            if (inBufP != INBUF) { free(inBufP); }
-            throwOutOfMemoryError(env, 0);
-            return 0;
-        }
-        rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
-    }
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDataLength, (jbyte *)outBufP);
-    }
-
-    if (inBufP != INBUF) { free(inBufP); }
-    if (outBufP != OUTBUF) { free(outBufP); }
-
-    return ckDataLength;
-}
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1157 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-/* declare file private functions */
-
-ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
-int isModulePresent(JNIEnv *env, jobject pkcs11Implementation);
-void removeAllModuleEntries(JNIEnv *env);
-
-
-/* ************************************************************************** */
-/* Functions for keeping track of currently active and loaded modules         */
-/* ************************************************************************** */
-
-
-/*
- * Create a new object for locking.
- */
-jobject createLockObject(JNIEnv *env) {
-    jclass jObjectClass;
-    jobject jLockObject;
-    jmethodID jConstructor;
-
-    jObjectClass = (*env)->FindClass(env, "java/lang/Object");
-    if (jObjectClass == NULL) { return NULL; }
-    jConstructor = (*env)->GetMethodID(env, jObjectClass, "<init>", "()V");
-    if (jConstructor == NULL) { return NULL; }
-    jLockObject = (*env)->NewObject(env, jObjectClass, jConstructor);
-    if (jLockObject == NULL) { return NULL; }
-    jLockObject = (*env)->NewGlobalRef(env, jLockObject);
-
-    return jLockObject ;
-}
-
-/*
- * Create a new object for locking.
- */
-void destroyLockObject(JNIEnv *env, jobject jLockObject) {
-    if (jLockObject != NULL) {
-        (*env)->DeleteGlobalRef(env, jLockObject);
-    }
-}
-
-/*
- * Add the given pkcs11Implementation object to the list of present modules.
- * Attach the given data to the entry. If the given pkcs11Implementation is
- * already in the lsit, just override its old module data with the new one.
- * None of the arguments can be NULL. If one of the arguments is NULL, this
- * function does nothing.
- */
-void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData) {
-    if (pkcs11Implementation == NULL_PTR) {
-        return ;
-    }
-    if (moduleData == NULL) {
-        return ;
-    }
-    (*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, ptr_to_jlong(moduleData));
-}
-
-
-/*
- * Get the module data of the entry for the given pkcs11Implementation. Returns
- * NULL, if the pkcs11Implementation is not in the list.
- */
-ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
-    jlong jData;
-    if (pkcs11Implementation == NULL) {
-        return NULL;
-    }
-    jData = (*env)->GetLongField(env, pkcs11Implementation, pNativeDataID);
-    return (ModuleData*)jlong_to_ptr(jData);
-}
-
-CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation) {
-    ModuleData *moduleData;
-    CK_FUNCTION_LIST_PTR ckpFunctions;
-
-    moduleData = getModuleEntry(env, pkcs11Implementation);
-    if (moduleData == NULL) {
-        throwDisconnectedRuntimeException(env);
-        return NULL;
-    }
-    ckpFunctions = moduleData->ckFunctionListPtr;
-    return ckpFunctions;
-}
-
-
-/*
- * Returns 1, if the given pkcs11Implementation is in the list.
- * 0, otherwise.
- */
-int isModulePresent(JNIEnv *env, jobject pkcs11Implementation) {
-    int present;
-
-    ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
-
-    present = (moduleData != NULL) ? 1 : 0;
-
-    return present ;
-}
-
-
-/*
- * Removes the entry for the given pkcs11Implementation from the list. Returns
- * the module's data, after the node was removed. If this function returns NULL
- * the pkcs11Implementation was not in the list.
- */
-ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
-    ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
-    if (moduleData == NULL) {
-        return NULL;
-    }
-    (*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, 0);
-    return moduleData;
-}
-
-/*
- * Removes all present entries from the list of modules and frees all
- * associated resources. This function is used for clean-up.
- */
-void removeAllModuleEntries(JNIEnv *env) {
-    /* XXX empty */
-}
-
-/* ************************************************************************** */
-/* Below there follow the helper functions to support conversions between     */
-/* Java and Cryptoki types                                                    */
-/* ************************************************************************** */
-
-/*
- * function to convert a PKCS#11 return value into a PKCS#11Exception
- *
- * This function generates a PKCS#11Exception with the returnValue as the errorcode
- * if the returnValue is not CKR_OK. The functin returns 0, if the returnValue is
- * CKR_OK. Otherwise, it returns the returnValue as a jLong.
- *
- * @param env - used to call JNI funktions and to get the Exception class
- * @param returnValue - of the PKCS#11 function
- */
-jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue)
-{
-    jclass jPKCS11ExceptionClass;
-    jmethodID jConstructor;
-    jthrowable jPKCS11Exception;
-    jlong jErrorCode = 0L;
-
-    if (returnValue != CKR_OK) {
-        jErrorCode = ckULongToJLong(returnValue);
-        jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
-        if (jPKCS11ExceptionClass != NULL) {
-            jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass, "<init>", "(J)V");
-            if (jConstructor != NULL) {
-                jPKCS11Exception = (jthrowable) (*env)->NewObject(env, jPKCS11ExceptionClass, jConstructor, jErrorCode);
-                if (jPKCS11Exception != NULL) {
-                    (*env)->Throw(env, jPKCS11Exception);
-                }
-            }
-        }
-        (*env)->DeleteLocalRef(env, jPKCS11ExceptionClass);
-    }
-    return jErrorCode ;
-}
-
-
-/*
- * Throws a Java Exception by name
- */
-void throwByName(JNIEnv *env, const char *name, const char *msg)
-{
-    jclass cls = (*env)->FindClass(env, name);
-
-    if (cls != 0) /* Otherwise an exception has already been thrown */
-        (*env)->ThrowNew(env, cls, msg);
-}
-
-/*
- * Throws java.lang.OutOfMemoryError
- */
-void throwOutOfMemoryError(JNIEnv *env, const char *msg)
-{
-    throwByName(env, "java/lang/OutOfMemoryError", msg);
-}
-
-/*
- * Throws java.lang.NullPointerException
- */
-void throwNullPointerException(JNIEnv *env, const char *msg)
-{
-    throwByName(env, "java/lang/NullPointerException", msg);
-}
-
-/*
- * Throws java.io.IOException
- */
-void throwIOException(JNIEnv *env, const char *msg)
-{
-    throwByName(env, "java/io/IOException", msg);
-}
-
-/*
- * This function simply throws a PKCS#11RuntimeException with the given
- * string as its message.
- *
- * @param env Used to call JNI funktions and to get the Exception class.
- * @param jmessage The message string of the Exception object.
- */
-void throwPKCS11RuntimeException(JNIEnv *env, const char *message)
-{
-    throwByName(env, CLASS_PKCS11RUNTIMEEXCEPTION, message);
-}
-
-/*
- * This function simply throws a PKCS#11RuntimeException. The message says that
- * the object is not connected to the module.
- *
- * @param env Used to call JNI funktions and to get the Exception class.
- */
-void throwDisconnectedRuntimeException(JNIEnv *env)
-{
-    throwPKCS11RuntimeException(env, "This object is not connected to a module.");
-}
-
-/* This function frees the specified CK_ATTRIBUTE array.
- *
- * @param attrPtr pointer to the to-be-freed CK_ATTRIBUTE array.
- * @param len the length of the array
- */
-void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len)
-{
-    int i;
-
-    for (i=0; i<len; i++) {
-        if (attrPtr[i].pValue != NULL_PTR) {
-            free(attrPtr[i].pValue);
-        }
-    }
-    free(attrPtr);
-}
-
-/*
- * the following functions convert Java arrays to PKCS#11 array pointers and
- * their array length and vice versa
- *
- * void j<Type>ArrayToCK<Type>Array(JNIEnv *env,
- *                                  const j<Type>Array jArray,
- *                                  CK_<Type>_PTR *ckpArray,
- *                                  CK_ULONG_PTR ckLength);
- *
- * j<Type>Array ck<Type>ArrayToJ<Type>Array(JNIEnv *env,
- *                                          const CK_<Type>_PTR ckpArray,
- *                                          CK_ULONG ckLength);
- *
- * PKCS#11 arrays consist always of a pointer to the beginning of the array and
- * the array length whereas Java arrays carry their array length.
- *
- * The Functions to convert a Java array to a PKCS#11 array are void functions.
- * Their arguments are the Java array object to convert, the reference to the
- * array pointer, where the new PKCS#11 array should be stored and the reference
- * to the array length where the PKCS#11 array length should be stored. These two
- * references must not be NULL_PTR.
- *
- * The functions first obtain the array length of the Java array and then allocate
- * the memory for the PKCS#11 array and set the array length. Then each element
- * gets converted depending on their type. After use the allocated memory of the
- * PKCS#11 array has to be explicitly freed.
- *
- * The Functions to convert a PKCS#11 array to a Java array get the PKCS#11 array
- * pointer and the array length and they return the new Java array object. The
- * Java array does not need to get freed after use.
- */
-
-/*
- * converts a jbooleanArray to a CK_BBOOL array. The allocated memory has to be freed after use!
- *
- * @param env - used to call JNI funktions to get the array informtaion
- * @param jArray - the Java array to convert
- * @param ckpArray - the reference, where the pointer to the new CK_BBOOL array will be stored
- * @param ckpLength - the reference, where the array length will be stored
- */
-void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckpLength)
-{
-    jboolean* jpTemp;
-    CK_ULONG i;
-
-    if(jArray == NULL) {
-        *ckpArray = NULL_PTR;
-        *ckpLength = 0L;
-        return;
-    }
-    *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jpTemp = (jboolean*) malloc((*ckpLength) * sizeof(jboolean));
-    if (jpTemp == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    (*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
-    if ((*env)->ExceptionCheck(env)) {
-        free(jpTemp);
-        return;
-    }
-
-    *ckpArray = (CK_BBOOL*) malloc ((*ckpLength) * sizeof(CK_BBOOL));
-    if (*ckpArray == NULL) {
-        free(jpTemp);
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    for (i=0; i<(*ckpLength); i++) {
-        (*ckpArray)[i] = jBooleanToCKBBool(jpTemp[i]);
-    }
-    free(jpTemp);
-}
-
-/*
- * converts a jbyteArray to a CK_BYTE array. The allocated memory has to be freed after use!
- *
- * @param env - used to call JNI funktions to get the array informtaion
- * @param jArray - the Java array to convert
- * @param ckpArray - the reference, where the pointer to the new CK_BYTE array will be stored
- * @param ckpLength - the reference, where the array length will be stored
- */
-void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
-{
-    jbyte* jpTemp;
-    CK_ULONG i;
-
-    if(jArray == NULL) {
-        *ckpArray = NULL_PTR;
-        *ckpLength = 0L;
-        return;
-    }
-    *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jpTemp = (jbyte*) malloc((*ckpLength) * sizeof(jbyte));
-    if (jpTemp == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    (*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
-    if ((*env)->ExceptionCheck(env)) {
-        free(jpTemp);
-        return;
-    }
-
-    /* if CK_BYTE is the same size as jbyte, we save an additional copy */
-    if (sizeof(CK_BYTE) == sizeof(jbyte)) {
-        *ckpArray = (CK_BYTE_PTR) jpTemp;
-    } else {
-        *ckpArray = (CK_BYTE_PTR) malloc ((*ckpLength) * sizeof(CK_BYTE));
-        if (*ckpArray == NULL) {
-            free(jpTemp);
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-        for (i=0; i<(*ckpLength); i++) {
-            (*ckpArray)[i] = jByteToCKByte(jpTemp[i]);
-        }
-        free(jpTemp);
-    }
-}
-
-/*
- * converts a jlongArray to a CK_ULONG array. The allocated memory has to be freed after use!
- *
- * @param env - used to call JNI funktions to get the array informtaion
- * @param jArray - the Java array to convert
- * @param ckpArray - the reference, where the pointer to the new CK_ULONG array will be stored
- * @param ckpLength - the reference, where the array length will be stored
- */
-void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckpLength)
-{
-    jlong* jTemp;
-    CK_ULONG i;
-
-    if(jArray == NULL) {
-        *ckpArray = NULL_PTR;
-        *ckpLength = 0L;
-        return;
-    }
-    *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jTemp = (jlong*) malloc((*ckpLength) * sizeof(jlong));
-    if (jTemp == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    (*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jTemp);
-    if ((*env)->ExceptionCheck(env)) {
-        free(jTemp);
-        return;
-    }
-
-    *ckpArray = (CK_ULONG_PTR) malloc (*ckpLength * sizeof(CK_ULONG));
-    if (*ckpArray == NULL) {
-        free(jTemp);
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    for (i=0; i<(*ckpLength); i++) {
-        (*ckpArray)[i] = jLongToCKULong(jTemp[i]);
-    }
-    free(jTemp);
-}
-
-/*
- * converts a jcharArray to a CK_CHAR array. The allocated memory has to be freed after use!
- *
- * @param env - used to call JNI funktions to get the array informtaion
- * @param jArray - the Java array to convert
- * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
- * @param ckpLength - the reference, where the array length will be stored
- */
-void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
-{
-    jchar* jpTemp;
-    CK_ULONG i;
-
-    if(jArray == NULL) {
-        *ckpArray = NULL_PTR;
-        *ckpLength = 0L;
-        return;
-    }
-    *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jpTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
-    if (jpTemp == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
-    if ((*env)->ExceptionCheck(env)) {
-        free(jpTemp);
-        return;
-    }
-
-    *ckpArray = (CK_CHAR_PTR) malloc (*ckpLength * sizeof(CK_CHAR));
-    if (*ckpArray == NULL) {
-        free(jpTemp);
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    for (i=0; i<(*ckpLength); i++) {
-        (*ckpArray)[i] = jCharToCKChar(jpTemp[i]);
-    }
-    free(jpTemp);
-}
-
-/*
- * converts a jcharArray to a CK_UTF8CHAR array. The allocated memory has to be freed after use!
- *
- * @param env - used to call JNI funktions to get the array informtaion
- * @param jArray - the Java array to convert
- * @param ckpArray - the reference, where the pointer to the new CK_UTF8CHAR array will be stored
- * @param ckpLength - the reference, where the array length will be stored
- */
-void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
-{
-    jchar* jTemp;
-    CK_ULONG i;
-
-    if(jArray == NULL) {
-        *ckpArray = NULL_PTR;
-        *ckpLength = 0L;
-        return;
-    }
-    *ckpLength = (*env)->GetArrayLength(env, jArray);
-    jTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
-    if (jTemp == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jTemp);
-    if ((*env)->ExceptionCheck(env)) {
-        free(jTemp);
-        return;
-    }
-
-    *ckpArray = (CK_UTF8CHAR_PTR) malloc (*ckpLength * sizeof(CK_UTF8CHAR));
-    if (*ckpArray == NULL) {
-        free(jTemp);
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    for (i=0; i<(*ckpLength); i++) {
-        (*ckpArray)[i] = jCharToCKUTF8Char(jTemp[i]);
-    }
-    free(jTemp);
-}
-
-/*
- * converts a jstring to a CK_CHAR array. The allocated memory has to be freed after use!
- *
- * @param env - used to call JNI funktions to get the array informtaion
- * @param jArray - the Java array to convert
- * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
- * @param ckpLength - the reference, where the array length will be stored
- */
-void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
-{
-    const char* pCharArray;
-    jboolean isCopy;
-
-    if(jArray == NULL) {
-        *ckpArray = NULL_PTR;
-        *ckpLength = 0L;
-        return;
-    }
-
-    pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
-    if (pCharArray == NULL) { return; }
-
-    *ckpLength = (CK_ULONG) strlen(pCharArray);
-    *ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
-    if (*ckpArray == NULL) {
-        (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    strcpy((char*)*ckpArray, pCharArray);
-    (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
-}
-
-/*
- * converts a jobjectArray with Java Attributes to a CK_ATTRIBUTE array. The allocated memory
- * has to be freed after use!
- *
- * @param env - used to call JNI funktions to get the array informtaion
- * @param jArray - the Java Attribute array (template) to convert
- * @param ckpArray - the reference, where the pointer to the new CK_ATTRIBUTE array will be
- *                   stored
- * @param ckpLength - the reference, where the array length will be stored
- */
-void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
-{
-    CK_ULONG i;
-    jlong jLength;
-    jobject jAttribute;
-
-    TRACE0("\nDEBUG: jAttributeArrayToCKAttributeArray");
-    if (jArray == NULL) {
-        *ckpArray = NULL_PTR;
-        *ckpLength = 0L;
-        return;
-    }
-    jLength = (*env)->GetArrayLength(env, jArray);
-    *ckpLength = jLongToCKULong(jLength);
-    *ckpArray = (CK_ATTRIBUTE_PTR) malloc(*ckpLength * sizeof(CK_ATTRIBUTE));
-    if (*ckpArray == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    TRACE1(", converting %d attributes", jLength);
-    for (i=0; i<(*ckpLength); i++) {
-        TRACE1(", getting %d. attribute", i);
-        jAttribute = (*env)->GetObjectArrayElement(env, jArray, i);
-        if ((*env)->ExceptionCheck(env)) {
-            freeCKAttributeArray(*ckpArray, i);
-            return;
-        }
-        TRACE1(", jAttribute = %d", jAttribute);
-        TRACE1(", converting %d. attribute", i);
-        (*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute);
-        if ((*env)->ExceptionCheck(env)) {
-            freeCKAttributeArray(*ckpArray, i);
-            return;
-        }
-    }
-    TRACE0("FINISHED\n");
-}
-
-/*
- * converts a CK_BYTE array and its length to a jbyteArray.
- *
- * @param env - used to call JNI funktions to create the new Java array
- * @param ckpArray - the pointer to the CK_BYTE array to convert
- * @param ckpLength - the length of the array to convert
- * @return - the new Java byte array or NULL if error occurred
- */
-jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength)
-{
-    CK_ULONG i;
-    jbyte* jpTemp;
-    jbyteArray jArray;
-
-    /* if CK_BYTE is the same size as jbyte, we save an additional copy */
-    if (sizeof(CK_BYTE) == sizeof(jbyte)) {
-        jpTemp = (jbyte*) ckpArray;
-    } else {
-        jpTemp = (jbyte*) malloc((ckLength) * sizeof(jbyte));
-        if (jpTemp == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return NULL;
-        }
-        for (i=0; i<ckLength; i++) {
-            jpTemp[i] = ckByteToJByte(ckpArray[i]);
-        }
-    }
-
-    jArray = (*env)->NewByteArray(env, ckULongToJSize(ckLength));
-    if (jArray != NULL) {
-        (*env)->SetByteArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
-    }
-
-    if (sizeof(CK_BYTE) != sizeof(jbyte)) { free(jpTemp); }
-
-    return jArray ;
-}
-
-/*
- * converts a CK_ULONG array and its length to a jlongArray.
- *
- * @param env - used to call JNI funktions to create the new Java array
- * @param ckpArray - the pointer to the CK_ULONG array to convert
- * @param ckpLength - the length of the array to convert
- * @return - the new Java long array
- */
-jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength)
-{
-    CK_ULONG i;
-    jlong* jpTemp;
-    jlongArray jArray;
-
-    jpTemp = (jlong*) malloc((ckLength) * sizeof(jlong));
-    if (jpTemp == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    for (i=0; i<ckLength; i++) {
-        jpTemp[i] = ckLongToJLong(ckpArray[i]);
-    }
-    jArray = (*env)->NewLongArray(env, ckULongToJSize(ckLength));
-    if (jArray != NULL) {
-        (*env)->SetLongArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
-    }
-    free(jpTemp);
-
-    return jArray ;
-}
-
-/*
- * converts a CK_CHAR array and its length to a jcharArray.
- *
- * @param env - used to call JNI funktions to create the new Java array
- * @param ckpArray - the pointer to the CK_CHAR array to convert
- * @param ckpLength - the length of the array to convert
- * @return - the new Java char array
- */
-jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG ckLength)
-{
-    CK_ULONG i;
-    jchar* jpTemp;
-    jcharArray jArray;
-
-    jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
-    if (jpTemp == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    for (i=0; i<ckLength; i++) {
-        jpTemp[i] = ckCharToJChar(ckpArray[i]);
-    }
-    jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
-    if (jArray != NULL) {
-        (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
-    }
-    free(jpTemp);
-
-    return jArray ;
-}
-
-/*
- * converts a CK_UTF8CHAR array and its length to a jcharArray.
- *
- * @param env - used to call JNI funktions to create the new Java array
- * @param ckpArray - the pointer to the CK_UTF8CHAR array to convert
- * @param ckpLength - the length of the array to convert
- * @return - the new Java char array
- */
-jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength)
-{
-    CK_ULONG i;
-    jchar* jpTemp;
-    jcharArray jArray;
-
-    jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
-    if (jpTemp == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    for (i=0; i<ckLength; i++) {
-        jpTemp[i] = ckUTF8CharToJChar(ckpArray[i]);
-    }
-    jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
-    if (jArray != NULL) {
-        (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
-    }
-    free(jpTemp);
-
-    return jArray ;
-}
-
-/*
- * the following functions convert Java objects to PKCS#11 pointers and the
- * length in bytes and vice versa
- *
- * CK_<Type>_PTR j<Object>ToCK<Type>Ptr(JNIEnv *env, jobject jObject);
- *
- * jobject ck<Type>PtrToJ<Object>(JNIEnv *env, const CK_<Type>_PTR ckpValue);
- *
- * The functions that convert a Java object to a PKCS#11 pointer first allocate
- * the memory for the PKCS#11 pointer. Then they set each element corresponding
- * to the fields in the Java object to convert. After use the allocated memory of
- * the PKCS#11 pointer has to be explicitly freed.
- *
- * The functions to convert a PKCS#11 pointer to a Java object create a new Java
- * object first and than they set all fields in the object depending on the values
- * of the type or structure where the PKCS#11 pointer points to.
- */
-
-/*
- * converts a CK_BBOOL pointer to a Java boolean Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpValue - the pointer to the CK_BBOOL value
- * @return - the new Java boolean object with the boolean value
- */
-jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL *ckpValue)
-{
-    jclass jValueObjectClass;
-    jmethodID jConstructor;
-    jobject jValueObject;
-    jboolean jValue;
-
-    jValueObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
-    if (jValueObjectClass == NULL) { return NULL; }
-    jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(Z)V");
-    if (jConstructor == NULL) { return NULL; }
-    jValue = ckBBoolToJBoolean(*ckpValue);
-    jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
-
-    return jValueObject ;
-}
-
-/*
- * converts a CK_ULONG pointer to a Java long Object.
- *
- * @param env - used to call JNI funktions to create the new Java object
- * @param ckpValue - the pointer to the CK_ULONG value
- * @return - the new Java long object with the long value
- */
-jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue)
-{
-    jclass jValueObjectClass;
-    jmethodID jConstructor;
-    jobject jValueObject;
-    jlong jValue;
-
-    jValueObjectClass = (*env)->FindClass(env, "java/lang/Long");
-    if (jValueObjectClass == NULL) { return NULL; }
-    jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V");
-    if (jConstructor == NULL) { return NULL; }
-    jValue = ckULongToJLong(*ckpValue);
-    jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
-
-    return jValueObject ;
-}
-
-/*
- * converts a Java boolean object into a pointer to a CK_BBOOL value. The memory has to be
- * freed after use!
- *
- * @param env - used to call JNI funktions to get the value out of the Java object
- * @param jObject - the "java/lang/Boolean" object to convert
- * @return - the pointer to the new CK_BBOOL value
- */
-CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject)
-{
-    jclass jObjectClass;
-    jmethodID jValueMethod;
-    jboolean jValue;
-    CK_BBOOL *ckpValue;
-
-    jObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
-    if (jObjectClass == NULL) { return NULL; }
-    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "booleanValue", "()Z");
-    if (jValueMethod == NULL) { return NULL; }
-    jValue = (*env)->CallBooleanMethod(env, jObject, jValueMethod);
-    ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL));
-    if (ckpValue == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    *ckpValue = jBooleanToCKBBool(jValue);
-
-    return ckpValue ;
-}
-
-/*
- * converts a Java byte object into a pointer to a CK_BYTE value. The memory has to be
- * freed after use!
- *
- * @param env - used to call JNI funktions to get the value out of the Java object
- * @param jObject - the "java/lang/Byte" object to convert
- * @return - the pointer to the new CK_BYTE value
- */
-CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject)
-{
-    jclass jObjectClass;
-    jmethodID jValueMethod;
-    jbyte jValue;
-    CK_BYTE_PTR ckpValue;
-
-    jObjectClass = (*env)->FindClass(env, "java/lang/Byte");
-    if (jObjectClass == NULL) { return NULL; }
-    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "byteValue", "()B");
-    if (jValueMethod == NULL) { return NULL; }
-    jValue = (*env)->CallByteMethod(env, jObject, jValueMethod);
-    ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE));
-    if (ckpValue == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    *ckpValue = jByteToCKByte(jValue);
-    return ckpValue ;
-}
-
-/*
- * converts a Java integer object into a pointer to a CK_ULONG value. The memory has to be
- * freed after use!
- *
- * @param env - used to call JNI funktions to get the value out of the Java object
- * @param jObject - the "java/lang/Integer" object to convert
- * @return - the pointer to the new CK_ULONG value
- */
-CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject)
-{
-    jclass jObjectClass;
-    jmethodID jValueMethod;
-    jint jValue;
-    CK_ULONG *ckpValue;
-
-    jObjectClass = (*env)->FindClass(env, "java/lang/Integer");
-    if (jObjectClass == NULL) { return NULL; }
-    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "intValue", "()I");
-    if (jValueMethod == NULL) { return NULL; }
-    jValue = (*env)->CallIntMethod(env, jObject, jValueMethod);
-    ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
-    if (ckpValue == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    *ckpValue = jLongToCKLong(jValue);
-    return ckpValue ;
-}
-
-/*
- * converts a Java long object into a pointer to a CK_ULONG value. The memory has to be
- * freed after use!
- *
- * @param env - used to call JNI funktions to get the value out of the Java object
- * @param jObject - the "java/lang/Long" object to convert
- * @return - the pointer to the new CK_ULONG value
- */
-CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject)
-{
-    jclass jObjectClass;
-    jmethodID jValueMethod;
-    jlong jValue;
-    CK_ULONG *ckpValue;
-
-    jObjectClass = (*env)->FindClass(env, "java/lang/Long");
-    if (jObjectClass == NULL) { return NULL; }
-    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J");
-    if (jValueMethod == NULL) { return NULL; }
-    jValue = (*env)->CallLongMethod(env, jObject, jValueMethod);
-    ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
-    if (ckpValue == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    *ckpValue = jLongToCKULong(jValue);
-
-    return ckpValue ;
-}
-
-/*
- * converts a Java char object into a pointer to a CK_CHAR value. The memory has to be
- * freed after use!
- *
- * @param env - used to call JNI funktions to get the value out of the Java object
- * @param jObject - the "java/lang/Char" object to convert
- * @return - the pointer to the new CK_CHAR value
- */
-CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject)
-{
-    jclass jObjectClass;
-    jmethodID jValueMethod;
-    jchar jValue;
-    CK_CHAR_PTR ckpValue;
-
-    jObjectClass = (*env)->FindClass(env, "java/lang/Char");
-    if (jObjectClass == NULL) { return NULL; }
-    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "charValue", "()C");
-    if (jValueMethod == NULL) { return NULL; }
-    jValue = (*env)->CallCharMethod(env, jObject, jValueMethod);
-    ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR));
-    if (ckpValue == NULL) {
-        throwOutOfMemoryError(env, 0);
-        return NULL;
-    }
-    *ckpValue = jCharToCKChar(jValue);
-
-    return ckpValue ;
-}
-
-/*
- * converts a Java object into a pointer to CK-type or a CK-structure with the length in Bytes.
- * The memory of *ckpObjectPtr to be freed after use! This function is only used by
- * jAttributeToCKAttribute by now.
- *
- * @param env - used to call JNI funktions to get the Java classes and objects
- * @param jObject - the Java object to convert
- * @param ckpObjectPtr - the reference of the new pointer to the new CK-value or CK-structure
- * @param ckpLength - the reference of the length in bytes of the new CK-value or CK-structure
- */
-void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *ckpLength)
-{
-    jclass jLongClass, jBooleanClass, jByteArrayClass, jCharArrayClass;
-    jclass jByteClass, jDateClass, jCharacterClass, jIntegerClass;
-    jclass jBooleanArrayClass, jIntArrayClass, jLongArrayClass;
-    jclass jStringClass;
-    jclass jObjectClass, jClassClass;
-    CK_VOID_PTR ckpVoid = *ckpObjectPtr;
-    jmethodID jMethod;
-    jobject jClassObject;
-    jstring jClassNameString;
-    char *classNameString, *exceptionMsgPrefix, *exceptionMsg;
-
-    TRACE0("\nDEBUG: jObjectToPrimitiveCKObjectPtrPtr");
-    if (jObject == NULL) {
-        *ckpObjectPtr = NULL;
-        *ckpLength = 0;
-        return;
-    }
-
-    jLongClass = (*env)->FindClass(env, "java/lang/Long");
-    if (jLongClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jLongClass)) {
-        *ckpObjectPtr = jLongObjectToCKULongPtr(env, jObject);
-        *ckpLength = sizeof(CK_ULONG);
-        TRACE1("<converted long value %X>", *((CK_ULONG *) *ckpObjectPtr));
-        return;
-    }
-
-    jBooleanClass = (*env)->FindClass(env, "java/lang/Boolean");
-    if (jBooleanClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) {
-        *ckpObjectPtr = jBooleanObjectToCKBBoolPtr(env, jObject);
-        *ckpLength = sizeof(CK_BBOOL);
-        TRACE0(" <converted boolean value ");
-        TRACE0((*((CK_BBOOL *) *ckpObjectPtr) == TRUE) ? "TRUE>" : "FALSE>");
-        return;
-    }
-
-    jByteArrayClass = (*env)->FindClass(env, "[B");
-    if (jByteArrayClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) {
-        jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*)ckpObjectPtr, ckpLength);
-        return;
-    }
-
-    jCharArrayClass = (*env)->FindClass(env, "[C");
-    if (jCharArrayClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) {
-        jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength);
-        return;
-    }
-
-    jByteClass = (*env)->FindClass(env, "java/lang/Byte");
-    if (jByteClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jByteClass)) {
-        *ckpObjectPtr = jByteObjectToCKBytePtr(env, jObject);
-        *ckpLength = sizeof(CK_BYTE);
-        TRACE1("<converted byte value %X>", *((CK_BYTE *) *ckpObjectPtr));
-        return;
-    }
-
-    jDateClass = (*env)->FindClass(env, CLASS_DATE);
-    if (jDateClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jDateClass)) {
-        *ckpObjectPtr = jDateObjectPtrToCKDatePtr(env, jObject);
-        *ckpLength = sizeof(CK_DATE);
-        TRACE3("<converted date value %.4s-%.2s-%.2s>", (*((CK_DATE *) *ckpObjectPtr)).year, (*((CK_DATE *) *ckpObjectPtr)).month, (*((CK_DATE *) *ckpObjectPtr)).day);
-        return;
-    }
-
-    jCharacterClass = (*env)->FindClass(env, "java/lang/Character");
-    if (jCharacterClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) {
-        *ckpObjectPtr = jCharObjectToCKCharPtr(env, jObject);
-        *ckpLength = sizeof(CK_UTF8CHAR);
-        TRACE1("<converted char value %c>", *((CK_CHAR *) *ckpObjectPtr));
-        return;
-    }
-
-    jIntegerClass = (*env)->FindClass(env, "java/lang/Integer");
-    if (jIntegerClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) {
-        *ckpObjectPtr = jIntegerObjectToCKULongPtr(env, jObject);
-        *ckpLength = sizeof(CK_ULONG);
-        TRACE1("<converted integer value %X>", *((CK_ULONG *) *ckpObjectPtr));
-        return;
-    }
-
-    jBooleanArrayClass = (*env)->FindClass(env, "[Z");
-    if (jBooleanArrayClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) {
-        jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**)ckpObjectPtr, ckpLength);
-        return;
-    }
-
-    jIntArrayClass = (*env)->FindClass(env, "[I");
-    if (jIntArrayClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) {
-        jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength);
-        return;
-    }
-
-    jLongArrayClass = (*env)->FindClass(env, "[J");
-    if (jLongArrayClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) {
-        jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength);
-        return;
-    }
-
-    jStringClass = (*env)->FindClass(env, "java/lang/String");
-    if (jStringClass == NULL) { return; }
-    if ((*env)->IsInstanceOf(env, jObject, jStringClass)) {
-        jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength);
-        return;
-    }
-
-    /* type of jObject unknown, throw PKCS11RuntimeException */
-    jObjectClass = (*env)->FindClass(env, "java/lang/Object");
-    if (jObjectClass == NULL) { return; }
-    jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;");
-    if (jMethod == NULL) { return; }
-    jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod);
-    assert(jClassObject != 0);
-    jClassClass = (*env)->FindClass(env, "java/lang/Class");
-    if (jClassClass == NULL) { return; }
-    jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;");
-    if (jMethod == NULL) { return; }
-    jClassNameString = (jstring)
-        (*env)->CallObjectMethod(env, jClassObject, jMethod);
-    assert(jClassNameString != 0);
-    classNameString = (char*)
-        (*env)->GetStringUTFChars(env, jClassNameString, NULL);
-    if (classNameString == NULL) { return; }
-    exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: ";
-    exceptionMsg = (char *)
-        malloc((strlen(exceptionMsgPrefix) + strlen(classNameString) + 1));
-    if (exceptionMsg == NULL) {
-        (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    strcpy(exceptionMsg, exceptionMsgPrefix);
-    strcat(exceptionMsg, classNameString);
-    (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
-    throwPKCS11RuntimeException(env, exceptionMsg);
-    free(exceptionMsg);
-    *ckpObjectPtr = NULL;
-    *ckpLength = 0;
-
-    TRACE0("FINISHED\n");
-}
-
-#ifdef P11_MEMORYDEBUG
-
-#undef malloc
-#undef free
-
-void *p11malloc(size_t c, char *file, int line) {
-    void *p = malloc(c);
-    printf("malloc\t%08x\t%d\t%s:%d\n", p, c, file, line); fflush(stdout);
-    return p;
-}
-
-void p11free(void *p, char *file, int line) {
-    printf("free\t%08x\t\t%s:%d\n", p, file, line); fflush(stdout);
-    free(p);
-}
-
-#endif
-
-// prints a message to stdout if debug output is enabled
-void printDebug(const char *format, ...) {
-    if (debug == JNI_TRUE) {
-        va_list args;
-        fprintf(stdout, "sunpkcs11: ");
-        va_start(args, format);
-        vfprintf(stdout, format, args);
-        va_end(args);
-        fflush(stdout);
-    }
-}
-
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs-11v2-20a3.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/* pkcs-11v2-20a3.h include file for the PKCS #11 Version 2.20 Amendment 3
-   document. */
-
-/* $Revision: 1.4 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki) Version 2.20 Amendment 3" in all material mentioning or
- * referencing this software.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* This file is preferably included after inclusion of pkcs11.h */
-
-#ifndef _PKCS_11V2_20A3_H_
-#define _PKCS_11V2_20A3_H_ 1
-
-/* Are the definitions of this file already included in pkcs11t.h ? */
-#ifndef CKK_CAMELLIA
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Key types */
-
-/* Camellia is new for PKCS #11 v2.20 amendment 3 */
-#define CKK_CAMELLIA                   0x00000025
-/* ARIA is new for PKCS #11 v2.20 amendment 3 */
-#define CKK_ARIA                       0x00000026
-
-
-/* Mask-generating functions */
-
-/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
-#define CKG_MGF1_SHA224                0x00000005
-
-
-/* Mechanism Identifiers */
-
-/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
-#define CKM_SHA224                     0x00000255
-#define CKM_SHA224_HMAC                0x00000256
-#define CKM_SHA224_HMAC_GENERAL        0x00000257
-
-/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
-#define CKM_SHA224_KEY_DERIVATION      0x00000396
-
-/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
-#define CKM_SHA224_RSA_PKCS            0x00000046
-#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
-
-/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
-#define CKM_AES_CTR                    0x00001086
-
-/* Camellia is new for PKCS #11 v2.20 amendment 3 */
-#define CKM_CAMELLIA_KEY_GEN           0x00000550
-#define CKM_CAMELLIA_ECB               0x00000551
-#define CKM_CAMELLIA_CBC               0x00000552
-#define CKM_CAMELLIA_MAC               0x00000553
-#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
-#define CKM_CAMELLIA_CBC_PAD           0x00000555
-#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
-#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
-#define CKM_CAMELLIA_CTR               0x00000558
-
-/* ARIA is new for PKCS #11 v2.20 amendment 3 */
-#define CKM_ARIA_KEY_GEN               0x00000560
-#define CKM_ARIA_ECB                   0x00000561
-#define CKM_ARIA_CBC                   0x00000562
-#define CKM_ARIA_MAC                   0x00000563
-#define CKM_ARIA_MAC_GENERAL           0x00000564
-#define CKM_ARIA_CBC_PAD               0x00000565
-#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
-#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
-
-
-/* Mechanism parameters */
-
-/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-typedef struct CK_AES_CTR_PARAMS {
-    CK_ULONG ulCounterBits;
-    CK_BYTE cb[16];
-} CK_AES_CTR_PARAMS;
-
-typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
-
-/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-typedef struct CK_CAMELLIA_CTR_PARAMS {
-    CK_ULONG ulCounterBits;
-    CK_BYTE cb[16];
-} CK_CAMELLIA_CTR_PARAMS;
-
-typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
-
-/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
-    CK_BYTE      iv[16];
-    CK_BYTE_PTR  pData;
-    CK_ULONG     length;
-} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
-    CK_BYTE      iv[16];
-    CK_BYTE_PTR  pData;
-    CK_ULONG     length;
-} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-/* pkcs11.h include file for PKCS #11. */
-/* $Revision: 1.4 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-#ifndef _PKCS11_H_
-#define _PKCS11_H_ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Before including this file (pkcs11.h) (or pkcs11t.h by
- * itself), 6 platform-specific macros must be defined.  These
- * macros are described below, and typical definitions for them
- * are also given.  Be advised that these definitions can depend
- * on both the platform and the compiler used (and possibly also
- * on whether a Cryptoki library is linked statically or
- * dynamically).
- *
- * In addition to defining these 6 macros, the packing convention
- * for Cryptoki structures should be set.  The Cryptoki
- * convention on packing is that structures should be 1-byte
- * aligned.
- *
- * If you're using Microsoft Developer Studio 5.0 to produce
- * Win32 stuff, this might be done by using the following
- * preprocessor directive before including pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(push, cryptoki, 1)
- *
- * and using the following preprocessor directive after including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(pop, cryptoki)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to produce Win16 stuff, this might be done by using
- * the following preprocessor directive before including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(1)
- *
- * In a UNIX environment, you're on your own for this.  You might
- * not need to do (or be able to do!) anything.
- *
- *
- * Now for the macros:
- *
- *
- * 1. CK_PTR: The indirection string for making a pointer to an
- * object.  It can be used like this:
- *
- * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
- *
- * If you're using Microsoft Developer Studio 5.0 to produce
- * Win32 stuff, it might be defined by:
- *
- * #define CK_PTR *
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to produce Win16 stuff, it might be defined by:
- *
- * #define CK_PTR far *
- *
- * In a typical UNIX environment, it might be defined by:
- *
- * #define CK_PTR *
- *
- *
- * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
- * an exportable Cryptoki library function definition out of a
- * return type and a function name.  It should be used in the
- * following fashion to define the exposed Cryptoki functions in
- * a Cryptoki library:
- *
- * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
- *   CK_VOID_PTR pReserved
- * )
- * {
- *   ...
- * }
- *
- * If you're using Microsoft Developer Studio 5.0 to define a
- * function in a Win32 Cryptoki .dll, it might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType __declspec(dllexport) name
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to define a function in a Win16 Cryptoki .dll, it
- * might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType name
- *
- *
- * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
- * an importable Cryptoki library function declaration out of a
- * return type and a function name.  It should be used in the
- * following fashion:
- *
- * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
- *   CK_VOID_PTR pReserved
- * );
- *
- * If you're using Microsoft Developer Studio 5.0 to declare a
- * function in a Win32 Cryptoki .dll, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType __declspec(dllimport) name
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to declare a function in a Win16 Cryptoki .dll, it
- * might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType name
- *
- *
- * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
- * which makes a Cryptoki API function pointer declaration or
- * function pointer type declaration out of a return type and a
- * function name.  It should be used in the following fashion:
- *
- * // Define funcPtr to be a pointer to a Cryptoki API function
- * // taking arguments args and returning CK_RV.
- * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
- *
- * or
- *
- * // Define funcPtrType to be the type of a pointer to a
- * // Cryptoki API function taking arguments args and returning
- * // CK_RV, and then define funcPtr to be a variable of type
- * // funcPtrType.
- * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
- * funcPtrType funcPtr;
- *
- * If you're using Microsoft Developer Studio 5.0 to access
- * functions in a Win32 Cryptoki .dll, in might be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType __declspec(dllimport) (* name)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to access functions in a Win16 Cryptoki .dll, it might
- * be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType __export _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType (* name)
- *
- *
- * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
- * a function pointer type for an application callback out of
- * a return type for the callback and a name for the callback.
- * It should be used in the following fashion:
- *
- * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
- *
- * to declare a function pointer, myCallback, to a callback
- * which takes arguments args and returns a CK_RV.  It can also
- * be used like this:
- *
- * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
- * myCallbackType myCallback;
- *
- * If you're using Microsoft Developer Studio 5.0 to do Win32
- * Cryptoki development, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType (* name)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to do Win16 development, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType (* name)
- *
- *
- * 6. NULL_PTR: This macro is the value of a NULL pointer.
- *
- * In any ANSI/ISO C environment (and in many others as well),
- * this should best be defined by
- *
- * #ifndef NULL_PTR
- * #define NULL_PTR 0
- * #endif
- */
-
-
-/* All the various Cryptoki types and #define'd values are in the
- * file pkcs11t.h. */
-#include "pkcs11t.h"
-
-#define __PASTE(x,y)      x##y
-
-
-/* ==============================================================
- * Define the "extern" form of all the entry points.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST  1
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  extern CK_DECLARE_FUNCTION(CK_RV, name)
-
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define the typedef form of all the entry points.  That is, for
- * each Cryptoki function C_XXX, define a type CK_C_XXX which is
- * a pointer to that kind of function.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST  1
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
-
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define structed vector of entry points.  A CK_FUNCTION_LIST
- * contains a CK_VERSION indicating a library's Cryptoki version
- * and then a whole slew of function pointers to the routines in
- * the library.  This type was declared, but not defined, in
- * pkcs11t.h.
- * ==============================================================
- */
-
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  __PASTE(CK_,name) name;
-
-struct CK_FUNCTION_LIST {
-
-  CK_VERSION    version;  /* Cryptoki version */
-
-/* Pile all the function pointers into the CK_FUNCTION_LIST. */
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-};
-
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-#undef __PASTE
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11f.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,912 +0,0 @@
-/* pkcs11f.h include file for PKCS #11. */
-/* $Revision: 1.4 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* This header file contains pretty much everything about all the */
-/* Cryptoki function prototypes.  Because this information is */
-/* used for more than just declaring function prototypes, the */
-/* order of the functions appearing herein is important, and */
-/* should not be altered. */
-
-/* General-purpose */
-
-/* C_Initialize initializes the Cryptoki library. */
-CK_PKCS11_FUNCTION_INFO(C_Initialize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
-                            * cast to CK_C_INITIALIZE_ARGS_PTR
-                            * and dereferenced */
-);
-#endif
-
-
-/* C_Finalize indicates that an application is done with the
- * Cryptoki library. */
-CK_PKCS11_FUNCTION_INFO(C_Finalize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
-);
-#endif
-
-
-/* C_GetInfo returns general information about Cryptoki. */
-CK_PKCS11_FUNCTION_INFO(C_GetInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_INFO_PTR   pInfo  /* location that receives information */
-);
-#endif
-
-
-/* C_GetFunctionList returns the function list. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
-                                            * function list */
-);
-#endif
-
-
-
-/* Slot and token management */
-
-/* C_GetSlotList obtains a list of slots in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
-  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
-  CK_ULONG_PTR   pulCount       /* receives number of slots */
-);
-#endif
-
-
-/* C_GetSlotInfo obtains information about a particular slot in
- * the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID       slotID,  /* the ID of the slot */
-  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
-);
-#endif
-
-
-/* C_GetTokenInfo obtains information about a particular token
- * in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID        slotID,  /* ID of the token's slot */
-  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
-);
-#endif
-
-
-/* C_GetMechanismList obtains a list of mechanism types
- * supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,          /* ID of token's slot */
-  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
-  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
-);
-#endif
-
-
-/* C_GetMechanismInfo obtains information about a particular
- * mechanism possibly supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,  /* ID of the token's slot */
-  CK_MECHANISM_TYPE     type,    /* type of mechanism */
-  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
-);
-#endif
-
-
-/* C_InitToken initializes a token. */
-CK_PKCS11_FUNCTION_INFO(C_InitToken)
-#ifdef CK_NEED_ARG_LIST
-/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
-(
-  CK_SLOT_ID      slotID,    /* ID of the token's slot */
-  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
-  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
-  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
-);
-#endif
-
-
-/* C_InitPIN initializes the normal user's PIN. */
-CK_PKCS11_FUNCTION_INFO(C_InitPIN)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
-  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
-);
-#endif
-
-
-/* C_SetPIN modifies the PIN of the user who is logged in. */
-CK_PKCS11_FUNCTION_INFO(C_SetPIN)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
-  CK_ULONG          ulOldLen,  /* length of the old PIN */
-  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
-  CK_ULONG          ulNewLen   /* length of the new PIN */
-);
-#endif
-
-
-
-/* Session management */
-
-/* C_OpenSession opens a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_OpenSession)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,        /* the slot's ID */
-  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
-  CK_VOID_PTR           pApplication,  /* passed to callback */
-  CK_NOTIFY             Notify,        /* callback function */
-  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
-);
-#endif
-
-
-/* C_CloseSession closes a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseSession)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-/* C_CloseAllSessions closes all sessions with a token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID     slotID  /* the token's slot */
-);
-#endif
-
-
-/* C_GetSessionInfo obtains information about the session. */
-CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE   hSession,  /* the session's handle */
-  CK_SESSION_INFO_PTR pInfo      /* receives session info */
-);
-#endif
-
-
-/* C_GetOperationState obtains the state of the cryptographic operation
- * in a session. */
-CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,             /* session's handle */
-  CK_BYTE_PTR       pOperationState,      /* gets state */
-  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
-);
-#endif
-
-
-/* C_SetOperationState restores the state of the cryptographic
- * operation in a session. */
-CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR      pOperationState,      /* holds state */
-  CK_ULONG         ulOperationStateLen,  /* holds state length */
-  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
-  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
-);
-#endif
-
-
-/* C_Login logs a user into a token. */
-CK_PKCS11_FUNCTION_INFO(C_Login)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_USER_TYPE      userType,  /* the user type */
-  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
-  CK_ULONG          ulPinLen   /* the length of the PIN */
-);
-#endif
-
-
-/* C_Logout logs a user out from a token. */
-CK_PKCS11_FUNCTION_INFO(C_Logout)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Object management */
-
-/* C_CreateObject creates a new object. */
-CK_PKCS11_FUNCTION_INFO(C_CreateObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
-  CK_ULONG          ulCount,     /* attributes in template */
-  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
-);
-#endif
-
-
-/* C_CopyObject copies an object, creating a new object for the
- * copy. */
-CK_PKCS11_FUNCTION_INFO(C_CopyObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,    /* the session's handle */
-  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
-  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
-  CK_ULONG             ulCount,     /* attributes in template */
-  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
-);
-#endif
-
-
-/* C_DestroyObject destroys an object. */
-CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hObject    /* the object's handle */
-);
-#endif
-
-
-/* C_GetObjectSize gets the size of an object in bytes. */
-CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
-  CK_ULONG_PTR      pulSize    /* receives size of object */
-);
-#endif
-
-
-/* C_GetAttributeValue obtains the value of one or more object
- * attributes. */
-CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
-  CK_ULONG          ulCount     /* attributes in template */
-);
-#endif
-
-
-/* C_SetAttributeValue modifies the value of one or more object
- * attributes */
-CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
-  CK_ULONG          ulCount     /* attributes in template */
-);
-#endif
-
-
-/* C_FindObjectsInit initializes a search for token and session
- * objects that match a template. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
-  CK_ULONG          ulCount     /* attrs in search template */
-);
-#endif
-
-
-/* C_FindObjects continues a search for token and session
- * objects that match a template, obtaining additional object
- * handles. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjects)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE    hSession,          /* session's handle */
- CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
- CK_ULONG             ulMaxObjectCount,  /* max handles to get */
- CK_ULONG_PTR         pulObjectCount     /* actual # returned */
-);
-#endif
-
-
-/* C_FindObjectsFinal finishes a search for token and session
- * objects. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Encryption and decryption */
-
-/* C_EncryptInit initializes an encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
-);
-#endif
-
-
-/* C_Encrypt encrypts single-part data. */
-CK_PKCS11_FUNCTION_INFO(C_Encrypt)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pData,               /* the plaintext data */
-  CK_ULONG          ulDataLen,           /* bytes of plaintext */
-  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptUpdate continues a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,           /* session's handle */
-  CK_BYTE_PTR       pPart,              /* the plaintext data */
-  CK_ULONG          ulPartLen,          /* plaintext data len */
-  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptFinal finishes a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,                /* session handle */
-  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
-  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
-);
-#endif
-
-
-/* C_DecryptInit initializes a decryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
-);
-#endif
-
-
-/* C_Decrypt decrypts encrypted data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Decrypt)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,           /* session's handle */
-  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
-  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
-  CK_BYTE_PTR       pData,              /* gets plaintext */
-  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
-);
-#endif
-
-
-/* C_DecryptUpdate continues a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
-  CK_ULONG          ulEncryptedPartLen,  /* input length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* p-text size */
-);
-#endif
-
-
-/* C_DecryptFinal finishes a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
-  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
-);
-#endif
-
-
-
-/* Message digesting */
-
-/* C_DigestInit initializes a message-digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
-);
-#endif
-
-
-/* C_Digest digests data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Digest)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_BYTE_PTR       pData,        /* data to be digested */
-  CK_ULONG          ulDataLen,    /* bytes of data to digest */
-  CK_BYTE_PTR       pDigest,      /* gets the message digest */
-  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
-);
-#endif
-
-
-/* C_DigestUpdate continues a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* data to be digested */
-  CK_ULONG          ulPartLen  /* bytes of data to be digested */
-);
-#endif
-
-
-/* C_DigestKey continues a multi-part message-digesting
- * operation, by digesting the value of a secret key as part of
- * the data already digested. */
-CK_PKCS11_FUNCTION_INFO(C_DigestKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
-);
-#endif
-
-
-/* C_DigestFinal finishes a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_BYTE_PTR       pDigest,      /* gets the message digest */
-  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
-);
-#endif
-
-
-
-/* Signing and MACing */
-
-/* C_SignInit initializes a signature (private key encryption)
- * operation, where the signature is (will be) an appendix to
- * the data, and plaintext cannot be recovered from the
- *signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
-);
-#endif
-
-
-/* C_Sign signs (encrypts with private key) data in a single
- * part, where the signature is (will be) an appendix to the
- * data, and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Sign)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pData,           /* the data to sign */
-  CK_ULONG          ulDataLen,       /* count of bytes to sign */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-/* C_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* the data to sign */
-  CK_ULONG          ulPartLen  /* count of bytes to sign */
-);
-#endif
-
-
-/* C_SignFinal finishes a multiple-part signature operation,
- * returning the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-/* C_SignRecoverInit initializes a signature operation, where
- * the data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
-  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
-);
-#endif
-
-
-/* C_SignRecover signs data in a single operation, where the
- * data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecover)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pData,           /* the data to sign */
-  CK_ULONG          ulDataLen,       /* count of bytes to sign */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-
-/* Verifying signatures and MACs */
-
-/* C_VerifyInit initializes a verification operation, where the
- * signature is an appendix to the data, and plaintext cannot
- *  cannot be recovered from the signature (e.g. DSA). */
-CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
-  CK_OBJECT_HANDLE  hKey         /* verification key */
-);
-#endif
-
-
-/* C_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data, and plaintext
- * cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Verify)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pData,          /* signed data */
-  CK_ULONG          ulDataLen,      /* length of signed data */
-  CK_BYTE_PTR       pSignature,     /* signature */
-  CK_ULONG          ulSignatureLen  /* signature length*/
-);
-#endif
-
-
-/* C_VerifyUpdate continues a multiple-part verification
- * operation, where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* signed data */
-  CK_ULONG          ulPartLen  /* length of signed data */
-);
-#endif
-
-
-/* C_VerifyFinal finishes a multiple-part verification
- * operation, checking the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pSignature,     /* signature to verify */
-  CK_ULONG          ulSignatureLen  /* signature length */
-);
-#endif
-
-
-/* C_VerifyRecoverInit initializes a signature verification
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
-  CK_OBJECT_HANDLE  hKey         /* verification key */
-);
-#endif
-
-
-/* C_VerifyRecover verifies a signature in a single-part
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pSignature,      /* signature to verify */
-  CK_ULONG          ulSignatureLen,  /* signature length */
-  CK_BYTE_PTR       pData,           /* gets signed data */
-  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
-);
-#endif
-
-
-
-/* Dual-function cryptographic operations */
-
-/* C_DigestEncryptUpdate continues a multiple-part digesting
- * and encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pPart,               /* the plaintext data */
-  CK_ULONG          ulPartLen,           /* plaintext length */
-  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptDigestUpdate continues a multiple-part decryption and
- * digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
-  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
-);
-#endif
-
-
-/* C_SignEncryptUpdate continues a multiple-part signing and
- * encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pPart,               /* the plaintext data */
-  CK_ULONG          ulPartLen,           /* plaintext length */
-  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptVerifyUpdate continues a multiple-part decryption and
- * verify operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
-  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
-);
-#endif
-
-
-
-/* Key management */
-
-/* C_GenerateKey generates a secret key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,    /* the session's handle */
-  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
-  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
-  CK_ULONG             ulCount,     /* # of attrs in template */
-  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
-);
-#endif
-
-
-/* C_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,                    /* session
-                                                     * handle */
-  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
-                                                     * mech. */
-  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
-                                                     * for pub.
-                                                     * key */
-  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
-                                                     * attrs. */
-  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
-                                                     * for priv.
-                                                     * key */
-  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
-                                                     * attrs. */
-  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
-                                                     * key
-                                                     * handle */
-  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
-                                                     * priv. key
-                                                     * handle */
-);
-#endif
-
-
-/* C_WrapKey wraps (i.e., encrypts) a key. */
-CK_PKCS11_FUNCTION_INFO(C_WrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
-  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
-  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
-  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
-  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
-);
-#endif
-
-
-/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
- * key object. */
-CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,          /* session's handle */
-  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
-  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
-  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
-  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
-  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
-  CK_ULONG             ulAttributeCount,  /* template length */
-  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
-);
-#endif
-
-
-/* C_DeriveKey derives a key from a base key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,          /* session's handle */
-  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
-  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
-  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
-  CK_ULONG             ulAttributeCount,  /* template length */
-  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
-);
-#endif
-
-
-
-/* Random number generation */
-
-/* C_SeedRandom mixes additional seed material into the token's
- * random number generator. */
-CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pSeed,     /* the seed material */
-  CK_ULONG          ulSeedLen  /* length of seed material */
-);
-#endif
-
-
-/* C_GenerateRandom generates random data. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_BYTE_PTR       RandomData,  /* receives the random data */
-  CK_ULONG          ulRandomLen  /* # of bytes to generate */
-);
-#endif
-
-
-
-/* Parallel function management */
-
-/* C_GetFunctionStatus is a legacy function; it obtains an
- * updated status of a function running in parallel with an
- * application. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-/* C_CancelFunction is a legacy function; it cancels a function
- * running in parallel. */
-CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Functions added in for Cryptoki Version 2.01 or later */
-
-/* C_WaitForSlotEvent waits for a slot event (token insertion,
- * removal, etc.) to occur. */
-CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_FLAGS flags,        /* blocking/nonblocking flag */
-  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
-  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
-);
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11t.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1685 +0,0 @@
-/* pkcs11t.h include file for PKCS #11. */
-/* $Revision: 1.6 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* See top of pkcs11.h for information about the macros that
- * must be defined and the structure-packing conventions that
- * must be set before including this file. */
-
-#ifndef _PKCS11T_H_
-#define _PKCS11T_H_ 1
-
-#define CK_TRUE 1
-#define CK_FALSE 0
-
-#ifndef CK_DISABLE_TRUE_FALSE
-#ifndef FALSE
-#define FALSE CK_FALSE
-#endif
-
-#ifndef TRUE
-#define TRUE CK_TRUE
-#endif
-#endif
-
-/* an unsigned 8-bit value */
-typedef unsigned char     CK_BYTE;
-
-/* an unsigned 8-bit character */
-typedef CK_BYTE           CK_CHAR;
-
-/* an 8-bit UTF-8 character */
-typedef CK_BYTE           CK_UTF8CHAR;
-
-/* a BYTE-sized Boolean flag */
-typedef CK_BYTE           CK_BBOOL;
-
-/* an unsigned value, at least 32 bits long */
-typedef unsigned long int CK_ULONG;
-
-/* a signed value, the same size as a CK_ULONG */
-/* CK_LONG is new for v2.0 */
-typedef long int          CK_LONG;
-
-/* at least 32 bits; each bit is a Boolean flag */
-typedef CK_ULONG          CK_FLAGS;
-
-
-/* some special values for certain CK_ULONG variables */
-#define CK_UNAVAILABLE_INFORMATION (~0UL)
-#define CK_EFFECTIVELY_INFINITE    0
-
-
-typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
-typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
-typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
-typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
-typedef void        CK_PTR   CK_VOID_PTR;
-
-/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
-typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
-
-
-/* The following value is always invalid if used as a session */
-/* handle or object handle */
-#define CK_INVALID_HANDLE 0
-
-
-typedef struct CK_VERSION {
-  CK_BYTE       major;  /* integer portion of version number */
-  CK_BYTE       minor;  /* 1/100ths portion of version number */
-} CK_VERSION;
-
-typedef CK_VERSION CK_PTR CK_VERSION_PTR;
-
-
-typedef struct CK_INFO {
-  /* manufacturerID and libraryDecription have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
-  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
-  CK_FLAGS      flags;               /* must be zero */
-
-  /* libraryDescription and libraryVersion are new for v2.0 */
-  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
-  CK_VERSION    libraryVersion;          /* version of library */
-} CK_INFO;
-
-typedef CK_INFO CK_PTR    CK_INFO_PTR;
-
-
-/* CK_NOTIFICATION enumerates the types of notifications that
- * Cryptoki provides to an application */
-/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_NOTIFICATION;
-#define CKN_SURRENDER       0
-
-
-typedef CK_ULONG          CK_SLOT_ID;
-
-typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
-
-
-/* CK_SLOT_INFO provides information about a slot */
-typedef struct CK_SLOT_INFO {
-  /* slotDescription and manufacturerID have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
-  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
-  CK_FLAGS      flags;
-
-  /* hardwareVersion and firmwareVersion are new for v2.0 */
-  CK_VERSION    hardwareVersion;  /* version of hardware */
-  CK_VERSION    firmwareVersion;  /* version of firmware */
-} CK_SLOT_INFO;
-
-/* flags: bit flags that provide capabilities of the slot
- *      Bit Flag              Mask        Meaning
- */
-#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
-#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
-#define CKF_HW_SLOT           0x00000004  /* hardware slot */
-
-typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
-
-
-/* CK_TOKEN_INFO provides information about a token */
-typedef struct CK_TOKEN_INFO {
-  /* label, manufacturerID, and model have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_UTF8CHAR   label[32];           /* blank padded */
-  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
-  CK_UTF8CHAR   model[16];           /* blank padded */
-  CK_CHAR       serialNumber[16];    /* blank padded */
-  CK_FLAGS      flags;               /* see below */
-
-  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
-   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
-   * changed from CK_USHORT to CK_ULONG for v2.0 */
-  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
-  CK_ULONG      ulSessionCount;        /* sess. now open */
-  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
-  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
-  CK_ULONG      ulMaxPinLen;           /* in bytes */
-  CK_ULONG      ulMinPinLen;           /* in bytes */
-  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
-  CK_ULONG      ulFreePublicMemory;    /* in bytes */
-  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
-  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
-
-  /* hardwareVersion, firmwareVersion, and time are new for
-   * v2.0 */
-  CK_VERSION    hardwareVersion;       /* version of hardware */
-  CK_VERSION    firmwareVersion;       /* version of firmware */
-  CK_CHAR       utcTime[16];           /* time */
-} CK_TOKEN_INFO;
-
-/* The flags parameter is defined as follows:
- *      Bit Flag                    Mask        Meaning
- */
-#define CKF_RNG                     0x00000001  /* has random #
-                                                 * generator */
-#define CKF_WRITE_PROTECTED         0x00000002  /* token is
-                                                 * write-
-                                                 * protected */
-#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
-                                                 * login */
-#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
-                                                 * PIN is set */
-
-/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
- * that means that *every* time the state of cryptographic
- * operations of a session is successfully saved, all keys
- * needed to continue those operations are stored in the state */
-#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
-
-/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
- * that the token has some sort of clock.  The time on that
- * clock is returned in the token info structure */
-#define CKF_CLOCK_ON_TOKEN          0x00000040
-
-/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
- * set, that means that there is some way for the user to login
- * without sending a PIN through the Cryptoki library itself */
-#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
-
-/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
- * that means that a single session with the token can perform
- * dual simultaneous cryptographic operations (digest and
- * encrypt; decrypt and digest; sign and encrypt; and decrypt
- * and sign) */
-#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
-
-/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
- * token has been initialized using C_InitializeToken or an
- * equivalent mechanism outside the scope of PKCS #11.
- * Calling C_InitializeToken when this flag is set will cause
- * the token to be reinitialized. */
-#define CKF_TOKEN_INITIALIZED       0x00000400
-
-/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
- * true, the token supports secondary authentication for
- * private key objects. This flag is deprecated in v2.11 and
-   onwards. */
-#define CKF_SECONDARY_AUTHENTICATION  0x00000800
-
-/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect user login PIN has been entered at least once
- * since the last successful authentication. */
-#define CKF_USER_PIN_COUNT_LOW       0x00010000
-
-/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect user PIN will it to become locked. */
-#define CKF_USER_PIN_FINAL_TRY       0x00020000
-
-/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
- * user PIN has been locked. User login to the token is not
- * possible. */
-#define CKF_USER_PIN_LOCKED          0x00040000
-
-/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the user PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
-
-/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect SO login PIN has been entered at least once since
- * the last successful authentication. */
-#define CKF_SO_PIN_COUNT_LOW         0x00100000
-
-/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect SO PIN will it to become locked. */
-#define CKF_SO_PIN_FINAL_TRY         0x00200000
-
-/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
- * PIN has been locked. SO login to the token is not possible.
- */
-#define CKF_SO_PIN_LOCKED            0x00400000
-
-/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the SO PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
-
-typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
-
-
-/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
- * identifies a session */
-typedef CK_ULONG          CK_SESSION_HANDLE;
-
-typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
-
-
-/* CK_USER_TYPE enumerates the types of Cryptoki users */
-/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_USER_TYPE;
-/* Security Officer */
-#define CKU_SO    0
-/* Normal user */
-#define CKU_USER  1
-/* Context specific (added in v2.20) */
-#define CKU_CONTEXT_SPECIFIC   2
-
-/* CK_STATE enumerates the session states */
-/* CK_STATE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_STATE;
-#define CKS_RO_PUBLIC_SESSION  0
-#define CKS_RO_USER_FUNCTIONS  1
-#define CKS_RW_PUBLIC_SESSION  2
-#define CKS_RW_USER_FUNCTIONS  3
-#define CKS_RW_SO_FUNCTIONS    4
-
-
-/* CK_SESSION_INFO provides information about a session */
-typedef struct CK_SESSION_INFO {
-  CK_SLOT_ID    slotID;
-  CK_STATE      state;
-  CK_FLAGS      flags;          /* see below */
-
-  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG      ulDeviceError;  /* device-dependent error code */
-} CK_SESSION_INFO;
-
-/* The flags are defined in the following table:
- *      Bit Flag                Mask        Meaning
- */
-#define CKF_RW_SESSION          0x00000002  /* session is r/w */
-#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
-
-typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
-
-
-/* CK_OBJECT_HANDLE is a token-specific identifier for an
- * object  */
-typedef CK_ULONG          CK_OBJECT_HANDLE;
-
-typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
-
-
-/* CK_OBJECT_CLASS is a value that identifies the classes (or
- * types) of objects that Cryptoki recognizes.  It is defined
- * as follows: */
-/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_OBJECT_CLASS;
-
-/* The following classes of objects are defined: */
-/* CKO_HW_FEATURE is new for v2.10 */
-/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
-/* CKO_MECHANISM is new for v2.20 */
-#define CKO_DATA              0x00000000
-#define CKO_CERTIFICATE       0x00000001
-#define CKO_PUBLIC_KEY        0x00000002
-#define CKO_PRIVATE_KEY       0x00000003
-#define CKO_SECRET_KEY        0x00000004
-#define CKO_HW_FEATURE        0x00000005
-#define CKO_DOMAIN_PARAMETERS 0x00000006
-#define CKO_MECHANISM         0x00000007
-#define CKO_VENDOR_DEFINED    0x80000000
-
-typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
-
-/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
- * value that identifies the hardware feature type of an object
- * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
-typedef CK_ULONG          CK_HW_FEATURE_TYPE;
-
-/* The following hardware feature types are defined */
-/* CKH_USER_INTERFACE is new for v2.20 */
-#define CKH_MONOTONIC_COUNTER  0x00000001
-#define CKH_CLOCK           0x00000002
-#define CKH_USER_INTERFACE  0x00000003
-#define CKH_VENDOR_DEFINED  0x80000000
-
-/* CK_KEY_TYPE is a value that identifies a key type */
-/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG          CK_KEY_TYPE;
-
-/* the following key types are defined: */
-#define CKK_RSA             0x00000000
-#define CKK_DSA             0x00000001
-#define CKK_DH              0x00000002
-
-/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
-#define CKK_ECDSA           0x00000003
-#define CKK_EC              0x00000003
-#define CKK_X9_42_DH        0x00000004
-#define CKK_KEA             0x00000005
-
-#define CKK_GENERIC_SECRET  0x00000010
-#define CKK_RC2             0x00000011
-#define CKK_RC4             0x00000012
-#define CKK_DES             0x00000013
-#define CKK_DES2            0x00000014
-#define CKK_DES3            0x00000015
-
-/* all these key types are new for v2.0 */
-#define CKK_CAST            0x00000016
-#define CKK_CAST3           0x00000017
-/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
-#define CKK_CAST5           0x00000018
-#define CKK_CAST128         0x00000018
-#define CKK_RC5             0x00000019
-#define CKK_IDEA            0x0000001A
-#define CKK_SKIPJACK        0x0000001B
-#define CKK_BATON           0x0000001C
-#define CKK_JUNIPER         0x0000001D
-#define CKK_CDMF            0x0000001E
-#define CKK_AES             0x0000001F
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKK_BLOWFISH        0x00000020
-#define CKK_TWOFISH         0x00000021
-
-#define CKK_VENDOR_DEFINED  0x80000000
-
-
-/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
- * type */
-/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
- * for v2.0 */
-typedef CK_ULONG          CK_CERTIFICATE_TYPE;
-
-/* The following certificate types are defined: */
-/* CKC_X_509_ATTR_CERT is new for v2.10 */
-/* CKC_WTLS is new for v2.20 */
-#define CKC_X_509           0x00000000
-#define CKC_X_509_ATTR_CERT 0x00000001
-#define CKC_WTLS            0x00000002
-#define CKC_VENDOR_DEFINED  0x80000000
-
-
-/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
- * type */
-/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
-
-/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
-   consists of an array of values. */
-#define CKF_ARRAY_ATTRIBUTE    0x40000000
-
-/* The following attribute types are defined: */
-#define CKA_CLASS              0x00000000
-#define CKA_TOKEN              0x00000001
-#define CKA_PRIVATE            0x00000002
-#define CKA_LABEL              0x00000003
-#define CKA_APPLICATION        0x00000010
-#define CKA_VALUE              0x00000011
-
-/* CKA_OBJECT_ID is new for v2.10 */
-#define CKA_OBJECT_ID          0x00000012
-
-#define CKA_CERTIFICATE_TYPE   0x00000080
-#define CKA_ISSUER             0x00000081
-#define CKA_SERIAL_NUMBER      0x00000082
-
-/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
- * for v2.10 */
-#define CKA_AC_ISSUER          0x00000083
-#define CKA_OWNER              0x00000084
-#define CKA_ATTR_TYPES         0x00000085
-
-/* CKA_TRUSTED is new for v2.11 */
-#define CKA_TRUSTED            0x00000086
-
-/* CKA_CERTIFICATE_CATEGORY ...
- * CKA_CHECK_VALUE are new for v2.20 */
-#define CKA_CERTIFICATE_CATEGORY        0x00000087
-#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
-#define CKA_URL                         0x00000089
-#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
-#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
-#define CKA_CHECK_VALUE                 0x00000090
-
-#define CKA_KEY_TYPE           0x00000100
-#define CKA_SUBJECT            0x00000101
-#define CKA_ID                 0x00000102
-#define CKA_SENSITIVE          0x00000103
-#define CKA_ENCRYPT            0x00000104
-#define CKA_DECRYPT            0x00000105
-#define CKA_WRAP               0x00000106
-#define CKA_UNWRAP             0x00000107
-#define CKA_SIGN               0x00000108
-#define CKA_SIGN_RECOVER       0x00000109
-#define CKA_VERIFY             0x0000010A
-#define CKA_VERIFY_RECOVER     0x0000010B
-#define CKA_DERIVE             0x0000010C
-#define CKA_START_DATE         0x00000110
-#define CKA_END_DATE           0x00000111
-#define CKA_MODULUS            0x00000120
-#define CKA_MODULUS_BITS       0x00000121
-#define CKA_PUBLIC_EXPONENT    0x00000122
-#define CKA_PRIVATE_EXPONENT   0x00000123
-#define CKA_PRIME_1            0x00000124
-#define CKA_PRIME_2            0x00000125
-#define CKA_EXPONENT_1         0x00000126
-#define CKA_EXPONENT_2         0x00000127
-#define CKA_COEFFICIENT        0x00000128
-#define CKA_PRIME              0x00000130
-#define CKA_SUBPRIME           0x00000131
-#define CKA_BASE               0x00000132
-
-/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
-#define CKA_PRIME_BITS         0x00000133
-#define CKA_SUBPRIME_BITS      0x00000134
-#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
-/* (To retain backwards-compatibility) */
-
-#define CKA_VALUE_BITS         0x00000160
-#define CKA_VALUE_LEN          0x00000161
-
-/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
- * and CKA_EC_POINT are new for v2.0 */
-#define CKA_EXTRACTABLE        0x00000162
-#define CKA_LOCAL              0x00000163
-#define CKA_NEVER_EXTRACTABLE  0x00000164
-#define CKA_ALWAYS_SENSITIVE   0x00000165
-
-/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
-#define CKA_KEY_GEN_MECHANISM  0x00000166
-
-#define CKA_MODIFIABLE         0x00000170
-
-/* CKA_ECDSA_PARAMS is deprecated in v2.11,
- * CKA_EC_PARAMS is preferred. */
-#define CKA_ECDSA_PARAMS       0x00000180
-#define CKA_EC_PARAMS          0x00000180
-
-#define CKA_EC_POINT           0x00000181
-
-/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
- * are new for v2.10. Deprecated in v2.11 and onwards. */
-#define CKA_SECONDARY_AUTH     0x00000200
-#define CKA_AUTH_PIN_FLAGS     0x00000201
-
-/* CKA_ALWAYS_AUTHENTICATE ...
- * CKA_UNWRAP_TEMPLATE are new for v2.20 */
-#define CKA_ALWAYS_AUTHENTICATE  0x00000202
-
-#define CKA_WRAP_WITH_TRUSTED    0x00000210
-#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
-#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
-
-/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
- * are new for v2.10 */
-#define CKA_HW_FEATURE_TYPE    0x00000300
-#define CKA_RESET_ON_INIT      0x00000301
-#define CKA_HAS_RESET          0x00000302
-
-/* The following attributes are new for v2.20 */
-#define CKA_PIXEL_X                     0x00000400
-#define CKA_PIXEL_Y                     0x00000401
-#define CKA_RESOLUTION                  0x00000402
-#define CKA_CHAR_ROWS                   0x00000403
-#define CKA_CHAR_COLUMNS                0x00000404
-#define CKA_COLOR                       0x00000405
-#define CKA_BITS_PER_PIXEL              0x00000406
-#define CKA_CHAR_SETS                   0x00000480
-#define CKA_ENCODING_METHODS            0x00000481
-#define CKA_MIME_TYPES                  0x00000482
-#define CKA_MECHANISM_TYPE              0x00000500
-#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
-#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
-#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
-#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
-
-#define CKA_VENDOR_DEFINED     0x80000000
-
-
-/* CK_ATTRIBUTE is a structure that includes the type, length
- * and value of an attribute */
-typedef struct CK_ATTRIBUTE {
-  CK_ATTRIBUTE_TYPE type;
-  CK_VOID_PTR       pValue;
-
-  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
-  CK_ULONG          ulValueLen;  /* in bytes */
-} CK_ATTRIBUTE;
-
-typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
-
-
-/* CK_DATE is a structure that defines a date */
-typedef struct CK_DATE{
-  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
-  CK_CHAR       month[2];  /* the month ("01" - "12") */
-  CK_CHAR       day[2];    /* the day   ("01" - "31") */
-} CK_DATE;
-
-
-/* CK_MECHANISM_TYPE is a value that identifies a mechanism
- * type */
-/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_MECHANISM_TYPE;
-
-/* the following mechanism types are defined: */
-#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
-#define CKM_RSA_PKCS                   0x00000001
-#define CKM_RSA_9796                   0x00000002
-#define CKM_RSA_X_509                  0x00000003
-
-/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
- * are new for v2.0.  They are mechanisms which hash and sign */
-#define CKM_MD2_RSA_PKCS               0x00000004
-#define CKM_MD5_RSA_PKCS               0x00000005
-#define CKM_SHA1_RSA_PKCS              0x00000006
-
-/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
- * CKM_RSA_PKCS_OAEP are new for v2.10 */
-#define CKM_RIPEMD128_RSA_PKCS         0x00000007
-#define CKM_RIPEMD160_RSA_PKCS         0x00000008
-#define CKM_RSA_PKCS_OAEP              0x00000009
-
-/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
- * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
-#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
-#define CKM_RSA_X9_31                  0x0000000B
-#define CKM_SHA1_RSA_X9_31             0x0000000C
-#define CKM_RSA_PKCS_PSS               0x0000000D
-#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
-
-#define CKM_DSA_KEY_PAIR_GEN           0x00000010
-#define CKM_DSA                        0x00000011
-#define CKM_DSA_SHA1                   0x00000012
-#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
-#define CKM_DH_PKCS_DERIVE             0x00000021
-
-/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
- * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
- * v2.11 */
-#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
-#define CKM_X9_42_DH_DERIVE            0x00000031
-#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
-#define CKM_X9_42_MQV_DERIVE           0x00000033
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_RSA_PKCS            0x00000040
-#define CKM_SHA384_RSA_PKCS            0x00000041
-#define CKM_SHA512_RSA_PKCS            0x00000042
-#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
-#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
-#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
-
-#define CKM_RC2_KEY_GEN                0x00000100
-#define CKM_RC2_ECB                    0x00000101
-#define CKM_RC2_CBC                    0x00000102
-#define CKM_RC2_MAC                    0x00000103
-
-/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-#define CKM_RC2_MAC_GENERAL            0x00000104
-#define CKM_RC2_CBC_PAD                0x00000105
-
-#define CKM_RC4_KEY_GEN                0x00000110
-#define CKM_RC4                        0x00000111
-#define CKM_DES_KEY_GEN                0x00000120
-#define CKM_DES_ECB                    0x00000121
-#define CKM_DES_CBC                    0x00000122
-#define CKM_DES_MAC                    0x00000123
-
-/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-#define CKM_DES_MAC_GENERAL            0x00000124
-#define CKM_DES_CBC_PAD                0x00000125
-
-#define CKM_DES2_KEY_GEN               0x00000130
-#define CKM_DES3_KEY_GEN               0x00000131
-#define CKM_DES3_ECB                   0x00000132
-#define CKM_DES3_CBC                   0x00000133
-#define CKM_DES3_MAC                   0x00000134
-
-/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
- * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
- * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-#define CKM_DES3_MAC_GENERAL           0x00000135
-#define CKM_DES3_CBC_PAD               0x00000136
-#define CKM_CDMF_KEY_GEN               0x00000140
-#define CKM_CDMF_ECB                   0x00000141
-#define CKM_CDMF_CBC                   0x00000142
-#define CKM_CDMF_MAC                   0x00000143
-#define CKM_CDMF_MAC_GENERAL           0x00000144
-#define CKM_CDMF_CBC_PAD               0x00000145
-
-/* the following four DES mechanisms are new for v2.20 */
-#define CKM_DES_OFB64                  0x00000150
-#define CKM_DES_OFB8                   0x00000151
-#define CKM_DES_CFB64                  0x00000152
-#define CKM_DES_CFB8                   0x00000153
-
-#define CKM_MD2                        0x00000200
-
-/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD2_HMAC                   0x00000201
-#define CKM_MD2_HMAC_GENERAL           0x00000202
-
-#define CKM_MD5                        0x00000210
-
-/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD5_HMAC                   0x00000211
-#define CKM_MD5_HMAC_GENERAL           0x00000212
-
-#define CKM_SHA_1                      0x00000220
-
-/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-#define CKM_SHA_1_HMAC                 0x00000221
-#define CKM_SHA_1_HMAC_GENERAL         0x00000222
-
-/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
- * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
- * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
-#define CKM_RIPEMD128                  0x00000230
-#define CKM_RIPEMD128_HMAC             0x00000231
-#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
-#define CKM_RIPEMD160                  0x00000240
-#define CKM_RIPEMD160_HMAC             0x00000241
-#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256                     0x00000250
-#define CKM_SHA256_HMAC                0x00000251
-#define CKM_SHA256_HMAC_GENERAL        0x00000252
-#define CKM_SHA384                     0x00000260
-#define CKM_SHA384_HMAC                0x00000261
-#define CKM_SHA384_HMAC_GENERAL        0x00000262
-#define CKM_SHA512                     0x00000270
-#define CKM_SHA512_HMAC                0x00000271
-#define CKM_SHA512_HMAC_GENERAL        0x00000272
-
-/* All of the following mechanisms are new for v2.0 */
-/* Note that CAST128 and CAST5 are the same algorithm */
-#define CKM_CAST_KEY_GEN               0x00000300
-#define CKM_CAST_ECB                   0x00000301
-#define CKM_CAST_CBC                   0x00000302
-#define CKM_CAST_MAC                   0x00000303
-#define CKM_CAST_MAC_GENERAL           0x00000304
-#define CKM_CAST_CBC_PAD               0x00000305
-#define CKM_CAST3_KEY_GEN              0x00000310
-#define CKM_CAST3_ECB                  0x00000311
-#define CKM_CAST3_CBC                  0x00000312
-#define CKM_CAST3_MAC                  0x00000313
-#define CKM_CAST3_MAC_GENERAL          0x00000314
-#define CKM_CAST3_CBC_PAD              0x00000315
-#define CKM_CAST5_KEY_GEN              0x00000320
-#define CKM_CAST128_KEY_GEN            0x00000320
-#define CKM_CAST5_ECB                  0x00000321
-#define CKM_CAST128_ECB                0x00000321
-#define CKM_CAST5_CBC                  0x00000322
-#define CKM_CAST128_CBC                0x00000322
-#define CKM_CAST5_MAC                  0x00000323
-#define CKM_CAST128_MAC                0x00000323
-#define CKM_CAST5_MAC_GENERAL          0x00000324
-#define CKM_CAST128_MAC_GENERAL        0x00000324
-#define CKM_CAST5_CBC_PAD              0x00000325
-#define CKM_CAST128_CBC_PAD            0x00000325
-#define CKM_RC5_KEY_GEN                0x00000330
-#define CKM_RC5_ECB                    0x00000331
-#define CKM_RC5_CBC                    0x00000332
-#define CKM_RC5_MAC                    0x00000333
-#define CKM_RC5_MAC_GENERAL            0x00000334
-#define CKM_RC5_CBC_PAD                0x00000335
-#define CKM_IDEA_KEY_GEN               0x00000340
-#define CKM_IDEA_ECB                   0x00000341
-#define CKM_IDEA_CBC                   0x00000342
-#define CKM_IDEA_MAC                   0x00000343
-#define CKM_IDEA_MAC_GENERAL           0x00000344
-#define CKM_IDEA_CBC_PAD               0x00000345
-#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
-#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
-#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
-#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
-#define CKM_XOR_BASE_AND_DATA          0x00000364
-#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
-#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
-#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
-#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
-
-/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
- * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
- * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
-#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
-#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
-#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
-#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
-#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
-
-/* CKM_TLS_PRF is new for v2.20 */
-#define CKM_TLS_PRF                    0x00000378
-
-#define CKM_SSL3_MD5_MAC               0x00000380
-#define CKM_SSL3_SHA1_MAC              0x00000381
-#define CKM_MD5_KEY_DERIVATION         0x00000390
-#define CKM_MD2_KEY_DERIVATION         0x00000391
-#define CKM_SHA1_KEY_DERIVATION        0x00000392
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_KEY_DERIVATION      0x00000393
-#define CKM_SHA384_KEY_DERIVATION      0x00000394
-#define CKM_SHA512_KEY_DERIVATION      0x00000395
-
-#define CKM_PBE_MD2_DES_CBC            0x000003A0
-#define CKM_PBE_MD5_DES_CBC            0x000003A1
-#define CKM_PBE_MD5_CAST_CBC           0x000003A2
-#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
-#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
-#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
-#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
-#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
-#define CKM_PBE_SHA1_RC4_128           0x000003A6
-#define CKM_PBE_SHA1_RC4_40            0x000003A7
-#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
-#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
-#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
-#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
-
-/* CKM_PKCS5_PBKD2 is new for v2.10 */
-#define CKM_PKCS5_PBKD2                0x000003B0
-
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
-
-/* WTLS mechanisms are new for v2.20 */
-#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
-#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
-#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
-#define CKM_WTLS_PRF                        0x000003D3
-#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
-#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
-
-#define CKM_KEY_WRAP_LYNKS             0x00000400
-#define CKM_KEY_WRAP_SET_OAEP          0x00000401
-
-/* CKM_CMS_SIG is new for v2.20 */
-#define CKM_CMS_SIG                    0x00000500
-
-/* Fortezza mechanisms */
-#define CKM_SKIPJACK_KEY_GEN           0x00001000
-#define CKM_SKIPJACK_ECB64             0x00001001
-#define CKM_SKIPJACK_CBC64             0x00001002
-#define CKM_SKIPJACK_OFB64             0x00001003
-#define CKM_SKIPJACK_CFB64             0x00001004
-#define CKM_SKIPJACK_CFB32             0x00001005
-#define CKM_SKIPJACK_CFB16             0x00001006
-#define CKM_SKIPJACK_CFB8              0x00001007
-#define CKM_SKIPJACK_WRAP              0x00001008
-#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
-#define CKM_SKIPJACK_RELAYX            0x0000100a
-#define CKM_KEA_KEY_PAIR_GEN           0x00001010
-#define CKM_KEA_KEY_DERIVE             0x00001011
-#define CKM_FORTEZZA_TIMESTAMP         0x00001020
-#define CKM_BATON_KEY_GEN              0x00001030
-#define CKM_BATON_ECB128               0x00001031
-#define CKM_BATON_ECB96                0x00001032
-#define CKM_BATON_CBC128               0x00001033
-#define CKM_BATON_COUNTER              0x00001034
-#define CKM_BATON_SHUFFLE              0x00001035
-#define CKM_BATON_WRAP                 0x00001036
-
-/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
- * CKM_EC_KEY_PAIR_GEN is preferred */
-#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
-#define CKM_EC_KEY_PAIR_GEN            0x00001040
-
-#define CKM_ECDSA                      0x00001041
-#define CKM_ECDSA_SHA1                 0x00001042
-
-/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
- * are new for v2.11 */
-#define CKM_ECDH1_DERIVE               0x00001050
-#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
-#define CKM_ECMQV_DERIVE               0x00001052
-
-#define CKM_JUNIPER_KEY_GEN            0x00001060
-#define CKM_JUNIPER_ECB128             0x00001061
-#define CKM_JUNIPER_CBC128             0x00001062
-#define CKM_JUNIPER_COUNTER            0x00001063
-#define CKM_JUNIPER_SHUFFLE            0x00001064
-#define CKM_JUNIPER_WRAP               0x00001065
-#define CKM_FASTHASH                   0x00001070
-
-/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
- * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
- * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
- * new for v2.11 */
-#define CKM_AES_KEY_GEN                0x00001080
-#define CKM_AES_ECB                    0x00001081
-#define CKM_AES_CBC                    0x00001082
-#define CKM_AES_MAC                    0x00001083
-#define CKM_AES_MAC_GENERAL            0x00001084
-#define CKM_AES_CBC_PAD                0x00001085
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKM_BLOWFISH_KEY_GEN           0x00001090
-#define CKM_BLOWFISH_CBC               0x00001091
-#define CKM_TWOFISH_KEY_GEN            0x00001092
-#define CKM_TWOFISH_CBC                0x00001093
-
-
-/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
-#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
-#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
-#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
-#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
-#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
-#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
-
-#define CKM_DSA_PARAMETER_GEN          0x00002000
-#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
-#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
-
-#define CKM_VENDOR_DEFINED             0x80000000
-
-typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
-
-
-/* CK_MECHANISM is a structure that specifies a particular
- * mechanism  */
-typedef struct CK_MECHANISM {
-  CK_MECHANISM_TYPE mechanism;
-  CK_VOID_PTR       pParameter;
-
-  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG          ulParameterLen;  /* in bytes */
-} CK_MECHANISM;
-
-typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
-
-
-/* CK_MECHANISM_INFO provides information about a particular
- * mechanism */
-typedef struct CK_MECHANISM_INFO {
-    CK_ULONG    ulMinKeySize;
-    CK_ULONG    ulMaxKeySize;
-    CK_FLAGS    flags;
-} CK_MECHANISM_INFO;
-
-/* The flags are defined as follows:
- *      Bit Flag               Mask        Meaning */
-#define CKF_HW                 0x00000001  /* performed by HW */
-
-/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
- * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
- * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
- * and CKF_DERIVE are new for v2.0.  They specify whether or not
- * a mechanism can be used for a particular task */
-#define CKF_ENCRYPT            0x00000100
-#define CKF_DECRYPT            0x00000200
-#define CKF_DIGEST             0x00000400
-#define CKF_SIGN               0x00000800
-#define CKF_SIGN_RECOVER       0x00001000
-#define CKF_VERIFY             0x00002000
-#define CKF_VERIFY_RECOVER     0x00004000
-#define CKF_GENERATE           0x00008000
-#define CKF_GENERATE_KEY_PAIR  0x00010000
-#define CKF_WRAP               0x00020000
-#define CKF_UNWRAP             0x00040000
-#define CKF_DERIVE             0x00080000
-
-/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
- * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
- * describe a token's EC capabilities not available in mechanism
- * information. */
-#define CKF_EC_F_P             0x00100000
-#define CKF_EC_F_2M            0x00200000
-#define CKF_EC_ECPARAMETERS    0x00400000
-#define CKF_EC_NAMEDCURVE      0x00800000
-#define CKF_EC_UNCOMPRESS      0x01000000
-#define CKF_EC_COMPRESS        0x02000000
-
-#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
-
-typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
-
-
-/* CK_RV is a value that identifies the return value of a
- * Cryptoki function */
-/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG          CK_RV;
-
-#define CKR_OK                                0x00000000
-#define CKR_CANCEL                            0x00000001
-#define CKR_HOST_MEMORY                       0x00000002
-#define CKR_SLOT_ID_INVALID                   0x00000003
-
-/* CKR_FLAGS_INVALID was removed for v2.0 */
-
-/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-#define CKR_GENERAL_ERROR                     0x00000005
-#define CKR_FUNCTION_FAILED                   0x00000006
-
-/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
- * and CKR_CANT_LOCK are new for v2.01 */
-#define CKR_ARGUMENTS_BAD                     0x00000007
-#define CKR_NO_EVENT                          0x00000008
-#define CKR_NEED_TO_CREATE_THREADS            0x00000009
-#define CKR_CANT_LOCK                         0x0000000A
-
-#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
-#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
-#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
-#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
-#define CKR_DATA_INVALID                      0x00000020
-#define CKR_DATA_LEN_RANGE                    0x00000021
-#define CKR_DEVICE_ERROR                      0x00000030
-#define CKR_DEVICE_MEMORY                     0x00000031
-#define CKR_DEVICE_REMOVED                    0x00000032
-#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
-#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
-#define CKR_FUNCTION_CANCELED                 0x00000050
-#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
-
-/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
-
-#define CKR_KEY_HANDLE_INVALID                0x00000060
-
-/* CKR_KEY_SENSITIVE was removed for v2.0 */
-
-#define CKR_KEY_SIZE_RANGE                    0x00000062
-#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
-
-/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
- * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
- * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
- * v2.0 */
-#define CKR_KEY_NOT_NEEDED                    0x00000064
-#define CKR_KEY_CHANGED                       0x00000065
-#define CKR_KEY_NEEDED                        0x00000066
-#define CKR_KEY_INDIGESTIBLE                  0x00000067
-#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
-#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
-#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
-
-#define CKR_MECHANISM_INVALID                 0x00000070
-#define CKR_MECHANISM_PARAM_INVALID           0x00000071
-
-/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
- * were removed for v2.0 */
-#define CKR_OBJECT_HANDLE_INVALID             0x00000082
-#define CKR_OPERATION_ACTIVE                  0x00000090
-#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
-#define CKR_PIN_INCORRECT                     0x000000A0
-#define CKR_PIN_INVALID                       0x000000A1
-#define CKR_PIN_LEN_RANGE                     0x000000A2
-
-/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-#define CKR_PIN_EXPIRED                       0x000000A3
-#define CKR_PIN_LOCKED                        0x000000A4
-
-#define CKR_SESSION_CLOSED                    0x000000B0
-#define CKR_SESSION_COUNT                     0x000000B1
-#define CKR_SESSION_HANDLE_INVALID            0x000000B3
-#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
-#define CKR_SESSION_READ_ONLY                 0x000000B5
-#define CKR_SESSION_EXISTS                    0x000000B6
-
-/* CKR_SESSION_READ_ONLY_EXISTS and
- * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
-#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
-
-#define CKR_SIGNATURE_INVALID                 0x000000C0
-#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
-#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
-#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
-#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
-#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
-#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
-#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
-#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
-#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
-#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
-#define CKR_USER_NOT_LOGGED_IN                0x00000101
-#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
-#define CKR_USER_TYPE_INVALID                 0x00000103
-
-/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
- * are new to v2.01 */
-#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
-#define CKR_USER_TOO_MANY_TYPES               0x00000105
-
-#define CKR_WRAPPED_KEY_INVALID               0x00000110
-#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
-#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
-#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
-#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
-#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
-
-/* These are new to v2.0 */
-#define CKR_RANDOM_NO_RNG                     0x00000121
-
-/* These are new to v2.11 */
-#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
-
-/* These are new to v2.0 */
-#define CKR_BUFFER_TOO_SMALL                  0x00000150
-#define CKR_SAVED_STATE_INVALID               0x00000160
-#define CKR_INFORMATION_SENSITIVE             0x00000170
-#define CKR_STATE_UNSAVEABLE                  0x00000180
-
-/* These are new to v2.01 */
-#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
-#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
-#define CKR_MUTEX_BAD                         0x000001A0
-#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
-
-/* This is new to v2.20 */
-#define CKR_FUNCTION_REJECTED                 0x00000200
-
-#define CKR_VENDOR_DEFINED                    0x80000000
-
-
-/* CK_NOTIFY is an application callback that processes events */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_NOTIFICATION   event,
-  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
-);
-
-
-/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
- * version and pointers of appropriate types to all the
- * Cryptoki functions */
-/* CK_FUNCTION_LIST is new for v2.0 */
-typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
-
-typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
-
-typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
-
-
-/* CK_CREATEMUTEX is an application callback for creating a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
-  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
-);
-
-
-/* CK_DESTROYMUTEX is an application callback for destroying a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_LOCKMUTEX is an application callback for locking a mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_UNLOCKMUTEX is an application callback for unlocking a
- * mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_C_INITIALIZE_ARGS provides the optional arguments to
- * C_Initialize */
-typedef struct CK_C_INITIALIZE_ARGS {
-  CK_CREATEMUTEX CreateMutex;
-  CK_DESTROYMUTEX DestroyMutex;
-  CK_LOCKMUTEX LockMutex;
-  CK_UNLOCKMUTEX UnlockMutex;
-  CK_FLAGS flags;
-  CK_VOID_PTR pReserved;
-} CK_C_INITIALIZE_ARGS;
-
-/* flags: bit flags that provide capabilities of the slot
- *      Bit Flag                           Mask       Meaning
- */
-#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
-#define CKF_OS_LOCKING_OK                  0x00000002
-
-typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
-
-
-/* additional flags for parameters to functions */
-
-/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-#define CKF_DONT_BLOCK     1
-
-/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
- * Generation Function (MGF) applied to a message block when
- * formatting a message block for the PKCS #1 OAEP encryption
- * scheme. */
-typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
-
-typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
-
-/* The following MGFs are defined */
-/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
- * are new for v2.20 */
-#define CKG_MGF1_SHA1         0x00000001
-#define CKG_MGF1_SHA256       0x00000002
-#define CKG_MGF1_SHA384       0x00000003
-#define CKG_MGF1_SHA512       0x00000004
-
-/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
- * of the encoding parameter when formatting a message block
- * for the PKCS #1 OAEP encryption scheme. */
-typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
-
-typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
-
-/* The following encoding parameter sources are defined */
-#define CKZ_DATA_SPECIFIED    0x00000001
-
-/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
- * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_OAEP mechanism. */
-typedef struct CK_RSA_PKCS_OAEP_PARAMS {
-        CK_MECHANISM_TYPE hashAlg;
-        CK_RSA_PKCS_MGF_TYPE mgf;
-        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
-        CK_VOID_PTR pSourceData;
-        CK_ULONG ulSourceDataLen;
-} CK_RSA_PKCS_OAEP_PARAMS;
-
-typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
-
-/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
- * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_PSS mechanism(s). */
-typedef struct CK_RSA_PKCS_PSS_PARAMS {
-        CK_MECHANISM_TYPE    hashAlg;
-        CK_RSA_PKCS_MGF_TYPE mgf;
-        CK_ULONG             sLen;
-} CK_RSA_PKCS_PSS_PARAMS;
-
-typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
-
-/* CK_EC_KDF_TYPE is new for v2.11. */
-typedef CK_ULONG CK_EC_KDF_TYPE;
-
-/* The following EC Key Derivation Functions are defined */
-#define CKD_NULL                 0x00000001
-#define CKD_SHA1_KDF             0x00000002
-
-/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
- * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
- * where each party contributes one key pair.
- */
-typedef struct CK_ECDH1_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-} CK_ECDH1_DERIVE_PARAMS;
-
-typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
-
-
-/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
- * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
-typedef struct CK_ECDH2_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-} CK_ECDH2_DERIVE_PARAMS;
-
-typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_ECMQV_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-  CK_OBJECT_HANDLE publicKey;
-} CK_ECMQV_DERIVE_PARAMS;
-
-typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
-
-/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
- * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
-typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
-typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
-
-/* The following X9.42 DH key derivation functions are defined
-   (besides CKD_NULL already defined : */
-#define CKD_SHA1_KDF_ASN1        0x00000003
-#define CKD_SHA1_KDF_CONCATENATE 0x00000004
-
-/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
- * contributes one key pair */
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-} CK_X9_42_DH1_DERIVE_PARAMS;
-
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
-
-/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
- * mechanisms, where each party contributes two key pairs */
-typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-} CK_X9_42_DH2_DERIVE_PARAMS;
-
-typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-  CK_OBJECT_HANDLE publicKey;
-} CK_X9_42_MQV_DERIVE_PARAMS;
-
-typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
-
-/* CK_KEA_DERIVE_PARAMS provides the parameters to the
- * CKM_KEA_DERIVE mechanism */
-/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-typedef struct CK_KEA_DERIVE_PARAMS {
-  CK_BBOOL      isSender;
-  CK_ULONG      ulRandomLen;
-  CK_BYTE_PTR   pRandomA;
-  CK_BYTE_PTR   pRandomB;
-  CK_ULONG      ulPublicDataLen;
-  CK_BYTE_PTR   pPublicData;
-} CK_KEA_DERIVE_PARAMS;
-
-typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
-
-
-/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
- * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
- * holds the effective keysize */
-typedef CK_ULONG          CK_RC2_PARAMS;
-
-typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
-
-
-/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
- * mechanism */
-typedef struct CK_RC2_CBC_PARAMS {
-  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
-
-  CK_BYTE       iv[8];            /* IV for CBC mode */
-} CK_RC2_CBC_PARAMS;
-
-typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
-
-
-/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC2_MAC_GENERAL mechanism */
-/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC2_MAC_GENERAL_PARAMS {
-  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
-  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
-} CK_RC2_MAC_GENERAL_PARAMS;
-
-typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
-  CK_RC2_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
- * CKM_RC5_MAC mechanisms */
-/* CK_RC5_PARAMS is new for v2.0 */
-typedef struct CK_RC5_PARAMS {
-  CK_ULONG      ulWordsize;  /* wordsize in bits */
-  CK_ULONG      ulRounds;    /* number of rounds */
-} CK_RC5_PARAMS;
-
-typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
-
-
-/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
- * mechanism */
-/* CK_RC5_CBC_PARAMS is new for v2.0 */
-typedef struct CK_RC5_CBC_PARAMS {
-  CK_ULONG      ulWordsize;  /* wordsize in bits */
-  CK_ULONG      ulRounds;    /* number of rounds */
-  CK_BYTE_PTR   pIv;         /* pointer to IV */
-  CK_ULONG      ulIvLen;     /* length of IV in bytes */
-} CK_RC5_CBC_PARAMS;
-
-typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
-
-
-/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC5_MAC_GENERAL mechanism */
-/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC5_MAC_GENERAL_PARAMS {
-  CK_ULONG      ulWordsize;   /* wordsize in bits */
-  CK_ULONG      ulRounds;     /* number of rounds */
-  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
-} CK_RC5_MAC_GENERAL_PARAMS;
-
-typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
-  CK_RC5_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
- * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
- * the MAC */
-/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
-
-typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
-
-/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
-typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
-  CK_BYTE      iv[8];
-  CK_BYTE_PTR  pData;
-  CK_ULONG     length;
-} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
-  CK_BYTE      iv[16];
-  CK_BYTE_PTR  pData;
-  CK_ULONG     length;
-} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
- * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
-  CK_ULONG      ulPasswordLen;
-  CK_BYTE_PTR   pPassword;
-  CK_ULONG      ulPublicDataLen;
-  CK_BYTE_PTR   pPublicData;
-  CK_ULONG      ulPAndGLen;
-  CK_ULONG      ulQLen;
-  CK_ULONG      ulRandomLen;
-  CK_BYTE_PTR   pRandomA;
-  CK_BYTE_PTR   pPrimeP;
-  CK_BYTE_PTR   pBaseG;
-  CK_BYTE_PTR   pSubprimeQ;
-} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
-
-typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
-  CK_SKIPJACK_PRIVATE_WRAP_PTR;
-
-
-/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
- * CKM_SKIPJACK_RELAYX mechanism */
-/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_RELAYX_PARAMS {
-  CK_ULONG      ulOldWrappedXLen;
-  CK_BYTE_PTR   pOldWrappedX;
-  CK_ULONG      ulOldPasswordLen;
-  CK_BYTE_PTR   pOldPassword;
-  CK_ULONG      ulOldPublicDataLen;
-  CK_BYTE_PTR   pOldPublicData;
-  CK_ULONG      ulOldRandomLen;
-  CK_BYTE_PTR   pOldRandomA;
-  CK_ULONG      ulNewPasswordLen;
-  CK_BYTE_PTR   pNewPassword;
-  CK_ULONG      ulNewPublicDataLen;
-  CK_BYTE_PTR   pNewPublicData;
-  CK_ULONG      ulNewRandomLen;
-  CK_BYTE_PTR   pNewRandomA;
-} CK_SKIPJACK_RELAYX_PARAMS;
-
-typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
-  CK_SKIPJACK_RELAYX_PARAMS_PTR;
-
-
-typedef struct CK_PBE_PARAMS {
-  CK_BYTE_PTR      pInitVector;
-  CK_UTF8CHAR_PTR  pPassword;
-  CK_ULONG         ulPasswordLen;
-  CK_BYTE_PTR      pSalt;
-  CK_ULONG         ulSaltLen;
-  CK_ULONG         ulIteration;
-} CK_PBE_PARAMS;
-
-typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
-
-
-/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
- * CKM_KEY_WRAP_SET_OAEP mechanism */
-/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
-  CK_BYTE       bBC;     /* block contents byte */
-  CK_BYTE_PTR   pX;      /* extra data */
-  CK_ULONG      ulXLen;  /* length of extra data in bytes */
-} CK_KEY_WRAP_SET_OAEP_PARAMS;
-
-typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
-  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_RANDOM_DATA {
-  CK_BYTE_PTR  pClientRandom;
-  CK_ULONG     ulClientRandomLen;
-  CK_BYTE_PTR  pServerRandom;
-  CK_ULONG     ulServerRandomLen;
-} CK_SSL3_RANDOM_DATA;
-
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
-  CK_SSL3_RANDOM_DATA RandomInfo;
-  CK_VERSION_PTR pVersion;
-} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_OUT {
-  CK_OBJECT_HANDLE hClientMacSecret;
-  CK_OBJECT_HANDLE hServerMacSecret;
-  CK_OBJECT_HANDLE hClientKey;
-  CK_OBJECT_HANDLE hServerKey;
-  CK_BYTE_PTR      pIVClient;
-  CK_BYTE_PTR      pIVServer;
-} CK_SSL3_KEY_MAT_OUT;
-
-typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_PARAMS {
-  CK_ULONG                ulMacSizeInBits;
-  CK_ULONG                ulKeySizeInBits;
-  CK_ULONG                ulIVSizeInBits;
-  CK_BBOOL                bIsExport;
-  CK_SSL3_RANDOM_DATA     RandomInfo;
-  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_SSL3_KEY_MAT_PARAMS;
-
-typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
-
-/* CK_TLS_PRF_PARAMS is new for version 2.20 */
-typedef struct CK_TLS_PRF_PARAMS {
-  CK_BYTE_PTR  pSeed;
-  CK_ULONG     ulSeedLen;
-  CK_BYTE_PTR  pLabel;
-  CK_ULONG     ulLabelLen;
-  CK_BYTE_PTR  pOutput;
-  CK_ULONG_PTR pulOutputLen;
-} CK_TLS_PRF_PARAMS;
-
-typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
-
-/* WTLS is new for version 2.20 */
-typedef struct CK_WTLS_RANDOM_DATA {
-  CK_BYTE_PTR pClientRandom;
-  CK_ULONG    ulClientRandomLen;
-  CK_BYTE_PTR pServerRandom;
-  CK_ULONG    ulServerRandomLen;
-} CK_WTLS_RANDOM_DATA;
-
-typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
-
-typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
-  CK_MECHANISM_TYPE   DigestMechanism;
-  CK_WTLS_RANDOM_DATA RandomInfo;
-  CK_BYTE_PTR         pVersion;
-} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
-
-typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-typedef struct CK_WTLS_PRF_PARAMS {
-  CK_MECHANISM_TYPE DigestMechanism;
-  CK_BYTE_PTR       pSeed;
-  CK_ULONG          ulSeedLen;
-  CK_BYTE_PTR       pLabel;
-  CK_ULONG          ulLabelLen;
-  CK_BYTE_PTR       pOutput;
-  CK_ULONG_PTR      pulOutputLen;
-} CK_WTLS_PRF_PARAMS;
-
-typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_OUT {
-  CK_OBJECT_HANDLE hMacSecret;
-  CK_OBJECT_HANDLE hKey;
-  CK_BYTE_PTR      pIV;
-} CK_WTLS_KEY_MAT_OUT;
-
-typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_PARAMS {
-  CK_MECHANISM_TYPE       DigestMechanism;
-  CK_ULONG                ulMacSizeInBits;
-  CK_ULONG                ulKeySizeInBits;
-  CK_ULONG                ulIVSizeInBits;
-  CK_ULONG                ulSequenceNumber;
-  CK_BBOOL                bIsExport;
-  CK_WTLS_RANDOM_DATA     RandomInfo;
-  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_WTLS_KEY_MAT_PARAMS;
-
-typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
-
-/* CMS is new for version 2.20 */
-typedef struct CK_CMS_SIG_PARAMS {
-  CK_OBJECT_HANDLE      certificateHandle;
-  CK_MECHANISM_PTR      pSigningMechanism;
-  CK_MECHANISM_PTR      pDigestMechanism;
-  CK_UTF8CHAR_PTR       pContentType;
-  CK_BYTE_PTR           pRequestedAttributes;
-  CK_ULONG              ulRequestedAttributesLen;
-  CK_BYTE_PTR           pRequiredAttributes;
-  CK_ULONG              ulRequiredAttributesLen;
-} CK_CMS_SIG_PARAMS;
-
-typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
-
-typedef struct CK_KEY_DERIVATION_STRING_DATA {
-  CK_BYTE_PTR pData;
-  CK_ULONG    ulLen;
-} CK_KEY_DERIVATION_STRING_DATA;
-
-typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
-  CK_KEY_DERIVATION_STRING_DATA_PTR;
-
-
-/* The CK_EXTRACT_PARAMS is used for the
- * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
- * of the base key should be used as the first bit of the
- * derived key */
-/* CK_EXTRACT_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_EXTRACT_PARAMS;
-
-typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-
-/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
- * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
- * indicate the Pseudo-Random Function (PRF) used to generate
- * key bits using PKCS #5 PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
-
-typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
-
-/* The following PRFs are defined in PKCS #5 v2.0. */
-#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
-
-
-/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
- * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
- * source of the salt value when deriving a key using PKCS #5
- * PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
-
-typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
-
-/* The following salt value sources are defined in PKCS #5 v2.0. */
-#define CKZ_SALT_SPECIFIED        0x00000001
-
-/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
- * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
- * parameters to the CKM_PKCS5_PBKD2 mechanism. */
-typedef struct CK_PKCS5_PBKD2_PARAMS {
-        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
-        CK_VOID_PTR                                pSaltSourceData;
-        CK_ULONG                                   ulSaltSourceDataLen;
-        CK_ULONG                                   iterations;
-        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-        CK_VOID_PTR                                pPrfData;
-        CK_ULONG                                   ulPrfDataLen;
-        CK_UTF8CHAR_PTR                            pPassword;
-        CK_ULONG_PTR                               ulPasswordLen;
-} CK_PKCS5_PBKD2_PARAMS;
-
-typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-
-#endif
--- a/jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11wrapper.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,473 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-/*
- * pkcs11wrapper.h
- * 18.05.2001
- *
- * declaration of all functions used by pkcs11wrapper.c
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
- */
-
-#ifndef _PKCS11WRAPPER_H
-#define _PKCS11WRAPPER_H 1
-
-/* disable asserts in product mode */
-#ifndef DEBUG
-  #ifndef NDEBUG
-    #define NDEBUG
-  #endif
-#endif
-
-/* extra PKCS#11 constants not in the standard include files */
-
-#define CKA_NETSCAPE_BASE                       (0x80000000 + 0x4E534350)
-#define CKA_NETSCAPE_TRUST_BASE                 (CKA_NETSCAPE_BASE + 0x2000)
-
-#define CKA_NETSCAPE_TRUST_SERVER_AUTH          (CKA_NETSCAPE_TRUST_BASE + 8)
-#define CKA_NETSCAPE_TRUST_CLIENT_AUTH          (CKA_NETSCAPE_TRUST_BASE + 9)
-#define CKA_NETSCAPE_TRUST_CODE_SIGNING (CKA_NETSCAPE_TRUST_BASE + 10)
-#define CKA_NETSCAPE_TRUST_EMAIL_PROTECTION     (CKA_NETSCAPE_TRUST_BASE + 11)
-
-/*
-
- Define the PKCS#11 functions to include and exclude. Reduces the size
- of the binary somewhat.
-
- This list needs to be kept in sync with the mapfile and PKCS11.java
-
-*/
-
-#define P11_ENABLE_C_INITIALIZE
-#define P11_ENABLE_C_FINALIZE
-#define P11_ENABLE_C_GETINFO
-#define P11_ENABLE_C_GETSLOTLIST
-#define P11_ENABLE_C_GETSLOTINFO
-#define P11_ENABLE_C_GETTOKENINFO
-#define P11_ENABLE_C_GETMECHANISMLIST
-#define P11_ENABLE_C_GETMECHANISMINFO
-#undef  P11_ENABLE_C_INITTOKEN
-#undef  P11_ENABLE_C_INITPIN
-#undef  P11_ENABLE_C_SETPIN
-#define P11_ENABLE_C_OPENSESSION
-#define P11_ENABLE_C_CLOSESESSION
-#undef  P11_ENABLE_C_CLOSEALLSESSIONS
-#define P11_ENABLE_C_GETSESSIONINFO
-#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
-#define P11_ENABLE_C_COPYOBJECT
-#define P11_ENABLE_C_DESTROYOBJECT
-#undef  P11_ENABLE_C_GETOBJECTSIZE
-#define P11_ENABLE_C_GETATTRIBUTEVALUE
-#define P11_ENABLE_C_SETATTRIBUTEVALUE
-#define P11_ENABLE_C_FINDOBJECTSINIT
-#define P11_ENABLE_C_FINDOBJECTS
-#define P11_ENABLE_C_FINDOBJECTSFINAL
-#define P11_ENABLE_C_ENCRYPTINIT
-#define P11_ENABLE_C_ENCRYPT
-#define P11_ENABLE_C_ENCRYPTUPDATE
-#define P11_ENABLE_C_ENCRYPTFINAL
-#define P11_ENABLE_C_DECRYPTINIT
-#define P11_ENABLE_C_DECRYPT
-#define P11_ENABLE_C_DECRYPTUPDATE
-#define P11_ENABLE_C_DECRYPTFINAL
-#define P11_ENABLE_C_DIGESTINIT
-#define P11_ENABLE_C_DIGEST
-#define P11_ENABLE_C_DIGESTUPDATE
-#define P11_ENABLE_C_DIGESTKEY
-#define P11_ENABLE_C_DIGESTFINAL
-#define P11_ENABLE_C_SIGNINIT
-#define P11_ENABLE_C_SIGN
-#define P11_ENABLE_C_SIGNUPDATE
-#define P11_ENABLE_C_SIGNFINAL
-#define P11_ENABLE_C_SIGNRECOVERINIT
-#define P11_ENABLE_C_SIGNRECOVER
-#define P11_ENABLE_C_VERIFYINIT
-#define P11_ENABLE_C_VERIFY
-#define P11_ENABLE_C_VERIFYUPDATE
-#define P11_ENABLE_C_VERIFYFINAL
-#define P11_ENABLE_C_VERIFYRECOVERINIT
-#define P11_ENABLE_C_VERIFYRECOVER
-#undef  P11_ENABLE_C_DIGESTENCRYPTUPDATE
-#undef  P11_ENABLE_C_DECRYPTDIGESTUPDATE
-#undef  P11_ENABLE_C_SIGNENCRYPTUPDATE
-#undef  P11_ENABLE_C_DECRYPTVERIFYUPDATE
-#define P11_ENABLE_C_GENERATEKEY
-#define P11_ENABLE_C_GENERATEKEYPAIR
-#define P11_ENABLE_C_WRAPKEY
-#define P11_ENABLE_C_UNWRAPKEY
-#define P11_ENABLE_C_DERIVEKEY
-#define P11_ENABLE_C_SEEDRANDOM
-#define P11_ENABLE_C_GENERATERANDOM
-#undef  P11_ENABLE_C_GETFUNCTIONSTATUS
-#undef  P11_ENABLE_C_CANCELFUNCTION
-#undef  P11_ENABLE_C_WAITFORSLOTEVENT
-
-/* include the platform dependent part of the header */
-#include "p11_md.h"
-
-#include "pkcs11.h"
-#include "pkcs-11v2-20a3.h"
-#include <jni.h>
-#include <jni_util.h>
-#include <stdarg.h>
-
-#define MAX_STACK_BUFFER_LEN (4 * 1024)
-#define MAX_HEAP_BUFFER_LEN (64 * 1024)
-
-#define MAX_DIGEST_LEN (64)
-
-#ifndef min
-#define min(a, b)       (((a) < (b)) ? (a) : (b))
-#endif
-
-#define ckBBoolToJBoolean(x) ((x == TRUE) ? JNI_TRUE : JNI_FALSE);
-#define jBooleanToCKBBool(x) ((x == JNI_TRUE) ? TRUE : FALSE);
-
-#define ckByteToJByte(x) ((jbyte) x)
-#define jByteToCKByte(x) ((CK_BYTE) x)
-
-#define ckLongToJLong(x) ((jlong) x)
-#define jLongToCKLong(x) ((CK_LONG) x)
-
-#define ckULongToJLong(x) ((jlong) x)
-#define jLongToCKULong(x) ((CK_ULONG) x)
-
-// For CK_UNAVAILABLE_INFORMATION, always return -1 to avoid 32/64 bit problems.
-#define ckULongSpecialToJLong(x) (((x) == CK_UNAVAILABLE_INFORMATION) \
-    ? (jlong)-1 : ((jlong) x))
-
-#define ckCharToJChar(x) ((jchar) x)
-#define jCharToCKChar(x) ((CK_CHAR) x)
-
-#define ckUTF8CharToJChar(x) ((jchar) x)
-#define jCharToCKUTF8Char(x) ((CK_UTF8CHAR) x)
-
-#define ckFlageToJLong(x) ((jlong) x)
-
-#define ckVoidPtrToJObject(x) ((jobject) x)
-#define jObjectToCKVoidPtr(x) ((CK_VOID_PTR) x)
-
-#define jIntToCKLong(x)         ((CK_LONG) x)
-#define jIntToCKULong(x)        ((CK_ULONG) x)
-#define ckLongToJInt(x)         ((jint) x)
-#define ckULongToJInt(x)        ((jint) x)
-#define ckULongToJSize(x)       ((jsize) x)
-#define unsignedIntToCKULong(x) ((CK_ULONG) x)
-
-#ifdef P11_DEBUG
-#define TRACE0(s) { printf(s); fflush(stdout); }
-#define TRACE1(s, p1) { printf(s, p1); fflush(stdout); }
-#define TRACE2(s, p1, p2) { printf(s, p1, p2); fflush(stdout); }
-#define TRACE3(s, p1, p2, p3) { printf(s, p1, p2, p3); fflush(stdout); }
-#else
-#define TRACE0(s)
-#define TRACE1(s, p1)
-#define TRACE2(s, p1, p2)
-#define TRACE3(s, p1, p2, p3)
-#define TRACE_INTEND
-#define TRACE_UNINTEND
-#endif
-
-/* debug output */
-extern jboolean debug;
-void printDebug(const char *format, ...);
-
-#define CK_ASSERT_OK 0L
-
-#define CLASS_INFO "sun/security/pkcs11/wrapper/CK_INFO"
-#define CLASS_VERSION "sun/security/pkcs11/wrapper/CK_VERSION"
-#define CLASS_SLOT_INFO "sun/security/pkcs11/wrapper/CK_SLOT_INFO"
-#define CLASS_TOKEN_INFO "sun/security/pkcs11/wrapper/CK_TOKEN_INFO"
-#define CLASS_MECHANISM "sun/security/pkcs11/wrapper/CK_MECHANISM"
-#define CLASS_MECHANISM_INFO "sun/security/pkcs11/wrapper/CK_MECHANISM_INFO"
-#define CLASS_SESSION_INFO "sun/security/pkcs11/wrapper/CK_SESSION_INFO"
-#define CLASS_ATTRIBUTE "sun/security/pkcs11/wrapper/CK_ATTRIBUTE"
-#define CLASS_DATE "sun/security/pkcs11/wrapper/CK_DATE"
-#define CLASS_PKCS11EXCEPTION "sun/security/pkcs11/wrapper/PKCS11Exception"
-#define CLASS_PKCS11RUNTIMEEXCEPTION "sun/security/pkcs11/wrapper/PKCS11RuntimeException"
-#define CLASS_FILE_NOT_FOUND_EXCEPTION "java/io/FileNotFoundException"
-#define CLASS_C_INITIALIZE_ARGS "sun/security/pkcs11/wrapper/CK_C_INITIALIZE_ARGS"
-#define CLASS_CREATEMUTEX "sun/security/pkcs11/wrapper/CK_CREATEMUTEX"
-#define CLASS_DESTROYMUTEX "sun/security/pkcs11/wrapper/CK_DESTROYMUTEX"
-#define CLASS_LOCKMUTEX "sun/security/pkcs11/wrapper/CK_LOCKMUTEX"
-#define CLASS_UNLOCKMUTEX "sun/security/pkcs11/wrapper/CK_UNLOCKMUTEX"
-#define CLASS_NOTIFY "sun/security/pkcs11/wrapper/CK_NOTIFY"
-
-
-/* mechanism parameter classes */
-
-#define CLASS_RSA_PKCS_OAEP_PARAMS "sun/security/pkcs11/wrapper/CK_RSA_PKCS_OAEP_PARAMS"
-#define CLASS_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_MAC_GENERAL_PARAMS"
-#define CLASS_PBE_PARAMS "sun/security/pkcs11/wrapper/CK_PBE_PARAMS"
-#define PBE_INIT_VECTOR_SIZE 8
-#define CLASS_PKCS5_PBKD2_PARAMS "sun/security/pkcs11/wrapper/CK_PKCS5_PBKD2_PARAMS"
-#define CLASS_EXTRACT_PARAMS "sun/security/pkcs11/wrapper/CK_EXTRACT_PARAMS"
-
-#define CLASS_RSA_PKCS_PSS_PARAMS "sun/security/pkcs11/wrapper/CK_RSA_PKCS_PSS_PARAMS"
-#define CLASS_ECDH1_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_ECDH1_DERIVE_PARAMS"
-#define CLASS_ECDH2_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_ECDH2_DERIVE_PARAMS"
-#define CLASS_X9_42_DH1_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_X9_42_DH1_DERIVE_PARAMS"
-#define CLASS_X9_42_DH2_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_X9_42_DH2_DERIVE_PARAMS"
-
-/*
-#define CLASS_KEA_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_KEA_DERIVE_PARAMS"
-#define CLASS_RC2_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_PARAMS"
-#define CLASS_RC2_CBC_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_CBC_PARAMS"
-#define CLASS_RC2_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_RC2_MAC_GENERAL_PARAMS"
-#define CLASS_RC5_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_PARAMS"
-#define CLASS_RC5_CBC_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_CBC_PARAMS"
-#define CLASS_RC5_MAC_GENERAL_PARAMS "sun/security/pkcs11/wrapper/CK_RC5_MAC_GENERAL_PARAMS"
-#define CLASS_SKIPJACK_PRIVATE_WRAP_PARAMS "sun/security/pkcs11/wrapper/CK_SKIPJACK_PRIVATE_WRAP_PARAMS"
-#define CLASS_SKIPJACK_RELAYX_PARAMS "sun/security/pkcs11/wrapper/CK_SKIPJACK_RELAYX_PARAMS"
-#define CLASS_KEY_WRAP_SET_OAEP_PARAMS "sun/security/pkcs11/wrapper/CK_KEY_WRAP_SET_OAEP_PARAMS"
-#define CLASS_KEY_DERIVATION_STRING_DATA "sun/security/pkcs11/wrapper/CK_KEY_DERIVATION_STRING_DATA"
-*/
-
-#define CLASS_SSL3_RANDOM_DATA "sun/security/pkcs11/wrapper/CK_SSL3_RANDOM_DATA"
-// CLASS_SSL3_RANDOM_DATA is used by CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS
-#define CLASS_SSL3_KEY_MAT_OUT "sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_OUT"
-// CLASS_SSL3_KEY_MAT_OUT is used by CLASS_SSL3_KEY_MAT_PARAMS
-#define CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS "sun/security/pkcs11/wrapper/CK_SSL3_MASTER_KEY_DERIVE_PARAMS"
-#define CLASS_SSL3_KEY_MAT_PARAMS "sun/security/pkcs11/wrapper/CK_SSL3_KEY_MAT_PARAMS"
-#define CLASS_TLS_PRF_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS"
-#define CLASS_AES_CTR_PARAMS "sun/security/pkcs11/wrapper/CK_AES_CTR_PARAMS"
-
-/* function to convert a PKCS#11 return value other than CK_OK into a Java Exception
- * or to throw a PKCS11RuntimeException
- */
-
-jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue);
-void throwOutOfMemoryError(JNIEnv *env, const char *message);
-void throwNullPointerException(JNIEnv *env, const char *message);
-void throwIOException(JNIEnv *env, const char *message);
-void throwPKCS11RuntimeException(JNIEnv *env, const char *message);
-void throwDisconnectedRuntimeException(JNIEnv *env);
-
-/* function to free CK_ATTRIBUTE array
- */
-void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len);
-
-/* funktions to convert Java arrays to a CK-type array and the array length */
-
-void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckLength);
-void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckLength);
-void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckLength);
-void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckLength);
-void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckLength);
-void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength);
-void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jAArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength);
-/*void jObjectArrayToCKVoidPtrArray(JNIEnv *env, const jobjectArray jArray, CK_VOID_PTR_PTR ckpArray, CK_ULONG_PTR ckpLength); */
-
-
-/* funktions to convert a CK-type array and the array length to a Java array */
-
-jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength);
-jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength);
-jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG length);
-jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength);
-
-
-/* funktions to convert a CK-type structure or a pointer to a CK-value to a Java object */
-
-jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL* ckpValue);
-jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue);
-jobject ckDatePtrToJDateObject(JNIEnv *env, const CK_DATE *ckpValue);
-jobject ckVersionPtrToJVersion(JNIEnv *env, const CK_VERSION_PTR ckpVersion);
-jobject ckSessionInfoPtrToJSessionInfo(JNIEnv *env, const CK_SESSION_INFO_PTR ckpSessionInfo);
-jobject ckAttributePtrToJAttribute(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute);
-
-
-/* funktion to convert the CK-value used by the CK_ATTRIBUTE structure to a Java object */
-
-jobject ckAttributeValueToJObject(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute);
-
-
-/* funktions to convert a Java object to a CK-type structure or a pointer to a CK-value */
-
-CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject);
-CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject);
-CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject);
-CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject);
-CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject);
-CK_VERSION_PTR jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion);
-CK_DATE * jDateObjectPtrToCKDatePtr(JNIEnv *env, jobject jDate);
-CK_ATTRIBUTE jAttributeToCKAttribute(JNIEnv *env, jobject jAttribute);
-/*CK_MECHANISM jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism);*/
-void jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism, CK_MECHANISM_PTR ckMechanismPtr);
-
-
-/* funktions to convert Java objects used by the Mechanism and Attribute class to a CK-type structure */
-
-void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *pLength);
-void jMechanismParameterToCKMechanismParameter(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength);
-
-
-/* functions to convert a specific Java mechanism parameter object to a CK-mechanism parameter structure */
-
-CK_RSA_PKCS_OAEP_PARAMS jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobject jParam);
-CK_KEA_DERIVE_PARAMS jKeaDeriveParamToCKKeaDeriveParam(JNIEnv *env, jobject jParam);
-CK_RC2_CBC_PARAMS jRc2CbcParamToCKRc2CbcParam(JNIEnv *env, jobject jParam);
-CK_RC2_MAC_GENERAL_PARAMS jRc2MacGeneralParamToCKRc2MacGeneralParam(JNIEnv *env, jobject jParam);
-CK_RC5_PARAMS jRc5ParamToCKRc5Param(JNIEnv *env, jobject jParam);
-CK_RC5_CBC_PARAMS jRc5CbcParamToCKRc5CbcParam(JNIEnv *env, jobject jParam);
-CK_RC5_MAC_GENERAL_PARAMS jRc5MacGeneralParamToCKRc5MacGeneralParam(JNIEnv *env, jobject jParam);
-CK_SKIPJACK_PRIVATE_WRAP_PARAMS jSkipjackPrivateWrapParamToCKSkipjackPrivateWrapParam(JNIEnv *env, jobject jParam);
-CK_SKIPJACK_RELAYX_PARAMS jSkipjackRelayxParamToCKSkipjackRelayxParam(JNIEnv *env, jobject jParam);
-CK_PBE_PARAMS jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam);
-void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
-CK_PKCS5_PBKD2_PARAMS jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject jParam);
-CK_KEY_WRAP_SET_OAEP_PARAMS jKeyWrapSetOaepParamToCKKeyWrapSetOaepParam(JNIEnv *env, jobject jParam);
-void copyBackSetUnwrappedKey(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
-CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam);
-void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
-CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam);
-void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism);
-CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam);
-CK_RSA_PKCS_PSS_PARAMS jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam);
-CK_ECDH1_DERIVE_PARAMS jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam);
-CK_ECDH2_DERIVE_PARAMS jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv *env, jobject jParam);
-CK_X9_42_DH1_DERIVE_PARAMS jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env, jobject jParam);
-CK_X9_42_DH2_DERIVE_PARAMS jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env, jobject jParam);
-
-
-/* functions to convert the InitArgs object for calling the right Java mutex functions */
-
-CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject pInitArgs);
-
-#ifndef NO_CALLBACKS /* if the library should not make callbacks; e.g. no javai.lib or jvm.lib available */
-CK_RV callJCreateMutex(CK_VOID_PTR_PTR ppMutex);
-CK_RV callJDestroyMutex(CK_VOID_PTR pMutex);
-CK_RV callJLockMutex(CK_VOID_PTR pMutex);
-CK_RV callJUnlockMutex(CK_VOID_PTR pMutex);
-#endif /* NO_CALLBACKS */
-
-void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData);
-ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
-CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation);
-
-/* A structure to encapsulate the required data for a Notify callback */
-struct NotifyEncapsulation {
-
-    /* The object that implements the CK_NOTIFY interface and which should be
-     * notified.
-     */
-    jobject jNotifyObject;
-
-    /* The data object to pass back to the Notify object upon callback. */
-    jobject jApplicationData;
-};
-typedef struct NotifyEncapsulation NotifyEncapsulation;
-
-/* The function for handling notify callbacks. */
-CK_RV notifyCallback(
-    CK_SESSION_HANDLE hSession,     /* the session's handle */
-    CK_NOTIFICATION   event,
-    CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
-);
-
-
-/* A node of the list of notify callbacks. To be able to free the resources after use. */
-struct NotifyListNode {
-
-    /* The handle of the session this notify object is attached to*/
-    CK_SESSION_HANDLE hSession;
-
-    /* Reference to the Notify encapsulation object that was passed to C_OpenSession. */
-    NotifyEncapsulation *notifyEncapsulation;
-
-    /* Pointer to the next node in the list. */
-    struct NotifyListNode *next;
-
-};
-typedef struct NotifyListNode NotifyListNode;
-
-void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation *notifyEncapsulation);
-NotifyEncapsulation * removeNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession);
-NotifyEncapsulation * removeFirstNotifyEntry(JNIEnv *env);
-
-jobject createLockObject(JNIEnv *env);
-void destroyLockObject(JNIEnv *env, jobject jLockObject);
-
-extern jfieldID pNativeDataID;
-extern jfieldID mech_mechanismID;
-extern jfieldID mech_pParameterID;
-
-extern jclass jByteArrayClass;
-extern jclass jLongClass;
-
-#ifndef NO_CALLBACKS
-extern NotifyListNode *notifyListHead;
-extern jobject notifyListLock;
-
-extern jobject jInitArgsObject;
-extern CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs;
-#endif /* NO_CALLBACKS */
-
-#ifdef P11_MEMORYDEBUG
-#include <stdlib.h>
-
-/* Simple malloc/free dumper */
-void *p11malloc(size_t c, char *file, int line);
-void p11free(void *p, char *file, int line);
-
-/* Use THIS_FILE when it is available. */
-#ifndef THIS_FILE
-    #define THIS_FILE __FILE__
-#endif
-
-#define malloc(c)       (p11malloc((c), THIS_FILE, __LINE__))
-#define free(c)         (p11free((c), THIS_FILE, __LINE__))
-
-#endif
-
-#endif /* _PKCS11WRAPPER_H */
--- a/jdk/src/jdk.crypto.token/solaris/conf/security/sunpkcs11-solaris.cfg	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#
-# Configuration file to allow the SunPKCS11 provider to utilize
-# the Solaris Cryptographic Framework, if it is available
-#
-
-name = Solaris
-
-description = SunPKCS11 accessing Solaris Cryptographic Framework
-
-library = /usr/lib/$ISA/libpkcs11.so
-
-handleStartupErrors = ignoreAll
-
-# Use the X9.63 encoding for EC points (do not wrap in an ASN.1 OctetString).
-useEcX963Encoding = true
-
-attributes = compatibility
-
-disabledMechanisms = {
-  CKM_DSA_KEY_PAIR_GEN
-  SecureRandom
-}
-
--- a/jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2005, 2016, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <dlfcn.h>
-
-#include <jni_util.h>
-
-#include "j2secmod.h"
-#include "pkcs11wrapper.h"
-
-void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
-    void *hModule = (void*)jlong_to_ptr(jHandle);
-    void *fAddress = dlsym(hModule, functionName);
-    if (fAddress == NULL) {
-        char errorMessage[256];
-        snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName);
-        throwNullPointerException(env, errorMessage);
-        return NULL;
-    }
-    return fAddress;
-}
-
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
-  (JNIEnv *env, jclass thisClass, jstring jLibName)
-{
-    void *hModule;
-    const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
-    if (libName == NULL) {
-        return 0L;
-    }
-
-    // look up existing handle only, do not load
-#if defined(AIX)
-    hModule = dlopen(libName, RTLD_LAZY);
-#else
-    hModule = dlopen(libName, RTLD_NOLOAD);
-#endif
-    dprintf2("-handle for %s: %u\n", libName, hModule);
-    (*env)->ReleaseStringUTFChars(env, jLibName, libName);
-    return ptr_to_jlong(hModule);
-}
-
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary
-  (JNIEnv *env, jclass thisClass, jstring jLibName)
-{
-    void *hModule;
-    const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
-    if (libName == NULL) {
-       return 0L;
-    }
-
-    dprintf1("-lib %s\n", libName);
-    hModule = dlopen(libName, RTLD_LAZY);
-    (*env)->ReleaseStringUTFChars(env, jLibName, libName);
-    dprintf2("-handle: %u (0X%X)\n", hModule, hModule);
-
-    if (hModule == NULL) {
-        throwIOException(env, dlerror());
-        return 0;
-    }
-
-    return ptr_to_jlong(hModule);
-}
--- a/jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-// in nss.h:
-// extern PRBool NSS_VersionCheck(const char *importedVersion);
-// extern SECStatus NSS_Initialize(const char *configdir,
-//     const char *certPrefix, const char *keyPrefix,
-//     const char *secmodName, PRUint32 flags);
-
-typedef int (*FPTR_VersionCheck)(const char *importedVersion);
-typedef int (*FPTR_Initialize)(const char *configdir,
-        const char *certPrefix, const char *keyPrefix,
-        const char *secmodName, unsigned int flags);
-
-// in secmod.h
-//extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent,
-//                                                      PRBool recurse);
-//char **SECMOD_GetModuleSpecList(SECMODModule *module);
-//extern SECMODModuleList *SECMOD_GetDBModuleList(void);
-
-typedef void *(*FPTR_LoadModule)(char *moduleSpec, void *parent, int recurse);
-typedef char **(*FPTR_GetModuleSpecList)(void *module);
-typedef void *(*FPTR_GetDBModuleList)(void);
--- a/jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-/*
- * pkcs11wrapper.c
- * 18.05.2001
- *
- * This module contains the native functions of the Java to PKCS#11 interface
- * which are platform dependent. This includes loading a dynamic link libary,
- * retrieving the function list and unloading the dynamic link library.
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <dlfcn.h>
-
-#include <jni.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    connect
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
-    (JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList)
-{
-    void *hModule;
-    char *error;
-    CK_C_GetFunctionList C_GetFunctionList=NULL;
-    CK_RV rv;
-    ModuleData *moduleData;
-    jobject globalPKCS11ImplementationReference;
-    char *systemErrorMessage;
-    char *exceptionMessage;
-    const char *getFunctionListStr;
-
-    const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0);
-    if (libraryNameStr == NULL) {
-        return;
-    }
-    TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
-
-
-    /*
-     * Load the PKCS #11 DLL
-     */
-    dlerror(); /* clear any old error message not fetched */
-#ifdef DEBUG
-    hModule = dlopen(libraryNameStr, RTLD_NOW);
-#else
-    hModule = dlopen(libraryNameStr, RTLD_LAZY);
-#endif /* DEBUG */
-
-    if (hModule == NULL) {
-        systemErrorMessage = dlerror();
-        exceptionMessage = (char *) malloc(sizeof(char) * (strlen(systemErrorMessage) + strlen(libraryNameStr) + 1));
-        if (exceptionMessage == NULL) {
-            throwOutOfMemoryError(env, 0);
-            return;
-        }
-        strcpy(exceptionMessage, systemErrorMessage);
-        strcat(exceptionMessage, libraryNameStr);
-        throwIOException(env, exceptionMessage);
-        (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
-        free(exceptionMessage);
-        return;
-    }
-
-    /*
-     * Get function pointer to C_GetFunctionList
-     */
-    dlerror(); /* clear any old error message not fetched */
-    // with the old JAR file jGetFunctionList is null, temporarily check for that
-    if (jGetFunctionList != NULL) {
-        getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
-        if (getFunctionListStr == NULL) {
-            return;
-        }
-        C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr);
-        (*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
-    }
-    if (C_GetFunctionList == NULL) {
-        throwIOException(env, "ERROR: C_GetFunctionList == NULL");
-        return;
-    } else if ( (systemErrorMessage = dlerror()) != NULL ){
-        throwIOException(env, systemErrorMessage);
-        return;
-    }
-
-    /*
-     * Get function pointers to all PKCS #11 functions
-     */
-    moduleData = (ModuleData *) malloc(sizeof(ModuleData));
-    if (moduleData == NULL) {
-        dlclose(hModule);
-        throwOutOfMemoryError(env, 0);
-        return;
-    }
-    moduleData->hModule = hModule;
-    moduleData->applicationMutexHandler = NULL;
-    rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
-    globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
-    putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
-
-    (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
-    TRACE0("FINISHED\n");
-
-    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    disconnect
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_disconnect
-    (JNIEnv *env, jobject obj)
-{
-    ModuleData *moduleData;
-    TRACE0("DEBUG: disconnecting module...");
-    moduleData = removeModuleEntry(env, obj);
-
-    if (moduleData != NULL) {
-        dlclose(moduleData->hModule);
-    }
-
-    free(moduleData);
-    TRACE0("FINISHED\n");
-
-}
--- a/jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-/*
- * pkcs11wrapper.h
- * 18.05.2001
- *
- * declaration of all functions used by pkcs11wrapper.c
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-
-/* defines for UNIX platforms *************************************************/
-
-#ifndef _P11_MD_H
-#define _P11_MD_H 1
-
-#define CK_PTR *
-#define CK_DEFINE_FUNCTION(returnType, name) returnType name
-#define CK_DECLARE_FUNCTION(returnType, name) returnType name
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
-#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
-#ifndef NULL_PTR
-#define NULL_PTR 0
-#endif
-
-#include "pkcs11.h"
-
-#include "jni.h"
-
-/* A data structure to hold required information about a PKCS#11 module. */
-struct ModuleData {
-
-    /* the module (DLL or shared library) handle */
-    void *hModule;
-
-    /* The pointer to the PKCS#11 functions of this module. */
-    CK_FUNCTION_LIST_PTR ckFunctionListPtr;
-
-    /* Reference to the object to use for mutex handling. NULL, if not used. */
-    jobject applicationMutexHandler;
-
-};
-typedef struct ModuleData ModuleData;
-
-#endif  /* _P11_MD_H */
--- a/jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/j2secmod_md.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2005, 2011, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <jni_util.h>
-
-#include "j2secmod.h"
-
-extern void throwNullPointerException(JNIEnv *env, const char *message);
-extern void throwIOException(JNIEnv *env, const char *message);
-
-void *findFunction(JNIEnv *env, jlong jHandle, const char *functionName) {
-    HINSTANCE hModule = (HINSTANCE)jHandle;
-    void *fAddress = GetProcAddress(hModule, functionName);
-    if (fAddress == NULL) {
-        char errorMessage[256];
-        _snprintf(errorMessage, sizeof(errorMessage), "Symbol not found: %s", functionName);
-        throwNullPointerException(env, errorMessage);
-        return NULL;
-    }
-    return fAddress;
-}
-
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssGetLibraryHandle
-  (JNIEnv *env, jclass thisClass, jstring jLibName)
-{
-    const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
-    HMODULE hModule = GetModuleHandle(libName);
-    dprintf2("-handle for %s: %d\n", libName, hModule);
-    (*env)->ReleaseStringUTFChars(env, jLibName, libName);
-    return (jlong)hModule;
-}
-
-JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary
-  (JNIEnv *env, jclass thisClass, jstring jName)
-{
-    HINSTANCE hModule;
-    LPVOID lpMsgBuf;
-
-    const char *libName = (*env)->GetStringUTFChars(env, jName, NULL);
-    dprintf1("-lib %s\n", libName);
-
-    hModule = LoadLibrary(libName);
-    (*env)->ReleaseStringUTFChars(env, jName, libName);
-
-    if (hModule == NULL) {
-        FormatMessage(
-            FORMAT_MESSAGE_ALLOCATE_BUFFER |
-            FORMAT_MESSAGE_FROM_SYSTEM |
-            FORMAT_MESSAGE_IGNORE_INSERTS,
-            NULL,
-            GetLastError(),
-            0, /* Default language */
-            (LPTSTR) &lpMsgBuf,
-            0,
-            NULL
-        );
-        dprintf1("-error: %s\n", lpMsgBuf);
-        throwIOException(env, (char*)lpMsgBuf);
-        LocalFree(lpMsgBuf);
-        return 0;
-    }
-    dprintf2("-handle: %d (0X%X)\n", hModule, hModule);
-    return (jlong)hModule;
-}
--- a/jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/j2secmod_md.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-#include <windows.h>
-
-// in nss.h:
-// extern PRBool NSS_VersionCheck(const char *importedVersion);
-// extern SECStatus NSS_Initialize(const char *configdir,
-//      const char *certPrefix, const char *keyPrefix,
-//      const char *secmodName, PRUint32 flags);
-
-typedef int __declspec(dllimport) (*FPTR_VersionCheck)(const char *importedVersion);
-typedef int __declspec(dllimport) (*FPTR_Initialize)(const char *configdir,
-        const char *certPrefix, const char *keyPrefix,
-        const char *secmodName, unsigned int flags);
-
-// in secmod.h
-//extern SECMODModule *SECMOD_LoadModule(char *moduleSpec,SECMODModule *parent,
-//                                                      PRBool recurse);
-//char **SECMOD_GetModuleSpecList(SECMODModule *module);
-//extern SECMODModuleList *SECMOD_GetDBModuleList(void);
-
-typedef void __declspec(dllimport) *(*FPTR_LoadModule)(char *moduleSpec, void *parent, int recurse);
-typedef char __declspec(dllimport) **(*FPTR_GetModuleSpecList)(void *module);
-typedef void __declspec(dllimport) *(*FPTR_GetDBModuleList)(void);
--- a/jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/p11_md.c	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-/*
- * pkcs11wrapper.c
- * 18.05.2001
- *
- * This module contains the native functions of the Java to PKCS#11 interface
- * which are platform dependent. This includes loading a dynamic link libary,
- * retrieving the function list and unloading the dynamic link library.
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-
-#include "pkcs11wrapper.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <windows.h>
-
-#include <jni.h>
-
-#include "sun_security_pkcs11_wrapper_PKCS11.h"
-
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    connect
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
-    (JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList)
-{
-    HINSTANCE hModule;
-    CK_C_GetFunctionList C_GetFunctionList;
-    CK_RV rv;
-    ModuleData *moduleData;
-    jobject globalPKCS11ImplementationReference;
-    LPVOID lpMsgBuf;
-    char *exceptionMessage;
-    const char *getFunctionListStr;
-
-    const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0);
-    TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
-
-
-  /*
-   * Load the PKCS #11 DLL
-   */
-    hModule = LoadLibrary(libraryNameStr);
-    if (hModule == NULL) {
-        FormatMessage(
-            FORMAT_MESSAGE_ALLOCATE_BUFFER |
-            FORMAT_MESSAGE_FROM_SYSTEM |
-            FORMAT_MESSAGE_IGNORE_INSERTS,
-            NULL,
-            GetLastError(),
-            0, /* Default language */
-            (LPTSTR) &lpMsgBuf,
-            0,
-            NULL
-        );
-        exceptionMessage = (char *) malloc(sizeof(char) * (strlen((LPTSTR) lpMsgBuf) + strlen(libraryNameStr) + 1));
-        strcpy(exceptionMessage, (LPTSTR) lpMsgBuf);
-        strcat(exceptionMessage, libraryNameStr);
-        throwIOException(env, (LPTSTR) exceptionMessage);
-        /* Free the buffer. */
-        free(exceptionMessage);
-        LocalFree(lpMsgBuf);
-        return;
-    }
-
-    /*
-     * Get function pointer to C_GetFunctionList
-     */
-    getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
-    C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule, getFunctionListStr);
-    (*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
-    if (C_GetFunctionList == NULL) {
-        FormatMessage(
-            FORMAT_MESSAGE_ALLOCATE_BUFFER |
-            FORMAT_MESSAGE_FROM_SYSTEM |
-            FORMAT_MESSAGE_IGNORE_INSERTS,
-            NULL,
-            GetLastError(),
-            0, /* Default language */
-            (LPTSTR) &lpMsgBuf,
-            0,
-            NULL
-        );
-        throwIOException(env, (LPTSTR) lpMsgBuf);
-        /* Free the buffer. */
-        LocalFree( lpMsgBuf );
-        return;
-    }
-
-    /*
-     * Get function pointers to all PKCS #11 functions
-     */
-    moduleData = (ModuleData *) malloc(sizeof(ModuleData));
-    moduleData->hModule = hModule;
-    moduleData->applicationMutexHandler = NULL;
-    rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
-    globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
-    putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
-
-    (*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
-    TRACE0("FINISHED\n");
-
-    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
-}
-
-/*
- * Class:     sun_security_pkcs11_wrapper_PKCS11
- * Method:    disconnect
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_disconnect
-    (JNIEnv *env, jobject obj)
-{
-    ModuleData *moduleData;
-    TRACE0("DEBUG: disconnecting module...");
-    moduleData = removeModuleEntry(env, obj);
-
-    if (moduleData != NULL) {
-        FreeLibrary(moduleData->hModule);
-    }
-
-    free(moduleData);
-    TRACE0("FINISHED\n");
-}
--- a/jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/p11_md.h	Mon Jan 23 14:04:44 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
- *
- * Redistribution and use in  source and binary forms, with or without
- * modification, are permitted  provided that the following conditions are met:
- *
- * 1. Redistributions of  source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in  binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- *
- * 3. The end-user documentation included with the redistribution, if any, must
- *    include the following acknowledgment:
- *
- *    "This product includes software developed by IAIK of Graz University of
- *     Technology."
- *
- *    Alternately, this acknowledgment may appear in the software itself, if
- *    and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Graz University of Technology" and "IAIK of Graz University of
- *    Technology" must not be used to endorse or promote products derived from
- *    this software without prior written permission.
- *
- * 5. Products derived from this software may not be called
- *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
- *    written permission of Graz University of Technology.
- *
- *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
- *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY  OF SUCH DAMAGE.
- */
-
-/*
- * platoform.h
- * 10.12.2001
- *
- * declaration of all platform dependent functions used by pkcs11wrapper.c
- *
- * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
- */
-
-/* defines for WIN32 platform *************************************************/
-
-#include <windows.h>
-
-/* statement according to PKCS11 docu */
-#pragma pack(push, cryptoki, 1)
-
-/* definitions according to PKCS#11 docu for Win32 environment */
-#define CK_PTR *
-#define CK_DEFINE_FUNCTION(returnType, name) returnType __declspec(dllexport) name
-#define CK_DECLARE_FUNCTION(returnType, name) returnType __declspec(dllimport) name
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType __declspec(dllimport) (* name)
-#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
-#ifndef NULL_PTR
-#define NULL_PTR 0
-#endif /* NULL_PTR */
-
-/* to avoid clash with Win32 #define */
-#ifdef CreateMutex
-#undef CreateMutex
-#endif /* CreateMutex */
-
-#include "pkcs11.h"
-
-/* statement according to PKCS11 docu */
-#pragma pack(pop, cryptoki)
-
-#include "jni.h"
-
-/* A data structure to hold required information about a PKCS#11 module. */
-struct ModuleData {
-
-    HINSTANCE hModule;
-
-    /* The pointer to the PKCS#11 functions of this module. */
-    CK_FUNCTION_LIST_PTR ckFunctionListPtr;
-
-    /* Reference to the object to use for mutex handling. NULL, if not used. */
-    jobject applicationMutexHandler;
-
-};
-typedef struct ModuleData ModuleData;
--- a/jdk/test/java/lang/SecurityManager/CheckSecurityProvider.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/java/lang/SecurityManager/CheckSecurityProvider.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, 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
@@ -62,7 +62,7 @@
         if (os.equals("SunOS")) {
             layer.findModule("jdk.crypto.ucrypto")
                 .ifPresent(m -> expected.add("com.oracle.security.ucrypto.UcryptoProvider"));
-            layer.findModule("jdk.crypto.token")
+            layer.findModule("jdk.crypto.cryptoki")
                 .ifPresent(m -> expected.add("sun.security.pkcs11.SunPKCS11"));
         }
         expected.add("sun.security.provider.Sun");
@@ -91,7 +91,7 @@
             expected.add("apple.security.AppleProvider");
         }
         if (!os.equals("SunOS")) {
-            layer.findModule("jdk.crypto.token")
+            layer.findModule("jdk.crypto.cryptoki")
                 .ifPresent(m -> expected.add("sun.security.pkcs11.SunPKCS11"));
         }
 
--- a/jdk/test/sun/security/ec/TestEC.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/ec/TestEC.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, 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
@@ -34,8 +34,8 @@
  * @library ../pkcs11/ec
  * @library ../pkcs11/sslecc
  * @library ../../../java/security/testlibrary
- * @modules jdk.crypto.token/sun.security.pkcs11.wrapper
- * @compile --add-modules jdk.crypto.token TestEC.java
+ * @modules jdk.crypto.cryptoki/sun.security.pkcs11.wrapper
+ * @compile --add-modules jdk.crypto.cryptoki TestEC.java
  * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
  * @run main/othervm/java.security.policy=TestEC.policy -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
  */
--- a/jdk/test/sun/security/pkcs11/Cipher/ReinitCipher.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Cipher/ReinitCipher.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm ReinitCipher
  * @run main/othervm ReinitCipher sm
  */
--- a/jdk/test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestPKCS5PaddingError.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Test internal PKCS5Padding impl with various error conditions.
  * @author Valerie Peng
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestPKCS5PaddingError
  * @run main/othervm TestPKCS5PaddingError sm
  */
--- a/jdk/test/sun/security/pkcs11/Cipher/TestRSACipher.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRSACipher.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestRSACipher
  * @run main/othervm TestRSACipher sm
  */
--- a/jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRSACipherWrap.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -27,7 +27,7 @@
  * @summary basic test for RSA cipher key wrapping functionality
  * @author Valerie Peng
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestRSACipherWrap
  * @run main/othervm TestRSACipherWrap sm
  */
--- a/jdk/test/sun/security/pkcs11/Cipher/TestRawRSACipher.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestRawRSACipher.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -28,7 +28,7 @@
  * @author Valerie Peng
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestRawRSACipher
  * @run main/othervm TestRawRSACipher sm
  */
--- a/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, 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
@@ -28,7 +28,7 @@
  * @author Valerie Peng
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestSymmCiphers
  * @run main/othervm TestSymmCiphers sm
  */
--- a/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2017, 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
@@ -28,7 +28,7 @@
  * @author Valerie Peng
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestSymmCiphersNoPad
  * @run main/othervm TestSymmCiphersNoPad sm
  */
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -26,7 +26,7 @@
  * @bug 8072452
  * @summary Support DHE sizes up to 8192-bits and DSA sizes up to 3072-bits
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm SupportedDHKeys
  * @run main/othervm SupportedDHKeys sm
  */
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/TestDH.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/TestDH.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Verify that DH works properly
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestDH
  * @run main/othervm TestDH sm
  */
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/TestInterop.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/TestInterop.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -26,7 +26,7 @@
  * @bug 7146728
  * @summary Interop test for DH with secret that has a leading 0x00 byte
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestInterop
  * @run main/othervm TestInterop sm
  */
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/TestShort.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/TestShort.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,7 +27,7 @@
  * @summary KAT test for DH (normal and with secret that has leading a 0x00 byte)
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestShort
  * @run main/othervm TestShort sm
  */
--- a/jdk/test/sun/security/pkcs11/KeyAgreement/UnsupportedDHKeys.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/KeyAgreement/UnsupportedDHKeys.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -26,7 +26,7 @@
  * @bug 8072452
  * @summary Support DHE sizes up to 8192-bits and DSA sizes up to 3072-bits
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm UnsupportedDHKeys
  * @run main/othervm UnsupportedDHKeys sm
  */
--- a/jdk/test/sun/security/pkcs11/KeyGenerator/DESParity.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/KeyGenerator/DESParity.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm DESParity
  * @run main/othervm DESParity sm
  */
--- a/jdk/test/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,7 +27,7 @@
  * @summary test the KeyGenerator
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestKeyGenerator
  * @run main/othervm TestKeyGenerator sm
  */
--- a/jdk/test/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/KeyPairGenerator/TestDH2048.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Ensure that DH key pairs can be generated for 512 - 8192 bits
  * @author Valerie Peng
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestDH2048
  * @run main/othervm TestDH2048 sm
  */
--- a/jdk/test/sun/security/pkcs11/Mac/MacKAT.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Mac/MacKAT.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Basic known-answer-test for Hmac algorithms
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm MacKAT
  * @run main/othervm MacKAT sm
  */
--- a/jdk/test/sun/security/pkcs11/Mac/MacSameTest.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Mac/MacSameTest.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Check if doFinal and update operation result in same Mac
  * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm MacSameTest
  * @run main/othervm MacSameTest sm
  * @key randomness
--- a/jdk/test/sun/security/pkcs11/Mac/ReinitMac.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Mac/ReinitMac.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm ReinitMac
  * @run main/othervm ReinitMac sm
  */
--- a/jdk/test/sun/security/pkcs11/MessageDigest/ByteBuffers.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/ByteBuffers.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm ByteBuffers
  * @run main/othervm ByteBuffers sm
  */
--- a/jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/DigestKAT.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Basic known-answer-test for all our MessageDigest algorithms
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm DigestKAT
  * @run main/othervm DigestKAT sm
  */
--- a/jdk/test/sun/security/pkcs11/MessageDigest/ReinitDigest.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/ReinitDigest.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm ReinitDigest
  * @run main/othervm ReinitDigest sm
  */
--- a/jdk/test/sun/security/pkcs11/MessageDigest/TestCloning.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/MessageDigest/TestCloning.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -28,7 +28,7 @@
  * @author Valerie Peng
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestCloning
  * @run main/othervm TestCloning sm
  */
--- a/jdk/test/sun/security/pkcs11/Provider/Absolute.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Provider/Absolute.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, 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
@@ -24,7 +24,7 @@
  * @test
  * @bug 7003952 7191662
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @summary load DLLs and launch executables using fully qualified path
  */
 
--- a/jdk/test/sun/security/pkcs11/SampleTest.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/SampleTest.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,7 +27,7 @@
  * @summary XXX todo
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  */
 
 import java.security.Provider;
--- a/jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Test that the PKCS#11 KeyStore handles RSA, DSA, and EC keys
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm AddPrivateKey
  * @run main/othervm AddPrivateKey sm policy
  */
--- a/jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -27,7 +27,7 @@
  * @summary make sure we can add a trusted cert to the NSS KeyStore module
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm AddTrustedCert
  * @run main/othervm AddTrustedCert sm policy
  */
--- a/jdk/test/sun/security/pkcs11/Secmod/Crypto.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Secmod/Crypto.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -27,7 +27,7 @@
  * @summary verify that NSS no-db mode works correctly
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm Crypto
  * @run main/othervm Crypto sm policy
  */
--- a/jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -28,7 +28,7 @@
  *          and use a private key
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm GetPrivateKey
  * @run main/othervm GetPrivateKey sm policy
  */
--- a/jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -27,7 +27,7 @@
  * @summary store a NSS PKCS11 PrivateKeyEntry to JKS KeyStore throws confusing NPE
  * @author Wang Weijun
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm JksSetPrivateKey
  * @run main/othervm JksSetPrivateKey sm policy
  */
--- a/jdk/test/sun/security/pkcs11/Secmod/LoadKeystore.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Secmod/LoadKeystore.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, 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
@@ -26,7 +26,7 @@
  * @bug 8048622 8134232
  * @summary Checks that PKCS#11 keystore can't be loaded with wrong password
  * @library ../
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm LoadKeystore
  * @run main/othervm LoadKeystore sm policy
  */
--- a/jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -27,7 +27,7 @@
  * @summary make sure we can access the NSS trust anchor module
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TrustAnchors
  * @run main/othervm TrustAnchors sm policy
  */
--- a/jdk/test/sun/security/pkcs11/SecureRandom/Basic.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/SecureRandom/Basic.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm Basic
  * @run main/othervm Basic sm
  */
--- a/jdk/test/sun/security/pkcs11/SecureRandom/TestDeserialization.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/SecureRandom/TestDeserialization.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -26,7 +26,7 @@
  * @bug 6837847
  * @summary Ensure a deserialized PKCS#11 SecureRandom is functional.
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  */
 
 import java.io.ByteArrayInputStream;
--- a/jdk/test/sun/security/pkcs11/Serialize/SerializeProvider.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Serialize/SerializeProvider.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Test that the SunPKCS11 provider can be serialized
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  */
 
 import java.io.ByteArrayInputStream;
--- a/jdk/test/sun/security/pkcs11/Signature/ByteBuffers.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Signature/ByteBuffers.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm ByteBuffers
  * @run main/othervm ByteBuffers sm
  */
--- a/jdk/test/sun/security/pkcs11/Signature/ReinitSignature.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Signature/ReinitSignature.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main ReinitSignature
  * @run main ReinitSignature
  * @run main ReinitSignature
--- a/jdk/test/sun/security/pkcs11/Signature/TestDSA.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Signature/TestDSA.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestDSA
  * @run main/othervm TestDSA sm
  */
--- a/jdk/test/sun/security/pkcs11/Signature/TestDSAKeyLength.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Signature/TestDSAKeyLength.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -28,7 +28,7 @@
  * with unsupported key sizes
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestDSAKeyLength
  * @run main/othervm TestDSAKeyLength sm
  */
--- a/jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/Signature/TestRSAKeyLength.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Make sure initSign/initVerify() check RSA key lengths
  * @author Yu-Ching Valerie Peng
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestRSAKeyLength
  * @run main/othervm TestRSAKeyLength sm
  */
--- a/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -29,7 +29,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @library ../../../../java/security/testlibrary
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm ReadCertificates
  * @run main/othervm ReadCertificates sm policy
  */
--- a/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -29,7 +29,7 @@
  * @library ..
  * @library ../../../../java/security/testlibrary
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm ReadPKCS12
  * @run main/othervm ReadPKCS12 sm policy
  */
--- a/jdk/test/sun/security/pkcs11/ec/TestCurves.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/TestCurves.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -27,8 +27,8 @@
  * @summary Basic consistency test for all curves using ECDSA and ECDH
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token/sun.security.pkcs11.wrapper
- * @compile --add-modules jdk.crypto.token TestCurves.java
+ * @modules jdk.crypto.cryptoki/sun.security.pkcs11.wrapper
+ * @compile --add-modules jdk.crypto.cryptoki TestCurves.java
  * @run main/othervm TestCurves
  * @run main/othervm TestCurves sm
  * @key randomness
--- a/jdk/test/sun/security/pkcs11/ec/TestECDH.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDH.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @library ../../../../java/security/testlibrary
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestECDH
  * @run main/othervm TestECDH sm policy
  */
--- a/jdk/test/sun/security/pkcs11/ec/TestECDH2.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDH2.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -29,7 +29,7 @@
  * @library ..
  * @library ../../../../java/security/testlibrary
  * @modules java.base/sun.security.util
- *          jdk.crypto.token
+ *          jdk.crypto.cryptoki
  * @compile -XDignore.symbol.file TestECDH2.java
  * @run main/othervm TestECDH2
  * @run main/othervm TestECDH2 sm
--- a/jdk/test/sun/security/pkcs11/ec/TestECDSA.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -29,7 +29,7 @@
  * @library ..
  * @library ../../../../java/security/testlibrary
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestECDSA
  * @run main/othervm TestECDSA sm policy
  */
--- a/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA2.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, 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
@@ -29,7 +29,7 @@
  * @library ..
  * @library ../../../../java/security/testlibrary
  * @modules java.base/sun.security.util
- *          jdk.crypto.token
+ *          jdk.crypto.cryptoki
  * @compile -XDignore.symbol.file TestECDSA2.java
  * @run main/othervm TestECDSA2
  * @run main/othervm TestECDSA2 sm
--- a/jdk/test/sun/security/pkcs11/ec/TestECGenSpec.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/TestECGenSpec.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Verify that we can use ECGenParameterSpec
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestECGenSpec
  * @run main/othervm TestECGenSpec sm
  */
--- a/jdk/test/sun/security/pkcs11/ec/TestKeyFactory.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/ec/TestKeyFactory.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Test the P11ECKeyFactory
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestKeyFactory
  * @run main/othervm TestKeyFactory sm
  */
--- a/jdk/test/sun/security/pkcs11/rsa/KeyWrap.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/rsa/KeyWrap.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm KeyWrap
  * @run main/othervm KeyWrap sm
  */
--- a/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @library ../../../../java/security/testlibrary
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestCACerts
  * @run main/othervm TestCACerts sm TestCACerts.policy
  */
--- a/jdk/test/sun/security/pkcs11/rsa/TestKeyFactory.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/rsa/TestKeyFactory.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Test KeyFactory of the new RSA provider
  * @author Andreas Sterbenz
  * @library ..
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestKeyFactory
  * @run main/othervm TestKeyFactory sm rsakeys.ks.policy
  */
--- a/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/rsa/TestKeyPairGenerator.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -29,7 +29,7 @@
  * @library ..
  * @library /lib/testlibrary
  * @build jdk.testlibrary.*
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm -Djava.security.debug=sunpkcs11 TestKeyPairGenerator
  * @run main/othervm -Djava.security.debug=sunpkcs11 TestKeyPairGenerator
  *                                                   sm TestKeyPairGenerator.policy
--- a/jdk/test/sun/security/pkcs11/rsa/TestSignatures.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/rsa/TestSignatures.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @key randomness
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestSignatures
  * @run main/othervm TestSignatures sm rsakeys.ks.policy
  */
--- a/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, 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
@@ -33,7 +33,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @library ../../../../java/security/testlibrary
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1"
  *      ClientJSSEServerJSSE
  * @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1"
--- a/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @modules java.base/sun.security.internal.spec
- *          jdk.crypto.token
+ *          jdk.crypto.cryptoki
  * @run main/othervm TestKeyMaterial
  * @run main/othervm TestKeyMaterial sm policy
  */
--- a/jdk/test/sun/security/pkcs11/tls/TestLeadingZeroesP11.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/tls/TestLeadingZeroesP11.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, 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
@@ -27,7 +27,7 @@
  * @summary Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
  * @library ..
  * @author Pasi Eronen
- * @modules jdk.crypto.token
+ * @modules jdk.crypto.cryptoki
  * @run main/othervm TestLeadingZeroesP11
  * @run main/othervm TestLeadingZeroesP11 sm
  */
--- a/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -29,7 +29,7 @@
  * @library ..
  * @modules java.base/sun.security.internal.interfaces
  *          java.base/sun.security.internal.spec
- *          jdk.crypto.token
+ *          jdk.crypto.cryptoki
  * @run main/othervm TestMasterSecret
  * @run main/othervm TestMasterSecret sm TestMasterSecret.policy
  */
--- a/jdk/test/sun/security/pkcs11/tls/TestPRF.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/tls/TestPRF.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @modules java.base/sun.security.internal.spec
- *          jdk.crypto.token
+ *          jdk.crypto.cryptoki
  * @run main/othervm TestPRF
  * @run main/othervm TestPRF sm policy
  */
--- a/jdk/test/sun/security/pkcs11/tls/TestPremaster.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/sun/security/pkcs11/tls/TestPremaster.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, 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
@@ -28,7 +28,7 @@
  * @author Andreas Sterbenz
  * @library ..
  * @modules java.base/sun.security.internal.spec
- *          jdk.crypto.token
+ *          jdk.crypto.cryptoki
  * @run main/othervm TestPremaster
  * @run main/othervm TestPremaster sm policy
  */
--- a/jdk/test/tools/launcher/MiscTests.java	Mon Jan 23 14:04:44 2017 +0100
+++ b/jdk/test/tools/launcher/MiscTests.java	Mon Jan 23 11:49:01 2017 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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
@@ -80,8 +80,8 @@
         createFile(new File(mainClass + ".java"), scratch);
 
         compile(mainClass + ".java",
-                "--add-modules=jdk.crypto.token",
-                "--add-exports=jdk.crypto.token/sun.security.pkcs11=ALL-UNNAMED");
+                "--add-modules=jdk.crypto.cryptoki",
+                "--add-exports=jdk.crypto.cryptoki/sun.security.pkcs11=ALL-UNNAMED");
 
         File testJar = new File("Foo.jar");
         testJar.delete();