OpenJDK / amber / amber
changeset 43514:0405ddec4224
Merge
author | prr |
---|---|
date | Thu, 26 Jan 2017 09:19:33 -0800 |
parents | 7cb602dc9001 230afa43a3b5 |
children | a089f3441356 |
files | jdk/make/copy/Copy-jdk.crypto.token.gmk jdk/make/lib/Lib-jdk.crypto.token.gmk 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 |
diffstat | 452 files changed, 43953 insertions(+), 38045 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Jan 24 18:44:13 2017 +0300 +++ b/.hgtags Thu Jan 26 09:19:33 2017 -0800 @@ -396,3 +396,4 @@ 37b95df0042ae0687324e1f7dc4a2519e230e704 jdk-9+151 ab2c8b03c3284fcbdd157551a66f807e3a182d9b jdk-9+152 d7034ff7f8e257e81c9f95c7785dd4eaaa3c2afc jdk-9+153 +8c70d170e62c0c58b5bc3ba666bd140399b98c9c jdk-10+0
--- a/common/bin/unshuffle_list.txt Tue Jan 24 18:44:13 2017 +0300 +++ b/common/bin/unshuffle_list.txt Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2015, 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 @@ -1266,33 +1266,33 @@ jdk/src/jdk.crypto.ec/share/native/libsunec/impl : jdk/src/share/native/sun/security/ec/impl jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi : jdk/src/windows/classes/sun/security/mscapi jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi : jdk/src/windows/native/sun/security/mscapi -jdk/src/jdk.crypto.token/share/classes/sun/security/pkcs11 : jdk/src/share/classes/sun/security/pkcs11 -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c : jdk/src/share/native/sun/security/pkcs11/j2secmod.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.h : jdk/src/share/native/sun/security/pkcs11/j2secmod.h -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_digest.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_dual.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_general.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_mutex.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_objmgmt.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_sessmgmt.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_sign.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_util.c -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11f.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11f.h -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11.h -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11t.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs-11v2-20a3.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs-11v2-20a3.h -jdk/src/jdk.crypto.token/share/native/libj2pkcs11/pkcs11wrapper.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h -jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c : jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.c -jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.h : jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.h -jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c : jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c -jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.h : jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.h -jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/j2secmod_md.c : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.c -jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/j2secmod_md.h : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.h -jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/p11_md.c : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.c -jdk/src/jdk.crypto.token/windows/native/libj2pkcs11/p11_md.h : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.h +jdk/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11 : jdk/src/share/classes/sun/security/pkcs11 +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c : jdk/src/share/native/sun/security/pkcs11/j2secmod.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.h : jdk/src/share/native/sun/security/pkcs11/j2secmod.h +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_convert.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_crypt.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_digest.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_dual.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_general.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_mutex.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_objmgmt.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_sessmgmt.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_sign.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c : jdk/src/share/native/sun/security/pkcs11/wrapper/p11_util.c +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11f.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11f.h +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11.h +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11t.h +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs-11v2-20a3.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs-11v2-20a3.h +jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h : jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h +jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c : jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.c +jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.h : jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.h +jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c : jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c +jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h : jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.h +jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.c : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.c +jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/j2secmod_md.h : jdk/src/windows/native/sun/security/pkcs11/j2secmod_md.h +jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.c : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.c +jdk/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h : jdk/src/windows/native/sun/security/pkcs11/wrapper/p11_md.h jdk/src/java.desktop/macosx/native/libosx/CFileManager.m : jdk/src/macosx/native/com/apple/eio/CFileManager.m jdk/src/java.base/macosx/native/libosxsecurity/KeystoreImpl.m : jdk/src/macosx/native/apple/security/KeystoreImpl.m jdk/src/jdk.hprof.agent/share/classes/com/sun/demo/jvmti/hprof : jdk/src/share/classes/com/sun/demo/jvmti/hprof
--- a/common/nb_native/nbproject/configurations.xml Tue Jan 24 18:44:13 2017 +0300 +++ b/common/nb_native/nbproject/configurations.xml Thu Jan 26 09:19:33 2017 -0800 @@ -2166,7 +2166,7 @@ </df> </df> </df> - <df name="jdk.crypto.token"> + <df name="jdk.crypto.cryptoki"> <df name="share"> <df name="native"> <df name="libj2pkcs11"> @@ -29422,35 +29422,35 @@ <cTool flags="5"> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c" ex="false" tool="0" flavor2="2"> @@ -29460,63 +29460,63 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c" - ex="false" - tool="0" - flavor2="3"> - <cTool flags="5"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c" + ex="false" + tool="0" + flavor2="3"> + <cTool flags="5"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c" ex="false" tool="0" flavor2="3"> @@ -31752,18 +31752,18 @@ </preprocessorList> </ccTool> </folder> - <folder path="0/jdk/src/jdk.crypto.token"> - <cTool> - <incDir> - <pElem>../../jdk/src/java.base/share/native/include</pElem> - <pElem>../../jdk/src/java.base/macosx/native/include</pElem> - <pElem>../../jdk/src/java.base/unix/native/include</pElem> - <pElem>../../jdk/src/java.base/share/native/libjava</pElem> - <pElem>../../jdk/src/java.base/unix/native/libjava</pElem> - <pElem>../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11</pElem> - <pElem>../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11</pElem> - <pElem>../../jdk/src/java.base/macosx/native/libjava</pElem> - <pElem>../../build/support/headers/jdk.crypto.token</pElem> + <folder path="0/jdk/src/jdk.crypto.cryptoki"> + <cTool> + <incDir> + <pElem>../../jdk/src/java.base/share/native/include</pElem> + <pElem>../../jdk/src/java.base/macosx/native/include</pElem> + <pElem>../../jdk/src/java.base/unix/native/include</pElem> + <pElem>../../jdk/src/java.base/share/native/libjava</pElem> + <pElem>../../jdk/src/java.base/unix/native/libjava</pElem> + <pElem>../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11</pElem> + <pElem>../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11</pElem> + <pElem>../../jdk/src/java.base/macosx/native/libjava</pElem> + <pElem>../../build/support/headers/jdk.crypto.cryptoki</pElem> <pElem>../../make</pElem> </incDir> <preprocessorList> @@ -31772,7 +31772,7 @@ </preprocessorList> </cTool> </folder> - <folder path="0/jdk/src/jdk.crypto.token/unix"> + <folder path="0/jdk/src/jdk.crypto.cryptoki/unix"> <cTool> <preprocessorList> <Elem>THIS_FILE="j2secmod_md.c"</Elem> @@ -44741,14 +44741,14 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c" - ex="false" - tool="0" - flavor2="0"> - <cTool flags="4"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c" + ex="false" + tool="0" + flavor2="0"> + <cTool flags="4"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c" ex="false" tool="0" flavor2="0"> @@ -44758,7 +44758,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c" ex="false" tool="0" flavor2="0"> @@ -44768,7 +44768,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c" ex="false" tool="0" flavor2="0"> @@ -44778,7 +44778,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c" ex="false" tool="0" flavor2="0"> @@ -44788,7 +44788,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c" ex="false" tool="0" flavor2="0"> @@ -44798,7 +44798,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c" ex="false" tool="0" flavor2="0"> @@ -44808,7 +44808,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c" ex="false" tool="0" flavor2="0"> @@ -44818,7 +44818,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c" ex="false" tool="0" flavor2="0"> @@ -44828,7 +44828,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c" ex="false" tool="0" flavor2="0"> @@ -44838,7 +44838,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c" ex="false" tool="0" flavor2="0"> @@ -44848,7 +44848,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c" ex="false" tool="0" flavor2="0"> @@ -44858,14 +44858,14 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c" - ex="false" - tool="0" - flavor2="0"> - <cTool flags="4"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c" + ex="false" + tool="0" + flavor2="0"> + <cTool flags="4"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c" ex="false" tool="0" flavor2="0"> @@ -47795,18 +47795,18 @@ </preprocessorList> </ccTool> </folder> - <folder path="0/jdk/src/jdk.crypto.token"> - <cTool> - <incDir> - <pElem>../../jdk/src/java.base/share/native/include</pElem> - <pElem>../../jdk/src/java.base/linux/native/include</pElem> - <pElem>../../jdk/src/java.base/unix/native/include</pElem> - <pElem>../../jdk/src/java.base/share/native/libjava</pElem> - <pElem>../../jdk/src/java.base/unix/native/libjava</pElem> - <pElem>../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11</pElem> - <pElem>../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11</pElem> - <pElem>../../jdk/src/java.base/linux/native/libjava</pElem> - <pElem>../../build/support/headers/jdk.crypto.token</pElem> + <folder path="0/jdk/src/jdk.crypto.cryptoki"> + <cTool> + <incDir> + <pElem>../../jdk/src/java.base/share/native/include</pElem> + <pElem>../../jdk/src/java.base/linux/native/include</pElem> + <pElem>../../jdk/src/java.base/unix/native/include</pElem> + <pElem>../../jdk/src/java.base/share/native/libjava</pElem> + <pElem>../../jdk/src/java.base/unix/native/libjava</pElem> + <pElem>../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11</pElem> + <pElem>../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11</pElem> + <pElem>../../jdk/src/java.base/linux/native/libjava</pElem> + <pElem>../../build/support/headers/jdk.crypto.cryptoki</pElem> <pElem>../../make</pElem> </incDir> <preprocessorList> @@ -47815,7 +47815,7 @@ </preprocessorList> </cTool> </folder> - <folder path="0/jdk/src/jdk.crypto.token/unix"> + <folder path="0/jdk/src/jdk.crypto.cryptoki/unix"> <cTool> <preprocessorList> <Elem>THIS_FILE="j2secmod_md.c"</Elem> @@ -62728,14 +62728,14 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/j2secmod.c" - ex="false" - tool="0" - flavor2="0"> - <cTool flags="2"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_convert.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/j2secmod.c" + ex="false" + tool="0" + flavor2="0"> + <cTool flags="2"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c" ex="false" tool="0" flavor2="0"> @@ -62745,7 +62745,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_crypt.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c" ex="false" tool="0" flavor2="0"> @@ -62755,7 +62755,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_digest.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_digest.c" ex="false" tool="0" flavor2="0"> @@ -62765,7 +62765,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_dual.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_dual.c" ex="false" tool="0" flavor2="0"> @@ -62775,7 +62775,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_general.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c" ex="false" tool="0" flavor2="0"> @@ -62785,7 +62785,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c" ex="false" tool="0" flavor2="0"> @@ -62795,7 +62795,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_mutex.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_mutex.c" ex="false" tool="0" flavor2="0"> @@ -62805,7 +62805,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_objmgmt.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_objmgmt.c" ex="false" tool="0" flavor2="0"> @@ -62815,7 +62815,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sessmgmt.c" ex="false" tool="0" flavor2="0"> @@ -62825,7 +62825,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sign.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c" ex="false" tool="0" flavor2="0"> @@ -62835,7 +62835,7 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c" ex="false" tool="0" flavor2="0"> @@ -62845,14 +62845,14 @@ </preprocessorList> </cTool> </item> - <item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/j2secmod_md.c" - ex="false" - tool="0" - flavor2="0"> - <cTool flags="2"> - </cTool> - </item> - <item path="../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11/p11_md.c" + <item path="../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/j2secmod_md.c" + ex="false" + tool="0" + flavor2="0"> + <cTool flags="2"> + </cTool> + </item> + <item path="../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.c" ex="false" tool="0" flavor2="0"> @@ -66281,18 +66281,18 @@ </preprocessorList> </ccTool> </folder> - <folder path="0/jdk/src/jdk.crypto.token"> - <cTool> - <incDir> - <pElem>../../jdk/src/java.base/share/native/include</pElem> - <pElem>../../jdk/src/java.base/solaris/native/include</pElem> - <pElem>../../jdk/src/java.base/unix/native/include</pElem> - <pElem>../../jdk/src/java.base/share/native/libjava</pElem> - <pElem>../../jdk/src/java.base/unix/native/libjava</pElem> - <pElem>../../jdk/src/jdk.crypto.token/share/native/libj2pkcs11</pElem> - <pElem>../../jdk/src/jdk.crypto.token/unix/native/libj2pkcs11</pElem> - <pElem>../../jdk/src/java.base/solaris/native/libjava</pElem> - <pElem>../../build/support/headers/jdk.crypto.token</pElem> + <folder path="0/jdk/src/jdk.crypto.cryptoki"> + <cTool> + <incDir> + <pElem>../../jdk/src/java.base/share/native/include</pElem> + <pElem>../../jdk/src/java.base/solaris/native/include</pElem> + <pElem>../../jdk/src/java.base/unix/native/include</pElem> + <pElem>../../jdk/src/java.base/share/native/libjava</pElem> + <pElem>../../jdk/src/java.base/unix/native/libjava</pElem> + <pElem>../../jdk/src/jdk.crypto.cryptoki/share/native/libj2pkcs11</pElem> + <pElem>../../jdk/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11</pElem> + <pElem>../../jdk/src/java.base/solaris/native/libjava</pElem> + <pElem>../../build/support/headers/jdk.crypto.cryptoki</pElem> <pElem>../../make</pElem> </incDir> <preprocessorList> @@ -66301,7 +66301,7 @@ </preprocessorList> </cTool> </folder> - <folder path="0/jdk/src/jdk.crypto.token/unix"> + <folder path="0/jdk/src/jdk.crypto.cryptoki/unix"> <cTool> <preprocessorList> <Elem>THIS_FILE="j2secmod_md.c"</Elem>
--- a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNBindingEnumeration.java Tue Jan 24 18:44:13 2017 +0300 +++ b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNBindingEnumeration.java Thu Jan 26 09:19:33 2017 -0800 @@ -33,6 +33,8 @@ import org.omg.CosNaming.*; +import com.sun.jndi.toolkit.corba.CorbaUtils; + /** * Implements the JNDI NamingEnumeration interface for COS * Naming. Gets hold of a list of bindings from the COS Naming Server @@ -212,7 +214,10 @@ Name cname = CNNameParser.cosNameToName(bndg.binding_name); try { - obj = NamingManager.getObjectInstance(obj, cname, _ctx, _env); + // Check whether object factory codebase is trusted + if (CorbaUtils.isObjectFactoryTrusted(obj)) { + obj = NamingManager.getObjectInstance(obj, cname, _ctx, _env); + } } catch (NamingException e) { throw e; } catch (Exception e) {
--- a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNCtx.java Tue Jan 24 18:44:13 2017 +0300 +++ b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/CNCtx.java Thu Jan 26 09:19:33 2017 -0800 @@ -36,6 +36,8 @@ import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.IOException; +import java.security.AccessController; +import java.security.PrivilegedAction; import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; @@ -82,6 +84,19 @@ private static final String FED_PROP = "com.sun.jndi.cosnaming.federation"; boolean federation = false; + /** + * Determines whether classes may be loaded from an arbitrary URL code base. + */ + public static final boolean trustURLCodebase; + static { + // System property to control whether classes may be loaded from an + // arbitrary URL code base + PrivilegedAction<String> act = () -> System.getProperty( + "com.sun.jndi.cosnaming.object.trustURLCodebase", "false"); + String trust = AccessController.doPrivileged(act); + trustURLCodebase = "true".equalsIgnoreCase(trust); + } + // Reference counter for tracking _orb references OrbReuseTracker orbTracker = null; int enumCount; @@ -534,12 +549,16 @@ if (name.size() == 0 ) return this; // %%% should clone() so that env can be changed NameComponent[] path = CNNameParser.nameToCosName(name); + java.lang.Object answer = null; try { - java.lang.Object answer = callResolve(path); - + answer = callResolve(path); try { - return NamingManager.getObjectInstance(answer, name, this, _env); + // Check whether object factory codebase is trusted + if (CorbaUtils.isObjectFactoryTrusted(answer)) { + answer = NamingManager.getObjectInstance( + answer, name, this, _env); + } } catch (NamingException e) { throw e; } catch (Exception e) { @@ -552,6 +571,7 @@ javax.naming.Context cctx = getContinuationContext(cpe); return cctx.lookup(cpe.getRemainingName()); } + return answer; } /**
--- a/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/ExceptionMapper.java Tue Jan 24 18:44:13 2017 +0300 +++ b/corba/src/java.corba/share/classes/com/sun/jndi/cosnaming/ExceptionMapper.java Thu Jan 26 09:19:33 2017 -0800 @@ -33,6 +33,8 @@ import org.omg.CosNaming.NamingContextPackage.*; import org.omg.CORBA.*; +import com.sun.jndi.toolkit.corba.CorbaUtils; + /** * A convenience class to map the COS Naming exceptions to the JNDI exceptions. * @author Raj Krishnamurthy @@ -202,10 +204,13 @@ // Not a context, use object factory to transform object. Name cname = CNNameParser.cosNameToName(resolvedName); - java.lang.Object resolvedObj2; + java.lang.Object resolvedObj2 = null; try { - resolvedObj2 = NamingManager.getObjectInstance(resolvedObj, - cname, ctx, ctx._env); + // Check whether object factory codebase is trusted + if (CorbaUtils.isObjectFactoryTrusted(resolvedObj)) { + resolvedObj2 = NamingManager.getObjectInstance(resolvedObj, + cname, ctx, ctx._env); + } } catch (NamingException ge) { throw ge; } catch (Exception ge) {
--- a/corba/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java Tue Jan 24 18:44:13 2017 +0300 +++ b/corba/src/java.corba/share/classes/com/sun/jndi/toolkit/corba/CorbaUtils.java Thu Jan 26 09:19:33 2017 -0800 @@ -36,11 +36,12 @@ import org.omg.CORBA.ORB; -import javax.naming.Context; -import javax.naming.ConfigurationException; +import javax.naming.*; import javax.rmi.CORBA.Stub; import javax.rmi.PortableRemoteObject; +import com.sun.jndi.cosnaming.CNCtx; + import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URLDecoder; @@ -183,6 +184,32 @@ } /** + * Check whether object factory code base is trusted. + * Classes may only be loaded from an arbitrary URL code base when + * the system property com.sun.jndi.rmi.object.trustURLCodebase + * has been set to "true". + */ + public static boolean isObjectFactoryTrusted(Object obj) + throws NamingException { + + // Extract Reference, if possible + Reference ref = null; + if (obj instanceof Reference) { + ref = (Reference) obj; + } else if (obj instanceof Referenceable) { + ref = ((Referenceable)(obj)).getReference(); + } + + if (ref != null && ref.getFactoryClassLocation() != null && + !CNCtx.trustURLCodebase) { + throw new ConfigurationException( + "The object factory is untrusted. Set the system property" + + " 'com.sun.jndi.cosnaming.object.trustURLCodebase' to 'true'."); + } + return true; + } + + /** * Decode a URI string (according to RFC 2396). */ public static final String decode(String s) throws MalformedURLException {
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Jan 24 18:44:13 2017 +0300 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Jan 26 09:19:33 2017 -0800 @@ -1025,16 +1025,20 @@ static int skip_annotation_value(const u1*, int, int); // fwd decl +// Safely increment index by val if does not pass limit +#define SAFE_ADD(index, limit, val) \ +if (index >= limit - val) return limit; \ +index += val; + // Skip an annotation. Return >=limit if there is any problem. static int skip_annotation(const u1* buffer, int limit, int index) { assert(buffer != NULL, "invariant"); // annotation := atype:u2 do(nmem:u2) {member:u2 value} // value := switch (tag:u1) { ... } - index += 2; // skip atype - if ((index += 2) >= limit) return limit; // read nmem + SAFE_ADD(index, limit, 4); // skip atype and read nmem int nmem = Bytes::get_Java_u2((address)buffer + index - 2); while (--nmem >= 0 && index < limit) { - index += 2; // skip member + SAFE_ADD(index, limit, 2); // skip member index = skip_annotation_value(buffer, limit, index); } return index; @@ -1052,7 +1056,7 @@ // case @: annotation; // case s: s_con:u2; // } - if ((index += 1) >= limit) return limit; // read tag + SAFE_ADD(index, limit, 1); // read tag const u1 tag = buffer[index - 1]; switch (tag) { case 'B': @@ -1065,14 +1069,14 @@ case 'J': case 'c': case 's': - index += 2; // skip con or s_con + SAFE_ADD(index, limit, 2); // skip con or s_con break; case 'e': - index += 4; // skip e_class, e_name + SAFE_ADD(index, limit, 4); // skip e_class, e_name break; case '[': { - if ((index += 2) >= limit) return limit; // read nval + SAFE_ADD(index, limit, 2); // read nval int nval = Bytes::get_Java_u2((address)buffer + index - 2); while (--nval >= 0 && index < limit) { index = skip_annotation_value(buffer, limit, index); @@ -1101,8 +1105,8 @@ assert(loader_data != NULL, "invariant"); // annotations := do(nann:u2) {annotation} - int index = 0; - if ((index += 2) >= limit) return; // read nann + int index = 2; // read nann + if (index >= limit) return; int nann = Bytes::get_Java_u2((address)buffer + index - 2); enum { // initial annotation layout atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;' @@ -1121,7 +1125,8 @@ s_size = 9, min_size = 6 // smallest possible size (zero members) }; - while ((--nann) >= 0 && (index - 2 + min_size <= limit)) { + // Cannot add min_size to index in case of overflow MAX_INT + while ((--nann) >= 0 && (index - 2 <= limit - min_size)) { int index0 = index; index = skip_annotation(buffer, limit, index); const u1* const abase = buffer + index0; @@ -1253,13 +1258,14 @@ runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); + cfs->guarantee_more(runtime_visible_annotations_length, CHECK); parse_annotations(cp, runtime_visible_annotations, runtime_visible_annotations_length, parsed_annotations, _loader_data, CHECK); - cfs->skip_u1(runtime_visible_annotations_length, CHECK); + cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { if (runtime_invisible_annotations_exists) { classfile_parse_error( @@ -2574,13 +2580,14 @@ runtime_visible_annotations_length = method_attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); + cfs->guarantee_more(runtime_visible_annotations_length, CHECK_NULL); parse_annotations(cp, runtime_visible_annotations, runtime_visible_annotations_length, &parsed_annotations, _loader_data, CHECK_NULL); - cfs->skip_u1(runtime_visible_annotations_length, CHECK_NULL); + cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { if (runtime_invisible_annotations_exists) { classfile_parse_error( @@ -3285,13 +3292,14 @@ runtime_visible_annotations_length = attribute_length; runtime_visible_annotations = cfs->get_u1_buffer(); assert(runtime_visible_annotations != NULL, "null visible annotations"); + cfs->guarantee_more(runtime_visible_annotations_length, CHECK); parse_annotations(cp, runtime_visible_annotations, runtime_visible_annotations_length, parsed_annotations, _loader_data, CHECK); - cfs->skip_u1(runtime_visible_annotations_length, CHECK); + cfs->skip_u1_fast(runtime_visible_annotations_length); } else if (tag == vmSymbols::tag_runtime_invisible_annotations()) { if (runtime_invisible_annotations_exists) { classfile_parse_error(
--- a/hotspot/src/share/vm/classfile/stackMapFrame.cpp Tue Jan 24 18:44:13 2017 +0300 +++ b/hotspot/src/share/vm/classfile/stackMapFrame.cpp Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -155,47 +155,8 @@ return i; } -bool StackMapFrame::has_flag_match_exception( - const StackMapFrame* target) const { - // We allow flags of {UninitThis} to assign to {} if-and-only-if the - // target frame does not depend upon the current type. - // This is slightly too strict, as we need only enforce that the - // slots that were initialized by the <init> (the things that were - // UninitializedThis before initialize_object() converted them) are unused. - // However we didn't save that information so we'll enforce this upon - // anything that might have been initialized. This is a rare situation - // and javac never generates code that would end up here, but some profilers - // (such as NetBeans) might, when adding exception handlers in <init> - // methods to cover the invokespecial instruction. See 7020118. - - assert(max_locals() == target->max_locals() && - stack_size() == target->stack_size(), "StackMap sizes must match"); - - VerificationType top = VerificationType::top_type(); - VerificationType this_type = verifier()->current_type(); - - if (!flag_this_uninit() || target->flags() != 0) { - return false; - } - - for (int i = 0; i < target->locals_size(); ++i) { - if (locals()[i] == this_type && target->locals()[i] != top) { - return false; - } - } - - for (int i = 0; i < target->stack_size(); ++i) { - if (stack()[i] == this_type && target->stack()[i] != top) { - return false; - } - } - - return true; -} - bool StackMapFrame::is_assignable_to( - const StackMapFrame* target, bool is_exception_handler, - ErrorContext* ctx, TRAPS) const { + const StackMapFrame* target, ErrorContext* ctx, TRAPS) const { if (_max_locals != target->max_locals()) { *ctx = ErrorContext::locals_size_mismatch( _offset, (StackMapFrame*)this, (StackMapFrame*)target); @@ -226,8 +187,7 @@ return false; } - bool match_flags = (_flags | target->flags()) == target->flags(); - if (match_flags || is_exception_handler && has_flag_match_exception(target)) { + if ((_flags | target->flags()) == target->flags()) { return true; } else { *ctx = ErrorContext::bad_flags(target->offset(),
--- a/hotspot/src/share/vm/classfile/stackMapFrame.hpp Tue Jan 24 18:44:13 2017 +0300 +++ b/hotspot/src/share/vm/classfile/stackMapFrame.hpp Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -167,8 +167,7 @@ // Return true if this stack map frame is assignable to target. bool is_assignable_to( - const StackMapFrame* target, bool is_exception_handler, - ErrorContext* ctx, TRAPS) const; + const StackMapFrame* target, ErrorContext* ctx, TRAPS) const; inline void set_mark() { #ifdef ASSERT @@ -290,8 +289,6 @@ int is_assignable_to( VerificationType* src, VerificationType* target, int32_t len, TRAPS) const; - bool has_flag_match_exception(const StackMapFrame* target) const; - TypeOrigin stack_top_ctx(); void print_on(outputStream* str) const;
--- a/hotspot/src/share/vm/classfile/stackMapTable.cpp Tue Jan 24 18:44:13 2017 +0300 +++ b/hotspot/src/share/vm/classfile/stackMapTable.cpp Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -70,26 +70,25 @@ bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { + bool match, bool update, ErrorContext* ctx, TRAPS) const { int index = get_index_from_offset(target); - return match_stackmap(frame, target, index, match, update, handler, ctx, THREAD); + return match_stackmap(frame, target, index, match, update, ctx, THREAD); } // Match and/or update current_frame to the frame in stackmap table with // specified offset and frame index. Return true if the two frames match. -// handler is true if the frame in stackmap_table is for an exception handler. // -// The values of match and update are: _match__update__handler +// The values of match and update are: _match__update // -// checking a branch target: true false false -// checking an exception handler: true false true +// checking a branch target: true false +// checking an exception handler: true false // linear bytecode verification following an -// unconditional branch: false true false +// unconditional branch: false true // linear bytecode verification not following an -// unconditional branch: true true false +// unconditional branch: true true bool StackMapTable::match_stackmap( StackMapFrame* frame, int32_t target, int32_t frame_index, - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const { + bool match, bool update, ErrorContext* ctx, TRAPS) const { if (frame_index < 0 || frame_index >= _frame_count) { *ctx = ErrorContext::missing_stackmap(frame->offset()); frame->verifier()->verify_error( @@ -102,7 +101,7 @@ if (match) { // Has direct control flow from last instruction, need to match the two // frames. - result = frame->is_assignable_to(stackmap_frame, handler, + result = frame->is_assignable_to(stackmap_frame, ctx, CHECK_VERIFY_(frame->verifier(), result)); } if (update) { @@ -126,7 +125,7 @@ StackMapFrame* frame, int32_t target, TRAPS) const { ErrorContext ctx; bool match = match_stackmap( - frame, target, true, false, false, &ctx, CHECK_VERIFY(frame->verifier())); + frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier())); if (!match || (target < 0 || target >= _code_length)) { frame->verifier()->verify_error(ctx, "Inconsistent stackmap frames at branch target %d", target);
--- a/hotspot/src/share/vm/classfile/stackMapTable.hpp Tue Jan 24 18:44:13 2017 +0300 +++ b/hotspot/src/share/vm/classfile/stackMapTable.hpp Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -60,12 +60,12 @@ // specified offset. Return true if the two frames match. bool match_stackmap( StackMapFrame* current_frame, int32_t offset, - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const; + bool match, bool update, ErrorContext* ctx, TRAPS) const; // Match and/or update current_frame to the frame in stackmap table with // specified offset and frame index. Return true if the two frames match. bool match_stackmap( StackMapFrame* current_frame, int32_t offset, int32_t frame_index, - bool match, bool update, bool handler, ErrorContext* ctx, TRAPS) const; + bool match, bool update, ErrorContext* ctx, TRAPS) const; // Check jump instructions. Make sure there are no uninitialized // instances on backward branch.
--- a/hotspot/src/share/vm/classfile/verifier.cpp Tue Jan 24 18:44:13 2017 +0300 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Thu Jan 26 09:19:33 2017 -0800 @@ -541,19 +541,13 @@ stack_map_frame* sm_frame = sm_table->entries(); streamIndentor si2(ss); int current_offset = -1; - // Subtract two from StackMapAttribute length because the length includes - // two bytes for number of table entries. - size_t sm_table_space = method->stackmap_data()->length() - 2; + address end_of_sm_table = (address)sm_table + method->stackmap_data()->length(); for (u2 i = 0; i < sm_table->number_of_entries(); ++i) { ss->indent(); - size_t sm_frame_size = sm_frame->size(); - // If the size of the next stackmap exceeds the length of the entire - // stackmap table then print a truncated message and return. - if (sm_frame_size > sm_table_space) { + if (!sm_frame->verify((address)sm_frame, end_of_sm_table)) { sm_frame->print_truncated(ss, current_offset); return; } - sm_table_space -= sm_frame_size; sm_frame->print_on(ss, current_offset); ss->cr(); current_offset += sm_frame->offset_delta(); @@ -1863,7 +1857,7 @@ // If matched, current_frame will be updated by this method. bool matches = stackmap_table->match_stackmap( current_frame, this_offset, stackmap_index, - !no_control_flow, true, false, &ctx, CHECK_VERIFY_(this, 0)); + !no_control_flow, true, &ctx, CHECK_VERIFY_(this, 0)); if (!matches) { // report type error verify_error(ctx, "Instruction type does not match stack map"); @@ -1913,7 +1907,7 @@ } ErrorContext ctx; bool matches = stackmap_table->match_stackmap( - new_frame, handler_pc, true, false, true, &ctx, CHECK_VERIFY(this)); + new_frame, handler_pc, true, false, &ctx, CHECK_VERIFY(this)); if (!matches) { verify_error(ctx, "Stack map does not match the one at " "exception handler %d", handler_pc);
--- a/hotspot/test/runtime/handlerInTry/LoadHandlerInTry.java Tue Jan 24 18:44:13 2017 +0300 +++ b/hotspot/test/runtime/handlerInTry/LoadHandlerInTry.java Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -24,7 +24,7 @@ /* * @test * @bug 8075118 - * @summary Allow a ctor to call super() from a switch bytecode. + * @summary JVM stuck in infinite loop during verification * @compile HandlerInTry.jasm * @compile IsolatedHandlerInTry.jasm * @run main/othervm -Xverify:all LoadHandlerInTry @@ -70,9 +70,10 @@ System.out.println("Regression test for bug 8075118"); try { Class newClass = Class.forName("HandlerInTry"); - } catch (Exception e) { - System.out.println("Failed: Exception was thrown: " + e.toString()); - throw e; + throw new RuntimeException( + "Failed to throw VerifyError for HandlerInTry"); + } catch (java.lang.VerifyError e) { + System.out.println("Passed: VerifyError exception was thrown"); } try {
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Thu Jan 26 09:19:33 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. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -37,6 +37,7 @@ import java.io.ObjectOutputStream; import java.io.ObjectStreamField; import java.io.Serializable; +import java.lang.RuntimePermission; import java.lang.module.Configuration; import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleFinder; @@ -45,7 +46,11 @@ import java.lang.reflect.Layer; import java.lang.reflect.Module; import java.security.AccessController; +import java.security.CodeSigner; +import java.security.CodeSource; +import java.security.PermissionCollection; import java.security.PrivilegedAction; +import java.security.ProtectionDomain; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -177,6 +182,7 @@ _loadedExternalExtensionFunctions = mapEF; } + @Override public Class<?> loadClass(String name) throws ClassNotFoundException { Class<?> ret = null; // The _loadedExternalExtensionFunctions will be empty when the @@ -196,6 +202,10 @@ Class defineClass(final byte[] b) { return defineClass(null, b, 0, b.length); } + + Class defineClass(final byte[] b, ProtectionDomain pd) { + return defineClass(null, b, 0, b.length, pd); + } } @@ -482,16 +492,24 @@ // the module needs access to runtime classes Module thisModule = TemplatesImpl.class.getModule(); - + // the module also needs permission to access each package + // that is exported to it + PermissionCollection perms = + new RuntimePermission("*").newPermissionCollection(); Arrays.asList(Constants.PKGS_USED_BY_TRANSLET_CLASSES).forEach(p -> { thisModule.addExports(p, m); + perms.add(new RuntimePermission("accessClassInPackage." + p)); }); - // java.xml needs to instanitate the translet class + CodeSource codeSource = new CodeSource(null, (CodeSigner[])null); + ProtectionDomain pd = new ProtectionDomain(codeSource, perms, + loader, null); + + // java.xml needs to instantiate the translet class thisModule.addReads(m); for (int i = 0; i < classCount; i++) { - _class[i] = loader.defineClass(_bytecodes[i]); + _class[i] = loader.defineClass(_bytecodes[i], pd); final Class superClass = _class[i].getSuperclass(); // Check if this is the main class
--- a/jaxp/test/javax/xml/jaxp/unittest/transform/TransformerTest.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jaxp/test/javax/xml/jaxp/unittest/transform/TransformerTest.java Thu Jan 26 09:19:33 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 @@ -24,6 +24,7 @@ package transform; import static jaxp.library.JAXPTestUtilities.getSystemProperty; +import static jaxp.library.JAXPTestUtilities.tryRunWithTmpPermission; import java.io.BufferedReader; import java.io.ByteArrayInputStream; @@ -217,7 +218,7 @@ * @summary Test for JDK-6272879 */ @Test - public final void testBug6272879() throws IOException, TransformerException { + public final void testBug6272879() throws Exception { final String xsl = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR + "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" + LINE_SEPARATOR + @@ -274,9 +275,11 @@ System.out.println("Result after transformation:"); System.out.println("============================"); - OutputFormat format = new OutputFormat(); - format.setIndenting(true); - new XMLSerializer(System.out, format).serialize(document); + tryRunWithTmpPermission(() -> { + OutputFormat format = new OutputFormat(); + format.setIndenting(true); + new XMLSerializer(System.out, format).serialize(document); + }, new RuntimePermission("accessClassInPackage.com.sun.org.apache.xml.internal.serialize")); System.out.println(); System.out.println("Node content for element valeur2:"); @@ -529,7 +532,7 @@ } } - public void run() throws IOException, TransformerException { + public void run() throws Exception { printSnippet("Source:", sourceXml); printSnippet("Stylesheet:", xsl); @@ -545,9 +548,11 @@ System.out.println("Result after transformation:"); System.out.println("============================"); - OutputFormat format = new OutputFormat(); - format.setIndenting(true); - new XMLSerializer(System.out, format).serialize(document); + tryRunWithTmpPermission(() -> { + OutputFormat format = new OutputFormat(); + format.setIndenting(true); + new XMLSerializer(System.out, format).serialize(document); + }, new RuntimePermission("accessClassInPackage.com.sun.org.apache.xml.internal.serialize")); System.out.println(); checkNodeNS(document.getElementsByTagName("test1").item(0), "ns2", "ns2", null); @@ -566,9 +571,7 @@ * definitions to reset the default namespace */ @Test - public final void testBug8162598() throws IOException, - TransformerException - { + public final void testBug8162598() throws Exception { new Test8162598().run(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/copy/Copy-jdk.crypto.cryptoki.gmk Thu Jan 26 09:19:33 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 Tue Jan 24 18:44:13 2017 +0300 +++ /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 - -################################################################################
--- a/jdk/make/gensrc/GensrcLocaleData.gmk Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/make/gensrc/GensrcLocaleData.gmk Thu Jan 26 09:19:33 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 @@ -89,8 +89,8 @@ $1_NON_BASE_LOCALES := $$(subst zh-MO,zh-MO$$(SPACE)zh-Hant-MO, $$($1_NON_BASE_LOCALES)) $1_NON_BASE_LOCALES := $$(subst zh-TW,zh-TW$$(SPACE)zh-Hant-TW, $$($1_NON_BASE_LOCALES)) -# Adding implict locales nn-NO and nb-NO - $1_NON_BASE_LOCALES += nn-NO nb-NO +# Adding implict locales nb nn-NO and nb-NO + $1_NON_BASE_LOCALES += nb nn-NO nb-NO $1_NON_BASE_LOCALES := $$(sort $$($1_NON_BASE_LOCALES)) ALL_BASE_LOCALES += $$($1_BASE_LOCALES)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/lib/Lib-jdk.crypto.cryptoki.gmk Thu Jan 26 09:19:33 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 Tue Jan 24 18:44:13 2017 +0300 +++ /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/make/src/classes/build/tools/cldrconverter/Bundle.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/make/src/classes/build/tools/cldrconverter/Bundle.java Thu Jan 26 09:19:33 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 @@ -389,6 +389,18 @@ } } } + // replace empty era names with parentMap era names + for (String key : ERA_KEYS) { + Object value = myMap.get(key); + if (value != null && value instanceof String[]) { + String[] eraStrings = (String[]) value; + for (String eraString : eraStrings) { + if (eraString == null || eraString.isEmpty()) { + fillInElements(parentsMap, key, value); + } + } + } + } // Remove all duplicates if (Objects.nonNull(parentsMap)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/make/src/classes/build/tools/taglet/Incubating.java Thu Jan 26 09:19:33 2017 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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. + */ + +package build.tools.taglet; + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import com.sun.source.doctree.DocTree; +import jdk.javadoc.doclet.taglet.Taglet; +import static jdk.javadoc.doclet.taglet.Taglet.Location.*; + +/** + * An inline tag to conveniently insert a standard Incubating warning. For + * use by members in Incubator Modules. + */ +public class Incubating implements Taglet { + + /** Returns the set of locations in which a taglet may be used. */ + @Override + public Set<Location> getAllowedLocations() { + return EnumSet.of(OVERVIEW, MODULE, PACKAGE, TYPE); + } + + @Override + public boolean isInlineTag() { + return true; + } + + @Override + public String getName() { + return "Incubating"; + } + + private static final String MESSAGE = + "<BR><b><a href=\"http://openjdk.java.net/jeps/11\">Incubating Feature.</a>" + + " Will be removed in a future release.</b>"; + + @Override + public String toString(DocTree tag) { + return MESSAGE; + } + + @Override + public String toString(List<? extends DocTree> tags) { + return MESSAGE; + } +} +
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -66,16 +66,16 @@ * refer to a directory. Otherwise, the URL is assumed to refer to a JAR file * which will be opened as needed. * <p> + * This class loader supports the loading of classes and resources from the + * contents of a <a href="../util/jar/JarFile.html#multirelease">multi-release</a> + * JAR file that is referred to by a given URL. + * <p> * The AccessControlContext of the thread that created the instance of * URLClassLoader will be used when subsequently loading classes and * resources. * <p> * The classes that are loaded are by default granted permission only to * access the URLs specified when the URLClassLoader was created. - * <p> - * This class loader supports the loading of classes from the contents of a - * <a href="../util/jar/JarFile.html#multirelease">multi-release</a> JAR file - * that is referred to by a given URL. * * @author David Connelly * @since 1.2
--- a/jdk/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/src/java.base/share/classes/java/security/AlgorithmParameterGenerator.java Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -71,7 +71,7 @@ * following standard {@code AlgorithmParameterGenerator} algorithms and * keysizes in parentheses: * <ul> - * <li>{@code DiffieHellman} (1024, 2048, 4096)</li> + * <li>{@code DiffieHellman} (1024, 2048)</li> * <li>{@code DSA} (1024, 2048)</li> * </ul> * These algorithms are described in the <a href=
--- a/jdk/src/java.base/share/classes/module-info.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/src/java.base/share/classes/module-info.java Thu Jan 26 09:19:33 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/classes/sun/security/provider/PolicyFile.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/src/java.base/share/classes/sun/security/provider/PolicyFile.java Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -32,7 +32,6 @@ import java.net.URI; import java.nio.file.Paths; import java.util.*; -import java.text.MessageFormat; import java.security.*; import java.security.cert.Certificate; import java.security.cert.X509Certificate; @@ -579,10 +578,9 @@ k.add(policy); return k; }); - MessageFormat form = new MessageFormat(ResourcesMgr.getString - (POLICY + ".error.parsing.policy.message")); Object[] source = {policy, pe.getLocalizedMessage()}; - System.err.println(form.format(source)); + System.err.println(LocalizedMessage.getMessage + (POLICY + ".error.parsing.policy.message", source)); if (debug != null) { pe.printStackTrace(); } @@ -805,32 +803,30 @@ } } } catch (java.lang.reflect.InvocationTargetException ite) { - MessageFormat form = new MessageFormat - (ResourcesMgr.getString - (POLICY + - ".error.adding.Permission.perm.message")); Object[] source = {pe.permission, ite.getTargetException().toString()}; - System.err.println(form.format(source)); + System.err.println( + LocalizedMessage.getMessage( + POLICY + ".error.adding.Permission.perm.message", + source)); } catch (Exception e) { - MessageFormat form = new MessageFormat - (ResourcesMgr.getString - (POLICY + - ".error.adding.Permission.perm.message")); Object[] source = {pe.permission, e.toString()}; - System.err.println(form.format(source)); + System.err.println( + LocalizedMessage.getMessage( + POLICY + ".error.adding.Permission.perm.message", + source)); } } // No need to sync because noone has access to newInfo yet newInfo.policyEntries.add(entry); } catch (Exception e) { - MessageFormat form = new MessageFormat(ResourcesMgr.getString - (POLICY - + ".error.adding.Entry.message")); Object[] source = {e.toString()}; - System.err.println(form.format(source)); + System.err.println( + LocalizedMessage.getMessage( + POLICY + ".error.adding.Entry.message", + source)); } if (debug != null) debug.println(); @@ -1803,29 +1799,29 @@ } else if (prefix.equalsIgnoreCase("alias")) { // get the suffix and perform keystore alias replacement if (colonIndex == -1) { - MessageFormat form = new MessageFormat - (ResourcesMgr.getString - ("alias.name.not.provided.pe.name.")); Object[] source = {pe.name}; - throw new Exception(form.format(source)); + throw new Exception( + LocalizedMessage.getMessage( + "alias.name.not.provided.pe.name.", + source)); } suffix = value.substring(colonIndex+1); if ((suffix = getDN(suffix, keystore)) == null) { - MessageFormat form = new MessageFormat - (ResourcesMgr.getString - ("unable.to.perform.substitution.on.alias.suffix")); Object[] source = {value.substring(colonIndex+1)}; - throw new Exception(form.format(source)); + throw new Exception( + LocalizedMessage.getMessage( + "unable.to.perform.substitution.on.alias.suffix", + source)); } sb.append(X500PRINCIPAL + " \"" + suffix + "\""); startIndex = e+2; } else { - MessageFormat form = new MessageFormat - (ResourcesMgr.getString - ("substitution.value.prefix.unsupported")); Object[] source = {prefix}; - throw new Exception(form.format(source)); + throw new Exception( + LocalizedMessage.getMessage( + "substitution.value.prefix.unsupported", + source)); } } @@ -2039,7 +2035,7 @@ super(type); if (type == null) { throw new NullPointerException - (ResourcesMgr.getString("type.can.t.be.null")); + (LocalizedMessage.getMessage("type.can.t.be.null")); } this.type = type; this.name = name;
--- a/jdk/src/java.base/share/classes/sun/security/provider/PolicyParser.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/src/java.base/share/classes/sun/security/provider/PolicyParser.java Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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,18 +26,14 @@ package sun.security.provider; import java.io.*; -import java.lang.RuntimePermission; -import java.net.SocketPermission; -import java.net.URL; import java.security.GeneralSecurityException; import java.security.Principal; -import java.text.MessageFormat; import java.util.*; import javax.security.auth.x500.X500Principal; import sun.security.util.Debug; import sun.security.util.PropertyExpander; -import sun.security.util.ResourcesMgr; +import sun.security.util.LocalizedMessage; /** * The policy for a Java runtime (specifying @@ -209,13 +205,12 @@ if (!domainEntries.containsKey(domainName)) { domainEntries.put(domainName, de); } else { - MessageFormat form = - new MessageFormat(ResourcesMgr.getString( - "duplicate.keystore.domain.name")); + LocalizedMessage localizedMsg = + new LocalizedMessage("duplicate.keystore.domain.name"); Object[] source = {domainName}; String msg = "duplicate keystore domain name: " + domainName; - throw new ParsingException(msg, form, source); + throw new ParsingException(msg, localizedMsg, source); } } } else { @@ -225,7 +220,7 @@ } if (keyStoreUrlString == null && storePassURL != null) { - throw new ParsingException(ResourcesMgr.getString + throw new ParsingException(LocalizedMessage.getMessage ("keystorePasswordURL.can.not.be.specified.without.also.specifying.keystore")); } } @@ -367,7 +362,7 @@ keyStoreType = match("quoted string"); } else { throw new ParsingException(st.lineno(), - ResourcesMgr.getString("expected.keystore.type")); + LocalizedMessage.getMessage("expected.keystore.type")); } // parse keystore provider @@ -380,7 +375,7 @@ keyStoreProvider = match("quoted string"); } else { throw new ParsingException(st.lineno(), - ResourcesMgr.getString("expected.keystore.provider")); + LocalizedMessage.getMessage("expected.keystore.provider")); } } @@ -430,7 +425,7 @@ if (e.codeBase != null) throw new ParsingException( st.lineno(), - ResourcesMgr.getString + LocalizedMessage.getMessage ("multiple.Codebase.expressions")); e.codeBase = match("quoted string"); peekAndMatch(","); @@ -438,8 +433,8 @@ if (e.signedBy != null) throw new ParsingException( st.lineno(), - ResourcesMgr.getString( - "multiple.SignedBy.expressions")); + LocalizedMessage.getMessage + ("multiple.SignedBy.expressions")); e.signedBy = match("quoted string"); // verify syntax of the aliases @@ -457,8 +452,8 @@ if (actr <= cctr) throw new ParsingException( st.lineno(), - ResourcesMgr.getString( - "SignedBy.has.empty.alias")); + LocalizedMessage.getMessage + ("SignedBy.has.empty.alias")); peekAndMatch(","); } else if (peekAndMatch("Principal")) { @@ -500,7 +495,7 @@ } throw new ParsingException (st.lineno(), - ResourcesMgr.getString + LocalizedMessage.getMessage ("can.not.specify.Principal.with.a.wildcard.class.without.a.wildcard.name")); } } @@ -537,8 +532,8 @@ } else { throw new ParsingException(st.lineno(), - ResourcesMgr.getString( - "expected.codeBase.or.SignedBy.or.Principal")); + LocalizedMessage.getMessage + ("expected.codeBase.or.SignedBy.or.Principal")); } } @@ -561,8 +556,8 @@ } else { throw new ParsingException(st.lineno(), - ResourcesMgr.getString( - "expected.permission.entry")); + LocalizedMessage.getMessage + ("expected.permission.entry")); } } match("}"); @@ -738,15 +733,14 @@ switch (lookahead) { case StreamTokenizer.TT_NUMBER: throw new ParsingException(st.lineno(), expect, - ResourcesMgr.getString("number.") + - String.valueOf(st.nval)); + LocalizedMessage.getMessage("number.") + + String.valueOf(st.nval)); case StreamTokenizer.TT_EOF: - MessageFormat form = new MessageFormat( - ResourcesMgr.getString - ("expected.expect.read.end.of.file.")); + LocalizedMessage localizedMsg = new LocalizedMessage + ("expected.expect.read.end.of.file."); Object[] source = {expect}; String msg = "expected [" + expect + "], read [end of file]"; - throw new ParsingException(msg, form, source); + throw new ParsingException(msg, localizedMsg, source); case StreamTokenizer.TT_WORD: if (expect.equalsIgnoreCase(st.sval)) { lookahead = st.nextToken(); @@ -832,10 +826,10 @@ switch (lookahead) { case StreamTokenizer.TT_NUMBER: throw new ParsingException(st.lineno(), ";", - ResourcesMgr.getString("number.") + - String.valueOf(st.nval)); + LocalizedMessage.getMessage("number.") + + String.valueOf(st.nval)); case StreamTokenizer.TT_EOF: - throw new ParsingException(ResourcesMgr.getString + throw new ParsingException(LocalizedMessage.getMessage ("expected.read.end.of.file.")); default: lookahead = st.nextToken(); @@ -993,8 +987,8 @@ */ public PrincipalEntry(String principalClass, String principalName) { if (principalClass == null || principalName == null) - throw new NullPointerException(ResourcesMgr.getString( - "null.principalClass.or.principalName")); + throw new NullPointerException(LocalizedMessage.getMessage + ("null.principalClass.or.principalName")); this.principalClass = principalClass; this.principalName = principalName; } @@ -1244,11 +1238,11 @@ if (!entries.containsKey(keystoreName)) { entries.put(keystoreName, entry); } else { - MessageFormat form = new MessageFormat(ResourcesMgr.getString( - "duplicate.keystore.name")); + LocalizedMessage localizedMsg = new LocalizedMessage + ("duplicate.keystore.name"); Object[] source = {keystoreName}; String msg = "duplicate keystore name: " + keystoreName; - throw new ParsingException(msg, form, source); + throw new ParsingException(msg, localizedMsg, source); } } @@ -1320,7 +1314,7 @@ private static final long serialVersionUID = -4330692689482574072L; private String i18nMessage; - private MessageFormat form; + private LocalizedMessage localizedMsg; private Object[] source; /** @@ -1336,10 +1330,10 @@ i18nMessage = msg; } - public ParsingException(String msg, MessageFormat form, + public ParsingException(String msg, LocalizedMessage localizedMsg, Object[] source) { super(msg); - this.form = form; + this.localizedMsg = localizedMsg; this.source = source; } @@ -1347,7 +1341,7 @@ super("line " + line + ": " + msg); // don't call form.format unless getLocalizedMessage is called // to avoid unnecessary permission checks - form = new MessageFormat(ResourcesMgr.getString("line.number.msg")); + localizedMsg = new LocalizedMessage("line.number.msg"); source = new Object[] {line, msg}; } @@ -1356,14 +1350,14 @@ "], found [" + actual + "]"); // don't call form.format unless getLocalizedMessage is called // to avoid unnecessary permission checks - form = new MessageFormat(ResourcesMgr.getString - ("line.number.expected.expect.found.actual.")); + localizedMsg = new LocalizedMessage + ("line.number.expected.expect.found.actual."); source = new Object[] {line, expect, actual}; } @Override public String getLocalizedMessage() { - return i18nMessage != null ? i18nMessage : form.format(source); + return i18nMessage != null ? i18nMessage : localizedMsg.format(source); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.base/share/classes/sun/security/util/LocalizedMessage.java Thu Jan 26 09:19:33 2017 -0800 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 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. + */ + +package sun.security.util; + +/** + * This class produces formatted and localized messages describing security + * issues. Some messages may be required when the VM is not fully booted. In + * this case, localization resources and classes used for message formatting + * may not be available. When the VM is not booted, the message will not be + * localized, and it will be formatted using simplified message formatting + * code that is contained in this class. + */ + +/* + * Some of this code is executed before the VM is fully booted. Some import + * statements have been omitted to help prevent accidental use of classes that + * may not be available during boot. + */ + +public class LocalizedMessage { + + private static final Resources resources = new Resources(); + + private final String key; + + /** + * A LocalizedMessage can be instantiated with a key and formatted with + * arguments later in the style of MessageFormat. This organization + * allows the actual formatting (and associated permission checks) to be + * avoided unless the resulting string is needed. + * @param key + */ + public LocalizedMessage(String key) { + this.key = key; + } + + /** + * Return a localized string corresponding to the key stored in this + * object, formatted with the provided arguments. When the VM is booted, + * this method will obtain the correct localized message and format it + * using java.text.MessageFormat. Otherwise, a non-localized string is + * returned, and the formatting is performed by simplified formatting code. + * + * @param arguments The arguments that should be placed in the message + * @return A formatted message string + */ + public String format(Object... arguments) { + return getMessage(key, arguments); + } + + /** + * Return a non-localized string corresponding to the provided key, and + * formatted with the provided arguments. All strings are obtained from + * sun.security.util.Resources, and the formatting only supports + * simple positional argument replacement (e.g. {1}). + * + * @param key The key of the desired string in Resources + * @param arguments The arguments that should be placed in the message + * @return A formatted message string + */ + public static String getMessageUnbooted(String key, + Object... arguments) { + + String value = resources.getString(key); + if (arguments == null || arguments.length == 0) { + return value; + } + // Classes like StringTokenizer may not be loaded, so parsing + // is performed with String methods + StringBuilder sb = new StringBuilder(); + int nextBraceIndex; + while ((nextBraceIndex = value.indexOf('{')) >= 0) { + + String firstPart = value.substring(0, nextBraceIndex); + sb.append(firstPart); + value = value.substring(nextBraceIndex + 1); + + // look for closing brace and argument index + nextBraceIndex = value.indexOf('}'); + if (nextBraceIndex < 0) { + // no closing brace + // MessageFormat would throw IllegalArgumentException, but + // that exception class may not be loaded yet + throw new RuntimeException("Unmatched braces"); + } + String indexStr = value.substring(0, nextBraceIndex); + try { + int index = Integer.parseInt(indexStr); + sb.append(arguments[index]); + } + catch(NumberFormatException e) { + // argument index is not an integer + throw new RuntimeException("not an integer: " + indexStr); + } + value = value.substring(nextBraceIndex + 1); + } + sb.append(value); + return sb.toString(); + } + + /** + * Return a localized string corresponding to the provided key, and + * formatted with the provided arguments. When the VM is booted, this + * method will obtain the correct localized message and format it using + * java.text.MessageFormat. Otherwise, a non-localized string is returned, + * and the formatting is performed by simplified formatting code. + * + * @param key The key of the desired string in the security resource bundle + * @param arguments The arguments that should be placed in the message + * @return A formatted message string + */ + public static String getMessage(String key, + Object... arguments) { + + if (jdk.internal.misc.VM.isBooted()) { + // Localization and formatting resources are available + String value = ResourcesMgr.getString(key); + if (arguments == null) { + return value; + } + java.text.MessageFormat form = new java.text.MessageFormat(value); + return form.format(arguments); + } else { + return getMessageUnbooted(key, arguments); + } + } + +}
--- a/jdk/src/java.base/share/classes/sun/security/util/ResourcesMgr.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/src/java.base/share/classes/sun/security/util/ResourcesMgr.java Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 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,37 +34,24 @@ */ public class ResourcesMgr { // intended for java.security, javax.security and sun.security resources - private final static String RESOURCES = "sun.security.util.Resources"; - private final static String AUTH_RESOURCES = "sun.security.util.AuthResources"; - private final static Map<String, ResourceBundle> bundles = new ConcurrentHashMap<>(); public static String getString(String s) { - ResourceBundle bundle = bundles.get(RESOURCES); - if (bundle == null) { - - // only load if/when needed - bundle = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<java.util.ResourceBundle>() { - public java.util.ResourceBundle run() { - return (java.util.ResourceBundle.getBundle - ("sun.security.util.Resources")); - } - }); - } - - return bundle.getString(s); + return getBundle("sun.security.util.Resources").getString(s); } public static String getAuthResourceString(String s) { - if (VM.initLevel() == 3) { - // cannot trigger loading of any resource bundle as - // it depends on the system class loader fully initialized. - throw new InternalError("system class loader is being initialized"); + return getBundle("sun.security.util.AuthResources").getString(s); + } + + private static ResourceBundle getBundle(String bundleName) { + if (!VM.isBooted()) { + // don't expect this be called before the system is fully initialized. + // This triggers loading of any resource bundle that should be + // be done during initialization of system class loader. + throw new InternalError("Expected to use ResourceBundle only after booted"); } - - return bundles.computeIfAbsent(AUTH_RESOURCES, ResourceBundle::getBundle) - .getString(s); + return bundles.computeIfAbsent(bundleName, ResourceBundle::getBundle); } }
--- a/jdk/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java Thu Jan 26 09:19:33 2017 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, 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 @@ -195,9 +195,26 @@ return parent; } + /** + * This method returns equivalent CLDR supported locale for zh-HK, + * no, no-NO locales so that COMPAT locales do not precede + * those locales during ResourceBundle search path. + */ + private static Locale getEquivalentLoc(Locale locale) { + switch (locale.toString()) { + case "zh_HK": + return Locale.forLanguageTag("zh-Hant-HK"); + case "no": + case "no_NO": + return Locale.forLanguageTag("nb"); + } + return locale; + } + @Override public boolean isSupportedProviderLocale(Locale locale, Set<String> langtags) { - return Locale.ROOT.equals(locale) || - langtags.contains(locale.stripExtensions().toLanguageTag()); + return Locale.ROOT.equals(locale) + || langtags.contains(locale.stripExtensions().toLanguageTag()) + || langtags.contains(getEquivalentLoc(locale).toLanguageTag()); } }
--- a/jdk/src/java.base/share/lib/security/default.policy Tue Jan 24 18:44:13 2017 +0300 +++ b/jdk/src/java.base/share/lib/security/default.policy Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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 Thu Jan 26 09:19:33 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.