As we mentioned earlier the JCE is not intended for hardware usage. Even when we achieved the usecase in combining JCE providers with smartcards not all features of the standard JCE can be satisfied. Also there are some deviations regarding the expected behavior compared to the standard JCE. Within this chapter we clarify which functions / features do not behave like they would be expected.
Objects
Whenever a key is created or returned by one of our JCE classes actually this is not directly the key itself. Smartcards internally operate with keyIDs – or more general – handles and will not return the complete key but rather the handle. Private keys / Secret keys will even never leave the card since they are stored in the smartcard's protected area. Due to this reason our JCE classes always return a wrapped key handle and never the binary key data.
The same applies to certificates and data objects. Whenever an object is retrieved this is actually not the binary data of the object but rather a handle for accessing it.
In other words – objects received from our JCE classes are not useable with other JCE classes of different providers! |
Certificates and public keys are able for being extracted in ASN1 raw data by getEncoded function.
KeyStore
As we learned in 4.1 all objects returned by our JCE classes are wrapped object handles. This concept also applies for outgoing objects of our keystore implementation while importing works as usual.
Before operating our keystore has to be loaded like each usual keystore by calling the load function. The first parameter stream is ignored while the second – password – plays a special role. When no password is given the keystore is loaded in public mode i.e. only public objects will be returned.
Lets clarify this within an example. First someone loads the keystore with both parameters set to null. Afterwards getKey is called with an alias usually storing a private and a public key. Since in public mode all private objects are invisible the function will return the public key.
Now we assume calling load carrying null as first parameter and the smartcard's PIN as the second one. This loads our keystore in private mode i.e. all objects are visible. The same getKey call now results in returning the private key.
Now someone could have the idea retrieving both keys – the public and the private key – by calling getKey in different modes. This would of course work for usual keystores but not for ours. As we learned in 4.1 our keys are implemented via handles. As soon as the load function is called all previously received handles are no more guilty. In order to retrieve both keys someone first has to call the load function with the correct PIN. Afterwards the private key can be received by calling the getKey function. Getting the public key needs two steps. First call the getCertificate function. Then use the certificate instance and call it's getPublicKey function.
The keystore is the only object which permanently connects to the smartcard and must be loaded in private mode in order to use private cryptographic operations from other SPI objects like Cipher and Signature. |
Before using the SmartCardExtension ensure unloading the keystore from private- to public mode! Otherwise the SmartCardExtension's functions being able to throw SmartCardInUseException will return with that error. |
When a keystore was previously loaded and the smartcard is removed and reinserted the keystore will automatically reload in public mode. |
KeyPairGenerator / KeyGenerators
As shown in 4.2 only the keystore opens a permanent connection to the smartcard. All other SPI objects generated from a SmartCardAuthProvider just open a temporary connection. This also applies for KeyGenerator / KeyPairGenerators.
When a Key- /KeyPairGenerator generates a key and the keystore was not yet loaded or loaded in public mode retrieved keys do not contain valid handles. In this case you have to load the keystore in private mode and receive the handle(s) again with the correct alias! You can extract the alias from invalid objects by calling getID after you casted them to SmartCardObject.
When a Key- /KeyPairGenerator generates a key and the keystore was loaded in private mode the handles retrieved by the generateKey / generateKeyPair stay valid as long as the keystore is reloaded or the smartcard is removed.
When the keystore is not loaded in private mode KeyGenrators or KeyPairGenerators do not return valid object handles! |
Configuration
Our SmartCardAuthProviders and even some parts of the SDKs where designed to be configurable. Currently we support to disable specific algorithms and allow PIN caching. In the following we will discuss those features.
Disable Algorithms
We learned that each SmartCardAuthProvider offers the cryptographic algorithms available on the currently inserted smartcard as services. For instance some of those algorithms could be outdated, broken or not recommended for some usecases. For this scenario we implemented the "DISABLED_ALGORITHMS" feature.
In order to disable some of the algorithms a provider would usually offer or to be more precise a smartcard would usually offer someone can use the "DISABLED_ALGORITHMS"-property during the instantiation of the SmartCardAuthProvider. The property shall carry all the algorithms which shall not be offered by the provider separated by a ";". The following example shows how some of the services can be disabled:
Properties prop = new Properties();
String disabledAlgorithms = "";
disabledAlgorithms += "RSA/NONE/PKCS1Padding;";
disabledAlgorithms += "DES3";
p.setProperty("DISABLED_ALGORITHMS", disabledAlgorithms);
SmartCardAuthProvider provider = new SmartCardAuthProvider(prop,
reader, extension, factory);
PIN Caching
So far we have learned that there are several situations where a prompt to the user is neccessary in order to get the smartcard's PIN. Those situations are always processes doing private smartcard operations i.e. using private- or secret-keys. Since it would be quite annoying for the user to re-enter the PIN all the times we implemented PIN caching. In some situations PIN caching is mandatory since otherwise functional expectations would be violated. In some others it is optional and can be prohibited. Lets have a look at those situations:
- During a login / logout session those functions are offerd by AuthProviders the PIN is asked once and always stays cached. This situation can't be prohibited since it would violate the expectations a user might have from previous uses of the JCE.
- As soon as a keystore is successfully loaded in private mode by using the load-function the PIN stays cached as long as the load-function is called again or the smartcard is removed. PIN caching within keystores is always independent from login / logout sessions and can not be prohibited.
- During the instantiation of a reader PIN caching can be allowed or not. When PIN caching was activated and the PIN was once entered correctly the PIN stays cached as long as the smartcard is removed. When a PIN was cached and login is called the user will not be asked for the PIN.
When no PIN caching and no login session is active the user is always prompted for the PIN as soon as a private cryptographic operation shall be executed.
A SmartCardAuthProvider instantiated with this reader will use PIN caching for it's complete lifetime!