-
Bug
-
Resolution: Future Project
-
P3
-
None
-
6u10
-
generic, x86
-
generic, windows_xp
There are some issues concerning PKCS#11 support in various JDKs an especially in the most recent JDK 6 Update 10.
The PKCS#11 standard generally distinguishes between public and user sessions.
Public session provide access to public objects (e.g. certificates) without the user being logged into the smartcard in question.
The SUN PKCS#11 support seems to contain a general design bug by forcing a user to login for any access to the smartcard. Such an approach results in various access policies and workflows of real life applications being violated when trying to use the Java KeyStore API for accessing smartcards.
Example:
For enumerating the aliases in a KeyStore, the following code snippet could be used:
KeyStore ks = KeyStore.getInstance("PKCS11", PKCS11.getProvider(0)); ks.load(null, "myPIN".toCharArray()); List<String> aliases = Collections.list(ks.aliases()); for (String alias : aliases) {
System.out.println(alias);
}
However, the above-cited code snippet does not work without any PIN being entered, i.e. without the user being logged in, even if the smartcard would allow such an enumeration during a public session (cf. the subsequent stacktrace when using ks.load(null, null)):
Exception in thread "main" java.io.IOException: load failed
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:754)
at java.security.KeyStore.load(Unknown Source)
at test.NoPin.main(NoPin.java:12) Caused by: javax.security.auth.login.LoginException: no password provided, and no callback handler available for retrieving password
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1087)
at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:854)
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:742)
... 2 more
Please eliminate the above-cited design bug in order to provide PKCS#11 KeyStore access using
CallbackHandlerProtection, which queries the PIN lazily, i.e. when really required by the smartcard in contrast to an early PIN query. Hence, SUN PKCS#11 support would become compatible with standard PKCS#11 access policies.
The sun.security.pkcs11.SunPCS11 class forces an early login, i.e.
during Keystore.load(), depending on the PKCS#11 token info flag
CKF_LOGIN_REQUIRED being set.
However, the PKCS#11 spec says that this flag means that SOME (but not
necessarily all) functions require the user to be logged in. We think
that a misinterpretation of this flag causes the reported bug.
As a consequence, some scenarios, e.g. enlisting certificates stored on
a smartcard, do not work without the user being logged in. This is a
showstopper for various PKI-enabled real life applications.
All critical functions like C_SignInit or C_DigestInit have a special return code called "CKR_USER_NOT_LOGGED_IN" which is returned by the PKCS#11 implementstion if the login on the card would have been required for the execution of the function. Such a return should be treated in a similar way that the CKR_DEVICE_REMOVED.
Functions looking for objects like for example C_FindObjectsInit, don't have such a return code. However, the PKCS#11 specification define that if no login has occurred, the function shall only return public objects. This is indeed what LuxTrust needs.
It's not evident to include such a public session management into the JCE/JCA given the diversity of possible tokens and vendors. We thus think that the application developer should have the possibility to define if a login on the card is required or not.
KeyStore ks = KeyStore.getInstance("PKCS11", PKCS11.getProvider(0)); ks.load(null, null); // no login on token necessary
List<String> aliases = Collections.list(ks.aliases()); // only alias of public objects are returned if no login as occurred
for (String alias : aliases)
{
....
}
The PKCS#11 standard generally distinguishes between public and user sessions.
Public session provide access to public objects (e.g. certificates) without the user being logged into the smartcard in question.
The SUN PKCS#11 support seems to contain a general design bug by forcing a user to login for any access to the smartcard. Such an approach results in various access policies and workflows of real life applications being violated when trying to use the Java KeyStore API for accessing smartcards.
Example:
For enumerating the aliases in a KeyStore, the following code snippet could be used:
KeyStore ks = KeyStore.getInstance("PKCS11", PKCS11.getProvider(0)); ks.load(null, "myPIN".toCharArray()); List<String> aliases = Collections.list(ks.aliases()); for (String alias : aliases) {
System.out.println(alias);
}
However, the above-cited code snippet does not work without any PIN being entered, i.e. without the user being logged in, even if the smartcard would allow such an enumeration during a public session (cf. the subsequent stacktrace when using ks.load(null, null)):
Exception in thread "main" java.io.IOException: load failed
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:754)
at java.security.KeyStore.load(Unknown Source)
at test.NoPin.main(NoPin.java:12) Caused by: javax.security.auth.login.LoginException: no password provided, and no callback handler available for retrieving password
at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1087)
at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:854)
at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:742)
... 2 more
Please eliminate the above-cited design bug in order to provide PKCS#11 KeyStore access using
CallbackHandlerProtection, which queries the PIN lazily, i.e. when really required by the smartcard in contrast to an early PIN query. Hence, SUN PKCS#11 support would become compatible with standard PKCS#11 access policies.
The sun.security.pkcs11.SunPCS11 class forces an early login, i.e.
during Keystore.load(), depending on the PKCS#11 token info flag
CKF_LOGIN_REQUIRED being set.
However, the PKCS#11 spec says that this flag means that SOME (but not
necessarily all) functions require the user to be logged in. We think
that a misinterpretation of this flag causes the reported bug.
As a consequence, some scenarios, e.g. enlisting certificates stored on
a smartcard, do not work without the user being logged in. This is a
showstopper for various PKI-enabled real life applications.
All critical functions like C_SignInit or C_DigestInit have a special return code called "CKR_USER_NOT_LOGGED_IN" which is returned by the PKCS#11 implementstion if the login on the card would have been required for the execution of the function. Such a return should be treated in a similar way that the CKR_DEVICE_REMOVED.
Functions looking for objects like for example C_FindObjectsInit, don't have such a return code. However, the PKCS#11 specification define that if no login has occurred, the function shall only return public objects. This is indeed what LuxTrust needs.
It's not evident to include such a public session management into the JCE/JCA given the diversity of possible tokens and vendors. We thus think that the application developer should have the possibility to define if a login on the card is required or not.
KeyStore ks = KeyStore.getInstance("PKCS11", PKCS11.getProvider(0)); ks.load(null, null); // no login on token necessary
List<String> aliases = Collections.list(ks.aliases()); // only alias of public objects are returned if no login as occurred
for (String alias : aliases)
{
....
}