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