The wrapper included in SunPKCS11 Java security provider enables calling the PKCS#11 functions described in the standard from Java code. It should enable the same functionality as if the C Cryptoki library was used. The functions provided by the wrapper, however, slightly differentiate from the PKCS#11 standard specification. This section will go through the dif- ferences and analyse their impact on this thesis.
Missing Functions
The PKCS#11 standard provides a list of functions to implement. The wrap- per does not include all of these functions. The missing ones are [16]
∙ CancelFunction- legacy function.
∙ CloseAllSessions - closes all sessions an application has with
a token.
∙ GetFunctionList- returns a pointer to the Cryptoki library’s list
of function pointers.
∙ GetFunctionStatus- legacy function.
∙ GetOperationState- used to save a state of a cryptographic op-
eration.
∙ GetObjectSize- returns the size of an object in bytes.
∙ Initialize- initializes the Cryptoki library.
∙ InitToken- initializes a token.
∙ SetPIN- changes PIN of a user.
∙ SetOperationState- used to restore a state of a cryptographic
operation.
∙ WaitForSlotEvent - waits for a slot event, such as token inser-
tion or token removal, to occur.
It is immediately clear that thelegacyfunctions are not important at all. For the other missing functions the important question to ask is: Are the functions relevant for the PKCS#11 key security tests? And is so, is it possi- ble to work around the fact that the wrapper does not include the function? Caetus tool only needs one session for proper tests and even if it needed more, it would be possible to manually close them one by one, so the func-
tionCloseAllSessionsis not necessary. Still, unlike most others, it is not
actually clear why this function is missing, since it provides an assurance that the sessions have been closed and the token can be safely removed.
Getting a list of functions would be obsolete, since the wrapper handles this functionality for the programmer. It also better fits Java philosophy, where the programmer must deal with as few low-level issues as possible. Similarly, initializing the Cryptoki library, or more specifically provider in this case, is done in setting up the provider in Java code, so there is no need to duplicate this functionality in the wrapper.
Saving and restoring a state of a cryptographic operation (functions
GetOperationStateandSetOperationState) and waiting for a slot
event are not needed by this thesis at all.
InitPINandInitTokenare functions specific to SO user and there-
fore not interesting for this thesis anyway. It is clear that since the wrapper does not include these two functions, SunPKCS provider cannot be used by SO user.
SetPINis similar to the above token management functions, but can
actually be used by anormal user. In practice its lack would severely limit the security of the token, as it would make it impossible to change PIN of a user. Still, in such a case another Cryptoki implementation could be used. From the point of view of this thesis, however,SetPINis not important at all. Caetus is a tool designed only to test, so it should never alter anything in any tested token. Changing PIN would be a severe violation of this policy.
GetObjectSizeis a function that seems necessary, since many func-
wrapper also handles this automatically, so that the programmer does not have to deal with object size or template size at all.
It has been shown that none of the functions missing in the wrapper is needed by this thesis. On the other hand the missing functions may limit practical functionality of the SunPKCS11 Provider.
Missing Structures
A very important difference between Cryptoki and Java PKCS#11 wrapper is that the Java version is missing certain structures defined by Cryptoki. In Cryptoki data structure is a structure that is used to hold particular prede- fined data. An example of such a structure isCK_EXTRACT_PARAMS. That is also one of the missing structures.CK_EXTRACT_PARAMSis a parameter
ofEXTRACT_KEY_FROM_KEY, which has been mentioned in previous chap-
ters as one of the weaker key derivation mechanisms. Since some otherkey derivation mechanismsalso use structures that are missing in the Java wrap- per, it may seem that the weakerkey derivation mechanismscannot be tested at all.
Fortunately, it has been discovered that the aforementioned data struc- tures were not included in the wrapper, because they would have been ob- solete anyway. The reason for this conclusion is thatCK_EXTRACT_PARAMS
only consists of one unsigned long int, so there is no need to create an ex- tra structure just for that single parameter. Instead thelongcan be directly input as the parameter of the EXTRACT_KEY_FROM_KEY mechanism. The same applies to otherweaker key derivation mechanisms, only the direct input is eitherbyte[]orkey handle.
Other crucial structures that are defined by Cryptoki but are not in- cluded in the Java wrapper are CK_SESSION_HANDLE that points to the current session andCK_OBJECT_HANDLEthat points to the location of ob- jects in the session. These structures are also replaced by simplelongvari- able. This, unlike the case withkey derivationstructures, was much easier to determine with the help of the publicly available documentation [12]. Different Function Parameters
As explained above, the functions in Java wrapper have different param- eters than in Cryptoki specification. Moreover, there is very little publicly available documentation for the Java wrapper [12]. Fortunately there is con- sistency between the two, so it is considerably easy to determine the correct Cryptoki function parameters in Java even without detailed documenta-
tion.
When a function in Cryptoki requires a parameter that determines ob- ject size or length of a template, the same function in Java wrapper will not require that parameter. From a high-level point of view this approach is very useful, since it means the programmer does not have to deal with parameters that can be determined from other parameters passed to the function. Over the course of work on the Caetus tool this approach caused a problem once, since it was discovered that if a flawed template is passed to a function, it will cause a connected software token to crash. Flawed tem- plate means a template that has less attributes than its length or a template that is missing an attribute in one of its slots.
Most Cryptoki functions related to this thesis also have an attribute that specifies the location that receives the output of the function, which usually is a newly created object or encrypted data. For example in Cryp-
tokiWrapKeyhas parameterpWrappedKeyof the typeBYTE_PTR, which
points to the location that receives the wrapped key [16]. In Java there is no such attribute and the function instead returns the wrapped bytes as its return value.
Cryptoki specification uses return values to determine whether the func- tion worked properly on not and if not, the return value further speci- fies the cause of the failure. As shown above, Java wrapper adheres to Java design and returns the essential function output instead. In order to notify the user of a function failure, it uses Java exceptions that contain the Cryptoki return values as exception messages. For example when the function WrapKey attempts to wrap a key that has its EXTRACTABLE =
false, it instead throws a newPKCS11Exceptionwith its message contain-
ing CKR_KEY_UNEXTRACTABLE. Actually, that is the behaviour specified
by Cryptoki and intended by the Java wrapper, but it has been shown that some tokens ignore even this basic rule [5].
7.3 Sample Code
This section shows a brief sample in order to depict the difference between Java and C implementations. The first code snippet is taken from the exam- ples provided in the standard [16] and the other comes from Caetus code.
C implementation
CK_OBJECT_HANDLE hWrappingKey, hKey; CK_MECHANISM mechanism = { CKM_DES3_ECB, NULL_PTR, 0 }; CK_BYTE wrappedKey[8]; CK_ULONG ulWrappedKeyLen; CK_RV rv; . . ulWrappedKeyLen = sizeof(wrappedKey);
rv = C_WrapKey(hSession, &mechanism, hWrappingKey, hKey, wrappedKey, &ulWrappedKeyLen);
if (rv == CKR_OK) { . . } Java implementation try { long sessionHandle; long wrappingKeyHandle; long hKey;
CK_MECHANISM mechanism = new CK_MECHANISM( PKCS11Constants.CKM_DES3_ECB); byte[] wrappedKey;
. .
wrappedKey = pkcs11.C_WrapKey(sessionHandle, mechanism, wrappingKeyHandle, hKey); } catch (PKCS11Exception ex) {
. . }
The most notable difference is that Java uses less parameters to accom- plish the same result. That is due to the aforementioned difference in the pa- rameters required by the functions. The other important difference is that C code examines the return value in order to determine the result, while Java code surrounds the procedure in atry-catchblock. The results are again the
same. Also note that Java code only uses two variable types,longandbyte[], while C code uses five different structures. The reason for this is that Java wrapper substitutes all the C structures that only effectively contain one longanyway with a plainlong.
The Java code snippet contains two objects crucial for the whole Caetus tool. The first one isPKCS11class which only has its instance, denoted as pkcs11, shown in the snippet. This class is the core of the Java PKCS#11 wrapper and handles all the functions. For example wrapping is called
bypkcs11.C_WrapKey(parameters). The wrapper takes the function,
translates it for the underlying PKCS#11 token and takes the Cryptoki re- turn value. If the return value is anything other thanCKR_OK, thePKCS11
class throws the PKCS11Exception with the Cryptoki return value in its message. If the Cryptoki return value isCKR_OK, the essential function out- put as described above is returned.
The other key class for the Java wrapper isPKCS11Constants, which basically bridges the Java wrapper and Cryptoki by providing the Java code pointers to the objects in Cryptoki. This approach greatly reduces the amount of Java classes needed in the wrapper.
7.4 Chapter Conclusion
It has been shown that the Java SunPKCS11 Provider offers functionality that is very similar to Cryptoki specifications. There are some limitations, but they do not concern this thesis, since they are not related to stored cryp- tographic key protection. Therefore Java has been deemed a viable choice for implementing the tool for automated token analysis.
Caetus Tool
The primary goal of this thesis was to develop an open-source tool that could be used to automatically analyse the PKCS#11 tokens. The tool fo- cuses on finding mistakes in PKCS#11 implementation and also tries to analyse vulnerability of the tested tokens to the attacks showed in previous chapters of this thesis and to some trivial key recovery attempts. The tool is distributed under theApache License, Version 2.0[25]. The model checker, which is distributed together with Caetus, consists of multiple parts, one of which (zChaff) has a more restrictive license that forbids distributing the software unless an explicit permission is given. The permission has been granted byJohn F. Ritter, JD, MBA. This is referenced in the license files dis- tributed with Caetus. The code is available at https://code.google.
com/p/caetus/.