1 /*
2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
6  *
7  * Redistribution and use in  source and binary forms, with or without
8  * modification, are permitted  provided that the following conditions are met:
9  *
10  * 1. Redistributions of  source code must retain the above copyright notice,
11  *    this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in  binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  *
17  * 3. The end-user documentation included with the redistribution, if any, must
18  *    include the following acknowledgment:
19  *
20  *    "This product includes software developed by IAIK of Graz University of
21  *     Technology."
22  *
23  *    Alternately, this acknowledgment may appear in the software itself, if
24  *    and wherever such third-party acknowledgments normally appear.
25  *
26  * 4. The names "Graz University of Technology" and "IAIK of Graz University of
27  *    Technology" must not be used to endorse or promote products derived from
28  *    this software without prior written permission.
29  *
30  * 5. Products derived from this software may not be called
31  *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
32  *    written permission of Graz University of Technology.
33  *
34  *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
35  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36  *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
38  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39  *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
41  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
43  *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
45  *  POSSIBILITY  OF SUCH DAMAGE.
46  */
47 
48 #include "pkcs11wrapper.h"
49 
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <assert.h>
54 #include "jlong.h"
55 
56 #include "sun_security_pkcs11_wrapper_PKCS11.h"
57 
58 /* declare file private functions */
59 
60 void prefetchFields(JNIEnv *env, jclass thisClass);
61 jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo);
62 jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo);
63 jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo);
64 jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo);
65 
66 /* define variables */
67 
68 jfieldID pNativeDataID;
69 jfieldID mech_mechanismID;
70 jfieldID mech_pParameterID;
71 jfieldID mech_pHandleID;
72 
73 jclass jByteArrayClass;
74 jclass jLongClass;
75 
76 JavaVM* jvm = NULL;
77 
78 jboolean debug = 0;
79 
DEF_JNI_OnLoad(JavaVM * vm,void * reserved)80 JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
81     jvm = vm;
82     return JNI_VERSION_1_4;
83 }
84 
85 /* ************************************************************************** */
86 /* The native implementation of the methods of the PKCS11Implementation class */
87 /* ************************************************************************** */
88 
89 /*
90  * This method is used to do free the memory allocated for CK_MECHANISM structure.
91  *
92  * Class:     sun_security_pkcs11_wrapper_PKCS11
93  * Method:    freeMechanism
94  * Signature: (J)J
95  */
96 JNIEXPORT jlong JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_freeMechanism(JNIEnv * env,jclass thisClass,jlong ckpMechanism)97 Java_sun_security_pkcs11_wrapper_PKCS11_freeMechanism
98 (JNIEnv *env, jclass thisClass, jlong ckpMechanism) {
99     if (ckpMechanism != 0L) {
100         freeCKMechanismPtr(jlong_to_ptr(ckpMechanism));
101         TRACE1("DEBUG PKCS11_freeMechanism: free pMech = %lld\n", (long long int) ckpMechanism);
102     }
103     return 0L;
104 }
105 
106 /*
107  * This method is used to do static initialization. This method is static and
108  * synchronized. Summary: use this method like a static initialization block.
109  *
110  * Class:     sun_security_pkcs11_wrapper_PKCS11
111  * Method:    initializeLibrary
112  * Signature: ()V
113  */
114 JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_initializeLibrary(JNIEnv * env,jclass thisClass,jboolean enableDebug)115 Java_sun_security_pkcs11_wrapper_PKCS11_initializeLibrary
116 (JNIEnv *env, jclass thisClass, jboolean enableDebug)
117 {
118 #ifndef NO_CALLBACKS
119     if (notifyListLock == NULL) {
120         notifyListLock = createLockObject(env);
121     }
122 #endif
123 
124     prefetchFields(env, thisClass);
125     debug = enableDebug;
126 }
127 
fetchClass(JNIEnv * env,const char * name)128 jclass fetchClass(JNIEnv *env, const char *name) {
129     jclass tmpClass = (*env)->FindClass(env, name);
130     if (tmpClass == NULL) { return NULL; }
131     return (*env)->NewGlobalRef(env, tmpClass);
132 }
133 
prefetchFields(JNIEnv * env,jclass thisClass)134 void prefetchFields(JNIEnv *env, jclass thisClass) {
135     jclass tmpClass;
136 
137     /* PKCS11 - pNativeData */
138     pNativeDataID = (*env)->GetFieldID(env, thisClass, "pNativeData", "J");
139     if (pNativeDataID == NULL) { return; }
140 
141     /* CK_MECHANISM - mechanism, pParameter, pHandle */
142     tmpClass = (*env)->FindClass(env, CLASS_MECHANISM);
143     if (tmpClass == NULL) { return; }
144     mech_mechanismID = (*env)->GetFieldID(env, tmpClass, "mechanism", "J");
145     if (mech_mechanismID == NULL) { return; }
146     mech_pParameterID = (*env)->GetFieldID(env, tmpClass, "pParameter",
147                                            "Ljava/lang/Object;");
148     if (mech_pParameterID == NULL) { return; }
149     mech_pHandleID = (*env)->GetFieldID(env, tmpClass, "pHandle", "J");
150     if (mech_pHandleID == NULL) { return; }
151 
152     /* java classes for primitive types - byte[], long */
153     jByteArrayClass = fetchClass(env, "[B");
154     if (jByteArrayClass == NULL) { return; }
155     jLongClass = fetchClass(env, "java/lang/Long");
156 }
157 
158 /* This method is designed to do a clean-up. It releases all global resources
159  * of this library. By now, this function is not called. Calling from
160  * JNI_OnUnload would be an option, but some VMs do not support JNI_OnUnload.
161  *
162  * Class:     sun_security_pkcs11_wrapper_PKCS11
163  * Method:    finalizeLibrary
164  * Signature: ()V
165  */
166 JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_finalizeLibrary(JNIEnv * env,jclass thisClass)167 Java_sun_security_pkcs11_wrapper_PKCS11_finalizeLibrary
168 (JNIEnv *env, jclass thisClass)
169 {
170 /* XXX
171     * remove all left lists and release the resources and the lock
172      * objects that synchroniz access to these lists.
173      *
174     removeAllModuleEntries(env);
175     if (moduleListHead == NULL) { * check, if we removed the last active module *
176         * remove also the moduleListLock, it is no longer used *
177         if (moduleListLock != NULL) {
178             destroyLockObject(env, moduleListLock);
179             moduleListLock = NULL;
180         }
181 #ifndef NO_CALLBACKS
182         * remove all left notify callback entries *
183         while (removeFirstNotifyEntry(env));
184         * remove also the notifyListLock, it is no longer used *
185         if (notifyListLock != NULL) {
186             destroyLockObject(env, notifyListLock);
187             notifyListLock = NULL;
188         }
189         if (jInitArgsObject != NULL) {
190             (*env)->DeleteGlobalRef(env, jInitArgsObject);
191         }
192         if (ckpGlobalInitArgs != NULL_PTR) {
193             free(ckpGlobalInitArgs);
194         }
195 #endif * NO_CALLBACKS *
196     }
197 */
198 }
199 
200 #ifdef P11_ENABLE_C_INITIALIZE
201 /*
202  * Class:     sun_security_pkcs11_wrapper_PKCS11
203  * Method:    C_Initialize
204  * Signature: (Ljava/lang/Object;)V
205  * Parametermapping:                    *PKCS11*
206  * @param   jobject jInitArgs           CK_VOID_PTR pInitArgs
207  */
208 JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1Initialize(JNIEnv * env,jobject obj,jobject jInitArgs)209 Java_sun_security_pkcs11_wrapper_PKCS11_C_1Initialize
210 (JNIEnv *env, jobject obj, jobject jInitArgs)
211 {
212     /*
213      * Initalize Cryptoki
214      */
215     CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
216     CK_RV rv;
217     CK_FUNCTION_LIST_PTR ckpFunctions;
218 
219     TRACE0("DEBUG: initializing module... ");
220 
221     ckpFunctions = getFunctionList(env, obj);
222     if (ckpFunctions == NULL) {
223         TRACE0("failed getting module entry");
224         return;
225     }
226 
227     ckpInitArgs = (jInitArgs != NULL)
228                 ? makeCKInitArgsAdapter(env, jInitArgs)
229                 : NULL_PTR;
230 
231     rv = (*ckpFunctions->C_Initialize)(ckpInitArgs);
232 
233     free(ckpInitArgs);
234 
235     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
236       TRACE1("DEBUG: C_Initialize had a bad return value %lu \n", (unsigned long) rv);
237       return;
238     }
239 
240     TRACE0("FINISHED\n");
241 }
242 #endif
243 
244 #ifdef P11_ENABLE_C_FINALIZE
245 /*
246  * Class:     sun_security_pkcs11_wrapper_PKCS11
247  * Method:    C_Finalize
248  * Signature: (Ljava/lang/Object;)V
249  * Parametermapping:                    *PKCS11*
250  * @param   jobject jReserved           CK_VOID_PTR pReserved
251  */
252 JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize(JNIEnv * env,jobject obj,jobject jReserved)253 Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize
254 (JNIEnv *env, jobject obj, jobject jReserved)
255 {
256     /*
257      * Finalize Cryptoki
258      */
259     CK_VOID_PTR ckpReserved;
260     CK_RV rv;
261 
262     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
263     if (ckpFunctions == NULL) { return; }
264 
265     ckpReserved = jObjectToCKVoidPtr(jReserved);
266 
267     rv = (*ckpFunctions->C_Finalize)(ckpReserved);
268     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
269 }
270 #endif
271 
272 #ifdef P11_ENABLE_C_GETINFO
273 /*
274  * Class:     sun_security_pkcs11_wrapper_PKCS11
275  * Method:    C_GetInfo
276  * Signature: ()Lsun/security/pkcs11/wrapper/CK_INFO;
277  * Parametermapping:                    *PKCS11*
278  * @return  jobject jInfoObject         CK_INFO_PTR pInfo
279  */
280 JNIEXPORT jobject JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo(JNIEnv * env,jobject obj)281 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo
282 (JNIEnv *env, jobject obj)
283 {
284     CK_INFO ckLibInfo;
285     jobject jInfoObject=NULL;
286     CK_RV rv;
287     CK_FUNCTION_LIST_PTR ckpFunctions;
288     memset(&ckLibInfo, 0, sizeof(CK_INFO));
289 
290     ckpFunctions = getFunctionList(env, obj);
291     if (ckpFunctions == NULL) { return NULL; }
292 
293     rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo);
294     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
295         jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo);
296     }
297     return jInfoObject ;
298 }
299 
300 /*
301  * converts a pointer to a CK_INFO structure into a Java CK_INFO Object.
302  *
303  * @param env - used to call JNI funktions to create the new Java object
304  * @param ckpInfo - the pointer to the CK_INFO structure
305  * @return - the new Java CK_INFO object
306  */
ckInfoPtrToJInfo(JNIEnv * env,const CK_INFO_PTR ckpInfo)307 jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo)
308 {
309     jclass jInfoClass;
310     jmethodID jCtrId;
311     jobject jInfoObject;
312     jobject jCryptokiVer;
313     jcharArray jVendor;
314     jlong jFlags;
315     jcharArray jLibraryDesc;
316     jobject jLibraryVer;
317 
318     /* load CK_INFO class */
319     jInfoClass = (*env)->FindClass(env, CLASS_INFO);
320     if (jInfoClass == NULL) { return NULL; };
321 
322     /* load CK_INFO constructor */
323     jCtrId = (*env)->GetMethodID
324       (env, jInfoClass, "<init>",
325        "(Lsun/security/pkcs11/wrapper/CK_VERSION;[CJ[CLsun/security/pkcs11/wrapper/CK_VERSION;)V");
326     if (jCtrId == NULL) { return NULL; }
327 
328     /* prep all fields */
329     jCryptokiVer = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion));
330     if (jCryptokiVer == NULL) { return NULL; }
331     jVendor =
332       ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32);
333     if (jVendor == NULL) { return NULL; }
334     jFlags = ckULongToJLong(ckpInfo->flags);
335     jLibraryDesc =
336       ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]), 32);
337     if (jLibraryDesc == NULL) { return NULL; }
338     jLibraryVer = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion));
339     if (jLibraryVer == NULL) { return NULL; }
340 
341     /* create new CK_INFO object */
342     jInfoObject = (*env)->NewObject(env, jInfoClass, jCtrId, jCryptokiVer,
343                                     jVendor, jFlags, jLibraryDesc, jLibraryVer);
344     if (jInfoObject == NULL) { return NULL; }
345 
346     /* free local references */
347     (*env)->DeleteLocalRef(env, jInfoClass);
348     (*env)->DeleteLocalRef(env, jCryptokiVer);
349     (*env)->DeleteLocalRef(env, jVendor);
350     (*env)->DeleteLocalRef(env, jLibraryDesc);
351     (*env)->DeleteLocalRef(env, jLibraryVer);
352 
353     return jInfoObject ;
354 }
355 #endif
356 
357 #ifdef P11_ENABLE_C_GETSLOTLIST
358 /*
359  * Class:     sun_security_pkcs11_wrapper_PKCS11
360  * Method:    C_GetSlotList
361  * Signature: (Z)[J
362  * Parametermapping:                    *PKCS11*
363  * @param   jboolean jTokenPresent      CK_BBOOL tokenPresent
364  * @return  jlongArray jSlotList        CK_SLOT_ID_PTR pSlotList
365  *                                      CK_ULONG_PTR pulCount
366  */
367 JNIEXPORT jlongArray JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList(JNIEnv * env,jobject obj,jboolean jTokenPresent)368 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList
369 (JNIEnv *env, jobject obj, jboolean jTokenPresent)
370 {
371     CK_ULONG ckTokenNumber;
372     CK_SLOT_ID_PTR ckpSlotList;
373     CK_BBOOL ckTokenPresent;
374     jlongArray jSlotList = NULL;
375     CK_RV rv;
376 
377     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
378     if (ckpFunctions == NULL) { return NULL; }
379 
380     ckTokenPresent = jBooleanToCKBBool(jTokenPresent);
381 
382     rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR,
383                                         &ckTokenNumber);
384     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
385 
386     ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID));
387     if (ckpSlotList == NULL) {
388         throwOutOfMemoryError(env, 0);
389         return NULL;
390     }
391 
392     rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList,
393                                         &ckTokenNumber);
394     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
395         jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber);
396     }
397     free(ckpSlotList);
398 
399     return jSlotList ;
400 }
401 #endif
402 
403 #ifdef P11_ENABLE_C_GETSLOTINFO
404 /*
405  * Class:     sun_security_pkcs11_wrapper_PKCS11
406  * Method:    C_GetSlotInfo
407  * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SLOT_INFO;
408  * Parametermapping:                    *PKCS11*
409  * @param   jlong jSlotID               CK_SLOT_ID slotID
410  * @return  jobject jSlotInfoObject     CK_SLOT_INFO_PTR pInfo
411  */
412 JNIEXPORT jobject JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo(JNIEnv * env,jobject obj,jlong jSlotID)413 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo
414 (JNIEnv *env, jobject obj, jlong jSlotID)
415 {
416     CK_SLOT_ID ckSlotID;
417     CK_SLOT_INFO ckSlotInfo;
418     jobject jSlotInfoObject=NULL;
419     CK_RV rv;
420 
421     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
422     if (ckpFunctions == NULL) { return NULL; }
423 
424     ckSlotID = jLongToCKULong(jSlotID);
425 
426     rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo);
427     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
428         jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo);
429     }
430     return jSlotInfoObject;
431 }
432 
433 /*
434  * converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO
435  * Object.
436  *
437  * @param env - used to call JNI funktions to create the new Java object
438  * @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure
439  * @return - the new Java CK_SLOT_INFO object
440  */
441 jobject
ckSlotInfoPtrToJSlotInfo(JNIEnv * env,const CK_SLOT_INFO_PTR ckpSlotInfo)442 ckSlotInfoPtrToJSlotInfo
443 (JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo)
444 {
445     jclass jSlotInfoClass;
446     jmethodID jCtrId;
447     jobject jSlotInfoObject;
448     jcharArray jSlotDesc;
449     jcharArray jVendor;
450     jlong jFlags;
451     jobject jHardwareVer;
452     jobject jFirmwareVer;
453 
454     /* load CK_SLOT_INFO class */
455     jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO);
456     if (jSlotInfoClass == NULL) { return NULL; };
457 
458     /* load CK_SLOT_INFO constructor */
459     jCtrId = (*env)->GetMethodID
460       (env, jSlotInfoClass, "<init>",
461        "([C[CJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;)V");
462     if (jCtrId == NULL) { return NULL; }
463 
464     /* prep all fields */
465     jSlotDesc =
466       ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]), 64);
467     if (jSlotDesc == NULL) { return NULL; }
468     jVendor =
469       ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]), 32);
470     if (jVendor == NULL) { return NULL; }
471     jFlags = ckULongToJLong(ckpSlotInfo->flags);
472     jHardwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion));
473     if (jHardwareVer == NULL) { return NULL; }
474     jFirmwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion));
475     if (jFirmwareVer == NULL) { return NULL; }
476 
477     /* create new CK_SLOT_INFO object */
478     jSlotInfoObject = (*env)->NewObject
479       (env, jSlotInfoClass, jCtrId, jSlotDesc, jVendor, jFlags,
480        jHardwareVer, jFirmwareVer);
481     if (jSlotInfoObject == NULL) { return NULL; }
482 
483     /* free local references */
484     (*env)->DeleteLocalRef(env, jSlotInfoClass);
485     (*env)->DeleteLocalRef(env, jSlotDesc);
486     (*env)->DeleteLocalRef(env, jVendor);
487     (*env)->DeleteLocalRef(env, jHardwareVer);
488     (*env)->DeleteLocalRef(env, jFirmwareVer);
489 
490     return jSlotInfoObject ;
491 }
492 
493 #endif
494 
495 #ifdef P11_ENABLE_C_GETTOKENINFO
496 /*
497  * Class:     sun_security_pkcs11_wrapper_PKCS11
498  * Method:    C_GetTokenInfo
499  * Signature: (J)Lsun/security/pkcs11/wrapper/CK_TOKEN_INFO;
500  * Parametermapping:                    *PKCS11*
501  * @param   jlong jSlotID               CK_SLOT_ID slotID
502  * @return  jobject jInfoTokenObject    CK_TOKEN_INFO_PTR pInfo
503  */
504 JNIEXPORT jobject JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo(JNIEnv * env,jobject obj,jlong jSlotID)505 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo
506 (JNIEnv *env, jobject obj, jlong jSlotID)
507 {
508     CK_SLOT_ID ckSlotID;
509     CK_TOKEN_INFO ckTokenInfo;
510     jobject jInfoTokenObject = NULL;
511     CK_RV rv;
512 
513     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
514     if (ckpFunctions == NULL) { return NULL; }
515 
516     ckSlotID = jLongToCKULong(jSlotID);
517 
518     rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo);
519     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
520         jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo);
521     }
522     return jInfoTokenObject ;
523 }
524 
525 /*
526  * converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO
527  * Object.
528  *
529  * @param env - used to call JNI funktions to create the new Java object
530  * @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure
531  * @return - the new Java CK_TOKEN_INFO object
532  */
533 jobject
ckTokenInfoPtrToJTokenInfo(JNIEnv * env,const CK_TOKEN_INFO_PTR ckpTokenInfo)534 ckTokenInfoPtrToJTokenInfo
535 (JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo)
536 {
537     jclass jTokenInfoClass;
538     jmethodID jCtrId;
539     jobject jTokenInfoObject;
540     jcharArray jLabel;
541     jcharArray jVendor;
542     jcharArray jModel;
543     jcharArray jSerialNo;
544     jlong jFlags;
545     jlong jMaxSnCnt;
546     jlong jSnCnt;
547     jlong jMaxRwSnCnt;
548     jlong jRwSnCnt;
549     jlong jMaxPinLen;
550     jlong jMinPinLen;
551     jlong jTotalPubMem;
552     jlong jFreePubMem;
553     jlong jTotalPrivMem;
554     jlong jFreePrivMem;
555     jobject jHardwareVer;
556     jobject jFirmwareVer;
557     jcharArray jUtcTime;
558 
559     /* load CK_TOKEN_INFO class */
560     jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO);
561     if (jTokenInfoClass == NULL)  { return NULL; };
562 
563     /* load CK_TOKEN_INFO constructor */
564     jCtrId = (*env)->GetMethodID
565       (env, jTokenInfoClass, "<init>",
566        "([C[C[C[CJJJJJJJJJJJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;[C)V");
567     if (jCtrId == NULL)  { return NULL; };
568 
569     /* prep all fields */
570     jLabel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]), 32);
571     if (jLabel == NULL)  { return NULL; };
572     jVendor =
573       ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]), 32);
574     if (jVendor == NULL)  { return NULL; };
575     jModel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]), 16);
576     if (jModel == NULL)  { return NULL; };
577     jSerialNo =
578       ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]), 16);
579     if (jSerialNo == NULL)  { return NULL; };
580     jFlags = ckULongToJLong(ckpTokenInfo->flags);
581     jMaxSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxSessionCount);
582     jSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulSessionCount);
583     jMaxRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxRwSessionCount);
584     jRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulRwSessionCount);
585     jMaxPinLen = ckULongToJLong(ckpTokenInfo->ulMaxPinLen);
586     jMinPinLen = ckULongToJLong(ckpTokenInfo->ulMinPinLen);
587     jTotalPubMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPublicMemory);
588     jFreePubMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePublicMemory);
589     jTotalPrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPrivateMemory);
590     jFreePrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePrivateMemory);
591     jHardwareVer =
592       ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion));
593     if (jHardwareVer == NULL) { return NULL; }
594     jFirmwareVer =
595       ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion));
596     if (jFirmwareVer == NULL) { return NULL; }
597     jUtcTime =
598       ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]), 16);
599     if (jUtcTime == NULL) { return NULL; }
600 
601     /* create new CK_TOKEN_INFO object */
602     jTokenInfoObject =
603       (*env)->NewObject(env, jTokenInfoClass, jCtrId, jLabel, jVendor, jModel,
604                         jSerialNo, jFlags,
605                         jMaxSnCnt, jSnCnt, jMaxRwSnCnt, jRwSnCnt,
606                         jMaxPinLen, jMinPinLen,
607                         jTotalPubMem, jFreePubMem, jTotalPrivMem, jFreePrivMem,
608                         jHardwareVer, jFirmwareVer, jUtcTime);
609     if (jTokenInfoObject == NULL) { return NULL; }
610 
611     /* free local references */
612     (*env)->DeleteLocalRef(env, jTokenInfoClass);
613     (*env)->DeleteLocalRef(env, jLabel);
614     (*env)->DeleteLocalRef(env, jVendor);
615     (*env)->DeleteLocalRef(env, jModel);
616     (*env)->DeleteLocalRef(env, jSerialNo);
617     (*env)->DeleteLocalRef(env, jHardwareVer);
618     (*env)->DeleteLocalRef(env, jFirmwareVer);
619 
620     return jTokenInfoObject ;
621 }
622 #endif
623 
624 #ifdef P11_ENABLE_C_WAITFORSLOTEVENT
625 /*
626  * Class:     sun_security_pkcs11_wrapper_PKCS11
627  * Method:    C_WaitForSlotEvent
628  * Signature: (JLjava/lang/Object;)J
629  * Parametermapping:                    *PKCS11*
630  * @param   jlong jFlags                CK_FLAGS flags
631  * @param   jobject jReserved           CK_VOID_PTR pReserved
632  * @return  jlong jSlotID               CK_SLOT_ID_PTR pSlot
633  */
634 JNIEXPORT jlong JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent(JNIEnv * env,jobject obj,jlong jFlags,jobject jReserved)635 Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent
636 (JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved)
637 {
638     CK_FLAGS ckFlags;
639     CK_SLOT_ID ckSlotID;
640     jlong jSlotID = 0L;
641     CK_RV rv;
642 
643     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
644     if (ckpFunctions == NULL) { return 0L; }
645 
646     ckFlags = jLongToCKULong(jFlags);
647 
648     rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR);
649     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
650         jSlotID = ckULongToJLong(ckSlotID);
651     }
652 
653     return jSlotID ;
654 }
655 #endif
656 
657 #ifdef P11_ENABLE_C_GETMECHANISMLIST
658 /*
659  * Class:     sun_security_pkcs11_wrapper_PKCS11
660  * Method:    C_GetMechanismList
661  * Signature: (J)[J
662  * Parametermapping:                    *PKCS11*
663  * @param   jlong jSlotID               CK_SLOT_ID slotID
664  * @return  jlongArray jMechanismList   CK_MECHANISM_TYPE_PTR pMechanismList
665  *                                      CK_ULONG_PTR pulCount
666  */
667 JNIEXPORT jlongArray JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList(JNIEnv * env,jobject obj,jlong jSlotID)668 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList
669 (JNIEnv *env, jobject obj, jlong jSlotID)
670 {
671     CK_SLOT_ID ckSlotID;
672     CK_ULONG ckMechanismNumber;
673     CK_MECHANISM_TYPE_PTR ckpMechanismList;
674     jlongArray jMechanismList = NULL;
675     CK_RV rv;
676 
677     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
678     if (ckpFunctions == NULL) { return NULL; }
679 
680     ckSlotID = jLongToCKULong(jSlotID);
681 
682     rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR,
683                                              &ckMechanismNumber);
684     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
685 
686     ckpMechanismList = (CK_MECHANISM_TYPE_PTR)
687       malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE));
688     if (ckpMechanismList == NULL) {
689         throwOutOfMemoryError(env, 0);
690         return NULL;
691     }
692 
693     rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList,
694                                              &ckMechanismNumber);
695     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
696         jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList,
697                                                   ckMechanismNumber);
698     }
699     free(ckpMechanismList);
700 
701     return jMechanismList ;
702 }
703 #endif
704 
705 #ifdef P11_ENABLE_C_GETMECHANISMINFO
706 /*
707  * Class:     sun_security_pkcs11_wrapper_PKCS11
708  * Method:    C_GetMechanismInfo
709  * Signature: (JJ)Lsun/security/pkcs11/wrapper/CK_MECHANISM_INFO;
710  * Parametermapping:                    *PKCS11*
711  * @param   jlong jSlotID               CK_SLOT_ID slotID
712  * @param   jlong jType                 CK_MECHANISM_TYPE type
713  * @return  jobject jMechanismInfo      CK_MECHANISM_INFO_PTR pInfo
714  */
715 JNIEXPORT jobject JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo(JNIEnv * env,jobject obj,jlong jSlotID,jlong jType)716 Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo
717 (JNIEnv *env, jobject obj, jlong jSlotID, jlong jType)
718 {
719     CK_SLOT_ID ckSlotID;
720     CK_MECHANISM_TYPE ckMechanismType;
721     CK_MECHANISM_INFO ckMechanismInfo;
722     jobject jMechanismInfo = NULL;
723     CK_RV rv;
724 
725     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
726     if (ckpFunctions == NULL) { return NULL; }
727 
728     ckSlotID = jLongToCKULong(jSlotID);
729     ckMechanismType = jLongToCKULong(jType);
730 
731     rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType,
732                                              &ckMechanismInfo);
733     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
734         jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo);
735     }
736     return jMechanismInfo ;
737 }
738 
739 /*
740  * converts a pointer to a CK_MECHANISM_INFO structure into a Java
741  * CK_MECHANISM_INFO Object.
742  *
743  * @param env - used to call JNI funktions to create the new Java object
744  * @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure
745  * @return - the new Java CK_MECHANISM_INFO object
746  */
747 jobject
ckMechanismInfoPtrToJMechanismInfo(JNIEnv * env,const CK_MECHANISM_INFO_PTR ckpMechanismInfo)748 ckMechanismInfoPtrToJMechanismInfo
749 (JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo)
750 {
751 
752     jclass jMechanismInfoClass;
753     jmethodID jCtrId;
754     jobject jMechanismInfoObject;
755     jlong jMinKeySize;
756     jlong jMaxKeySize;
757     jlong jFlags;
758 
759     /* load CK_MECHANISM_INFO class */
760     jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO);
761     if (jMechanismInfoClass == NULL) { return NULL; };
762 
763     /* load CK_MECHANISM_INFO constructor */
764     jCtrId = (*env)->GetMethodID(env, jMechanismInfoClass, "<init>", "(JJJ)V");
765     if (jCtrId == NULL) { return NULL; };
766 
767     /* prep all fields */
768     jMinKeySize = ckULongToJLong(ckpMechanismInfo->ulMinKeySize);
769     jMaxKeySize = ckULongToJLong(ckpMechanismInfo->ulMaxKeySize);
770     jFlags = ckULongToJLong(ckpMechanismInfo->flags);
771 
772     /* create new CK_MECHANISM_INFO object */
773     jMechanismInfoObject = (*env)->NewObject(env, jMechanismInfoClass, jCtrId,
774                                              jMinKeySize, jMaxKeySize, jFlags);
775     if (jMechanismInfoObject == NULL) { return NULL; };
776 
777     /* free local references */
778     (*env)->DeleteLocalRef(env, jMechanismInfoClass);
779 
780     return jMechanismInfoObject ;
781 }
782 #endif
783 
784 #ifdef P11_ENABLE_C_INITTOKEN
785 /*
786  * Class:     sun_security_pkcs11_wrapper_PKCS11
787  * Method:    C_InitToken
788  * Signature: (J[C[C)V
789  * Parametermapping:                    *PKCS11*
790  * @param   jlong jSlotID               CK_SLOT_ID slotID
791  * @param   jcharArray jPin             CK_CHAR_PTR pPin
792  *                                      CK_ULONG ulPinLen
793  * @param   jcharArray jLabel           CK_UTF8CHAR_PTR pLabel
794  */
795 JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken(JNIEnv * env,jobject obj,jlong jSlotID,jcharArray jPin,jcharArray jLabel)796 Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken
797 (JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel)
798 {
799     CK_SLOT_ID ckSlotID;
800     CK_CHAR_PTR ckpPin = NULL_PTR;
801     CK_UTF8CHAR_PTR ckpLabel = NULL_PTR;
802     CK_ULONG ckPinLength;
803     CK_ULONG ckLabelLength;
804     CK_RV rv;
805 
806     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
807     if (ckpFunctions == NULL) { return; }
808 
809     ckSlotID = jLongToCKULong(jSlotID);
810     jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
811     if ((*env)->ExceptionCheck(env)) { return; }
812     /* ckLabelLength <= 32 !!! */
813     jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength);
814     if ((*env)->ExceptionCheck(env)) {
815         free(ckpPin);
816         return;
817     }
818 
819     rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel);
820     TRACE1("InitToken return code: %d", rv);
821 
822     free(ckpPin);
823     free(ckpLabel);
824 
825     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
826 }
827 #endif
828 
829 #ifdef P11_ENABLE_C_INITPIN
830 /*
831  * Class:     sun_security_pkcs11_wrapper_PKCS11
832  * Method:    C_InitPIN
833  * Signature: (J[C)V
834  * Parametermapping:                    *PKCS11*
835  * @param   jlong jSessionHandle        CK_SESSION_HANDLE
836  * @param   jcharArray jPin             CK_CHAR_PTR pPin
837  *                                      CK_ULONG ulPinLen
838  */
839 JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN(JNIEnv * env,jobject obj,jlong jSessionHandle,jcharArray jPin)840 Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN
841 (JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin)
842 {
843     CK_SESSION_HANDLE ckSessionHandle;
844     CK_CHAR_PTR ckpPin = NULL_PTR;
845     CK_ULONG ckPinLength;
846     CK_RV rv;
847 
848     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
849     if (ckpFunctions == NULL) { return; }
850 
851     ckSessionHandle = jLongToCKULong(jSessionHandle);
852     jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
853     if ((*env)->ExceptionCheck(env)) { return; }
854 
855     rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength);
856 
857     free(ckpPin);
858 
859     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
860 }
861 #endif
862 
863 #ifdef P11_ENABLE_C_SETPIN
864 /*
865  * Class:     sun_security_pkcs11_wrapper_PKCS11
866  * Method:    C_SetPIN
867  * Signature: (J[C[C)V
868  * Parametermapping:                    *PKCS11*
869  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
870  * @param   jcharArray jOldPin          CK_CHAR_PTR pOldPin
871  *                                      CK_ULONG ulOldLen
872  * @param   jcharArray jNewPin          CK_CHAR_PTR pNewPin
873  *                                      CK_ULONG ulNewLen
874  */
875 JNIEXPORT void JNICALL
Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN(JNIEnv * env,jobject obj,jlong jSessionHandle,jcharArray jOldPin,jcharArray jNewPin)876 Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN
877 (JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin,
878 jcharArray jNewPin)
879 {
880     CK_SESSION_HANDLE ckSessionHandle;
881     CK_CHAR_PTR ckpOldPin = NULL_PTR;
882     CK_CHAR_PTR ckpNewPin = NULL_PTR;
883     CK_ULONG ckOldPinLength;
884     CK_ULONG ckNewPinLength;
885     CK_RV rv;
886 
887     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
888     if (ckpFunctions == NULL) { return; }
889 
890     ckSessionHandle = jLongToCKULong(jSessionHandle);
891     jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength);
892     if ((*env)->ExceptionCheck(env)) { return; }
893     jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength);
894     if ((*env)->ExceptionCheck(env)) {
895         free(ckpOldPin);
896         return;
897     }
898 
899     rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength,
900                                    ckpNewPin, ckNewPinLength);
901 
902     free(ckpOldPin);
903     free(ckpNewPin);
904 
905     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
906 }
907 #endif
908