1/*
2 * Copyright (c) 2003, 2016, 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
60void prefetchFields(JNIEnv *env, jclass thisClass);
61jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo);
62jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo);
63jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo);
64jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo);
65
66/* define variables */
67
68jfieldID pNativeDataID;
69jfieldID mech_mechanismID;
70jfieldID mech_pParameterID;
71jfieldID mech_pHandleID;
72
73jclass jByteArrayClass;
74jclass jLongClass;
75
76JavaVM* jvm = NULL;
77
78jboolean debug = 0;
79
80JNIEXPORT 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 */
96JNIEXPORT jlong JNICALL
97Java_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 = %x\n", 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 */
114JNIEXPORT void JNICALL
115Java_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
128jclass 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
134void 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 */
166JNIEXPORT void JNICALL
167Java_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 */
208JNIEXPORT void JNICALL
209Java_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) { return; }
236
237 TRACE0("FINISHED\n");
238}
239#endif
240
241#ifdef P11_ENABLE_C_FINALIZE
242/*
243 * Class: sun_security_pkcs11_wrapper_PKCS11
244 * Method: C_Finalize
245 * Signature: (Ljava/lang/Object;)V
246 * Parametermapping: *PKCS11*
247 * @param jobject jReserved CK_VOID_PTR pReserved
248 */
249JNIEXPORT void JNICALL
250Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize
251(JNIEnv *env, jobject obj, jobject jReserved)
252{
253 /*
254 * Finalize Cryptoki
255 */
256 CK_VOID_PTR ckpReserved;
257 CK_RV rv;
258
259 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
260 if (ckpFunctions == NULL) { return; }
261
262 ckpReserved = jObjectToCKVoidPtr(jReserved);
263
264 rv = (*ckpFunctions->C_Finalize)(ckpReserved);
265 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
266}
267#endif
268
269#ifdef P11_ENABLE_C_GETINFO
270/*
271 * Class: sun_security_pkcs11_wrapper_PKCS11
272 * Method: C_GetInfo
273 * Signature: ()Lsun/security/pkcs11/wrapper/CK_INFO;
274 * Parametermapping: *PKCS11*
275 * @return jobject jInfoObject CK_INFO_PTR pInfo
276 */
277JNIEXPORT jobject JNICALL
278Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo
279(JNIEnv *env, jobject obj)
280{
281 CK_INFO ckLibInfo;
282 jobject jInfoObject=NULL;
283 CK_RV rv;
284 CK_FUNCTION_LIST_PTR ckpFunctions;
285 memset(&ckLibInfo, 0, sizeof(CK_INFO));
286
287 ckpFunctions = getFunctionList(env, obj);
288 if (ckpFunctions == NULL) { return NULL; }
289
290 rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo);
291 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
292 jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo);
293 }
294 return jInfoObject ;
295}
296
297/*
298 * converts a pointer to a CK_INFO structure into a Java CK_INFO Object.
299 *
300 * @param env - used to call JNI funktions to create the new Java object
301 * @param ckpInfo - the pointer to the CK_INFO structure
302 * @return - the new Java CK_INFO object
303 */
304jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo)
305{
306 jclass jInfoClass;
307 jmethodID jCtrId;
308 jobject jInfoObject;
309 jobject jCryptokiVer;
310 jcharArray jVendor;
311 jlong jFlags;
312 jcharArray jLibraryDesc;
313 jobject jLibraryVer;
314
315 /* load CK_INFO class */
316 jInfoClass = (*env)->FindClass(env, CLASS_INFO);
317 if (jInfoClass == NULL) { return NULL; };
318
319 /* load CK_INFO constructor */
320 jCtrId = (*env)->GetMethodID
321 (env, jInfoClass, "<init>",
322 "(Lsun/security/pkcs11/wrapper/CK_VERSION;[CJ[CLsun/security/pkcs11/wrapper/CK_VERSION;)V");
323 if (jCtrId == NULL) { return NULL; }
324
325 /* prep all fields */
326 jCryptokiVer = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion));
327 if (jCryptokiVer == NULL) { return NULL; }
328 jVendor =
329 ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32);
330 if (jVendor == NULL) { return NULL; }
331 jFlags = ckULongToJLong(ckpInfo->flags);
332 jLibraryDesc =
333 ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]), 32);
334 if (jLibraryDesc == NULL) { return NULL; }
335 jLibraryVer = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion));
336 if (jLibraryVer == NULL) { return NULL; }
337
338 /* create new CK_INFO object */
339 jInfoObject = (*env)->NewObject(env, jInfoClass, jCtrId, jCryptokiVer,
340 jVendor, jFlags, jLibraryDesc, jLibraryVer);
341 if (jInfoObject == NULL) { return NULL; }
342
343 /* free local references */
344 (*env)->DeleteLocalRef(env, jInfoClass);
345 (*env)->DeleteLocalRef(env, jCryptokiVer);
346 (*env)->DeleteLocalRef(env, jVendor);
347 (*env)->DeleteLocalRef(env, jLibraryDesc);
348 (*env)->DeleteLocalRef(env, jLibraryVer);
349
350 return jInfoObject ;
351}
352#endif
353
354#ifdef P11_ENABLE_C_GETSLOTLIST
355/*
356 * Class: sun_security_pkcs11_wrapper_PKCS11
357 * Method: C_GetSlotList
358 * Signature: (Z)[J
359 * Parametermapping: *PKCS11*
360 * @param jboolean jTokenPresent CK_BBOOL tokenPresent
361 * @return jlongArray jSlotList CK_SLOT_ID_PTR pSlotList
362 * CK_ULONG_PTR pulCount
363 */
364JNIEXPORT jlongArray JNICALL
365Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList
366(JNIEnv *env, jobject obj, jboolean jTokenPresent)
367{
368 CK_ULONG ckTokenNumber;
369 CK_SLOT_ID_PTR ckpSlotList;
370 CK_BBOOL ckTokenPresent;
371 jlongArray jSlotList = NULL;
372 CK_RV rv;
373
374 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
375 if (ckpFunctions == NULL) { return NULL; }
376
377 ckTokenPresent = jBooleanToCKBBool(jTokenPresent);
378
379 rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR,
380 &ckTokenNumber);
381 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
382
383 ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID));
384 if (ckpSlotList == NULL) {
385 throwOutOfMemoryError(env, 0);
386 return NULL;
387 }
388
389 rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList,
390 &ckTokenNumber);
391 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
392 jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber);
393 }
394 free(ckpSlotList);
395
396 return jSlotList ;
397}
398#endif
399
400#ifdef P11_ENABLE_C_GETSLOTINFO
401/*
402 * Class: sun_security_pkcs11_wrapper_PKCS11
403 * Method: C_GetSlotInfo
404 * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SLOT_INFO;
405 * Parametermapping: *PKCS11*
406 * @param jlong jSlotID CK_SLOT_ID slotID
407 * @return jobject jSlotInfoObject CK_SLOT_INFO_PTR pInfo
408 */
409JNIEXPORT jobject JNICALL
410Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo
411(JNIEnv *env, jobject obj, jlong jSlotID)
412{
413 CK_SLOT_ID ckSlotID;
414 CK_SLOT_INFO ckSlotInfo;
415 jobject jSlotInfoObject=NULL;
416 CK_RV rv;
417
418 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
419 if (ckpFunctions == NULL) { return NULL; }
420
421 ckSlotID = jLongToCKULong(jSlotID);
422
423 rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo);
424 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
425 jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo);
426 }
427 return jSlotInfoObject;
428}
429
430/*
431 * converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO
432 * Object.
433 *
434 * @param env - used to call JNI funktions to create the new Java object
435 * @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure
436 * @return - the new Java CK_SLOT_INFO object
437 */
438jobject
439ckSlotInfoPtrToJSlotInfo
440(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo)
441{
442 jclass jSlotInfoClass;
443 jmethodID jCtrId;
444 jobject jSlotInfoObject;
445 jcharArray jSlotDesc;
446 jcharArray jVendor;
447 jlong jFlags;
448 jobject jHardwareVer;
449 jobject jFirmwareVer;
450
451 /* load CK_SLOT_INFO class */
452 jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO);
453 if (jSlotInfoClass == NULL) { return NULL; };
454
455 /* load CK_SLOT_INFO constructor */
456 jCtrId = (*env)->GetMethodID
457 (env, jSlotInfoClass, "<init>",
458 "([C[CJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;)V");
459 if (jCtrId == NULL) { return NULL; }
460
461 /* prep all fields */
462 jSlotDesc =
463 ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]), 64);
464 if (jSlotDesc == NULL) { return NULL; }
465 jVendor =
466 ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]), 32);
467 if (jVendor == NULL) { return NULL; }
468 jFlags = ckULongToJLong(ckpSlotInfo->flags);
469 jHardwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion));
470 if (jHardwareVer == NULL) { return NULL; }
471 jFirmwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion));
472 if (jFirmwareVer == NULL) { return NULL; }
473
474 /* create new CK_SLOT_INFO object */
475 jSlotInfoObject = (*env)->NewObject
476 (env, jSlotInfoClass, jCtrId, jSlotDesc, jVendor, jFlags,
477 jHardwareVer, jFirmwareVer);
478 if (jSlotInfoObject == NULL) { return NULL; }
479
480 /* free local references */
481 (*env)->DeleteLocalRef(env, jSlotInfoClass);
482 (*env)->DeleteLocalRef(env, jSlotDesc);
483 (*env)->DeleteLocalRef(env, jVendor);
484 (*env)->DeleteLocalRef(env, jHardwareVer);
485 (*env)->DeleteLocalRef(env, jFirmwareVer);
486
487 return jSlotInfoObject ;
488}
489
490#endif
491
492#ifdef P11_ENABLE_C_GETTOKENINFO
493/*
494 * Class: sun_security_pkcs11_wrapper_PKCS11
495 * Method: C_GetTokenInfo
496 * Signature: (J)Lsun/security/pkcs11/wrapper/CK_TOKEN_INFO;
497 * Parametermapping: *PKCS11*
498 * @param jlong jSlotID CK_SLOT_ID slotID
499 * @return jobject jInfoTokenObject CK_TOKEN_INFO_PTR pInfo
500 */
501JNIEXPORT jobject JNICALL
502Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo
503(JNIEnv *env, jobject obj, jlong jSlotID)
504{
505 CK_SLOT_ID ckSlotID;
506 CK_TOKEN_INFO ckTokenInfo;
507 jobject jInfoTokenObject = NULL;
508 CK_RV rv;
509
510 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
511 if (ckpFunctions == NULL) { return NULL; }
512
513 ckSlotID = jLongToCKULong(jSlotID);
514
515 rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo);
516 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
517 jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo);
518 }
519 return jInfoTokenObject ;
520}
521
522/*
523 * converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO
524 * Object.
525 *
526 * @param env - used to call JNI funktions to create the new Java object
527 * @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure
528 * @return - the new Java CK_TOKEN_INFO object
529 */
530jobject
531ckTokenInfoPtrToJTokenInfo
532(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo)
533{
534 jclass jTokenInfoClass;
535 jmethodID jCtrId;
536 jobject jTokenInfoObject;
537 jcharArray jLabel;
538 jcharArray jVendor;
539 jcharArray jModel;
540 jcharArray jSerialNo;
541 jlong jFlags;
542 jlong jMaxSnCnt;
543 jlong jSnCnt;
544 jlong jMaxRwSnCnt;
545 jlong jRwSnCnt;
546 jlong jMaxPinLen;
547 jlong jMinPinLen;
548 jlong jTotalPubMem;
549 jlong jFreePubMem;
550 jlong jTotalPrivMem;
551 jlong jFreePrivMem;
552 jobject jHardwareVer;
553 jobject jFirmwareVer;
554 jcharArray jUtcTime;
555
556 /* load CK_TOKEN_INFO class */
557 jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO);
558 if (jTokenInfoClass == NULL) { return NULL; };
559
560 /* load CK_TOKEN_INFO constructor */
561 jCtrId = (*env)->GetMethodID
562 (env, jTokenInfoClass, "<init>",
563 "([C[C[C[CJJJJJJJJJJJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;[C)V");
564 if (jCtrId == NULL) { return NULL; };
565
566 /* prep all fields */
567 jLabel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]), 32);
568 if (jLabel == NULL) { return NULL; };
569 jVendor =
570 ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]), 32);
571 if (jVendor == NULL) { return NULL; };
572 jModel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]), 16);
573 if (jModel == NULL) { return NULL; };
574 jSerialNo =
575 ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]), 16);
576 if (jSerialNo == NULL) { return NULL; };
577 jFlags = ckULongToJLong(ckpTokenInfo->flags);
578 jMaxSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxSessionCount);
579 jSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulSessionCount);
580 jMaxRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxRwSessionCount);
581 jRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulRwSessionCount);
582 jMaxPinLen = ckULongToJLong(ckpTokenInfo->ulMaxPinLen);
583 jMinPinLen = ckULongToJLong(ckpTokenInfo->ulMinPinLen);
584 jTotalPubMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPublicMemory);
585 jFreePubMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePublicMemory);
586 jTotalPrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPrivateMemory);
587 jFreePrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePrivateMemory);
588 jHardwareVer =
589 ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion));
590 if (jHardwareVer == NULL) { return NULL; }
591 jFirmwareVer =
592 ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion));
593 if (jFirmwareVer == NULL) { return NULL; }
594 jUtcTime =
595 ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]), 16);
596 if (jUtcTime == NULL) { return NULL; }
597
598 /* create new CK_TOKEN_INFO object */
599 jTokenInfoObject =
600 (*env)->NewObject(env, jTokenInfoClass, jCtrId, jLabel, jVendor, jModel,
601 jSerialNo, jFlags,
602 jMaxSnCnt, jSnCnt, jMaxRwSnCnt, jRwSnCnt,
603 jMaxPinLen, jMinPinLen,
604 jTotalPubMem, jFreePubMem, jTotalPrivMem, jFreePrivMem,
605 jHardwareVer, jFirmwareVer, jUtcTime);
606 if (jTokenInfoObject == NULL) { return NULL; }
607
608 /* free local references */
609 (*env)->DeleteLocalRef(env, jTokenInfoClass);
610 (*env)->DeleteLocalRef(env, jLabel);
611 (*env)->DeleteLocalRef(env, jVendor);
612 (*env)->DeleteLocalRef(env, jModel);
613 (*env)->DeleteLocalRef(env, jSerialNo);
614 (*env)->DeleteLocalRef(env, jHardwareVer);
615 (*env)->DeleteLocalRef(env, jFirmwareVer);
616
617 return jTokenInfoObject ;
618}
619#endif
620
621#ifdef P11_ENABLE_C_WAITFORSLOTEVENT
622/*
623 * Class: sun_security_pkcs11_wrapper_PKCS11
624 * Method: C_WaitForSlotEvent
625 * Signature: (JLjava/lang/Object;)J
626 * Parametermapping: *PKCS11*
627 * @param jlong jFlags CK_FLAGS flags
628 * @param jobject jReserved CK_VOID_PTR pReserved
629 * @return jlong jSlotID CK_SLOT_ID_PTR pSlot
630 */
631JNIEXPORT jlong JNICALL
632Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent
633(JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved)
634{
635 CK_FLAGS ckFlags;
636 CK_SLOT_ID ckSlotID;
637 jlong jSlotID = 0L;
638 CK_RV rv;
639
640 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
641 if (ckpFunctions == NULL) { return 0L; }
642
643 ckFlags = jLongToCKULong(jFlags);
644
645 rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR);
646 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
647 jSlotID = ckULongToJLong(ckSlotID);
648 }
649
650 return jSlotID ;
651}
652#endif
653
654#ifdef P11_ENABLE_C_GETMECHANISMLIST
655/*
656 * Class: sun_security_pkcs11_wrapper_PKCS11
657 * Method: C_GetMechanismList
658 * Signature: (J)[J
659 * Parametermapping: *PKCS11*
660 * @param jlong jSlotID CK_SLOT_ID slotID
661 * @return jlongArray jMechanismList CK_MECHANISM_TYPE_PTR pMechanismList
662 * CK_ULONG_PTR pulCount
663 */
664JNIEXPORT jlongArray JNICALL
665Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList
666(JNIEnv *env, jobject obj, jlong jSlotID)
667{
668 CK_SLOT_ID ckSlotID;
669 CK_ULONG ckMechanismNumber;
670 CK_MECHANISM_TYPE_PTR ckpMechanismList;
671 jlongArray jMechanismList = NULL;
672 CK_RV rv;
673
674 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
675 if (ckpFunctions == NULL) { return NULL; }
676
677 ckSlotID = jLongToCKULong(jSlotID);
678
679 rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR,
680 &ckMechanismNumber);
681 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
682
683 ckpMechanismList = (CK_MECHANISM_TYPE_PTR)
684 malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE));
685 if (ckpMechanismList == NULL) {
686 throwOutOfMemoryError(env, 0);
687 return NULL;
688 }
689
690 rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList,
691 &ckMechanismNumber);
692 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
693 jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList,
694 ckMechanismNumber);
695 }
696 free(ckpMechanismList);
697
698 return jMechanismList ;
699}
700#endif
701
702#ifdef P11_ENABLE_C_GETMECHANISMINFO
703/*
704 * Class: sun_security_pkcs11_wrapper_PKCS11
705 * Method: C_GetMechanismInfo
706 * Signature: (JJ)Lsun/security/pkcs11/wrapper/CK_MECHANISM_INFO;
707 * Parametermapping: *PKCS11*
708 * @param jlong jSlotID CK_SLOT_ID slotID
709 * @param jlong jType CK_MECHANISM_TYPE type
710 * @return jobject jMechanismInfo CK_MECHANISM_INFO_PTR pInfo
711 */
712JNIEXPORT jobject JNICALL
713Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo
714(JNIEnv *env, jobject obj, jlong jSlotID, jlong jType)
715{
716 CK_SLOT_ID ckSlotID;
717 CK_MECHANISM_TYPE ckMechanismType;
718 CK_MECHANISM_INFO ckMechanismInfo;
719 jobject jMechanismInfo = NULL;
720 CK_RV rv;
721
722 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
723 if (ckpFunctions == NULL) { return NULL; }
724
725 ckSlotID = jLongToCKULong(jSlotID);
726 ckMechanismType = jLongToCKULong(jType);
727
728 rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType,
729 &ckMechanismInfo);
730 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
731 jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo);
732 }
733 return jMechanismInfo ;
734}
735
736/*
737 * converts a pointer to a CK_MECHANISM_INFO structure into a Java
738 * CK_MECHANISM_INFO Object.
739 *
740 * @param env - used to call JNI funktions to create the new Java object
741 * @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure
742 * @return - the new Java CK_MECHANISM_INFO object
743 */
744jobject
745ckMechanismInfoPtrToJMechanismInfo
746(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo)
747{
748
749 jclass jMechanismInfoClass;
750 jmethodID jCtrId;
751 jobject jMechanismInfoObject;
752 jlong jMinKeySize;
753 jlong jMaxKeySize;
754 jlong jFlags;
755
756 /* load CK_MECHANISM_INFO class */
757 jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO);
758 if (jMechanismInfoClass == NULL) { return NULL; };
759
760 /* load CK_MECHANISM_INFO constructor */
761 jCtrId = (*env)->GetMethodID(env, jMechanismInfoClass, "<init>", "(JJJ)V");
762 if (jCtrId == NULL) { return NULL; };
763
764 /* prep all fields */
765 jMinKeySize = ckULongToJLong(ckpMechanismInfo->ulMinKeySize);
766 jMaxKeySize = ckULongToJLong(ckpMechanismInfo->ulMaxKeySize);
767 jFlags = ckULongToJLong(ckpMechanismInfo->flags);
768
769 /* create new CK_MECHANISM_INFO object */
770 jMechanismInfoObject = (*env)->NewObject(env, jMechanismInfoClass, jCtrId,
771 jMinKeySize, jMaxKeySize, jFlags);
772 if (jMechanismInfoObject == NULL) { return NULL; };
773
774 /* free local references */
775 (*env)->DeleteLocalRef(env, jMechanismInfoClass);
776
777 return jMechanismInfoObject ;
778}
779#endif
780
781#ifdef P11_ENABLE_C_INITTOKEN
782/*
783 * Class: sun_security_pkcs11_wrapper_PKCS11
784 * Method: C_InitToken
785 * Signature: (J[C[C)V
786 * Parametermapping: *PKCS11*
787 * @param jlong jSlotID CK_SLOT_ID slotID
788 * @param jcharArray jPin CK_CHAR_PTR pPin
789 * CK_ULONG ulPinLen
790 * @param jcharArray jLabel CK_UTF8CHAR_PTR pLabel
791 */
792JNIEXPORT void JNICALL
793Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken
794(JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel)
795{
796 CK_SLOT_ID ckSlotID;
797 CK_CHAR_PTR ckpPin = NULL_PTR;
798 CK_UTF8CHAR_PTR ckpLabel = NULL_PTR;
799 CK_ULONG ckPinLength;
800 CK_ULONG ckLabelLength;
801 CK_RV rv;
802
803 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
804 if (ckpFunctions == NULL) { return; }
805
806 ckSlotID = jLongToCKULong(jSlotID);
807 jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
808 if ((*env)->ExceptionCheck(env)) { return; }
809 /* ckLabelLength <= 32 !!! */
810 jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength);
811 if ((*env)->ExceptionCheck(env)) {
812 free(ckpPin);
813 return;
814 }
815
816 rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel);
817 TRACE1("InitToken return code: %d", rv);
818
819 free(ckpPin);
820 free(ckpLabel);
821
822 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
823}
824#endif
825
826#ifdef P11_ENABLE_C_INITPIN
827/*
828 * Class: sun_security_pkcs11_wrapper_PKCS11
829 * Method: C_InitPIN
830 * Signature: (J[C)V
831 * Parametermapping: *PKCS11*
832 * @param jlong jSessionHandle CK_SESSION_HANDLE
833 * @param jcharArray jPin CK_CHAR_PTR pPin
834 * CK_ULONG ulPinLen
835 */
836JNIEXPORT void JNICALL
837Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN
838(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin)
839{
840 CK_SESSION_HANDLE ckSessionHandle;
841 CK_CHAR_PTR ckpPin = NULL_PTR;
842 CK_ULONG ckPinLength;
843 CK_RV rv;
844
845 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
846 if (ckpFunctions == NULL) { return; }
847
848 ckSessionHandle = jLongToCKULong(jSessionHandle);
849 jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
850 if ((*env)->ExceptionCheck(env)) { return; }
851
852 rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength);
853
854 free(ckpPin);
855
856 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
857}
858#endif
859
860#ifdef P11_ENABLE_C_SETPIN
861/*
862 * Class: sun_security_pkcs11_wrapper_PKCS11
863 * Method: C_SetPIN
864 * Signature: (J[C[C)V
865 * Parametermapping: *PKCS11*
866 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
867 * @param jcharArray jOldPin CK_CHAR_PTR pOldPin
868 * CK_ULONG ulOldLen
869 * @param jcharArray jNewPin CK_CHAR_PTR pNewPin
870 * CK_ULONG ulNewLen
871 */
872JNIEXPORT void JNICALL
873Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN
874(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin,
875jcharArray jNewPin)
876{
877 CK_SESSION_HANDLE ckSessionHandle;
878 CK_CHAR_PTR ckpOldPin = NULL_PTR;
879 CK_CHAR_PTR ckpNewPin = NULL_PTR;
880 CK_ULONG ckOldPinLength;
881 CK_ULONG ckNewPinLength;
882 CK_RV rv;
883
884 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
885 if (ckpFunctions == NULL) { return; }
886
887 ckSessionHandle = jLongToCKULong(jSessionHandle);
888 jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength);
889 if ((*env)->ExceptionCheck(env)) { return; }
890 jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength);
891 if ((*env)->ExceptionCheck(env)) {
892 free(ckpOldPin);
893 return;
894 }
895
896 rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength,
897 ckpNewPin, ckNewPinLength);
898
899 free(ckpOldPin);
900 free(ckpNewPin);
901
902 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
903}
904#endif
905