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 | |
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 | |
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 |
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 = %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 | */ |
114 | JNIEXPORT void JNICALL |
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 | |
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 | |
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 |
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 |
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) { 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 | */ |
249 | JNIEXPORT void JNICALL |
250 | Java_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 | */ |
277 | JNIEXPORT jobject JNICALL |
278 | Java_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 | */ |
304 | jobject 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 | */ |
364 | JNIEXPORT jlongArray JNICALL |
365 | Java_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 | */ |
409 | JNIEXPORT jobject JNICALL |
410 | Java_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 | */ |
438 | jobject |
439 | ckSlotInfoPtrToJSlotInfo |
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 | */ |
501 | JNIEXPORT jobject JNICALL |
502 | Java_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 | */ |
530 | jobject |
531 | ckTokenInfoPtrToJTokenInfo |
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 | */ |
631 | JNIEXPORT jlong JNICALL |
632 | Java_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 | */ |
664 | JNIEXPORT jlongArray JNICALL |
665 | Java_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 | */ |
712 | JNIEXPORT jobject JNICALL |
713 | Java_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 | */ |
744 | jobject |
745 | ckMechanismInfoPtrToJMechanismInfo |
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 | */ |
792 | JNIEXPORT void JNICALL |
793 | Java_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 | */ |
836 | JNIEXPORT void JNICALL |
837 | Java_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 | */ |
872 | JNIEXPORT void JNICALL |
873 | Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN |
874 | (JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin, |
875 | jcharArray 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 | |