|
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 |
|
55 /* declare file private functions */ |
|
56 |
|
57 ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation); |
|
58 int isModulePresent(JNIEnv *env, jobject pkcs11Implementation); |
|
59 void removeAllModuleEntries(JNIEnv *env); |
|
60 |
|
61 |
|
62 /* ************************************************************************** */ |
|
63 /* Functions for keeping track of currently active and loaded modules */ |
|
64 /* ************************************************************************** */ |
|
65 |
|
66 |
|
67 /* |
|
68 * Create a new object for locking. |
|
69 */ |
|
70 jobject createLockObject(JNIEnv *env) { |
|
71 jclass jObjectClass; |
|
72 jobject jLockObject; |
|
73 jmethodID jConstructor; |
|
74 |
|
75 jObjectClass = (*env)->FindClass(env, "java/lang/Object"); |
|
76 if (jObjectClass == NULL) { return NULL; } |
|
77 jConstructor = (*env)->GetMethodID(env, jObjectClass, "<init>", "()V"); |
|
78 if (jConstructor == NULL) { return NULL; } |
|
79 jLockObject = (*env)->NewObject(env, jObjectClass, jConstructor); |
|
80 if (jLockObject == NULL) { return NULL; } |
|
81 jLockObject = (*env)->NewGlobalRef(env, jLockObject); |
|
82 |
|
83 return jLockObject ; |
|
84 } |
|
85 |
|
86 /* |
|
87 * Create a new object for locking. |
|
88 */ |
|
89 void destroyLockObject(JNIEnv *env, jobject jLockObject) { |
|
90 if (jLockObject != NULL) { |
|
91 (*env)->DeleteGlobalRef(env, jLockObject); |
|
92 } |
|
93 } |
|
94 |
|
95 /* |
|
96 * Add the given pkcs11Implementation object to the list of present modules. |
|
97 * Attach the given data to the entry. If the given pkcs11Implementation is |
|
98 * already in the lsit, just override its old module data with the new one. |
|
99 * None of the arguments can be NULL. If one of the arguments is NULL, this |
|
100 * function does nothing. |
|
101 */ |
|
102 void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData) { |
|
103 if (pkcs11Implementation == NULL_PTR) { |
|
104 return ; |
|
105 } |
|
106 if (moduleData == NULL) { |
|
107 return ; |
|
108 } |
|
109 (*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, ptr_to_jlong(moduleData)); |
|
110 } |
|
111 |
|
112 |
|
113 /* |
|
114 * Get the module data of the entry for the given pkcs11Implementation. Returns |
|
115 * NULL, if the pkcs11Implementation is not in the list. |
|
116 */ |
|
117 ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation) { |
|
118 jlong jData; |
|
119 if (pkcs11Implementation == NULL) { |
|
120 return NULL; |
|
121 } |
|
122 jData = (*env)->GetLongField(env, pkcs11Implementation, pNativeDataID); |
|
123 return (ModuleData*)jlong_to_ptr(jData); |
|
124 } |
|
125 |
|
126 CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation) { |
|
127 ModuleData *moduleData; |
|
128 CK_FUNCTION_LIST_PTR ckpFunctions; |
|
129 |
|
130 moduleData = getModuleEntry(env, pkcs11Implementation); |
|
131 if (moduleData == NULL) { |
|
132 throwDisconnectedRuntimeException(env); |
|
133 return NULL; |
|
134 } |
|
135 ckpFunctions = moduleData->ckFunctionListPtr; |
|
136 return ckpFunctions; |
|
137 } |
|
138 |
|
139 |
|
140 /* |
|
141 * Returns 1, if the given pkcs11Implementation is in the list. |
|
142 * 0, otherwise. |
|
143 */ |
|
144 int isModulePresent(JNIEnv *env, jobject pkcs11Implementation) { |
|
145 int present; |
|
146 |
|
147 ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation); |
|
148 |
|
149 present = (moduleData != NULL) ? 1 : 0; |
|
150 |
|
151 return present ; |
|
152 } |
|
153 |
|
154 |
|
155 /* |
|
156 * Removes the entry for the given pkcs11Implementation from the list. Returns |
|
157 * the module's data, after the node was removed. If this function returns NULL |
|
158 * the pkcs11Implementation was not in the list. |
|
159 */ |
|
160 ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation) { |
|
161 ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation); |
|
162 if (moduleData == NULL) { |
|
163 return NULL; |
|
164 } |
|
165 (*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, 0); |
|
166 return moduleData; |
|
167 } |
|
168 |
|
169 /* |
|
170 * Removes all present entries from the list of modules and frees all |
|
171 * associated resources. This function is used for clean-up. |
|
172 */ |
|
173 void removeAllModuleEntries(JNIEnv *env) { |
|
174 /* XXX empty */ |
|
175 } |
|
176 |
|
177 /* ************************************************************************** */ |
|
178 /* Below there follow the helper functions to support conversions between */ |
|
179 /* Java and Cryptoki types */ |
|
180 /* ************************************************************************** */ |
|
181 |
|
182 /* |
|
183 * function to convert a PKCS#11 return value into a PKCS#11Exception |
|
184 * |
|
185 * This function generates a PKCS#11Exception with the returnValue as the errorcode |
|
186 * if the returnValue is not CKR_OK. The functin returns 0, if the returnValue is |
|
187 * CKR_OK. Otherwise, it returns the returnValue as a jLong. |
|
188 * |
|
189 * @param env - used to call JNI funktions and to get the Exception class |
|
190 * @param returnValue - of the PKCS#11 function |
|
191 */ |
|
192 jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue) |
|
193 { |
|
194 jclass jPKCS11ExceptionClass; |
|
195 jmethodID jConstructor; |
|
196 jthrowable jPKCS11Exception; |
|
197 jlong jErrorCode = 0L; |
|
198 |
|
199 if (returnValue != CKR_OK) { |
|
200 jErrorCode = ckULongToJLong(returnValue); |
|
201 jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION); |
|
202 if (jPKCS11ExceptionClass != NULL) { |
|
203 jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass, "<init>", "(J)V"); |
|
204 if (jConstructor != NULL) { |
|
205 jPKCS11Exception = (jthrowable) (*env)->NewObject(env, jPKCS11ExceptionClass, jConstructor, jErrorCode); |
|
206 if (jPKCS11Exception != NULL) { |
|
207 (*env)->Throw(env, jPKCS11Exception); |
|
208 } |
|
209 } |
|
210 } |
|
211 (*env)->DeleteLocalRef(env, jPKCS11ExceptionClass); |
|
212 } |
|
213 return jErrorCode ; |
|
214 } |
|
215 |
|
216 |
|
217 /* |
|
218 * Throws a Java Exception by name |
|
219 */ |
|
220 void throwByName(JNIEnv *env, const char *name, const char *msg) |
|
221 { |
|
222 jclass cls = (*env)->FindClass(env, name); |
|
223 |
|
224 if (cls != 0) /* Otherwise an exception has already been thrown */ |
|
225 (*env)->ThrowNew(env, cls, msg); |
|
226 } |
|
227 |
|
228 /* |
|
229 * Throws java.lang.OutOfMemoryError |
|
230 */ |
|
231 void throwOutOfMemoryError(JNIEnv *env, const char *msg) |
|
232 { |
|
233 throwByName(env, "java/lang/OutOfMemoryError", msg); |
|
234 } |
|
235 |
|
236 /* |
|
237 * Throws java.lang.NullPointerException |
|
238 */ |
|
239 void throwNullPointerException(JNIEnv *env, const char *msg) |
|
240 { |
|
241 throwByName(env, "java/lang/NullPointerException", msg); |
|
242 } |
|
243 |
|
244 /* |
|
245 * Throws java.io.IOException |
|
246 */ |
|
247 void throwIOException(JNIEnv *env, const char *msg) |
|
248 { |
|
249 throwByName(env, "java/io/IOException", msg); |
|
250 } |
|
251 |
|
252 /* |
|
253 * This function simply throws a PKCS#11RuntimeException with the given |
|
254 * string as its message. |
|
255 * |
|
256 * @param env Used to call JNI funktions and to get the Exception class. |
|
257 * @param jmessage The message string of the Exception object. |
|
258 */ |
|
259 void throwPKCS11RuntimeException(JNIEnv *env, const char *message) |
|
260 { |
|
261 throwByName(env, CLASS_PKCS11RUNTIMEEXCEPTION, message); |
|
262 } |
|
263 |
|
264 /* |
|
265 * This function simply throws a PKCS#11RuntimeException. The message says that |
|
266 * the object is not connected to the module. |
|
267 * |
|
268 * @param env Used to call JNI funktions and to get the Exception class. |
|
269 */ |
|
270 void throwDisconnectedRuntimeException(JNIEnv *env) |
|
271 { |
|
272 throwPKCS11RuntimeException(env, "This object is not connected to a module."); |
|
273 } |
|
274 |
|
275 /* This function frees the specified CK_ATTRIBUTE array. |
|
276 * |
|
277 * @param attrPtr pointer to the to-be-freed CK_ATTRIBUTE array. |
|
278 * @param len the length of the array |
|
279 */ |
|
280 void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len) |
|
281 { |
|
282 int i; |
|
283 |
|
284 for (i=0; i<len; i++) { |
|
285 if (attrPtr[i].pValue != NULL_PTR) { |
|
286 free(attrPtr[i].pValue); |
|
287 } |
|
288 } |
|
289 free(attrPtr); |
|
290 } |
|
291 |
|
292 /* |
|
293 * the following functions convert Java arrays to PKCS#11 array pointers and |
|
294 * their array length and vice versa |
|
295 * |
|
296 * void j<Type>ArrayToCK<Type>Array(JNIEnv *env, |
|
297 * const j<Type>Array jArray, |
|
298 * CK_<Type>_PTR *ckpArray, |
|
299 * CK_ULONG_PTR ckLength); |
|
300 * |
|
301 * j<Type>Array ck<Type>ArrayToJ<Type>Array(JNIEnv *env, |
|
302 * const CK_<Type>_PTR ckpArray, |
|
303 * CK_ULONG ckLength); |
|
304 * |
|
305 * PKCS#11 arrays consist always of a pointer to the beginning of the array and |
|
306 * the array length whereas Java arrays carry their array length. |
|
307 * |
|
308 * The Functions to convert a Java array to a PKCS#11 array are void functions. |
|
309 * Their arguments are the Java array object to convert, the reference to the |
|
310 * array pointer, where the new PKCS#11 array should be stored and the reference |
|
311 * to the array length where the PKCS#11 array length should be stored. These two |
|
312 * references must not be NULL_PTR. |
|
313 * |
|
314 * The functions first obtain the array length of the Java array and then allocate |
|
315 * the memory for the PKCS#11 array and set the array length. Then each element |
|
316 * gets converted depending on their type. After use the allocated memory of the |
|
317 * PKCS#11 array has to be explicitly freed. |
|
318 * |
|
319 * The Functions to convert a PKCS#11 array to a Java array get the PKCS#11 array |
|
320 * pointer and the array length and they return the new Java array object. The |
|
321 * Java array does not need to get freed after use. |
|
322 */ |
|
323 |
|
324 /* |
|
325 * converts a jbooleanArray to a CK_BBOOL array. The allocated memory has to be freed after use! |
|
326 * |
|
327 * @param env - used to call JNI funktions to get the array informtaion |
|
328 * @param jArray - the Java array to convert |
|
329 * @param ckpArray - the reference, where the pointer to the new CK_BBOOL array will be stored |
|
330 * @param ckpLength - the reference, where the array length will be stored |
|
331 */ |
|
332 void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckpLength) |
|
333 { |
|
334 jboolean* jpTemp; |
|
335 CK_ULONG i; |
|
336 |
|
337 if(jArray == NULL) { |
|
338 *ckpArray = NULL_PTR; |
|
339 *ckpLength = 0L; |
|
340 return; |
|
341 } |
|
342 *ckpLength = (*env)->GetArrayLength(env, jArray); |
|
343 jpTemp = (jboolean*) malloc((*ckpLength) * sizeof(jboolean)); |
|
344 if (jpTemp == NULL) { |
|
345 throwOutOfMemoryError(env, 0); |
|
346 return; |
|
347 } |
|
348 (*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp); |
|
349 if ((*env)->ExceptionCheck(env)) { |
|
350 free(jpTemp); |
|
351 return; |
|
352 } |
|
353 |
|
354 *ckpArray = (CK_BBOOL*) malloc ((*ckpLength) * sizeof(CK_BBOOL)); |
|
355 if (*ckpArray == NULL) { |
|
356 free(jpTemp); |
|
357 throwOutOfMemoryError(env, 0); |
|
358 return; |
|
359 } |
|
360 for (i=0; i<(*ckpLength); i++) { |
|
361 (*ckpArray)[i] = jBooleanToCKBBool(jpTemp[i]); |
|
362 } |
|
363 free(jpTemp); |
|
364 } |
|
365 |
|
366 /* |
|
367 * converts a jbyteArray to a CK_BYTE array. The allocated memory has to be freed after use! |
|
368 * |
|
369 * @param env - used to call JNI funktions to get the array informtaion |
|
370 * @param jArray - the Java array to convert |
|
371 * @param ckpArray - the reference, where the pointer to the new CK_BYTE array will be stored |
|
372 * @param ckpLength - the reference, where the array length will be stored |
|
373 */ |
|
374 void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckpLength) |
|
375 { |
|
376 jbyte* jpTemp; |
|
377 CK_ULONG i; |
|
378 |
|
379 if(jArray == NULL) { |
|
380 *ckpArray = NULL_PTR; |
|
381 *ckpLength = 0L; |
|
382 return; |
|
383 } |
|
384 *ckpLength = (*env)->GetArrayLength(env, jArray); |
|
385 jpTemp = (jbyte*) malloc((*ckpLength) * sizeof(jbyte)); |
|
386 if (jpTemp == NULL) { |
|
387 throwOutOfMemoryError(env, 0); |
|
388 return; |
|
389 } |
|
390 (*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp); |
|
391 if ((*env)->ExceptionCheck(env)) { |
|
392 free(jpTemp); |
|
393 return; |
|
394 } |
|
395 |
|
396 /* if CK_BYTE is the same size as jbyte, we save an additional copy */ |
|
397 if (sizeof(CK_BYTE) == sizeof(jbyte)) { |
|
398 *ckpArray = (CK_BYTE_PTR) jpTemp; |
|
399 } else { |
|
400 *ckpArray = (CK_BYTE_PTR) malloc ((*ckpLength) * sizeof(CK_BYTE)); |
|
401 if (*ckpArray == NULL) { |
|
402 free(jpTemp); |
|
403 throwOutOfMemoryError(env, 0); |
|
404 return; |
|
405 } |
|
406 for (i=0; i<(*ckpLength); i++) { |
|
407 (*ckpArray)[i] = jByteToCKByte(jpTemp[i]); |
|
408 } |
|
409 free(jpTemp); |
|
410 } |
|
411 } |
|
412 |
|
413 /* |
|
414 * converts a jlongArray to a CK_ULONG array. The allocated memory has to be freed after use! |
|
415 * |
|
416 * @param env - used to call JNI funktions to get the array informtaion |
|
417 * @param jArray - the Java array to convert |
|
418 * @param ckpArray - the reference, where the pointer to the new CK_ULONG array will be stored |
|
419 * @param ckpLength - the reference, where the array length will be stored |
|
420 */ |
|
421 void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckpLength) |
|
422 { |
|
423 jlong* jTemp; |
|
424 CK_ULONG i; |
|
425 |
|
426 if(jArray == NULL) { |
|
427 *ckpArray = NULL_PTR; |
|
428 *ckpLength = 0L; |
|
429 return; |
|
430 } |
|
431 *ckpLength = (*env)->GetArrayLength(env, jArray); |
|
432 jTemp = (jlong*) malloc((*ckpLength) * sizeof(jlong)); |
|
433 if (jTemp == NULL) { |
|
434 throwOutOfMemoryError(env, 0); |
|
435 return; |
|
436 } |
|
437 (*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jTemp); |
|
438 if ((*env)->ExceptionCheck(env)) { |
|
439 free(jTemp); |
|
440 return; |
|
441 } |
|
442 |
|
443 *ckpArray = (CK_ULONG_PTR) malloc (*ckpLength * sizeof(CK_ULONG)); |
|
444 if (*ckpArray == NULL) { |
|
445 free(jTemp); |
|
446 throwOutOfMemoryError(env, 0); |
|
447 return; |
|
448 } |
|
449 for (i=0; i<(*ckpLength); i++) { |
|
450 (*ckpArray)[i] = jLongToCKULong(jTemp[i]); |
|
451 } |
|
452 free(jTemp); |
|
453 } |
|
454 |
|
455 /* |
|
456 * converts a jcharArray to a CK_CHAR array. The allocated memory has to be freed after use! |
|
457 * |
|
458 * @param env - used to call JNI funktions to get the array informtaion |
|
459 * @param jArray - the Java array to convert |
|
460 * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored |
|
461 * @param ckpLength - the reference, where the array length will be stored |
|
462 */ |
|
463 void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength) |
|
464 { |
|
465 jchar* jpTemp; |
|
466 CK_ULONG i; |
|
467 |
|
468 if(jArray == NULL) { |
|
469 *ckpArray = NULL_PTR; |
|
470 *ckpLength = 0L; |
|
471 return; |
|
472 } |
|
473 *ckpLength = (*env)->GetArrayLength(env, jArray); |
|
474 jpTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar)); |
|
475 if (jpTemp == NULL) { |
|
476 throwOutOfMemoryError(env, 0); |
|
477 return; |
|
478 } |
|
479 (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp); |
|
480 if ((*env)->ExceptionCheck(env)) { |
|
481 free(jpTemp); |
|
482 return; |
|
483 } |
|
484 |
|
485 *ckpArray = (CK_CHAR_PTR) malloc (*ckpLength * sizeof(CK_CHAR)); |
|
486 if (*ckpArray == NULL) { |
|
487 free(jpTemp); |
|
488 throwOutOfMemoryError(env, 0); |
|
489 return; |
|
490 } |
|
491 for (i=0; i<(*ckpLength); i++) { |
|
492 (*ckpArray)[i] = jCharToCKChar(jpTemp[i]); |
|
493 } |
|
494 free(jpTemp); |
|
495 } |
|
496 |
|
497 /* |
|
498 * converts a jcharArray to a CK_UTF8CHAR array. The allocated memory has to be freed after use! |
|
499 * |
|
500 * @param env - used to call JNI funktions to get the array informtaion |
|
501 * @param jArray - the Java array to convert |
|
502 * @param ckpArray - the reference, where the pointer to the new CK_UTF8CHAR array will be stored |
|
503 * @param ckpLength - the reference, where the array length will be stored |
|
504 */ |
|
505 void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength) |
|
506 { |
|
507 jchar* jTemp; |
|
508 CK_ULONG i; |
|
509 |
|
510 if(jArray == NULL) { |
|
511 *ckpArray = NULL_PTR; |
|
512 *ckpLength = 0L; |
|
513 return; |
|
514 } |
|
515 *ckpLength = (*env)->GetArrayLength(env, jArray); |
|
516 jTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar)); |
|
517 if (jTemp == NULL) { |
|
518 throwOutOfMemoryError(env, 0); |
|
519 return; |
|
520 } |
|
521 (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jTemp); |
|
522 if ((*env)->ExceptionCheck(env)) { |
|
523 free(jTemp); |
|
524 return; |
|
525 } |
|
526 |
|
527 *ckpArray = (CK_UTF8CHAR_PTR) malloc (*ckpLength * sizeof(CK_UTF8CHAR)); |
|
528 if (*ckpArray == NULL) { |
|
529 free(jTemp); |
|
530 throwOutOfMemoryError(env, 0); |
|
531 return; |
|
532 } |
|
533 for (i=0; i<(*ckpLength); i++) { |
|
534 (*ckpArray)[i] = jCharToCKUTF8Char(jTemp[i]); |
|
535 } |
|
536 free(jTemp); |
|
537 } |
|
538 |
|
539 /* |
|
540 * converts a jstring to a CK_CHAR array. The allocated memory has to be freed after use! |
|
541 * |
|
542 * @param env - used to call JNI funktions to get the array informtaion |
|
543 * @param jArray - the Java array to convert |
|
544 * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored |
|
545 * @param ckpLength - the reference, where the array length will be stored |
|
546 */ |
|
547 void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength) |
|
548 { |
|
549 const char* pCharArray; |
|
550 jboolean isCopy; |
|
551 |
|
552 if(jArray == NULL) { |
|
553 *ckpArray = NULL_PTR; |
|
554 *ckpLength = 0L; |
|
555 return; |
|
556 } |
|
557 |
|
558 pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy); |
|
559 if (pCharArray == NULL) { return; } |
|
560 |
|
561 *ckpLength = (CK_ULONG) strlen(pCharArray); |
|
562 *ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR)); |
|
563 if (*ckpArray == NULL) { |
|
564 (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray); |
|
565 throwOutOfMemoryError(env, 0); |
|
566 return; |
|
567 } |
|
568 strcpy((char*)*ckpArray, pCharArray); |
|
569 (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray); |
|
570 } |
|
571 |
|
572 /* |
|
573 * converts a jobjectArray with Java Attributes to a CK_ATTRIBUTE array. The allocated memory |
|
574 * has to be freed after use! |
|
575 * |
|
576 * @param env - used to call JNI funktions to get the array informtaion |
|
577 * @param jArray - the Java Attribute array (template) to convert |
|
578 * @param ckpArray - the reference, where the pointer to the new CK_ATTRIBUTE array will be |
|
579 * stored |
|
580 * @param ckpLength - the reference, where the array length will be stored |
|
581 */ |
|
582 void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength) |
|
583 { |
|
584 CK_ULONG i; |
|
585 jlong jLength; |
|
586 jobject jAttribute; |
|
587 |
|
588 TRACE0("\nDEBUG: jAttributeArrayToCKAttributeArray"); |
|
589 if (jArray == NULL) { |
|
590 *ckpArray = NULL_PTR; |
|
591 *ckpLength = 0L; |
|
592 return; |
|
593 } |
|
594 jLength = (*env)->GetArrayLength(env, jArray); |
|
595 *ckpLength = jLongToCKULong(jLength); |
|
596 *ckpArray = (CK_ATTRIBUTE_PTR) malloc(*ckpLength * sizeof(CK_ATTRIBUTE)); |
|
597 if (*ckpArray == NULL) { |
|
598 throwOutOfMemoryError(env, 0); |
|
599 return; |
|
600 } |
|
601 TRACE1(", converting %d attributes", jLength); |
|
602 for (i=0; i<(*ckpLength); i++) { |
|
603 TRACE1(", getting %d. attribute", i); |
|
604 jAttribute = (*env)->GetObjectArrayElement(env, jArray, i); |
|
605 if ((*env)->ExceptionCheck(env)) { |
|
606 freeCKAttributeArray(*ckpArray, i); |
|
607 return; |
|
608 } |
|
609 TRACE1(", jAttribute = %d", jAttribute); |
|
610 TRACE1(", converting %d. attribute", i); |
|
611 (*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute); |
|
612 if ((*env)->ExceptionCheck(env)) { |
|
613 freeCKAttributeArray(*ckpArray, i); |
|
614 return; |
|
615 } |
|
616 } |
|
617 TRACE0("FINISHED\n"); |
|
618 } |
|
619 |
|
620 /* |
|
621 * converts a CK_BYTE array and its length to a jbyteArray. |
|
622 * |
|
623 * @param env - used to call JNI funktions to create the new Java array |
|
624 * @param ckpArray - the pointer to the CK_BYTE array to convert |
|
625 * @param ckpLength - the length of the array to convert |
|
626 * @return - the new Java byte array or NULL if error occurred |
|
627 */ |
|
628 jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength) |
|
629 { |
|
630 CK_ULONG i; |
|
631 jbyte* jpTemp; |
|
632 jbyteArray jArray; |
|
633 |
|
634 /* if CK_BYTE is the same size as jbyte, we save an additional copy */ |
|
635 if (sizeof(CK_BYTE) == sizeof(jbyte)) { |
|
636 jpTemp = (jbyte*) ckpArray; |
|
637 } else { |
|
638 jpTemp = (jbyte*) malloc((ckLength) * sizeof(jbyte)); |
|
639 if (jpTemp == NULL) { |
|
640 throwOutOfMemoryError(env, 0); |
|
641 return NULL; |
|
642 } |
|
643 for (i=0; i<ckLength; i++) { |
|
644 jpTemp[i] = ckByteToJByte(ckpArray[i]); |
|
645 } |
|
646 } |
|
647 |
|
648 jArray = (*env)->NewByteArray(env, ckULongToJSize(ckLength)); |
|
649 if (jArray != NULL) { |
|
650 (*env)->SetByteArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp); |
|
651 } |
|
652 |
|
653 if (sizeof(CK_BYTE) != sizeof(jbyte)) { free(jpTemp); } |
|
654 |
|
655 return jArray ; |
|
656 } |
|
657 |
|
658 /* |
|
659 * converts a CK_ULONG array and its length to a jlongArray. |
|
660 * |
|
661 * @param env - used to call JNI funktions to create the new Java array |
|
662 * @param ckpArray - the pointer to the CK_ULONG array to convert |
|
663 * @param ckpLength - the length of the array to convert |
|
664 * @return - the new Java long array |
|
665 */ |
|
666 jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength) |
|
667 { |
|
668 CK_ULONG i; |
|
669 jlong* jpTemp; |
|
670 jlongArray jArray; |
|
671 |
|
672 jpTemp = (jlong*) malloc((ckLength) * sizeof(jlong)); |
|
673 if (jpTemp == NULL) { |
|
674 throwOutOfMemoryError(env, 0); |
|
675 return NULL; |
|
676 } |
|
677 for (i=0; i<ckLength; i++) { |
|
678 jpTemp[i] = ckLongToJLong(ckpArray[i]); |
|
679 } |
|
680 jArray = (*env)->NewLongArray(env, ckULongToJSize(ckLength)); |
|
681 if (jArray != NULL) { |
|
682 (*env)->SetLongArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp); |
|
683 } |
|
684 free(jpTemp); |
|
685 |
|
686 return jArray ; |
|
687 } |
|
688 |
|
689 /* |
|
690 * converts a CK_CHAR array and its length to a jcharArray. |
|
691 * |
|
692 * @param env - used to call JNI funktions to create the new Java array |
|
693 * @param ckpArray - the pointer to the CK_CHAR array to convert |
|
694 * @param ckpLength - the length of the array to convert |
|
695 * @return - the new Java char array |
|
696 */ |
|
697 jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG ckLength) |
|
698 { |
|
699 CK_ULONG i; |
|
700 jchar* jpTemp; |
|
701 jcharArray jArray; |
|
702 |
|
703 jpTemp = (jchar*) malloc(ckLength * sizeof(jchar)); |
|
704 if (jpTemp == NULL) { |
|
705 throwOutOfMemoryError(env, 0); |
|
706 return NULL; |
|
707 } |
|
708 for (i=0; i<ckLength; i++) { |
|
709 jpTemp[i] = ckCharToJChar(ckpArray[i]); |
|
710 } |
|
711 jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength)); |
|
712 if (jArray != NULL) { |
|
713 (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp); |
|
714 } |
|
715 free(jpTemp); |
|
716 |
|
717 return jArray ; |
|
718 } |
|
719 |
|
720 /* |
|
721 * converts a CK_UTF8CHAR array and its length to a jcharArray. |
|
722 * |
|
723 * @param env - used to call JNI funktions to create the new Java array |
|
724 * @param ckpArray - the pointer to the CK_UTF8CHAR array to convert |
|
725 * @param ckpLength - the length of the array to convert |
|
726 * @return - the new Java char array |
|
727 */ |
|
728 jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength) |
|
729 { |
|
730 CK_ULONG i; |
|
731 jchar* jpTemp; |
|
732 jcharArray jArray; |
|
733 |
|
734 jpTemp = (jchar*) malloc(ckLength * sizeof(jchar)); |
|
735 if (jpTemp == NULL) { |
|
736 throwOutOfMemoryError(env, 0); |
|
737 return NULL; |
|
738 } |
|
739 for (i=0; i<ckLength; i++) { |
|
740 jpTemp[i] = ckUTF8CharToJChar(ckpArray[i]); |
|
741 } |
|
742 jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength)); |
|
743 if (jArray != NULL) { |
|
744 (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp); |
|
745 } |
|
746 free(jpTemp); |
|
747 |
|
748 return jArray ; |
|
749 } |
|
750 |
|
751 /* |
|
752 * the following functions convert Java objects to PKCS#11 pointers and the |
|
753 * length in bytes and vice versa |
|
754 * |
|
755 * CK_<Type>_PTR j<Object>ToCK<Type>Ptr(JNIEnv *env, jobject jObject); |
|
756 * |
|
757 * jobject ck<Type>PtrToJ<Object>(JNIEnv *env, const CK_<Type>_PTR ckpValue); |
|
758 * |
|
759 * The functions that convert a Java object to a PKCS#11 pointer first allocate |
|
760 * the memory for the PKCS#11 pointer. Then they set each element corresponding |
|
761 * to the fields in the Java object to convert. After use the allocated memory of |
|
762 * the PKCS#11 pointer has to be explicitly freed. |
|
763 * |
|
764 * The functions to convert a PKCS#11 pointer to a Java object create a new Java |
|
765 * object first and than they set all fields in the object depending on the values |
|
766 * of the type or structure where the PKCS#11 pointer points to. |
|
767 */ |
|
768 |
|
769 /* |
|
770 * converts a CK_BBOOL pointer to a Java boolean Object. |
|
771 * |
|
772 * @param env - used to call JNI funktions to create the new Java object |
|
773 * @param ckpValue - the pointer to the CK_BBOOL value |
|
774 * @return - the new Java boolean object with the boolean value |
|
775 */ |
|
776 jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL *ckpValue) |
|
777 { |
|
778 jclass jValueObjectClass; |
|
779 jmethodID jConstructor; |
|
780 jobject jValueObject; |
|
781 jboolean jValue; |
|
782 |
|
783 jValueObjectClass = (*env)->FindClass(env, "java/lang/Boolean"); |
|
784 if (jValueObjectClass == NULL) { return NULL; } |
|
785 jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(Z)V"); |
|
786 if (jConstructor == NULL) { return NULL; } |
|
787 jValue = ckBBoolToJBoolean(*ckpValue); |
|
788 jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue); |
|
789 |
|
790 return jValueObject ; |
|
791 } |
|
792 |
|
793 /* |
|
794 * converts a CK_ULONG pointer to a Java long Object. |
|
795 * |
|
796 * @param env - used to call JNI funktions to create the new Java object |
|
797 * @param ckpValue - the pointer to the CK_ULONG value |
|
798 * @return - the new Java long object with the long value |
|
799 */ |
|
800 jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue) |
|
801 { |
|
802 jclass jValueObjectClass; |
|
803 jmethodID jConstructor; |
|
804 jobject jValueObject; |
|
805 jlong jValue; |
|
806 |
|
807 jValueObjectClass = (*env)->FindClass(env, "java/lang/Long"); |
|
808 if (jValueObjectClass == NULL) { return NULL; } |
|
809 jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V"); |
|
810 if (jConstructor == NULL) { return NULL; } |
|
811 jValue = ckULongToJLong(*ckpValue); |
|
812 jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue); |
|
813 |
|
814 return jValueObject ; |
|
815 } |
|
816 |
|
817 /* |
|
818 * converts a Java boolean object into a pointer to a CK_BBOOL value. The memory has to be |
|
819 * freed after use! |
|
820 * |
|
821 * @param env - used to call JNI funktions to get the value out of the Java object |
|
822 * @param jObject - the "java/lang/Boolean" object to convert |
|
823 * @return - the pointer to the new CK_BBOOL value |
|
824 */ |
|
825 CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject) |
|
826 { |
|
827 jclass jObjectClass; |
|
828 jmethodID jValueMethod; |
|
829 jboolean jValue; |
|
830 CK_BBOOL *ckpValue; |
|
831 |
|
832 jObjectClass = (*env)->FindClass(env, "java/lang/Boolean"); |
|
833 if (jObjectClass == NULL) { return NULL; } |
|
834 jValueMethod = (*env)->GetMethodID(env, jObjectClass, "booleanValue", "()Z"); |
|
835 if (jValueMethod == NULL) { return NULL; } |
|
836 jValue = (*env)->CallBooleanMethod(env, jObject, jValueMethod); |
|
837 ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL)); |
|
838 if (ckpValue == NULL) { |
|
839 throwOutOfMemoryError(env, 0); |
|
840 return NULL; |
|
841 } |
|
842 *ckpValue = jBooleanToCKBBool(jValue); |
|
843 |
|
844 return ckpValue ; |
|
845 } |
|
846 |
|
847 /* |
|
848 * converts a Java byte object into a pointer to a CK_BYTE value. The memory has to be |
|
849 * freed after use! |
|
850 * |
|
851 * @param env - used to call JNI funktions to get the value out of the Java object |
|
852 * @param jObject - the "java/lang/Byte" object to convert |
|
853 * @return - the pointer to the new CK_BYTE value |
|
854 */ |
|
855 CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject) |
|
856 { |
|
857 jclass jObjectClass; |
|
858 jmethodID jValueMethod; |
|
859 jbyte jValue; |
|
860 CK_BYTE_PTR ckpValue; |
|
861 |
|
862 jObjectClass = (*env)->FindClass(env, "java/lang/Byte"); |
|
863 if (jObjectClass == NULL) { return NULL; } |
|
864 jValueMethod = (*env)->GetMethodID(env, jObjectClass, "byteValue", "()B"); |
|
865 if (jValueMethod == NULL) { return NULL; } |
|
866 jValue = (*env)->CallByteMethod(env, jObject, jValueMethod); |
|
867 ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE)); |
|
868 if (ckpValue == NULL) { |
|
869 throwOutOfMemoryError(env, 0); |
|
870 return NULL; |
|
871 } |
|
872 *ckpValue = jByteToCKByte(jValue); |
|
873 return ckpValue ; |
|
874 } |
|
875 |
|
876 /* |
|
877 * converts a Java integer object into a pointer to a CK_ULONG value. The memory has to be |
|
878 * freed after use! |
|
879 * |
|
880 * @param env - used to call JNI funktions to get the value out of the Java object |
|
881 * @param jObject - the "java/lang/Integer" object to convert |
|
882 * @return - the pointer to the new CK_ULONG value |
|
883 */ |
|
884 CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject) |
|
885 { |
|
886 jclass jObjectClass; |
|
887 jmethodID jValueMethod; |
|
888 jint jValue; |
|
889 CK_ULONG *ckpValue; |
|
890 |
|
891 jObjectClass = (*env)->FindClass(env, "java/lang/Integer"); |
|
892 if (jObjectClass == NULL) { return NULL; } |
|
893 jValueMethod = (*env)->GetMethodID(env, jObjectClass, "intValue", "()I"); |
|
894 if (jValueMethod == NULL) { return NULL; } |
|
895 jValue = (*env)->CallIntMethod(env, jObject, jValueMethod); |
|
896 ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG)); |
|
897 if (ckpValue == NULL) { |
|
898 throwOutOfMemoryError(env, 0); |
|
899 return NULL; |
|
900 } |
|
901 *ckpValue = jLongToCKLong(jValue); |
|
902 return ckpValue ; |
|
903 } |
|
904 |
|
905 /* |
|
906 * converts a Java long object into a pointer to a CK_ULONG value. The memory has to be |
|
907 * freed after use! |
|
908 * |
|
909 * @param env - used to call JNI funktions to get the value out of the Java object |
|
910 * @param jObject - the "java/lang/Long" object to convert |
|
911 * @return - the pointer to the new CK_ULONG value |
|
912 */ |
|
913 CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject) |
|
914 { |
|
915 jclass jObjectClass; |
|
916 jmethodID jValueMethod; |
|
917 jlong jValue; |
|
918 CK_ULONG *ckpValue; |
|
919 |
|
920 jObjectClass = (*env)->FindClass(env, "java/lang/Long"); |
|
921 if (jObjectClass == NULL) { return NULL; } |
|
922 jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J"); |
|
923 if (jValueMethod == NULL) { return NULL; } |
|
924 jValue = (*env)->CallLongMethod(env, jObject, jValueMethod); |
|
925 ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG)); |
|
926 if (ckpValue == NULL) { |
|
927 throwOutOfMemoryError(env, 0); |
|
928 return NULL; |
|
929 } |
|
930 *ckpValue = jLongToCKULong(jValue); |
|
931 |
|
932 return ckpValue ; |
|
933 } |
|
934 |
|
935 /* |
|
936 * converts a Java char object into a pointer to a CK_CHAR value. The memory has to be |
|
937 * freed after use! |
|
938 * |
|
939 * @param env - used to call JNI funktions to get the value out of the Java object |
|
940 * @param jObject - the "java/lang/Char" object to convert |
|
941 * @return - the pointer to the new CK_CHAR value |
|
942 */ |
|
943 CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject) |
|
944 { |
|
945 jclass jObjectClass; |
|
946 jmethodID jValueMethod; |
|
947 jchar jValue; |
|
948 CK_CHAR_PTR ckpValue; |
|
949 |
|
950 jObjectClass = (*env)->FindClass(env, "java/lang/Char"); |
|
951 if (jObjectClass == NULL) { return NULL; } |
|
952 jValueMethod = (*env)->GetMethodID(env, jObjectClass, "charValue", "()C"); |
|
953 if (jValueMethod == NULL) { return NULL; } |
|
954 jValue = (*env)->CallCharMethod(env, jObject, jValueMethod); |
|
955 ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR)); |
|
956 if (ckpValue == NULL) { |
|
957 throwOutOfMemoryError(env, 0); |
|
958 return NULL; |
|
959 } |
|
960 *ckpValue = jCharToCKChar(jValue); |
|
961 |
|
962 return ckpValue ; |
|
963 } |
|
964 |
|
965 /* |
|
966 * converts a Java object into a pointer to CK-type or a CK-structure with the length in Bytes. |
|
967 * The memory of *ckpObjectPtr to be freed after use! This function is only used by |
|
968 * jAttributeToCKAttribute by now. |
|
969 * |
|
970 * @param env - used to call JNI funktions to get the Java classes and objects |
|
971 * @param jObject - the Java object to convert |
|
972 * @param ckpObjectPtr - the reference of the new pointer to the new CK-value or CK-structure |
|
973 * @param ckpLength - the reference of the length in bytes of the new CK-value or CK-structure |
|
974 */ |
|
975 void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *ckpLength) |
|
976 { |
|
977 jclass jLongClass, jBooleanClass, jByteArrayClass, jCharArrayClass; |
|
978 jclass jByteClass, jDateClass, jCharacterClass, jIntegerClass; |
|
979 jclass jBooleanArrayClass, jIntArrayClass, jLongArrayClass; |
|
980 jclass jStringClass; |
|
981 jclass jObjectClass, jClassClass; |
|
982 CK_VOID_PTR ckpVoid = *ckpObjectPtr; |
|
983 jmethodID jMethod; |
|
984 jobject jClassObject; |
|
985 jstring jClassNameString; |
|
986 char *classNameString, *exceptionMsgPrefix, *exceptionMsg; |
|
987 |
|
988 TRACE0("\nDEBUG: jObjectToPrimitiveCKObjectPtrPtr"); |
|
989 if (jObject == NULL) { |
|
990 *ckpObjectPtr = NULL; |
|
991 *ckpLength = 0; |
|
992 return; |
|
993 } |
|
994 |
|
995 jLongClass = (*env)->FindClass(env, "java/lang/Long"); |
|
996 if (jLongClass == NULL) { return; } |
|
997 if ((*env)->IsInstanceOf(env, jObject, jLongClass)) { |
|
998 *ckpObjectPtr = jLongObjectToCKULongPtr(env, jObject); |
|
999 *ckpLength = sizeof(CK_ULONG); |
|
1000 TRACE1("<converted long value %X>", *((CK_ULONG *) *ckpObjectPtr)); |
|
1001 return; |
|
1002 } |
|
1003 |
|
1004 jBooleanClass = (*env)->FindClass(env, "java/lang/Boolean"); |
|
1005 if (jBooleanClass == NULL) { return; } |
|
1006 if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) { |
|
1007 *ckpObjectPtr = jBooleanObjectToCKBBoolPtr(env, jObject); |
|
1008 *ckpLength = sizeof(CK_BBOOL); |
|
1009 TRACE0(" <converted boolean value "); |
|
1010 TRACE0((*((CK_BBOOL *) *ckpObjectPtr) == TRUE) ? "TRUE>" : "FALSE>"); |
|
1011 return; |
|
1012 } |
|
1013 |
|
1014 jByteArrayClass = (*env)->FindClass(env, "[B"); |
|
1015 if (jByteArrayClass == NULL) { return; } |
|
1016 if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) { |
|
1017 jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*)ckpObjectPtr, ckpLength); |
|
1018 return; |
|
1019 } |
|
1020 |
|
1021 jCharArrayClass = (*env)->FindClass(env, "[C"); |
|
1022 if (jCharArrayClass == NULL) { return; } |
|
1023 if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) { |
|
1024 jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength); |
|
1025 return; |
|
1026 } |
|
1027 |
|
1028 jByteClass = (*env)->FindClass(env, "java/lang/Byte"); |
|
1029 if (jByteClass == NULL) { return; } |
|
1030 if ((*env)->IsInstanceOf(env, jObject, jByteClass)) { |
|
1031 *ckpObjectPtr = jByteObjectToCKBytePtr(env, jObject); |
|
1032 *ckpLength = sizeof(CK_BYTE); |
|
1033 TRACE1("<converted byte value %X>", *((CK_BYTE *) *ckpObjectPtr)); |
|
1034 return; |
|
1035 } |
|
1036 |
|
1037 jDateClass = (*env)->FindClass(env, CLASS_DATE); |
|
1038 if (jDateClass == NULL) { return; } |
|
1039 if ((*env)->IsInstanceOf(env, jObject, jDateClass)) { |
|
1040 *ckpObjectPtr = jDateObjectPtrToCKDatePtr(env, jObject); |
|
1041 *ckpLength = sizeof(CK_DATE); |
|
1042 TRACE3("<converted date value %.4s-%.2s-%.2s>", (*((CK_DATE *) *ckpObjectPtr)).year, (*((CK_DATE *) *ckpObjectPtr)).month, (*((CK_DATE *) *ckpObjectPtr)).day); |
|
1043 return; |
|
1044 } |
|
1045 |
|
1046 jCharacterClass = (*env)->FindClass(env, "java/lang/Character"); |
|
1047 if (jCharacterClass == NULL) { return; } |
|
1048 if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) { |
|
1049 *ckpObjectPtr = jCharObjectToCKCharPtr(env, jObject); |
|
1050 *ckpLength = sizeof(CK_UTF8CHAR); |
|
1051 TRACE1("<converted char value %c>", *((CK_CHAR *) *ckpObjectPtr)); |
|
1052 return; |
|
1053 } |
|
1054 |
|
1055 jIntegerClass = (*env)->FindClass(env, "java/lang/Integer"); |
|
1056 if (jIntegerClass == NULL) { return; } |
|
1057 if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) { |
|
1058 *ckpObjectPtr = jIntegerObjectToCKULongPtr(env, jObject); |
|
1059 *ckpLength = sizeof(CK_ULONG); |
|
1060 TRACE1("<converted integer value %X>", *((CK_ULONG *) *ckpObjectPtr)); |
|
1061 return; |
|
1062 } |
|
1063 |
|
1064 jBooleanArrayClass = (*env)->FindClass(env, "[Z"); |
|
1065 if (jBooleanArrayClass == NULL) { return; } |
|
1066 if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) { |
|
1067 jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**)ckpObjectPtr, ckpLength); |
|
1068 return; |
|
1069 } |
|
1070 |
|
1071 jIntArrayClass = (*env)->FindClass(env, "[I"); |
|
1072 if (jIntArrayClass == NULL) { return; } |
|
1073 if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) { |
|
1074 jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength); |
|
1075 return; |
|
1076 } |
|
1077 |
|
1078 jLongArrayClass = (*env)->FindClass(env, "[J"); |
|
1079 if (jLongArrayClass == NULL) { return; } |
|
1080 if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) { |
|
1081 jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength); |
|
1082 return; |
|
1083 } |
|
1084 |
|
1085 jStringClass = (*env)->FindClass(env, "java/lang/String"); |
|
1086 if (jStringClass == NULL) { return; } |
|
1087 if ((*env)->IsInstanceOf(env, jObject, jStringClass)) { |
|
1088 jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength); |
|
1089 return; |
|
1090 } |
|
1091 |
|
1092 /* type of jObject unknown, throw PKCS11RuntimeException */ |
|
1093 jObjectClass = (*env)->FindClass(env, "java/lang/Object"); |
|
1094 if (jObjectClass == NULL) { return; } |
|
1095 jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;"); |
|
1096 if (jMethod == NULL) { return; } |
|
1097 jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod); |
|
1098 assert(jClassObject != 0); |
|
1099 jClassClass = (*env)->FindClass(env, "java/lang/Class"); |
|
1100 if (jClassClass == NULL) { return; } |
|
1101 jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;"); |
|
1102 if (jMethod == NULL) { return; } |
|
1103 jClassNameString = (jstring) |
|
1104 (*env)->CallObjectMethod(env, jClassObject, jMethod); |
|
1105 assert(jClassNameString != 0); |
|
1106 classNameString = (char*) |
|
1107 (*env)->GetStringUTFChars(env, jClassNameString, NULL); |
|
1108 if (classNameString == NULL) { return; } |
|
1109 exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: "; |
|
1110 exceptionMsg = (char *) |
|
1111 malloc((strlen(exceptionMsgPrefix) + strlen(classNameString) + 1)); |
|
1112 if (exceptionMsg == NULL) { |
|
1113 (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString); |
|
1114 throwOutOfMemoryError(env, 0); |
|
1115 return; |
|
1116 } |
|
1117 strcpy(exceptionMsg, exceptionMsgPrefix); |
|
1118 strcat(exceptionMsg, classNameString); |
|
1119 (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString); |
|
1120 throwPKCS11RuntimeException(env, exceptionMsg); |
|
1121 free(exceptionMsg); |
|
1122 *ckpObjectPtr = NULL; |
|
1123 *ckpLength = 0; |
|
1124 |
|
1125 TRACE0("FINISHED\n"); |
|
1126 } |
|
1127 |
|
1128 #ifdef P11_MEMORYDEBUG |
|
1129 |
|
1130 #undef malloc |
|
1131 #undef free |
|
1132 |
|
1133 void *p11malloc(size_t c, char *file, int line) { |
|
1134 void *p = malloc(c); |
|
1135 printf("malloc\t%08x\t%d\t%s:%d\n", p, c, file, line); fflush(stdout); |
|
1136 return p; |
|
1137 } |
|
1138 |
|
1139 void p11free(void *p, char *file, int line) { |
|
1140 printf("free\t%08x\t\t%s:%d\n", p, file, line); fflush(stdout); |
|
1141 free(p); |
|
1142 } |
|
1143 |
|
1144 #endif |
|
1145 |
|
1146 // prints a message to stdout if debug output is enabled |
|
1147 void printDebug(const char *format, ...) { |
|
1148 if (debug == JNI_TRUE) { |
|
1149 va_list args; |
|
1150 fprintf(stdout, "sunpkcs11: "); |
|
1151 va_start(args, format); |
|
1152 vfprintf(stdout, format, args); |
|
1153 va_end(args); |
|
1154 fflush(stdout); |
|
1155 } |
|
1156 } |
|
1157 |