1 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
2  *
3  * Redistribution and use in  source and binary forms, with or without
4  * modification, are permitted  provided that the following conditions are met:
5  *
6  * 1. Redistributions of  source code must retain the above copyright notice,
7  *    this list of conditions and the following disclaimer.
8  *
9  * 2. Redistributions in  binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *
13  * 3. The end-user documentation included with the redistribution, if any, must
14  *    include the following acknowledgment:
15  *
16  *    "This product includes software developed by IAIK of Graz University of
17  *     Technology."
18  *
19  *    Alternately, this acknowledgment may appear in the software itself, if
20  *    and wherever such third-party acknowledgments normally appear.
21  *
22  * 4. The names "Graz University of Technology" and "IAIK of Graz University of
23  *    Technology" must not be used to endorse or promote products derived from
24  *    this software without prior written permission.
25  *
26  * 5. Products derived from this software may not be called
27  *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
28  *    written permission of Graz University of Technology.
29  *
30  *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
31  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32  *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
34  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
35  *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
36  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
37  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
38  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39  *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  *  POSSIBILITY  OF SUCH DAMAGE.
42  */
43 
44 /*
45  * pkcs11wrapper.c
46  * 18.05.2001
47  *
48  * This is the implementation of the native functions of the Java to PKCS#11 interface.
49  * All function use some helper functions to convert the JNI types to PKCS#11 types.
50  *
51  * @author Karl Scheibelhofer <Karl.Scheibelhofer@iaik.at>
52  * @author Martin Schlaeffer <schlaeff@sbox.tugraz.at>
53  */
54 
55 #include "pkcs11wrapper.h"
56 
57 
58 /* Include the platform specific functions; i.e. the implementations of the
59  * connect and disconnect functions, which load/bind and unbind/unload the
60  * native PKCS#11 module.
61  */
62 #include "platform.c"
63 
64 
65 
66 /* ************************************************************************** */
67 /* Variables global to the wrapper                                            */
68 /* ************************************************************************** */
69 
70 /* The initArgs that enable the application to do custom mutex-handling */
71 #ifndef NO_CALLBACKS
72 jobject jInitArgsObject = NULL;
73 CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs = NULL;
74 #endif /* NO_CALLBACKS */
75 
76 
77 /* The list of currently connected modules. Will normally contain one element,
78  * but seldom more than a few.
79  */
80 ModuleListNode *moduleListHead = NULL;
81 jobject moduleListLock = NULL;
82 
83 
84 /* The list of notify callback handles that are currently active and waiting
85  * for callbacks from their sessions.
86  */
87 #ifndef NO_CALLBACKS
88 NotifyListNode *notifyListHead = NULL;
89 jobject notifyListLock = NULL;
90 #endif /* NO_CALLBACKS */
91 
92 
93 
94 /* ************************************************************************** */
95 /* Functions called by the VM when it loads or unloads this library           */
96 /* ************************************************************************** */
97 
98 
99 /*
100 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
101 {
102   return JNI_VERSION_1_2 ;
103 }
104 
105 JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
106 {
107 
108 }
109 */
110 
111 /* ************************************************************************** */
112 /* Helper functions                                                           */
113 /* ************************************************************************** */
114 
115 /*
116  * This method retrieves the function pointers from the module struct. Returns NULL
117  * if either the module is NULL or the function pointer list is NULL. Returns the
118  * function pointer list on success.
119  */
getFunctionList(JNIEnv * env,ModuleData * moduleData)120 CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, ModuleData *moduleData)
121 {
122   CK_FUNCTION_LIST_PTR ckpFunctions;
123 
124   ckpFunctions = moduleData->ckFunctionListPtr;
125   if(ckpFunctions == NULL_PTR) { throwPKCS11RuntimeException(env, (*env)->NewStringUTF(env, "This modules does not provide methods")); return NULL_PTR; }
126   return ckpFunctions;
127 }
128 
129 /*
130  * converts a given array of chars into a human readable hex string
131  */
byteArrayToHexString(char * array,int array_length,char * result,int result_length)132 void byteArrayToHexString(char* array, int array_length, char* result, int result_length)
133 {
134 	int i = 0;
135 	char lut[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
136 	for(i; i < array_length; i++)
137 	{
138 		if(2 * i + 1 > result_length - 4) {
139 			result[2 * i] = '.';
140 			result[2 * i + 1] = '.';
141 			result[2 * i + 2] = '.';
142 			break;
143 		}
144 
145 		result[2 * i] = lut[(array[i] & 0xF0) >> 4];
146 		result[2 * i + 1] = lut[array[i] & 0x0F];
147 	}
148 }
149 
150 /* ************************************************************************** */
151 /* The native implementation of the methods of the PKCS11Implementation class */
152 /* ************************************************************************** */
153 
154 /*
155  * This method is used to do static initialization. This method is static and
156  * synchronized. Summary: use this method like a static initialization block.
157  *
158  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
159  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
160  * Method:    initializeLibrary
161  * Signature: ()V
162  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_initializeLibrary(JNIEnv * env,jclass thisClass)163 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_initializeLibrary
164   (JNIEnv *env, jclass thisClass)
165 {
166   TRACE0(tag_call, __FUNCTION__, "entering");
167   if (moduleListLock == NULL) {
168     moduleListLock = createLockObject(env);
169   }
170 #ifndef NO_CALLBACKS
171   if (notifyListLock == NULL) {
172     notifyListLock = createLockObject(env);
173   }
174 #endif
175   TRACE0(tag_call, __FUNCTION__, "exiting ");
176 }
177 
178 /* This method is designed to do a clean-up. It releases all global resources
179  * of this library. By now, this function is not called. Calling from
180  * JNI_OnUnload would be an option, but some VMs do not support JNI_OnUnload.
181  *
182  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
183  * Method:    finalizeLibrary
184  * Signature: ()V
185  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_finalizeLibrary(JNIEnv * env,jclass thisClass)186 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_finalizeLibrary
187   (JNIEnv *env, jclass thisClass)
188 {
189   /* remove all left lists and release the resources and the lock
190    * objects that synchroniz access to these lists.
191    */
192   removeAllModuleEntries(env);
193   if (moduleListHead == NULL) { /* check, if we removed the last active module */
194     /* remove also the moduleListLock, it is no longer used */
195 		if (moduleListLock != NULL) {
196 			destroyLockObject(env, moduleListLock);
197       moduleListLock = NULL;
198 		}
199 #ifndef NO_CALLBACKS
200     /* remove all left notify callback entries */
201     while (removeFirstNotifyEntry(env));
202     /* remove also the notifyListLock, it is no longer used */
203     if (notifyListLock != NULL) {
204       destroyLockObject(env, notifyListLock);
205       notifyListLock = NULL;
206     }
207     if (jInitArgsObject != NULL) {
208       (*env)->DeleteGlobalRef(env, jInitArgsObject);
209     }
210     if (ckpGlobalInitArgs != NULL_PTR) {
211       if (ckpGlobalInitArgs->pReserved != NULL_PTR) {
212         free(ckpGlobalInitArgs->pReserved);
213       }
214       free(ckpGlobalInitArgs);
215     }
216 #endif /* NO_CALLBACKS */
217   }
218   TRACE0(tag_call, __FUNCTION__, "exiting ");
219 }
220 
221 
222 /*
223  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
224  * Method:    connect
225  * Signature: (Ljava/lang/String;)V
226  */
227 /* see platform.c, because the implementation is platform dependent */
228 
229 
230 /*
231  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
232  * Method:    disconnect
233  * Signature: ()V
234  */
235 /* see platform.c, because the implementation is platform dependent */
236 
237 
238 /*
239  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
240  * Method:    C_Initialize
241  * Signature: (Ljava/lang/Object;)V
242  * Parametermapping:                    *PKCS11*
243  * @param   jobject jInitArgs           CK_VOID_PTR pInitArgs
244  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Initialize(JNIEnv * env,jobject obj,jobject jInitArgs)245 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Initialize
246 	(JNIEnv *env, jobject obj, jobject jInitArgs)
247 {
248   /*
249    * Initalize Cryptoki
250    */
251   CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
252 	CK_RV rv;
253   ModuleData *moduleData;
254   CK_FUNCTION_LIST_PTR ckpFunctions;
255 
256   TRACE0(tag_call, __FUNCTION__, "entering");
257   moduleData = getModuleEntry(env, obj);
258   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
259   ckpFunctions = getFunctionList(env, moduleData);
260   if (ckpFunctions == NULL_PTR) { return; }
261 
262   if (jInitArgs != NULL) {
263     ckpInitArgs = makeCKInitArgsAdapter(env, jInitArgs);
264     if (ckpInitArgs == NULL_PTR) { return; }
265   } else {
266     ckpInitArgs = NULL_PTR;
267   }
268 
269 	rv = (*ckpFunctions->C_Initialize)(ckpInitArgs);
270   ckAssertReturnValueOK(env, rv, __FUNCTION__);
271 
272   if (ckpInitArgs != NULL_PTR) {
273     if (ckpInitArgs->pReserved != NULL_PTR) {
274       free(ckpInitArgs->pReserved);
275     }
276     free(ckpInitArgs);
277   }
278 
279   TRACE0(tag_call, __FUNCTION__, "exiting ");
280 }
281 
282 /*
283  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
284  * Method:    C_Finalize
285  * Signature: (Ljava/lang/Object;)V
286  * Parametermapping:                    *PKCS11*
287  * @param   jobject jReserved           CK_VOID_PTR pReserved
288  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Finalize(JNIEnv * env,jobject obj,jobject jReserved)289 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Finalize
290 	(JNIEnv *env, jobject obj, jobject jReserved)
291 {
292   /*
293    * Finalize Cryptoki
294    */
295 	CK_VOID_PTR ckpReserved;
296   CK_RV rv;
297   ModuleData *moduleData;
298   CK_FUNCTION_LIST_PTR ckpFunctions;
299 
300   TRACE0(tag_call, __FUNCTION__, "entering");
301 
302   moduleData = getModuleEntry(env, obj);
303   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
304   ckpFunctions = getFunctionList(env, moduleData);
305   if (ckpFunctions == NULL_PTR) { return; }
306 
307 	ckpReserved = jObjectToCKVoidPtr(jReserved);
308 
309   rv = (*ckpFunctions->C_Finalize)(ckpReserved);
310   ckAssertReturnValueOK(env, rv, __FUNCTION__);
311 
312   TRACE0(tag_call, __FUNCTION__, "exiting ");
313 }
314 
315 /*
316  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
317  * Method:    C_GetInfo
318  * Signature: ()Liaik/pkcs/pkcs11/wrapper/CK_INFO;
319  * Parametermapping:                    *PKCS11*
320  * @return  jobject jInfoObject         CK_INFO_PTR pInfo
321  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetInfo(JNIEnv * env,jobject obj)322 JNIEXPORT jobject JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetInfo
323 	(JNIEnv *env, jobject obj)
324 {
325 	CK_INFO ckLibInfo;
326 	jobject jInfoObject;
327   CK_RV rv;
328   ModuleData *moduleData;
329   CK_FUNCTION_LIST_PTR ckpFunctions;
330 
331   TRACE0(tag_call, __FUNCTION__, "entering");
332 
333   moduleData = getModuleEntry(env, obj);
334   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
335   ckpFunctions = getFunctionList(env, moduleData);
336   if (ckpFunctions == NULL_PTR) { return NULL; }
337 
338 	rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo);
339 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
340 
341 	jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo);
342 
343   TRACE0(tag_call, __FUNCTION__, "exiting ");
344 	return jInfoObject ;
345 }
346 
347 /*
348  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
349  * Method:    C_GetSlotList
350  * Signature: (Z)[J
351  * Parametermapping:                    *PKCS11*
352  * @param   jboolean jTokenPresent      CK_BBOOL tokenPresent
353  * @return  jlongArray jSlotList        CK_SLOT_ID_PTR pSlotList
354  *                                      CK_ULONG_PTR pulCount
355  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetSlotList(JNIEnv * env,jobject obj,jboolean jTokenPresent)356 JNIEXPORT jlongArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetSlotList
357 	(JNIEnv *env, jobject obj, jboolean jTokenPresent)
358 {
359 	CK_ULONG ckTokenNumber;
360 	CK_SLOT_ID_PTR ckpSlotList;
361 	CK_BBOOL ckTokenPresent;
362 	jlongArray jSlotList;
363   CK_RV rv;
364   ModuleData *moduleData;
365   CK_FUNCTION_LIST_PTR ckpFunctions;
366 
367   TRACE0(tag_call, __FUNCTION__, "entering");
368 
369   moduleData = getModuleEntry(env, obj);
370   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
371   ckpFunctions = getFunctionList(env, moduleData);
372   if (ckpFunctions == NULL_PTR) { return NULL; }
373 
374 	ckTokenPresent = jBooleanToCKBBool(jTokenPresent);
375 
376 	rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR, &ckTokenNumber);
377 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
378 
379   if (ckTokenNumber != 0) { /* only make the second call, if the number is not zero */
380 	  ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID));
381     if (ckpSlotList == NULL && ckTokenNumber!=0) { throwOutOfMemoryError(env); return NULL; }
382 
383 	  rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList, &ckTokenNumber);
384 
385 	  if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
386 	    jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber);
387 	  else
388 	    jSlotList = NULL;
389 
390 	  free(ckpSlotList);
391   } else {
392     jSlotList = ckULongArrayToJLongArray(env, NULL_PTR, ckTokenNumber);
393   }
394 
395   TRACE0(tag_call, __FUNCTION__, "exiting ");
396 	return jSlotList ;
397 }
398 
399 /*
400  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
401  * Method:    C_GetSlotInfo
402  * Signature: (J)Liaik/pkcs/pkcs11/wrapper/CK_SLOT_INFO;
403  * Parametermapping:                    *PKCS11*
404  * @param   jlong jSlotID               CK_SLOT_ID slotID
405  * @return  jobject jSlotInfoObject     CK_SLOT_INFO_PTR pInfo
406  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetSlotInfo(JNIEnv * env,jobject obj,jlong jSlotID)407 JNIEXPORT jobject JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetSlotInfo
408 	(JNIEnv *env, jobject obj, jlong jSlotID)
409 {
410 	CK_SLOT_ID ckSlotID;
411 	CK_SLOT_INFO ckSlotInfo;
412 	jobject jSlotInfoObject;
413   CK_RV rv;
414   ModuleData *moduleData;
415   CK_FUNCTION_LIST_PTR ckpFunctions;
416 
417   TRACE0(tag_call, __FUNCTION__, "entering");
418 
419   moduleData = getModuleEntry(env, obj);
420   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
421   ckpFunctions = getFunctionList(env, moduleData);
422   if (ckpFunctions == NULL_PTR) { return NULL; }
423 
424 	ckSlotID = jLongToCKULong(jSlotID);
425 
426 	rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo);
427 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
428 
429 	jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo);
430 
431   TRACE0(tag_call, __FUNCTION__, "exiting ");
432 	return jSlotInfoObject ;
433 }
434 
435 /*
436  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
437  * Method:    C_GetTokenInfo
438  * Signature: (J)Liaik/pkcs/pkcs11/wrapper/CK_TOKEN_INFO;
439  * Parametermapping:                    *PKCS11*
440  * @param   jlong jSlotID               CK_SLOT_ID slotID
441  * @return  jobject jInfoTokenObject    CK_TOKEN_INFO_PTR pInfo
442  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetTokenInfo(JNIEnv * env,jobject obj,jlong jSlotID)443 JNIEXPORT jobject JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetTokenInfo
444   (JNIEnv *env, jobject obj, jlong jSlotID)
445 {
446 	CK_SLOT_ID ckSlotID;
447 	CK_TOKEN_INFO ckTokenInfo;
448 	jobject jInfoTokenObject;
449   CK_RV rv;
450   ModuleData *moduleData;
451   CK_FUNCTION_LIST_PTR ckpFunctions;
452 
453   TRACE0(tag_call, __FUNCTION__, "entering");
454 
455   moduleData = getModuleEntry(env, obj);
456   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
457   ckpFunctions = getFunctionList(env, moduleData);
458   if (ckpFunctions == NULL_PTR) { return NULL; }
459 
460 	ckSlotID = jLongToCKULong(jSlotID);
461 
462 	rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo);
463 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
464 
465 	jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo);
466 
467   TRACE0(tag_call, __FUNCTION__, "exiting ");
468 	return jInfoTokenObject ;
469 }
470 
471 /*
472  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
473  * Method:    C_GetMechanismList
474  * Signature: (J)[J
475  * Parametermapping:                    *PKCS11*
476  * @param   jlong jSlotID               CK_SLOT_ID slotID
477  * @return  jlongArray jMechanismList   CK_MECHANISM_TYPE_PTR pMechanismList
478  *                                      CK_ULONG_PTR pulCount
479  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetMechanismList(JNIEnv * env,jobject obj,jlong jSlotID)480 JNIEXPORT jlongArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetMechanismList
481   (JNIEnv *env, jobject obj, jlong jSlotID)
482 {
483 	CK_SLOT_ID ckSlotID;
484 	CK_ULONG ckMechanismNumber;
485 	CK_MECHANISM_TYPE_PTR ckpMechanismList;
486 	jlongArray jMechanismList;
487 	CK_RV rv;
488   ModuleData *moduleData;
489   CK_FUNCTION_LIST_PTR ckpFunctions;
490 
491   TRACE0(tag_call, __FUNCTION__, "entering");
492 
493   moduleData = getModuleEntry(env, obj);
494   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
495   ckpFunctions = getFunctionList(env, moduleData);
496   if (ckpFunctions == NULL_PTR) { return NULL; }
497 
498 	ckSlotID = jLongToCKULong(jSlotID);
499 
500 	rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR, &ckMechanismNumber);
501 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
502 
503 	ckpMechanismList = (CK_MECHANISM_TYPE_PTR) malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE));
504   if (ckpMechanismList == NULL && ckMechanismNumber!=0) { throwOutOfMemoryError(env); return NULL; }
505 
506 	rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList, &ckMechanismNumber);
507   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
508     jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList, ckMechanismNumber);
509   else
510     jMechanismList = NULL;
511 
512 	free(ckpMechanismList);
513 
514   TRACE0(tag_call, __FUNCTION__, "exiting ");
515 	return jMechanismList ;
516 }
517 
518 /*
519  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
520  * Method:    C_GetMechanismInfo
521  * Signature: (JJ)Liaik/pkcs/pkcs11/wrapper/CK_MECHANISM_INFO;
522  * Parametermapping:                    *PKCS11*
523  * @param   jlong jSlotID               CK_SLOT_ID slotID
524  * @param   jlong jType                 CK_MECHANISM_TYPE type
525  * @return  jobject jMechanismInfo      CK_MECHANISM_INFO_PTR pInfo
526  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetMechanismInfo(JNIEnv * env,jobject obj,jlong jSlotID,jlong jType)527 JNIEXPORT jobject JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetMechanismInfo
528   (JNIEnv *env, jobject obj, jlong jSlotID, jlong jType)
529 {
530 	CK_SLOT_ID ckSlotID;
531 	CK_MECHANISM_TYPE ckMechanismType;
532 	CK_MECHANISM_INFO ckMechanismInfo;
533 	jobject jMechanismInfo;
534 	CK_RV rv;
535   ModuleData *moduleData;
536   CK_FUNCTION_LIST_PTR ckpFunctions;
537 
538   TRACE0(tag_call, __FUNCTION__, "entering");
539 
540   moduleData = getModuleEntry(env, obj);
541   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
542   ckpFunctions = getFunctionList(env, moduleData);
543   if (ckpFunctions == NULL_PTR) { return NULL; }
544 
545 	ckSlotID = jLongToCKULong(jSlotID);
546 	ckMechanismType = jLongToCKULong(jType);
547 
548 	rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType, &ckMechanismInfo);
549 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
550 
551 	jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo);
552 
553   TRACE0(tag_call, __FUNCTION__, "exiting ");
554 	return jMechanismInfo ;
555 }
556 
557 /*
558  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
559  * Method:    C_InitToken
560  * Signature: (J[C[C)V
561  * Parametermapping:                    *PKCS11*
562  * @param   jlong jSlotID               CK_SLOT_ID slotID
563  * @param   jcharArray jPin             CK_CHAR_PTR pPin
564  *                                      CK_ULONG ulPinLen
565  * @param   jcharArray jLabel           CK_UTF8CHAR_PTR pLabel
566  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1InitToken(JNIEnv * env,jobject obj,jlong jSlotID,jcharArray jPin,jcharArray jLabel)567 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1InitToken
568   (JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel)
569 {
570 	CK_SLOT_ID ckSlotID;
571 	CK_CHAR_PTR ckpPin = NULL_PTR;
572 	CK_UTF8CHAR_PTR ckpLabel = NULL_PTR;
573 	CK_ULONG ckPinLength;
574 	CK_ULONG ckLabelLength;
575 	CK_RV rv;
576   ModuleData *moduleData;
577   CK_FUNCTION_LIST_PTR ckpFunctions;
578 
579   TRACE0(tag_call, __FUNCTION__, "entering");
580 
581   moduleData = getModuleEntry(env, obj);
582   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
583   ckpFunctions = getFunctionList(env, moduleData);
584   if (ckpFunctions == NULL_PTR) { return; }
585 
586 	ckSlotID = jLongToCKULong(jSlotID);
587   if(jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength)) { return; }
588 	if(jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength)) { return; }
589 	/* ckLabelLength <= 32 !!! */
590 
591 	rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel);
592 
593 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
594 	  TRACE1(tag_info, __FUNCTION__,"InitToken return code: %d", rv);
595 
596 	free(ckpPin);
597 	free(ckpLabel);
598   TRACE0(tag_call, __FUNCTION__, "exiting ");
599 }
600 
601 /*
602  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
603  * Method:    C_InitPIN
604  * Signature: (J[C)V
605  * Parametermapping:                    *PKCS11*
606  * @param   jlong jSessionHandle        CK_SESSION_HANDLE
607  * @param   jcharArray jPin             CK_CHAR_PTR pPin
608  *                                      CK_ULONG ulPinLen
609  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1InitPIN(JNIEnv * env,jobject obj,jlong jSessionHandle,jcharArray jPin)610 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1InitPIN
611   (JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin)
612 {
613 	CK_SESSION_HANDLE ckSessionHandle;
614 	CK_CHAR_PTR ckpPin = NULL_PTR;
615 	CK_ULONG ckPinLength;
616 	CK_RV rv;
617   ModuleData *moduleData;
618   CK_FUNCTION_LIST_PTR ckpFunctions;
619 
620   TRACE0(tag_call, __FUNCTION__, "entering");
621 
622   moduleData = getModuleEntry(env, obj);
623   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
624   ckpFunctions = getFunctionList(env, moduleData);
625   if (ckpFunctions == NULL_PTR) { return; }
626 
627 	ckSessionHandle = jLongToCKULong(jSessionHandle);
628   if(jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength)) { return; }
629 
630 	rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength);
631   ckAssertReturnValueOK(env, rv, __FUNCTION__);
632 
633 	free(ckpPin);
634 
635   TRACE0(tag_call, __FUNCTION__, "exiting ");
636 }
637 
638 /*
639  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
640  * Method:    C_SetPIN
641  * Signature: (J[C[C)V
642  * Parametermapping:                    *PKCS11*
643  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
644  * @param   jcharArray jOldPin          CK_CHAR_PTR pOldPin
645  *                                      CK_ULONG ulOldLen
646  * @param   jcharArray jNewPin          CK_CHAR_PTR pNewPin
647  *                                      CK_ULONG ulNewLen
648  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SetPIN(JNIEnv * env,jobject obj,jlong jSessionHandle,jcharArray jOldPin,jcharArray jNewPin)649 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SetPIN
650   (JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin, jcharArray jNewPin)
651 {
652 	CK_SESSION_HANDLE ckSessionHandle;
653 	CK_CHAR_PTR ckpOldPin = NULL_PTR;
654 	CK_CHAR_PTR ckpNewPin = NULL_PTR;
655 	CK_ULONG ckOldPinLength;
656 	CK_ULONG ckNewPinLength;
657 	CK_RV rv;
658   ModuleData *moduleData;
659   CK_FUNCTION_LIST_PTR ckpFunctions;
660 
661   TRACE0(tag_call, __FUNCTION__, "entering");
662 
663   moduleData = getModuleEntry(env, obj);
664   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
665   ckpFunctions = getFunctionList(env, moduleData);
666   if (ckpFunctions == NULL_PTR) { return; }
667 
668 	ckSessionHandle = jLongToCKULong(jSessionHandle);
669 	if (jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength)) { return; }
670 	if (jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength)) { return; }
671 
672 	rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength, ckpNewPin, ckNewPinLength);
673   ckAssertReturnValueOK(env, rv, __FUNCTION__);
674 
675 	free(ckpOldPin);
676 	free(ckpNewPin);
677 
678   TRACE0(tag_call, __FUNCTION__, "exiting ");
679 }
680 
681 /*
682  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
683  * Method:    C_OpenSession
684  * Signature: (JJLjava/lang/Object;Liaik/pkcs/pkcs11/wrapper/CK_NOTIFY;)J
685  * Parametermapping:                    *PKCS11*
686  * @param   jlong jSlotID               CK_SLOT_ID slotID
687  * @param   jlong jFlags                CK_FLAGS flags
688  * @param   jobject jApplication        CK_VOID_PTR pApplication
689  * @param   jobject jNotify             CK_NOTIFY Notify
690  * @return  jlong jSessionHandle        CK_SESSION_HANDLE_PTR phSession
691  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1OpenSession(JNIEnv * env,jobject obj,jlong jSlotID,jlong jFlags,jobject jApplication,jobject jNotify)692 JNIEXPORT jlong JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1OpenSession
693   (JNIEnv *env, jobject obj, jlong jSlotID, jlong jFlags, jobject jApplication, jobject jNotify)
694 {
695 	CK_SESSION_HANDLE ckSessionHandle;
696 	CK_SLOT_ID ckSlotID;
697 	CK_FLAGS ckFlags;
698 	CK_VOID_PTR ckpApplication;
699 	CK_NOTIFY ckNotify;
700 	jlong jSessionHandle;
701 	CK_RV rv;
702   ModuleData *moduleData;
703   CK_FUNCTION_LIST_PTR ckpFunctions;
704 #ifndef NO_CALLBACKS
705   NotifyEncapsulation *notifyEncapsulation = NULL;
706 #endif /* NO_CALLBACKS */
707 
708   TRACE0(tag_call, __FUNCTION__, "entering");
709 
710   moduleData = getModuleEntry(env, obj);
711   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return 0L; }
712   ckpFunctions = getFunctionList(env, moduleData);
713   if (ckpFunctions == NULL_PTR) { return 0L; }
714 
715 	ckSlotID = jLongToCKULong(jSlotID);
716 	ckFlags = jLongToCKULong(jFlags);
717 
718 #ifndef NO_CALLBACKS
719   if (jNotify != NULL) {
720     notifyEncapsulation = (NotifyEncapsulation *) malloc(sizeof(NotifyEncapsulation));
721     if (notifyEncapsulation == NULL) { throwOutOfMemoryError(env); return 0L; }
722     notifyEncapsulation->jApplicationData = (jApplication != NULL)
723         ? (*env)->NewGlobalRef(env, jApplication)
724         : NULL;
725     notifyEncapsulation->jNotifyObject = (*env)->NewGlobalRef(env, jNotify);
726 	  ckpApplication = notifyEncapsulation;
727     ckNotify = (CK_NOTIFY) &notifyCallback;
728   } else {
729     ckpApplication = NULL_PTR;
730 	  ckNotify = NULL_PTR;
731   }
732 #else
733     ckpApplication = NULL_PTR;
734 	  ckNotify = NULL_PTR;
735 #endif /* NO_CALLBACKS */
736 
737 	TRACE2(tag_debug, __FUNCTION__,"  slotID=%u, flags=%x", ckSlotID,ckFlags);
738 
739 	rv = (*ckpFunctions->C_OpenSession)(ckSlotID, ckFlags, ckpApplication, ckNotify, &ckSessionHandle);
740 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return 0L ; }
741 
742 	TRACE1(tag_info, __FUNCTION__,"got session, SessionHandle=%u", ckSessionHandle);
743 
744 	jSessionHandle = ckULongToJLong(ckSessionHandle);
745 
746 #ifndef NO_CALLBACKS
747   if (notifyEncapsulation != NULL) {
748     /* store the notifyEncapsulation to enable later cleanup */
749     putNotifyEntry(env, ckSessionHandle, notifyEncapsulation);
750   }
751 #endif /* NO_CALLBACKS */
752 
753   TRACE0(tag_call, __FUNCTION__, "exiting ");
754 
755 	return jSessionHandle ;
756 }
757 
758 /*
759  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
760  * Method:    C_CloseSession
761  * Signature: (J)V
762  * Parametermapping:                    *PKCS11*
763  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
764  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CloseSession(JNIEnv * env,jobject obj,jlong jSessionHandle)765 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CloseSession
766   (JNIEnv *env, jobject obj, jlong jSessionHandle)
767 {
768 	CK_SESSION_HANDLE ckSessionHandle;
769 	CK_RV rv;
770   ModuleData *moduleData;
771   CK_FUNCTION_LIST_PTR ckpFunctions;
772 #ifndef NO_CALLBACKS
773   NotifyEncapsulation *notifyEncapsulation;
774   jobject jApplicationData;
775 #endif /* NO_CALLBACKS */
776   TRACE0(tag_call, __FUNCTION__, "entering");
777 
778   moduleData = getModuleEntry(env, obj);
779   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
780   ckpFunctions = getFunctionList(env, moduleData);
781   if (ckpFunctions == NULL_PTR) { return; }
782 
783 	ckSessionHandle = jLongToCKULong(jSessionHandle);
784 
785   TRACE1(tag_info, __FUNCTION__, "going to close session with handle %d", jSessionHandle);
786 
787 	rv = (*ckpFunctions->C_CloseSession)(ckSessionHandle);
788 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return; }
789 
790 #ifndef NO_CALLBACKS
791   notifyEncapsulation = removeNotifyEntry(env, ckSessionHandle);
792 
793   if (notifyEncapsulation != NULL) {
794     /* there was a notify object used with this session, now dump the
795      * encapsulation object
796      */
797     (*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject);
798     jApplicationData = notifyEncapsulation->jApplicationData;
799     if (jApplicationData != NULL) {
800       (*env)->DeleteGlobalRef(env, jApplicationData);
801     }
802     free(notifyEncapsulation);
803   }
804 #endif /* NO_CALLBACKS */
805   TRACE0(tag_call, __FUNCTION__, "exiting ");
806 
807 }
808 
809 /*
810  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
811  * Method:    C_CloseAllSessions
812  * Signature: (J)V
813  * Parametermapping:                    *PKCS11*
814  * @param   jlong jSlotID               CK_SLOT_ID slotID
815  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CloseAllSessions(JNIEnv * env,jobject obj,jlong jSlotID)816 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CloseAllSessions
817   (JNIEnv *env, jobject obj, jlong jSlotID)
818 {
819 	CK_SLOT_ID ckSlotID;
820 	CK_RV rv;
821   ModuleData *moduleData;
822   CK_FUNCTION_LIST_PTR ckpFunctions;
823 #ifndef NO_CALLBACKS
824   NotifyEncapsulation *notifyEncapsulation;
825   jobject jApplicationData;
826 #endif /* NO_CALLBACKS */
827   TRACE0(tag_call, __FUNCTION__, "entering");
828 
829   moduleData = getModuleEntry(env, obj);
830   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
831   ckpFunctions = getFunctionList(env, moduleData);
832   if (ckpFunctions == NULL_PTR) { return; }
833 
834 	ckSlotID = jLongToCKULong(jSlotID);
835 
836 	rv = (*ckpFunctions->C_CloseAllSessions)(ckSlotID);
837 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return; }
838 
839 #ifndef NO_CALLBACKS
840   /* Remove all notify callback helper objects. */
841   while ((notifyEncapsulation = removeFirstNotifyEntry(env)) != NULL) {
842     /* there was a notify object used with this session, now dump the
843      * encapsulation object
844      */
845     (*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject);
846     jApplicationData = notifyEncapsulation->jApplicationData;
847     if (jApplicationData != NULL) {
848       (*env)->DeleteGlobalRef(env, jApplicationData);
849     }
850     free(notifyEncapsulation);
851   }
852 #endif /* NO_CALLBACKS */
853   TRACE0(tag_call, __FUNCTION__, "exiting ");
854 }
855 
856 /*
857  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
858  * Method:    C_GetSessionInfo
859  * Signature: (J)Liaik/pkcs/pkcs11/wrapper/CK_SESSION_INFO;
860  * Parametermapping:                    *PKCS11*
861  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
862  * @return  jobject jSessionInfo        CK_SESSION_INFO_PTR pInfo
863  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetSessionInfo(JNIEnv * env,jobject obj,jlong jSessionHandle)864 JNIEXPORT jobject JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetSessionInfo
865   (JNIEnv *env, jobject obj, jlong jSessionHandle)
866 {
867 	CK_SESSION_HANDLE ckSessionHandle;
868 	CK_SESSION_INFO ckSessionInfo;
869 	jobject jSessionInfo;
870 	CK_RV rv;
871   ModuleData *moduleData;
872   CK_FUNCTION_LIST_PTR ckpFunctions;
873   TRACE0(tag_call, __FUNCTION__, "entering");
874 
875   moduleData = getModuleEntry(env, obj);
876   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
877   ckpFunctions = getFunctionList(env, moduleData);
878   if (ckpFunctions == NULL_PTR) { return NULL; }
879 
880 	ckSessionHandle = jLongToCKULong(jSessionHandle);
881 
882 	rv = (*ckpFunctions->C_GetSessionInfo)(ckSessionHandle, &ckSessionInfo);
883 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
884 
885 	jSessionInfo = ckSessionInfoPtrToJSessionInfo(env, &ckSessionInfo);
886 
887   TRACE0(tag_call, __FUNCTION__, "exiting ");
888 	return jSessionInfo ;
889 }
890 
891 /*
892  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
893  * Method:    C_GetOperationState
894  * Signature: (J)[B
895  * Parametermapping:                    *PKCS11*
896  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
897  * @return  jbyteArray jState           CK_BYTE_PTR pOperationState
898  *                                      CK_ULONG_PTR pulOperationStateLen
899  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetOperationState(JNIEnv * env,jobject obj,jlong jSessionHandle)900 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetOperationState
901   (JNIEnv *env, jobject obj, jlong jSessionHandle)
902 {
903 	CK_SESSION_HANDLE ckSessionHandle;
904 	CK_BYTE_PTR ckpState;
905 	CK_ULONG ckStateLength;
906 	jbyteArray jState;
907 	CK_RV rv;
908   ModuleData *moduleData;
909   CK_FUNCTION_LIST_PTR ckpFunctions;
910 
911   TRACE0(tag_call, __FUNCTION__, "entering");
912 
913   moduleData = getModuleEntry(env, obj);
914   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
915   ckpFunctions = getFunctionList(env, moduleData);
916   if (ckpFunctions == NULL_PTR) { return NULL; }
917 
918 	ckSessionHandle = jLongToCKULong(jSessionHandle);
919 
920 	rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, NULL_PTR, &ckStateLength);
921 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
922 
923 	ckpState = (CK_BYTE_PTR) malloc(ckStateLength);
924   if (ckpState == NULL && ckStateLength!=0) { throwOutOfMemoryError(env); return NULL; }
925 
926 	rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, ckpState, &ckStateLength);
927   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
928     jState = ckByteArrayToJByteArray(env, ckpState, ckStateLength);
929   else
930     jState = NULL;
931 
932 	free(ckpState);
933 
934   TRACE0(tag_call, __FUNCTION__, "exiting ");
935 	return jState ;
936 }
937 
938 /*
939  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
940  * Method:    C_SetOperationState
941  * Signature: (J[BJJ)V
942  * Parametermapping:                        *PKCS11*
943  * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
944  * @param   jbyteArray jOperationState      CK_BYTE_PTR pOperationState
945  *                                          CK_ULONG ulOperationStateLen
946  * @param   jlong jEncryptionKeyHandle      CK_OBJECT_HANDLE hEncryptionKey
947  * @param   jlong jAuthenticationKeyHandle  CK_OBJECT_HANDLE hAuthenticationKey
948  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SetOperationState(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jOperationState,jlong jEncryptionKeyHandle,jlong jAuthenticationKeyHandle)949 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SetOperationState
950   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jOperationState, jlong jEncryptionKeyHandle, jlong jAuthenticationKeyHandle)
951 {
952 	CK_SESSION_HANDLE ckSessionHandle;
953 	CK_BYTE_PTR ckpState = NULL_PTR;
954 	CK_ULONG ckStateLength;
955 	CK_OBJECT_HANDLE ckEncryptionKeyHandle;
956 	CK_OBJECT_HANDLE ckAuthenticationKeyHandle;
957 	CK_RV rv;
958   ModuleData *moduleData;
959   CK_FUNCTION_LIST_PTR ckpFunctions;
960 
961   TRACE0(tag_call, __FUNCTION__, "entering");
962   moduleData = getModuleEntry(env, obj);
963   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
964   ckpFunctions = getFunctionList(env, moduleData);
965   if (ckpFunctions == NULL_PTR) { return; }
966 
967 	ckSessionHandle = jLongToCKULong(jSessionHandle);
968 	if (jCharArrayToCKCharArray(env, jOperationState, &ckpState, &ckStateLength)) { return; }
969 	ckEncryptionKeyHandle = jLongToCKULong(jEncryptionKeyHandle);
970 	ckAuthenticationKeyHandle = jLongToCKULong(jAuthenticationKeyHandle);
971 
972 	rv = (*ckpFunctions->C_SetOperationState)(ckSessionHandle, ckpState, ckStateLength, ckEncryptionKeyHandle, ckAuthenticationKeyHandle);
973   ckAssertReturnValueOK(env, rv, __FUNCTION__);
974 
975 	free(ckpState);
976 
977   TRACE0(tag_call, __FUNCTION__, "exiting ");
978 }
979 
980 /*
981  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
982  * Method:    C_Login
983  * Signature: (JJ[C)V
984  * Parametermapping:                    *PKCS11*
985  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
986  * @param   jlong jUserType             CK_USER_TYPE userType
987  * @param   jcharArray jPin             CK_CHAR_PTR pPin
988  *                                      CK_ULONG ulPinLen
989  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Login(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jUserType,jcharArray jPin)990 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Login
991   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, jcharArray jPin)
992 {
993 	CK_SESSION_HANDLE ckSessionHandle;
994 	CK_USER_TYPE ckUserType;
995 	CK_CHAR_PTR ckpPinArray = NULL_PTR;
996 	CK_ULONG ckPinLength;
997 	CK_RV rv;
998   ModuleData *moduleData;
999   CK_FUNCTION_LIST_PTR ckpFunctions;
1000 
1001   TRACE0(tag_call, __FUNCTION__, "entering");
1002 
1003   moduleData = getModuleEntry(env, obj);
1004   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1005   ckpFunctions = getFunctionList(env, moduleData);
1006   if (ckpFunctions == NULL_PTR) { return; }
1007 
1008 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1009 	ckUserType = jLongToCKULong(jUserType);
1010 	if (jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength)) { return; }
1011 
1012 	rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray, ckPinLength);
1013   ckAssertReturnValueOK(env, rv, __FUNCTION__);
1014 
1015 	free(ckpPinArray);
1016 
1017   TRACE0(tag_call, __FUNCTION__, "exiting ");
1018 }
1019 
1020 /*
1021  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1022  * Method:    C_Logout
1023  * Signature: (J)V
1024  * Parametermapping:                    *PKCS11*
1025  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1026  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Logout(JNIEnv * env,jobject obj,jlong jSessionHandle)1027 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Logout
1028   (JNIEnv *env, jobject obj, jlong jSessionHandle)
1029 {
1030 	CK_SESSION_HANDLE ckSessionHandle;
1031 	CK_RV rv;
1032   ModuleData *moduleData;
1033   CK_FUNCTION_LIST_PTR ckpFunctions;
1034 
1035   TRACE0(tag_call, __FUNCTION__, "entering");
1036 
1037   moduleData = getModuleEntry(env, obj);
1038   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1039   ckpFunctions = getFunctionList(env, moduleData);
1040   if (ckpFunctions == NULL_PTR) { return; }
1041 
1042 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1043 
1044 	rv = (*ckpFunctions->C_Logout)(ckSessionHandle);
1045   ckAssertReturnValueOK(env, rv, __FUNCTION__);
1046 
1047   TRACE0(tag_call, __FUNCTION__, "exiting ");
1048 }
1049 
1050 /*
1051  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1052  * Method:    C_CreateObject
1053  * Signature: (J[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)J
1054  * Parametermapping:                    *PKCS11*
1055  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1056  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
1057  *                                      CK_ULONG ulCount
1058  * @return  jlong jObjectHandle         CK_OBJECT_HANDLE_PTR phObject
1059  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CreateObject(JNIEnv * env,jobject obj,jlong jSessionHandle,jobjectArray jTemplate)1060 JNIEXPORT jlong JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CreateObject
1061   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
1062 {
1063 	CK_SESSION_HANDLE ckSessionHandle;
1064 	CK_OBJECT_HANDLE ckObjectHandle;
1065 	CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR, ckAttributeArray;
1066 	CK_ULONG ckAttributesLength;
1067 	jlong jObjectHandle;
1068 	CK_ULONG i, j, length;
1069 	CK_RV rv;
1070   ModuleData *moduleData;
1071   CK_FUNCTION_LIST_PTR ckpFunctions;
1072 
1073   TRACE0(tag_call, __FUNCTION__, "entering");
1074 
1075   moduleData = getModuleEntry(env, obj);
1076   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return 0L; }
1077   ckpFunctions = getFunctionList(env, moduleData);
1078   if (ckpFunctions == NULL_PTR) { return 0L; }
1079 
1080 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1081 	if (jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength)) { return 0L; }
1082 
1083 	rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle, ckpAttributes, ckAttributesLength, &ckObjectHandle);
1084   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
1085     jObjectHandle = ckULongToJLong(ckObjectHandle);
1086   else
1087     jObjectHandle = 0L;
1088 
1089 	for(i=0; i<ckAttributesLength; i++)
1090 		if(ckpAttributes[i].pValue != NULL_PTR){
1091 			if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
1092 				ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
1093 				length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
1094 				for (j=0; j<length; j++){
1095 					free(ckAttributeArray[j].pValue);
1096 				}
1097 			}
1098 			free(ckpAttributes[i].pValue);
1099 		}
1100 	free(ckpAttributes);
1101 
1102   TRACE0(tag_call, __FUNCTION__, "exiting ");
1103 	return jObjectHandle ;
1104 }
1105 
1106 /*
1107  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1108  * Method:    C_CopyObject
1109  * Signature: (JJ[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)J
1110  * Parametermapping:                    *PKCS11*
1111  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1112  * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
1113  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
1114  *                                      CK_ULONG ulCount
1115  * @return  jlong jNewObjectHandle      CK_OBJECT_HANDLE_PTR phNewObject
1116  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CopyObject(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jObjectHandle,jobjectArray jTemplate)1117 JNIEXPORT jlong JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CopyObject
1118   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
1119 {
1120 	CK_SESSION_HANDLE ckSessionHandle;
1121 	CK_OBJECT_HANDLE ckObjectHandle;
1122 	CK_OBJECT_HANDLE ckNewObjectHandle;
1123 	CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR, ckAttributeArray;
1124 	CK_ULONG ckAttributesLength;
1125 	jlong jNewObjectHandle;
1126 	CK_ULONG i, j, length;
1127 	CK_RV rv;
1128   ModuleData *moduleData;
1129   CK_FUNCTION_LIST_PTR ckpFunctions;
1130 
1131   TRACE0(tag_call, __FUNCTION__, "entering");
1132 
1133   moduleData = getModuleEntry(env, obj);
1134   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return 0L; }
1135   ckpFunctions = getFunctionList(env, moduleData);
1136   if (ckpFunctions == NULL_PTR) { return 0L; }
1137 
1138 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1139 	ckObjectHandle = jLongToCKULong(jObjectHandle);
1140 	if (jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength)) { return 0L; }
1141 
1142 	rv = (*ckpFunctions->C_CopyObject)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength, &ckNewObjectHandle);
1143   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
1144     jNewObjectHandle = ckULongToJLong(ckNewObjectHandle);
1145   else
1146     jNewObjectHandle = 0L;
1147 
1148 	for(i=0; i<ckAttributesLength; i++)
1149 		if(ckpAttributes[i].pValue != NULL_PTR){
1150 			if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
1151 				ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
1152 				length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
1153 				for (j=0; j<length; j++){
1154 					free(ckAttributeArray[j].pValue);
1155 				}
1156 			}
1157 			free(ckpAttributes[i].pValue);
1158 		}
1159 	free(ckpAttributes);
1160 
1161   TRACE0(tag_call, __FUNCTION__, "exiting ");
1162 
1163 	return jNewObjectHandle ;
1164 }
1165 
1166 /*
1167  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1168  * Method:    C_DestroyObject
1169  * Signature: (JJ)V
1170  * Parametermapping:                    *PKCS11*
1171  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1172  * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
1173  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DestroyObject(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jObjectHandle)1174 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DestroyObject
1175   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
1176 {
1177 	CK_SESSION_HANDLE ckSessionHandle;
1178 	CK_OBJECT_HANDLE ckObjectHandle;
1179 	CK_RV rv;
1180   ModuleData *moduleData;
1181   CK_FUNCTION_LIST_PTR ckpFunctions;
1182 
1183   TRACE0(tag_call, __FUNCTION__, "entering");
1184 
1185   moduleData = getModuleEntry(env, obj);
1186   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1187   ckpFunctions = getFunctionList(env, moduleData);
1188   if (ckpFunctions == NULL_PTR) { return; }
1189 
1190 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1191 	ckObjectHandle = jLongToCKULong(jObjectHandle);
1192 
1193 	rv = (*ckpFunctions->C_DestroyObject)(ckSessionHandle, ckObjectHandle);
1194   ckAssertReturnValueOK(env, rv, __FUNCTION__);
1195 
1196   TRACE0(tag_call, __FUNCTION__, "exiting ");
1197 }
1198 
1199 /*
1200  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1201  * Method:    C_GetObjectSize
1202  * Signature: (JJ)J
1203  * Parametermapping:                    *PKCS11*
1204  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1205  * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
1206  * @return  jlong jObjectSize           CK_ULONG_PTR pulSize
1207  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetObjectSize(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jObjectHandle)1208 JNIEXPORT jlong JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetObjectSize
1209   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle)
1210 {
1211 	CK_SESSION_HANDLE ckSessionHandle;
1212 	CK_OBJECT_HANDLE ckObjectHandle;
1213 	CK_ULONG ckObjectSize;
1214 	jlong jObjectSize;
1215 	CK_RV rv;
1216   ModuleData *moduleData;
1217   CK_FUNCTION_LIST_PTR ckpFunctions;
1218 
1219   TRACE0(tag_call, __FUNCTION__, "entering");
1220 
1221   moduleData = getModuleEntry(env, obj);
1222   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return 0L; }
1223   ckpFunctions = getFunctionList(env, moduleData);
1224   if (ckpFunctions == NULL_PTR) { return 0L; }
1225 
1226 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1227 	ckObjectHandle = jLongToCKULong(jObjectHandle);
1228 
1229 	rv = (*ckpFunctions->C_GetObjectSize)(ckSessionHandle, ckObjectHandle, &ckObjectSize);
1230 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return 0L ; }
1231 
1232 	jObjectSize = ckULongToJLong(ckObjectSize);
1233 
1234   TRACE0(tag_call, __FUNCTION__, "exiting ");
1235 	return jObjectSize ;
1236 }
1237 
1238 /*
1239  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1240  * Method:    C_GetAttributeValue
1241  * Signature: (JJ[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;
1242  * Parametermapping:                    *PKCS11*
1243  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1244  * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
1245  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
1246  *                                      CK_ULONG ulCount
1247  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetAttributeValue(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jObjectHandle,jobjectArray jTemplate)1248 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetAttributeValue
1249   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
1250 {
1251 	CK_SESSION_HANDLE ckSessionHandle;
1252 	CK_OBJECT_HANDLE ckObjectHandle;
1253 	CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR, ckAttributeArray;
1254 	CK_ULONG ckAttributesLength;
1255 	CK_ULONG ckBufferLength;
1256 	CK_ULONG length;
1257 	CK_ULONG i, j, y;
1258 	jobject jAttribute;
1259 	CK_RV rv;
1260 	CK_ULONG error = 0;
1261 	CK_BBOOL array = FALSE;
1262   ModuleData *moduleData;
1263   CK_FUNCTION_LIST_PTR ckpFunctions;
1264 
1265   TRACE0(tag_call, __FUNCTION__, "entering");
1266 
1267   moduleData = getModuleEntry(env, obj);
1268   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1269   ckpFunctions = getFunctionList(env, moduleData);
1270   if (ckpFunctions == NULL_PTR) { return; }
1271 
1272   TRACE3(tag_debug, __FUNCTION__, "hSession=%u, hObject=%u, pTemplate=%p", jSessionHandle, jObjectHandle, jTemplate);
1273 
1274 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1275 	ckObjectHandle = jLongToCKULong(jObjectHandle);
1276 	TRACE1(tag_debug, __FUNCTION__,"jAttributeArrayToCKAttributeArray now with jTemplate = %d", jTemplate);
1277 	if (jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength)) { return; }
1278 	TRACE2(tag_debug, __FUNCTION__,"jAttributeArrayToCKAttributeArray finished with ckpAttribute = %d, Length = %d\n", ckpAttributes, ckAttributesLength);
1279 
1280 	/* first set all pValue to NULL, to get the needed buffer length */
1281 	for(i = 0; i < ckAttributesLength; i++) {
1282 		if(ckpAttributes[i].pValue != NULL_PTR) {
1283 			free(ckpAttributes[i].pValue);
1284 		}
1285 	}
1286 	for (i = 0; i < ckAttributesLength; i++) {
1287 		ckpAttributes[i].pValue = NULL_PTR;
1288 	}
1289 	rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
1290 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) {
1291     for (i = 0; i < ckAttributesLength; i++) {
1292       if(ckpAttributes[i].pValue != NULL_PTR) {
1293         free(ckpAttributes[i].pValue);
1294       }
1295     }
1296     free(ckpAttributes);
1297 	  TRACE0(tag_call, __FUNCTION__, "exiting ");
1298 		return ;
1299 	}
1300 
1301 	for (i = 0; i < ckAttributesLength; i++) {
1302 		if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
1303 			signed long signedLength = ckpAttributes[i].ulValueLen;
1304 			if (signedLength != -1){
1305 				ckBufferLength = sizeof(CK_BYTE) * ckpAttributes[i].ulValueLen;
1306 				ckpAttributes[i].pValue = (CK_ATTRIBUTE_PTR) malloc(ckBufferLength);
1307 				ckpAttributes[i].ulValueLen = ckBufferLength;
1308 			}
1309 			if ((ckpAttributes[i].pValue == NULL && ckBufferLength!=0) || signedLength == -1) {
1310 				/* free previously allocated memory*/
1311     			for (j = 0; j < i; j++) {
1312 					if(ckpAttributes[j].pValue != NULL_PTR) {
1313 					  free(ckpAttributes[j].pValue);
1314 					}
1315 				}
1316 				free(ckpAttributes);
1317 				if (signedLength == -1){
1318 					rv = 0x12;
1319 					ckAssertReturnValueOK(env, rv, __FUNCTION__);
1320 				  TRACE0(tag_call, __FUNCTION__, "exiting ");
1321 					return ;
1322 				}
1323 				throwOutOfMemoryError(env);
1324 			  TRACE0(tag_call, __FUNCTION__, "exiting ");
1325 				return ;
1326 			}
1327 			ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
1328 			length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
1329 			for (j=0; j<length; j++){
1330 				ckAttributeArray[j].pValue = NULL_PTR;
1331 			}
1332 			array = TRUE;
1333 		}
1334 	}
1335 
1336 	if (array == TRUE) {
1337 	// get ulValueLen of the attributes of a CKF_ARRAY_ATTRIBUTE if present
1338 	rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
1339 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) {
1340 		for (i = 0; i < ckAttributesLength; i++) {
1341 			if(ckpAttributes[i].pValue != NULL_PTR) {
1342 				free(ckpAttributes[i].pValue);
1343 			}
1344 		}
1345 		free(ckpAttributes);
1346 	  TRACE0(tag_call, __FUNCTION__, "exiting ");
1347 		return ;
1348 	}
1349 	}
1350 
1351 	/* now, the ulValueLength field of each attribute should hold the exact buffer length needed
1352 	 * to allocate the needed buffers accordingly
1353      */
1354 	for (i = 0; i < ckAttributesLength; i++) {
1355 		if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
1356 			ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
1357 			length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
1358 			for (j=0; j<length; j++){
1359 				if (ckAttributeArray[j].pValue == NULL_PTR){
1360 					signed long signedLength = ckpAttributes[i].ulValueLen;
1361 					if (signedLength != -1){
1362 						ckBufferLength = sizeof(CK_BYTE) * ckAttributeArray[j].ulValueLen;
1363 						ckAttributeArray[j].pValue = (void *) malloc(ckBufferLength);
1364 						ckAttributeArray[j].ulValueLen = ckBufferLength;
1365 					}
1366 					if ((ckAttributeArray[j].pValue == NULL && ckBufferLength!=0) || signedLength == -1) {
1367 						for (y = 0; y < j; y++) {
1368 							free(ckAttributeArray[y].pValue);
1369 						}
1370 						free(ckpAttributes[i].pValue);
1371 						if (signedLength == -1)
1372 							error = 2;
1373 						else
1374 							error = 1;
1375 						break;
1376 					}
1377 				// if module doesn't support ARRAY ATTRIBUTES, the pointer was saved as byte array
1378 				// and is therefore no valid pointer to a value.
1379 				// Attribute value is set to NULL in that case.
1380 				}else{
1381 					free(ckpAttributes[i].pValue);
1382 					ckpAttributes[i].pValue = NULL;
1383 					break;
1384 				}
1385 			}
1386 		} else{
1387 			signed long signedLength = ckpAttributes[i].ulValueLen;
1388 			if (signedLength != -1){
1389 				ckBufferLength = sizeof(CK_BYTE) * ckpAttributes[i].ulValueLen;
1390 				ckpAttributes[i].pValue = (void *) malloc(ckBufferLength);
1391 				ckpAttributes[i].ulValueLen = ckBufferLength;
1392 			}
1393 			if (signedLength == -1)
1394 				error = 2;
1395 			else if (ckpAttributes[i].pValue == NULL && ckBufferLength!=0)
1396 				error = 1;
1397 		}
1398 		if (error == 1 || error == 2) {
1399 			/* free previously allocated memory*/
1400 			for (j = 0; j < i; j++) {
1401 				if ((ckpAttributes[j].type == 0x40000211) || (ckpAttributes[j].type == 0x40000212)){
1402 					ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[j].pValue;
1403 					length = ckpAttributes[j].ulValueLen/sizeof(CK_ATTRIBUTE);
1404 					for (y=0; y<length; y++){
1405 						free(ckAttributeArray[y].pValue);
1406 					}
1407 				}
1408 				free(ckpAttributes[j].pValue);
1409 			}
1410 			free(ckpAttributes);
1411 			if (error == 2){
1412 				rv = 0x12;
1413 				ckAssertReturnValueOK(env, rv, __FUNCTION__);
1414 			  TRACE0(tag_call, __FUNCTION__, "exiting ");
1415 				return ;
1416 			}
1417 			throwOutOfMemoryError(env);
1418 		  TRACE0(tag_call, __FUNCTION__, "exiting ");
1419 			return ;
1420 		}
1421 	}
1422 
1423 	/* now get the attributes with all values */
1424 	rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
1425   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
1426   {
1427     /* copy back the values to the Java attributes */
1428     for (i = 0; i < ckAttributesLength; i++) {
1429       jAttribute = ckAttributePtrToJAttribute(env, &(ckpAttributes[i]));
1430       (*env)->SetObjectArrayElement(env, jTemplate, i, jAttribute);
1431     }
1432   }
1433   else
1434     TRACE0(tag_info, __FUNCTION__,"rv != OK\n");
1435 
1436 	for (i = 0; i < ckAttributesLength; i++) {
1437 		if (ckpAttributes[i].pValue != NULL_PTR) {
1438 			if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
1439 				ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
1440 				length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
1441 	 			for (j=0; j<length; j++){
1442 					free(ckAttributeArray[j].pValue);
1443 				}
1444 			}
1445 			free(ckpAttributes[i].pValue);
1446 		}
1447 	}
1448 	free(ckpAttributes);
1449   TRACE0(tag_call, __FUNCTION__, "exiting ");
1450 }
1451 
1452 /*
1453  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1454  * Method:    C_SetAttributeValue
1455  * Signature: (JJ[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)V
1456  * Parametermapping:                    *PKCS11*
1457  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1458  * @param   jlong jObjectHandle         CK_OBJECT_HANDLE hObject
1459  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
1460  *                                      CK_ULONG ulCount
1461  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SetAttributeValue(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jObjectHandle,jobjectArray jTemplate)1462 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SetAttributeValue
1463   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate)
1464 {
1465 	CK_SESSION_HANDLE ckSessionHandle;
1466 	CK_OBJECT_HANDLE ckObjectHandle;
1467 	CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR, ckAttributeArray;
1468 	CK_ULONG ckAttributesLength;
1469 	CK_ULONG i, j, length;
1470 	CK_RV rv;
1471   ModuleData *moduleData;
1472   CK_FUNCTION_LIST_PTR ckpFunctions;
1473 
1474   TRACE0(tag_call, __FUNCTION__, "entering");
1475 
1476   moduleData = getModuleEntry(env, obj);
1477   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1478   ckpFunctions = getFunctionList(env, moduleData);
1479   if (ckpFunctions == NULL_PTR) { return; }
1480 
1481 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1482 	ckObjectHandle = jLongToCKULong(jObjectHandle);
1483 	jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
1484 
1485 	rv = (*ckpFunctions->C_SetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength);
1486   ckAssertReturnValueOK(env, rv, __FUNCTION__);
1487 
1488 	for(i=0; i<ckAttributesLength; i++) {
1489 		if(ckpAttributes[i].pValue != NULL_PTR) {
1490 			if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
1491 			ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
1492 			length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
1493 			for (j=0; j<length; j++){
1494 				free(ckAttributeArray[j].pValue);
1495 			}
1496 		}
1497 			free(ckpAttributes[i].pValue);
1498 		}
1499 	}
1500 	free(ckpAttributes);
1501 
1502   TRACE0(tag_call, __FUNCTION__, "exiting ");
1503 }
1504 
1505 /*
1506  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1507  * Method:    C_FindObjectsInit
1508  * Signature: (J[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)V
1509  * Parametermapping:                    *PKCS11*
1510  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1511  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
1512  *                                      CK_ULONG ulCount
1513  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1FindObjectsInit(JNIEnv * env,jobject obj,jlong jSessionHandle,jobjectArray jTemplate)1514 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1FindObjectsInit
1515   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobjectArray jTemplate)
1516 {
1517 	CK_SESSION_HANDLE ckSessionHandle;
1518 	CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR, ckAttributeArray;
1519 	CK_ULONG ckAttributesLength;
1520 	CK_ULONG i, j, length;
1521 	CK_RV rv;
1522   ModuleData *moduleData;
1523   CK_FUNCTION_LIST_PTR ckpFunctions;
1524 
1525   TRACE0(tag_call, __FUNCTION__, "entering");
1526 
1527   moduleData = getModuleEntry(env, obj);
1528   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1529   ckpFunctions = getFunctionList(env, moduleData);
1530   if (ckpFunctions == NULL_PTR) { return; }
1531 
1532 	TRACE2(tag_debug, __FUNCTION__,", hSession=%u, pTemplate=%p", jSessionHandle, jTemplate);
1533 
1534 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1535 	if (jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength)) { return; }
1536 
1537 	rv = (*ckpFunctions->C_FindObjectsInit)(ckSessionHandle, ckpAttributes, ckAttributesLength);
1538 	ckAssertReturnValueOK(env, rv, __FUNCTION__);
1539 
1540 	for(i=0; i<ckAttributesLength; i++) {
1541 		if(ckpAttributes[i].pValue != NULL_PTR) {
1542 			if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
1543 				ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
1544 				length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
1545 				for (j=0; j<length; j++){
1546 					free(ckAttributeArray[j].pValue);
1547 				}
1548 			}
1549 			free(ckpAttributes[i].pValue);
1550 		}
1551 	}
1552 	free(ckpAttributes);
1553 
1554   TRACE0(tag_call, __FUNCTION__, "exiting ");
1555 }
1556 
1557 /*
1558  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1559  * Method:    C_FindObjects
1560  * Signature: (JJ)[J
1561  * Parametermapping:                        *PKCS11*
1562  * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
1563  * @param   jlong jMaxObjectCount           CK_ULONG ulMaxObjectCount
1564  * @return  jlongArray jObjectHandleArray   CK_OBJECT_HANDLE_PTR phObject
1565  *                                          CK_ULONG_PTR pulObjectCount
1566  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1FindObjects(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jMaxObjectCount)1567 JNIEXPORT jlongArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1FindObjects
1568   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jMaxObjectCount)
1569 {
1570 	CK_RV rv;
1571 	CK_SESSION_HANDLE ckSessionHandle;
1572 	CK_ULONG ckMaxObjectLength;
1573 	CK_OBJECT_HANDLE_PTR ckpObjectHandleArray;
1574 	CK_ULONG ckActualObjectCount;
1575 	jlongArray jObjectHandleArray;
1576   ModuleData *moduleData;
1577   CK_FUNCTION_LIST_PTR ckpFunctions;
1578 
1579   TRACE0(tag_call, __FUNCTION__, "entering");
1580 
1581   moduleData = getModuleEntry(env, obj);
1582   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
1583   ckpFunctions = getFunctionList(env, moduleData);
1584   if (ckpFunctions == NULL_PTR) { return NULL; }
1585 
1586 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1587 	ckMaxObjectLength = jLongToCKULong(jMaxObjectCount);
1588 	ckpObjectHandleArray = (CK_OBJECT_HANDLE_PTR) malloc(sizeof(CK_OBJECT_HANDLE) * ckMaxObjectLength);
1589   if (ckpObjectHandleArray == NULL && ckMaxObjectLength!=0) { throwOutOfMemoryError(env); return NULL; }
1590 
1591 	rv = (*ckpFunctions->C_FindObjects)(ckSessionHandle, ckpObjectHandleArray, ckMaxObjectLength, &ckActualObjectCount);
1592   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK) {
1593     TRACE3(tag_debug, __FUNCTION__, "got ArrayHandle %u limited to %u entries having %u entries", ckpObjectHandleArray, ckMaxObjectLength, ckActualObjectCount);
1594     jObjectHandleArray = ckULongArrayToJLongArray(env, ckpObjectHandleArray, ckActualObjectCount);
1595   }
1596   else
1597     jObjectHandleArray = NULL;
1598 
1599   free(ckpObjectHandleArray);
1600 
1601   TRACE0(tag_call, __FUNCTION__, "exiting ");
1602 	return jObjectHandleArray ;
1603 }
1604 
1605 /*
1606  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1607  * Method:    C_FindObjectsFinal
1608  * Signature: (J)V
1609  * Parametermapping:                    *PKCS11*
1610  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1611  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1FindObjectsFinal(JNIEnv * env,jobject obj,jlong jSessionHandle)1612 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1FindObjectsFinal
1613   (JNIEnv *env, jobject obj, jlong jSessionHandle)
1614 {
1615 	CK_SESSION_HANDLE ckSessionHandle;
1616 	CK_RV rv;
1617   ModuleData *moduleData;
1618   CK_FUNCTION_LIST_PTR ckpFunctions;
1619 
1620   TRACE0(tag_call, __FUNCTION__, "entering");
1621 
1622   moduleData = getModuleEntry(env, obj);
1623   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1624   ckpFunctions = getFunctionList(env, moduleData);
1625   if (ckpFunctions == NULL_PTR) { return; }
1626 
1627 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1628 	rv = (*ckpFunctions->C_FindObjectsFinal)(ckSessionHandle);
1629   ckAssertReturnValueOK(env, rv, __FUNCTION__);
1630 
1631   TRACE0(tag_call, __FUNCTION__, "exiting ");
1632 }
1633 
1634 /*
1635  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1636  * Method:    C_EncryptInit
1637  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;J)V
1638  * Parametermapping:                    *PKCS11*
1639  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1640  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
1641  * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
1642  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1EncryptInit(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jKeyHandle)1643 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1EncryptInit
1644   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
1645 {
1646 	CK_SESSION_HANDLE ckSessionHandle;
1647 	CK_MECHANISM ckMechanism;
1648 	CK_OBJECT_HANDLE ckKeyHandle;
1649 	CK_RV rv;
1650   ModuleData *moduleData;
1651   CK_FUNCTION_LIST_PTR ckpFunctions;
1652 
1653   TRACE0(tag_call, __FUNCTION__, "entering");
1654 
1655   moduleData = getModuleEntry(env, obj);
1656   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1657   ckpFunctions = getFunctionList(env, moduleData);
1658   if (ckpFunctions == NULL_PTR) { return; }
1659 
1660 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1661 	ckKeyHandle = jLongToCKULong(jKeyHandle);
1662 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
1663 
1664 	rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
1665   ckAssertReturnValueOK(env, rv, __FUNCTION__);
1666 
1667 	if(ckMechanism.pParameter != NULL_PTR) {
1668 		freeCKMechanismParameter(&ckMechanism);
1669 	}
1670 
1671   TRACE0(tag_call, __FUNCTION__, "exiting ");
1672 }
1673 
1674 /*
1675  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1676  * Method:    C_Encrypt
1677  * Signature: (J[B)[B
1678  * Parametermapping:                    *PKCS11*
1679  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1680  * @param   jbyteArray jData            CK_BYTE_PTR pData
1681  *                                      CK_ULONG ulDataLen
1682  * @return  jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
1683  *                                      CK_ULONG_PTR pulEncryptedDataLen
1684  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Encrypt(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jData)1685 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Encrypt
1686   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
1687 {
1688 	CK_SESSION_HANDLE ckSessionHandle;
1689 	CK_BYTE_PTR ckpData = NULL_PTR, ckpEncryptedData;
1690 	CK_ULONG ckDataLength, ckEncryptedDataLength = 0;
1691 	jbyteArray jEncryptedData;
1692 	CK_RV rv;
1693   ModuleData *moduleData;
1694   CK_FUNCTION_LIST_PTR ckpFunctions;
1695 
1696   TRACE0(tag_call, __FUNCTION__, "entering");
1697 
1698   moduleData = getModuleEntry(env, obj);
1699   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
1700   ckpFunctions = getFunctionList(env, moduleData);
1701   if (ckpFunctions == NULL_PTR) { return NULL; }
1702 
1703 	/* convert jTypes to ckTypes */
1704 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1705 	if (jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength)) { return NULL; }
1706 
1707 	/* call C_Encrypt to determine DataLength */
1708 	rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckEncryptedDataLength);
1709 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
1710 
1711 	/* allocate memory for Data */
1712 	ckpEncryptedData = (CK_BYTE_PTR) malloc(ckEncryptedDataLength * sizeof(CK_BYTE));
1713   if (ckpEncryptedData == NULL && ckEncryptedDataLength!=0) { free(ckpEncryptedData); throwOutOfMemoryError(env); return NULL; }
1714 
1715 	/* call C_Encrypt */
1716 	rv = (*ckpFunctions->C_Encrypt)(ckSessionHandle, ckpData, ckDataLength, ckpEncryptedData, &ckEncryptedDataLength);
1717   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
1718     /* convert ckTypes to jTypes */
1719     jEncryptedData = ckByteArrayToJByteArray(env, ckpEncryptedData, ckEncryptedDataLength);
1720   else
1721     jEncryptedData = NULL;
1722 
1723 	free(ckpData);
1724 	free(ckpEncryptedData);
1725 
1726   TRACE0(tag_call, __FUNCTION__, "exiting ");
1727 
1728 	return jEncryptedData ;
1729 }
1730 
1731 /*
1732  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1733  * Method:    C_EncryptUpdate
1734  * Signature: (J[B)[B
1735  * Parametermapping:                    *PKCS11*
1736  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1737  * @param   jbyteArray jPart            CK_BYTE_PTR pPart
1738  *                                      CK_ULONG ulPartLen
1739  * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
1740  *                                      CK_ULONG_PTR pulEncryptedPartLen
1741  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1EncryptUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jPart)1742 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1EncryptUpdate
1743   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
1744 {
1745 	CK_SESSION_HANDLE ckSessionHandle;
1746 	CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
1747 	CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
1748 	jbyteArray jEncryptedPart;
1749 	CK_RV rv;
1750   ModuleData *moduleData;
1751   CK_FUNCTION_LIST_PTR ckpFunctions;
1752 
1753   TRACE0(tag_call, __FUNCTION__, "entering");
1754 
1755   moduleData = getModuleEntry(env, obj);
1756   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
1757   ckpFunctions = getFunctionList(env, moduleData);
1758   if (ckpFunctions == NULL_PTR) { return NULL; }
1759 
1760 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1761 	if (jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength)) { return NULL; }
1762 
1763 	rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
1764 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
1765 
1766 	ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
1767   if (ckpEncryptedPart == NULL && ckEncryptedPartLength!=0) { free(ckpEncryptedPart); throwOutOfMemoryError(env); return NULL; }
1768 
1769 	rv = (*ckpFunctions->C_EncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
1770   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
1771     jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
1772   else
1773     jEncryptedPart = NULL;
1774 
1775 	free(ckpPart);
1776 	free(ckpEncryptedPart);
1777 
1778   TRACE0(tag_call, __FUNCTION__, "exiting ");
1779 	return jEncryptedPart ;
1780 }
1781 
1782 /*
1783  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1784  * Method:    C_EncryptFinal
1785  * Signature: (J)[B
1786  * Parametermapping:                        *PKCS11*
1787  * @param   jlong jSessionHandle            CK_SESSION_HANDLE hSession
1788  * @return  jbyteArray jLastEncryptedPart   CK_BYTE_PTR pLastEncryptedDataPart
1789  *                                          CK_ULONG_PTR pulLastEncryptedDataPartLen
1790  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1EncryptFinal(JNIEnv * env,jobject obj,jlong jSessionHandle)1791 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1EncryptFinal
1792   (JNIEnv *env, jobject obj, jlong jSessionHandle)
1793 {
1794 	CK_SESSION_HANDLE ckSessionHandle;
1795 	CK_BYTE_PTR ckpLastEncryptedPart;
1796 	CK_ULONG ckLastEncryptedPartLength = 0;
1797 	jbyteArray jLastEncryptedPart;
1798 	CK_RV rv;
1799   ModuleData *moduleData;
1800   CK_FUNCTION_LIST_PTR ckpFunctions;
1801 
1802   TRACE0(tag_call, __FUNCTION__, "entering");
1803 
1804   moduleData = getModuleEntry(env, obj);
1805   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
1806   ckpFunctions = getFunctionList(env, moduleData);
1807   if (ckpFunctions == NULL_PTR) { return NULL; }
1808 
1809 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1810 
1811 	rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle, NULL_PTR, &ckLastEncryptedPartLength);
1812 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
1813 
1814 	ckpLastEncryptedPart = (CK_BYTE_PTR) malloc(ckLastEncryptedPartLength * sizeof(CK_BYTE));
1815   if (ckpLastEncryptedPart == NULL && ckLastEncryptedPartLength!=0) { throwOutOfMemoryError(env); return NULL; }
1816 
1817 	rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle, ckpLastEncryptedPart, &ckLastEncryptedPartLength);
1818   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
1819     jLastEncryptedPart = ckByteArrayToJByteArray(env, ckpLastEncryptedPart, ckLastEncryptedPartLength);
1820   else
1821     jLastEncryptedPart = NULL;
1822 
1823 	free(ckpLastEncryptedPart);
1824 
1825   TRACE0(tag_call, __FUNCTION__, "exiting ");
1826 
1827 	return jLastEncryptedPart ;
1828 }
1829 
1830 /*
1831  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1832  * Method:    C_DecryptInit
1833  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;J)V
1834  * Parametermapping:                    *PKCS11*
1835  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1836  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
1837  * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
1838  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptInit(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jKeyHandle)1839 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptInit
1840   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
1841 {
1842 	CK_SESSION_HANDLE ckSessionHandle;
1843 	CK_MECHANISM ckMechanism;
1844 	CK_OBJECT_HANDLE ckKeyHandle;
1845 	CK_RV rv;
1846   ModuleData *moduleData;
1847   CK_FUNCTION_LIST_PTR ckpFunctions;
1848 
1849   TRACE0(tag_call, __FUNCTION__, "entering");
1850 
1851   moduleData = getModuleEntry(env, obj);
1852   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
1853   ckpFunctions = getFunctionList(env, moduleData);
1854   if (ckpFunctions == NULL_PTR) { return; }
1855 
1856 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1857 	ckKeyHandle = jLongToCKULong(jKeyHandle);
1858 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
1859 
1860 	rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
1861   ckAssertReturnValueOK(env, rv, __FUNCTION__);
1862 
1863 	if(ckMechanism.pParameter != NULL_PTR) {
1864 		freeCKMechanismParameter(&ckMechanism);
1865 	}
1866 
1867   TRACE0(tag_call, __FUNCTION__, "exiting ");
1868 }
1869 
1870 /*
1871  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1872  * Method:    C_Decrypt
1873  * Signature: (J[B)[B
1874  * Parametermapping:                    *PKCS11*
1875  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1876  * @param   jbyteArray jEncryptedData   CK_BYTE_PTR pEncryptedData
1877  *                                      CK_ULONG ulEncryptedDataLen
1878  * @return  jbyteArray jData            CK_BYTE_PTR pData
1879  *                                      CK_ULONG_PTR pulDataLen
1880  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Decrypt(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jEncryptedData)1881 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Decrypt
1882   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedData)
1883 {
1884 	CK_SESSION_HANDLE ckSessionHandle;
1885 	CK_BYTE_PTR ckpData, ckpEncryptedData = NULL_PTR;
1886 	CK_ULONG ckDataLength = 0, ckEncryptedDataLength;
1887 	jbyteArray jData;
1888 	CK_RV rv;
1889   ModuleData *moduleData;
1890   CK_FUNCTION_LIST_PTR ckpFunctions;
1891 
1892   TRACE0(tag_call, __FUNCTION__, "entering");
1893 
1894   moduleData = getModuleEntry(env, obj);
1895   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
1896   ckpFunctions = getFunctionList(env, moduleData);
1897   if (ckpFunctions == NULL_PTR) { return NULL; }
1898 
1899 	/* convert jTypes to ckTypes */
1900 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1901 	if (jByteArrayToCKByteArray(env, jEncryptedData, &ckpEncryptedData, &ckEncryptedDataLength)) { return NULL; }
1902 
1903 	/* call C_Decrypt to determine DataLength */
1904 	rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle, ckpEncryptedData, ckEncryptedDataLength, NULL_PTR, &ckDataLength);
1905 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL; }
1906 
1907 	/* allocate memory for Data */
1908 	ckpData = (CK_BYTE_PTR) malloc(ckDataLength * sizeof(CK_BYTE));
1909   if (ckpData == NULL && ckDataLength!=0) { free(ckpEncryptedData); throwOutOfMemoryError(env); return NULL; }
1910 
1911 	/* call C_Decrypt */
1912 	rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle, ckpEncryptedData, ckEncryptedDataLength, ckpData, &ckDataLength);
1913   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
1914     /* convert ckTypes to jTypes */
1915     jData = ckByteArrayToJByteArray(env, ckpData, ckDataLength);
1916   else
1917     jData = NULL;
1918 
1919 	free(ckpData);
1920 	free(ckpEncryptedData);
1921 
1922   TRACE0(tag_call, __FUNCTION__, "exiting ");
1923 	return jData ;
1924 }
1925 
1926 /*
1927  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1928  * Method:    C_DecryptUpdate
1929  * Signature: (J[B)[B
1930  * Parametermapping:                    *PKCS11*
1931  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1932  * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
1933  *                                      CK_ULONG ulEncryptedPartLen
1934  * @return  jbyteArray jPart            CK_BYTE_PTR pPart
1935  *                                      CK_ULONG_PTR pulPartLen
1936  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jEncryptedPart)1937 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptUpdate
1938   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
1939 {
1940 	CK_SESSION_HANDLE ckSessionHandle;
1941 	CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
1942 	CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
1943 	jbyteArray jPart;
1944 	CK_RV rv;
1945   ModuleData *moduleData;
1946   CK_FUNCTION_LIST_PTR ckpFunctions;
1947 
1948   TRACE0(tag_call, __FUNCTION__, "entering");
1949 
1950   moduleData = getModuleEntry(env, obj);
1951   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
1952   ckpFunctions = getFunctionList(env, moduleData);
1953   if (ckpFunctions == NULL_PTR) { return NULL; }
1954 
1955 	ckSessionHandle = jLongToCKULong(jSessionHandle);
1956 	if (jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength)) { return NULL; }
1957 
1958 	rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
1959 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
1960 
1961 	ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
1962   if (ckpPart == NULL && ckPartLength!=0) { free(ckpEncryptedPart); throwOutOfMemoryError(env); return NULL; }
1963 
1964 	rv = (*ckpFunctions->C_DecryptUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
1965   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
1966     jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
1967   else
1968     jPart = NULL;
1969 
1970 	free(ckpPart);
1971 	free(ckpEncryptedPart);
1972 
1973   TRACE0(tag_call, __FUNCTION__, "exiting ");
1974 	return jPart ;
1975 }
1976 
1977 /*
1978  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
1979  * Method:    C_DecryptFinal
1980  * Signature: (J)[B
1981  * Parametermapping:                    *PKCS11*
1982  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
1983  * @return  jbyteArray jLastPart        CK_BYTE_PTR pLastPart
1984  *                                      CK_ULONG_PTR pulLastPartLen
1985  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptFinal(JNIEnv * env,jobject obj,jlong jSessionHandle)1986 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptFinal
1987   (JNIEnv *env, jobject obj, jlong jSessionHandle)
1988 {
1989 	CK_SESSION_HANDLE ckSessionHandle;
1990 	CK_BYTE_PTR ckpLastPart;
1991 	CK_ULONG ckLastPartLength = 0;
1992 	jbyteArray jLastPart;
1993 	CK_RV rv;
1994   ModuleData *moduleData;
1995   CK_FUNCTION_LIST_PTR ckpFunctions;
1996 
1997   TRACE0(tag_call, __FUNCTION__, "entering");
1998 
1999   moduleData = getModuleEntry(env, obj);
2000   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2001   ckpFunctions = getFunctionList(env, moduleData);
2002   if (ckpFunctions == NULL_PTR) { return NULL; }
2003 
2004 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2005 
2006 	rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle, NULL_PTR, &ckLastPartLength);
2007 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2008 
2009 	ckpLastPart = (CK_BYTE_PTR) malloc(ckLastPartLength * sizeof(CK_BYTE));
2010   if (ckpLastPart == NULL && ckLastPartLength !=0) { throwOutOfMemoryError(env); return NULL; }
2011 
2012 	rv = (*ckpFunctions->C_DecryptFinal)(ckSessionHandle, ckpLastPart, &ckLastPartLength);
2013   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2014     jLastPart = ckByteArrayToJByteArray(env, ckpLastPart, ckLastPartLength);
2015   else
2016     jLastPart = NULL;
2017 
2018 	free(ckpLastPart);
2019 
2020   TRACE0(tag_call, __FUNCTION__, "exiting ");
2021 	return jLastPart ;
2022 }
2023 
2024 /*
2025  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2026  * Method:    C_DigestInit
2027  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;)V
2028  * Parametermapping:                    *PKCS11*
2029  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2030  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
2031  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestInit(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism)2032 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestInit
2033   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism)
2034 {
2035 	CK_SESSION_HANDLE ckSessionHandle;
2036 	CK_MECHANISM ckMechanism;
2037 	CK_SSL3_KEY_MAT_PARAMS_PTR ckpParam;
2038 	CK_RV rv;
2039   ModuleData *moduleData;
2040   CK_FUNCTION_LIST_PTR ckpFunctions;
2041 
2042   TRACE0(tag_call, __FUNCTION__, "entering");
2043 
2044   moduleData = getModuleEntry(env, obj);
2045   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2046   ckpFunctions = getFunctionList(env, moduleData);
2047   if (ckpFunctions == NULL_PTR) { return; }
2048 
2049 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2050 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
2051 	ckpParam = ckMechanism.pParameter;
2052 
2053 	rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, &ckMechanism);
2054   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2055 
2056 	if(ckMechanism.pParameter != NULL_PTR) {
2057 		freeCKMechanismParameter(&ckMechanism);
2058 	}
2059 
2060   TRACE0(tag_call, __FUNCTION__, "exiting ");
2061 }
2062 
2063 /*
2064  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2065  * Method:    C_Digest
2066  * Signature: (J[B)[B
2067  * Parametermapping:                    *PKCS11*
2068  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2069  * @param   jbyteArray jData            CK_BYTE_PTR pData
2070  *                                      CK_ULONG ulDataLen
2071  * @return  jbyteArray jDigest          CK_BYTE_PTR pDigest
2072  *                                      CK_ULONG_PTR pulDigestLen
2073  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Digest(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jData)2074 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Digest
2075   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
2076 {
2077 	CK_SESSION_HANDLE ckSessionHandle;
2078 	CK_BYTE_PTR ckpData = NULL_PTR, ckpDigest;
2079 	CK_ULONG ckDataLength, ckDigestLength = 0;
2080 	jbyteArray jDigest;
2081 	CK_RV rv;
2082   ModuleData *moduleData;
2083   CK_FUNCTION_LIST_PTR ckpFunctions;
2084 
2085   TRACE0(tag_call, __FUNCTION__, "entering");
2086 
2087   moduleData = getModuleEntry(env, obj);
2088   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2089   ckpFunctions = getFunctionList(env, moduleData);
2090   if (ckpFunctions == NULL_PTR) { return NULL; }
2091 
2092 	/* convert jTypes to ckTypes */
2093 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2094 	if (jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength)) { return NULL; }
2095 
2096 	/* call C_Encrypt to determine DataLength */
2097 	rv = (*ckpFunctions->C_Digest)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckDigestLength);
2098 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2099 
2100 	/* allocate memory for Data */
2101 	ckpDigest = (CK_BYTE_PTR) malloc(ckDigestLength * sizeof(CK_BYTE));
2102   if (ckpDigest == NULL && ckDigestLength!=0) { free(ckpDigest); throwOutOfMemoryError(env); return NULL; }
2103 
2104 	/* call C_Encrypt */
2105 	rv = (*ckpFunctions->C_Digest)(ckSessionHandle, ckpData, ckDataLength, ckpDigest, &ckDigestLength);
2106   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2107     /* convert ckTypes to jTypes */
2108     jDigest = ckByteArrayToJByteArray(env, ckpDigest, ckDigestLength);
2109   else
2110     jDigest = NULL;
2111 
2112 	free(ckpData);
2113 	free(ckpDigest);
2114 
2115   TRACE0(tag_call, __FUNCTION__, "exiting ");
2116 	return jDigest ;
2117 }
2118 
2119 /*
2120  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2121  * Method:    C_DigestUpdate
2122  * Signature: (J[B)V
2123  * Parametermapping:                    *PKCS11*
2124  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2125  * @param   jbyteArray jData            CK_BYTE_PTR pData
2126  *                                      CK_ULONG ulDataLen
2127  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jPart)2128 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestUpdate
2129   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
2130 {
2131 	CK_SESSION_HANDLE ckSessionHandle;
2132 	CK_BYTE_PTR ckpPart = NULL_PTR;
2133 	CK_ULONG ckPartLength;
2134 	CK_RV rv;
2135   ModuleData *moduleData;
2136   CK_FUNCTION_LIST_PTR ckpFunctions;
2137 
2138   TRACE0(tag_call, __FUNCTION__, "entering");
2139 
2140   moduleData = getModuleEntry(env, obj);
2141   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2142   ckpFunctions = getFunctionList(env, moduleData);
2143   if (ckpFunctions == NULL_PTR) { return; }
2144 
2145 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2146 
2147   jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength);
2148 
2149 	rv = (*ckpFunctions->C_DigestUpdate)(ckSessionHandle, ckpPart, ckPartLength);
2150   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2151 
2152 	free(ckpPart);
2153 
2154   TRACE0(tag_call, __FUNCTION__, "exiting ");
2155 }
2156 
2157 /*
2158  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2159  * Method:    C_DigestKey
2160  * Signature: (JJ)V
2161  * Parametermapping:                    *PKCS11*
2162  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2163  * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
2164  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jlong jKeyHandle)2165 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestKey
2166   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jKeyHandle)
2167 {
2168 	CK_SESSION_HANDLE ckSessionHandle;
2169 	CK_ULONG ckKeyHandle;
2170 	CK_RV rv;
2171   ModuleData *moduleData;
2172   CK_FUNCTION_LIST_PTR ckpFunctions;
2173 
2174   TRACE0(tag_call, __FUNCTION__, "entering");
2175 
2176   moduleData = getModuleEntry(env, obj);
2177   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2178   ckpFunctions = getFunctionList(env, moduleData);
2179   if (ckpFunctions == NULL_PTR) { return; }
2180 
2181 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2182 	ckKeyHandle = jLongToCKULong(jKeyHandle);
2183 
2184 	rv = (*ckpFunctions->C_DigestKey)(ckSessionHandle, ckKeyHandle);
2185   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2186 
2187   TRACE0(tag_call, __FUNCTION__, "exiting ");
2188 }
2189 
2190 /*
2191  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2192  * Method:    C_DigestFinal
2193  * Signature: (J)[B
2194  * Parametermapping:                    *PKCS11*
2195  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2196  * @return  jbyteArray jDigest          CK_BYTE_PTR pDigest
2197  *                                      CK_ULONG_PTR pulDigestLen
2198  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestFinal(JNIEnv * env,jobject obj,jlong jSessionHandle)2199 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestFinal
2200   (JNIEnv *env, jobject obj, jlong jSessionHandle)
2201 {
2202 	CK_SESSION_HANDLE ckSessionHandle;
2203 	CK_BYTE_PTR ckpDigest;
2204 	CK_ULONG ckDigestLength = 0;
2205 	jbyteArray jDigest;
2206 	CK_RV rv;
2207   ModuleData *moduleData;
2208   CK_FUNCTION_LIST_PTR ckpFunctions;
2209 
2210   TRACE0(tag_call, __FUNCTION__, "entering");
2211 
2212   moduleData = getModuleEntry(env, obj);
2213   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2214   ckpFunctions = getFunctionList(env, moduleData);
2215   if (ckpFunctions == NULL_PTR) { return NULL; }
2216 
2217 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2218 
2219 	rv = (*ckpFunctions->C_DigestFinal)(ckSessionHandle, NULL_PTR, &ckDigestLength);
2220 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2221 
2222 	ckpDigest = (CK_BYTE_PTR) malloc(ckDigestLength * sizeof(CK_BYTE));
2223   if (ckpDigest == NULL && ckDigestLength!=0) { throwOutOfMemoryError(env); return NULL; }
2224 
2225 	rv = (*ckpFunctions->C_DigestFinal)(ckSessionHandle, ckpDigest, &ckDigestLength);
2226   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2227     jDigest = ckByteArrayToJByteArray(env, ckpDigest, ckDigestLength);
2228   else
2229     jDigest = NULL;
2230 
2231 	free(ckpDigest);
2232   TRACE0(tag_call, __FUNCTION__, "exiting ");
2233 
2234 	return jDigest ;
2235 }
2236 
2237 /*
2238  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2239  * Method:    C_SignInit
2240  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;J)V
2241  * Parametermapping:                    *PKCS11*
2242  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2243  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
2244  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
2245  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignInit(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jKeyHandle)2246 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignInit
2247   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
2248 {
2249 	CK_SESSION_HANDLE ckSessionHandle;
2250 	CK_MECHANISM ckMechanism;
2251 	CK_OBJECT_HANDLE ckKeyHandle;
2252 	CK_RV rv;
2253   ModuleData *moduleData;
2254   CK_FUNCTION_LIST_PTR ckpFunctions;
2255 
2256   TRACE0(tag_call, __FUNCTION__, "entering");
2257 
2258   moduleData = getModuleEntry(env, obj);
2259   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2260   ckpFunctions = getFunctionList(env, moduleData);
2261   if (ckpFunctions == NULL_PTR) { return; }
2262 
2263 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2264 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
2265 	ckKeyHandle = jLongToCKULong(jKeyHandle);
2266 
2267 	rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
2268   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2269 
2270 	if(ckMechanism.pParameter != NULL_PTR) {
2271 		freeCKMechanismParameter(&ckMechanism);
2272 	}
2273 
2274   TRACE0(tag_call, __FUNCTION__, "exiting ");
2275 }
2276 
2277 /*
2278  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2279  * Method:    C_Sign
2280  * Signature: (J[B)[B
2281  * Parametermapping:                    *PKCS11*
2282  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2283  * @param   jbyteArray jData            CK_BYTE_PTR pData
2284  *                                      CK_ULONG ulDataLen
2285  * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
2286  *                                      CK_ULONG_PTR pulSignatureLen
2287  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Sign(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jData)2288 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Sign
2289   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
2290 {
2291 	CK_SESSION_HANDLE ckSessionHandle;
2292 	CK_BYTE_PTR ckpData = NULL_PTR;
2293 	CK_BYTE_PTR ckpSignature;
2294 	CK_ULONG ckDataLength;
2295 	CK_ULONG ckSignatureLength = 0;
2296 	jbyteArray jSignature;
2297 	CK_RV rv;
2298   ModuleData *moduleData;
2299   CK_FUNCTION_LIST_PTR ckpFunctions;
2300 
2301   TRACE0(tag_call, __FUNCTION__, "entering");
2302 
2303   moduleData = getModuleEntry(env, obj);
2304   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2305   ckpFunctions = getFunctionList(env, moduleData);
2306   if (ckpFunctions == NULL_PTR) { return NULL; }
2307 
2308 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2309 	jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
2310 
2311 /*
2312   /* START standard code * /
2313 
2314 	/* first determine the length of the signature * /
2315 	rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckSignatureLength);
2316 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2317 
2318 	ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
2319   if (ckpSignature == NULL  && ckSignatureLength!=0) { free(ckpData); throwOutOfMemoryError(env); return NULL; }
2320 
2321   /* now get the signature * /
2322 	rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
2323  /* END standard code * /
2324  */
2325 
2326 
2327   /* START workaround code for operation abort bug in pkcs#11 of Datakey and iButton */
2328   ckSignatureLength = 512;
2329 	ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
2330   if (ckpSignature == NULL && ckSignatureLength!=0) { free(ckpData); throwOutOfMemoryError(env); return NULL; }
2331 	rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
2332 
2333   if (rv == CKR_BUFFER_TOO_SMALL) {
2334     free(ckpSignature);
2335 	  ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
2336     if (ckpSignature == NULL && ckSignatureLength!=0) { free(ckpData); throwOutOfMemoryError(env); return NULL; }
2337 	  rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
2338   }
2339   /* END workaround code */
2340 
2341   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2342     jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength);
2343   else
2344     jSignature = NULL;
2345 
2346 	free(ckpData);
2347 	free(ckpSignature);
2348 
2349   TRACE0(tag_call, __FUNCTION__, "exiting ");
2350 	return jSignature ;
2351 }
2352 
2353 /*
2354  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2355  * Method:    C_SignUpdate
2356  * Signature: (J[B)V
2357  * Parametermapping:                    *PKCS11*
2358  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2359  * @param   jbyteArray jPart            CK_BYTE_PTR pPart
2360  *                                      CK_ULONG ulPartLen
2361  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jPart)2362 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignUpdate
2363   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
2364 {
2365 	CK_SESSION_HANDLE ckSessionHandle;
2366 	CK_BYTE_PTR ckpPart = NULL_PTR;
2367 	CK_ULONG ckPartLength;
2368 	CK_RV rv;
2369   ModuleData *moduleData;
2370   CK_FUNCTION_LIST_PTR ckpFunctions;
2371 
2372   TRACE0(tag_call, __FUNCTION__, "entering");
2373 
2374   moduleData = getModuleEntry(env, obj);
2375   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2376   ckpFunctions = getFunctionList(env, moduleData);
2377   if (ckpFunctions == NULL_PTR) { return; }
2378 
2379 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2380 	if (jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength)) { return; }
2381 
2382 	rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, ckpPart, ckPartLength);
2383   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2384 
2385 	free(ckpPart);
2386 
2387   TRACE0(tag_call, __FUNCTION__, "exiting ");
2388 }
2389 
2390 /*
2391  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2392  * Method:    C_SignFinal
2393  * Signature: (J)[B
2394  * Parametermapping:                    *PKCS11*
2395  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2396  * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
2397  *                                      CK_ULONG_PTR pulSignatureLen
2398  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignFinal(JNIEnv * env,jobject obj,jlong jSessionHandle)2399 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignFinal
2400   (JNIEnv *env, jobject obj, jlong jSessionHandle)
2401 {
2402 	CK_SESSION_HANDLE ckSessionHandle;
2403 	CK_BYTE_PTR ckpSignature;
2404 	CK_ULONG ckSignatureLength = 0;
2405 	jbyteArray jSignature;
2406 	CK_RV rv;
2407   ModuleData *moduleData;
2408   CK_FUNCTION_LIST_PTR ckpFunctions;
2409 
2410   TRACE0(tag_call, __FUNCTION__, "entering");
2411 
2412   moduleData = getModuleEntry(env, obj);
2413   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2414   ckpFunctions = getFunctionList(env, moduleData);
2415   if (ckpFunctions == NULL_PTR) { return NULL; }
2416 
2417 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2418 
2419 	/* first determine the length of the signature */
2420 	rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, NULL, &ckSignatureLength);
2421 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2422 
2423 	ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
2424   if (ckpSignature == NULL && ckSignatureLength!=0) { throwOutOfMemoryError(env); return NULL; }
2425 
2426 	/* now get the signature */
2427 	rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, ckpSignature, &ckSignatureLength);
2428   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2429     jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength);
2430   else
2431     jSignature = NULL;
2432 
2433 	free(ckpSignature);
2434 
2435   TRACE0(tag_call, __FUNCTION__, "exiting ");
2436 	return jSignature ;
2437 }
2438 
2439 /*
2440  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2441  * Method:    C_SignRecoverInit
2442  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;J)V
2443  * Parametermapping:                    *PKCS11*
2444  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2445  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
2446  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
2447  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignRecoverInit(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jKeyHandle)2448 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignRecoverInit
2449   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
2450 {
2451 	CK_SESSION_HANDLE ckSessionHandle;
2452 	CK_MECHANISM ckMechanism;
2453 	CK_OBJECT_HANDLE ckKeyHandle;
2454 	CK_RV rv;
2455   ModuleData *moduleData;
2456   CK_FUNCTION_LIST_PTR ckpFunctions;
2457 
2458   TRACE0(tag_call, __FUNCTION__, "entering");
2459 
2460   moduleData = getModuleEntry(env, obj);
2461   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2462   ckpFunctions = getFunctionList(env, moduleData);
2463   if (ckpFunctions == NULL_PTR) { return; }
2464 
2465 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2466 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
2467 	ckKeyHandle = jLongToCKULong(jKeyHandle);
2468 
2469 	rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
2470   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2471 
2472 	if(ckMechanism.pParameter != NULL_PTR) {
2473 		freeCKMechanismParameter(&ckMechanism);
2474 	}
2475 
2476   TRACE0(tag_call, __FUNCTION__, "exiting ");
2477 }
2478 
2479 /*
2480  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2481  * Method:    C_SignRecover
2482  * Signature: (J[B)[B
2483  * Parametermapping:                    *PKCS11*
2484  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2485  * @param   jbyteArray jData            CK_BYTE_PTR pData
2486  *                                      CK_ULONG ulDataLen
2487  * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
2488  *                                      CK_ULONG_PTR pulSignatureLen
2489  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignRecover(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jData)2490 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignRecover
2491   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
2492 {
2493 	CK_SESSION_HANDLE ckSessionHandle;
2494 	CK_BYTE_PTR ckpData = NULL_PTR;
2495 	CK_BYTE_PTR ckpSignature;
2496 	CK_ULONG ckDataLength;
2497 	CK_ULONG ckSignatureLength = 0;
2498 	jbyteArray jSignature;
2499 	CK_RV rv;
2500   ModuleData *moduleData;
2501   CK_FUNCTION_LIST_PTR ckpFunctions;
2502 
2503   TRACE0(tag_call, __FUNCTION__, "entering");
2504 
2505   moduleData = getModuleEntry(env, obj);
2506   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2507   ckpFunctions = getFunctionList(env, moduleData);
2508   if (ckpFunctions == NULL_PTR) { return NULL; }
2509 
2510 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2511 	if (jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength)) { return NULL; }
2512 
2513 	/* first determine the length of the signature */
2514 	rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckSignatureLength);
2515 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2516 
2517 	ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
2518   if (ckpSignature == NULL && ckSignatureLength!=0) { free(ckpData); throwOutOfMemoryError(env); return NULL; }
2519 
2520 	/* now get the signature */
2521 	rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
2522   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2523     jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength);
2524   else
2525     jSignature = NULL;
2526 
2527 	free(ckpData);
2528 	free(ckpSignature);
2529 
2530   TRACE0(tag_call, __FUNCTION__, "exiting ");
2531 	return jSignature ;
2532 }
2533 
2534 /*
2535  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2536  * Method:    C_VerifyInit
2537  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;J)V
2538  * Parametermapping:                    *PKCS11*
2539  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2540  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
2541  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
2542  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyInit(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jKeyHandle)2543 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyInit
2544   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
2545 {
2546 	CK_SESSION_HANDLE ckSessionHandle;
2547 	CK_MECHANISM ckMechanism;
2548 	CK_OBJECT_HANDLE ckKeyHandle;
2549 	CK_RV rv;
2550   ModuleData *moduleData;
2551   CK_FUNCTION_LIST_PTR ckpFunctions;
2552 
2553 
2554   TRACE0(tag_call, __FUNCTION__, "entering");
2555 
2556   moduleData = getModuleEntry(env, obj);
2557   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2558   ckpFunctions = getFunctionList(env, moduleData);
2559   if (ckpFunctions == NULL_PTR) { return; }
2560 
2561 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2562 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
2563 	ckKeyHandle = jLongToCKULong(jKeyHandle);
2564 
2565 	rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
2566   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2567 
2568 	if(ckMechanism.pParameter != NULL_PTR) {
2569 		freeCKMechanismParameter(&ckMechanism);
2570 	}
2571 
2572   TRACE0(tag_call, __FUNCTION__, "exiting ");
2573 }
2574 
2575 /*
2576  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2577  * Method:    C_Verify
2578  * Signature: (J[B[B)V
2579  * Parametermapping:                    *PKCS11*
2580  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2581  * @param   jbyteArray jData            CK_BYTE_PTR pData
2582  *                                      CK_ULONG ulDataLen
2583  * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
2584  *                                      CK_ULONG_PTR pulSignatureLen
2585  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Verify(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jData,jbyteArray jSignature)2586 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1Verify
2587   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData, jbyteArray jSignature)
2588 {
2589 	CK_SESSION_HANDLE ckSessionHandle;
2590 	CK_BYTE_PTR ckpData = NULL_PTR;
2591 	CK_BYTE_PTR ckpSignature = NULL_PTR;
2592 	CK_ULONG ckDataLength;
2593 	CK_ULONG ckSignatureLength;
2594 	CK_RV rv;
2595   ModuleData *moduleData;
2596   CK_FUNCTION_LIST_PTR ckpFunctions;
2597 
2598   TRACE0(tag_call, __FUNCTION__, "entering");
2599 
2600   moduleData = getModuleEntry(env, obj);
2601   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2602   ckpFunctions = getFunctionList(env, moduleData);
2603   if (ckpFunctions == NULL_PTR) { return; }
2604 
2605 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2606 	if (jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength)) { return; }
2607 	if (jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength)) { return; }
2608 
2609 	/* verify the signature */
2610 	rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength);
2611   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2612 
2613 	free(ckpData);
2614 	free(ckpSignature);
2615 
2616   TRACE0(tag_call, __FUNCTION__, "exiting ");
2617 }
2618 
2619 /*
2620  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2621  * Method:    C_VerifyUpdate
2622  * Signature: (J[B)V
2623  * Parametermapping:                    *PKCS11*
2624  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2625  * @param   jbyteArray jPart            CK_BYTE_PTR pPart
2626  *                                      CK_ULONG ulPartLen
2627  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jPart)2628 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyUpdate
2629   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
2630 {
2631 	CK_SESSION_HANDLE ckSessionHandle;
2632 	CK_BYTE_PTR ckpPart = NULL_PTR;
2633 	CK_ULONG ckPartLength;
2634 	CK_RV rv;
2635   ModuleData *moduleData;
2636   CK_FUNCTION_LIST_PTR ckpFunctions;
2637 
2638   TRACE0(tag_call, __FUNCTION__, "entering");
2639 
2640   moduleData = getModuleEntry(env, obj);
2641   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2642   ckpFunctions = getFunctionList(env, moduleData);
2643   if (ckpFunctions == NULL_PTR) { return; }
2644 
2645 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2646 	if (jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength)) { return; }
2647 
2648 	rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, ckpPart, ckPartLength);
2649   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2650 
2651 	free(ckpPart);
2652 
2653   TRACE0(tag_call, __FUNCTION__, "exiting ");
2654 }
2655 
2656 /*
2657  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2658  * Method:    C_VerifyFinal
2659  * Signature: (J[B)V
2660  * Parametermapping:                    *PKCS11*
2661  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2662  * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
2663  *                                      CK_ULONG ulSignatureLen
2664  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyFinal(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jSignature)2665 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyFinal
2666   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature)
2667 {
2668 	CK_SESSION_HANDLE ckSessionHandle;
2669 	CK_BYTE_PTR ckpSignature = NULL_PTR;
2670 	CK_ULONG ckSignatureLength;
2671 	CK_RV rv;
2672   ModuleData *moduleData;
2673   CK_FUNCTION_LIST_PTR ckpFunctions;
2674 
2675   TRACE0(tag_call, __FUNCTION__, "entering");
2676 
2677   moduleData = getModuleEntry(env, obj);
2678   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2679   ckpFunctions = getFunctionList(env, moduleData);
2680   if (ckpFunctions == NULL_PTR) { return; }
2681 
2682 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2683 	if (jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength)) { return; }
2684 
2685 	/* verify the signature */
2686 	rv = (*ckpFunctions->C_VerifyFinal)(ckSessionHandle, ckpSignature, ckSignatureLength);
2687   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2688 
2689 	free(ckpSignature);
2690 
2691   TRACE0(tag_call, __FUNCTION__, "exiting ");
2692 }
2693 
2694 /*
2695  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2696  * Method:    C_VerifyRecoverInit
2697  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;J)V
2698  * Parametermapping:                    *PKCS11*
2699  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2700  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
2701  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
2702  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyRecoverInit(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jKeyHandle)2703 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyRecoverInit
2704   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
2705 {
2706 	CK_SESSION_HANDLE ckSessionHandle;
2707 	CK_MECHANISM ckMechanism;
2708 	CK_OBJECT_HANDLE ckKeyHandle;
2709 	CK_RV rv;
2710   ModuleData *moduleData;
2711   CK_FUNCTION_LIST_PTR ckpFunctions;
2712 
2713   TRACE0(tag_call, __FUNCTION__, "entering");
2714 
2715   moduleData = getModuleEntry(env, obj);
2716   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
2717   ckpFunctions = getFunctionList(env, moduleData);
2718   if (ckpFunctions == NULL_PTR) { return; }
2719 
2720 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2721 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
2722 	ckKeyHandle = jLongToCKULong(jKeyHandle);
2723 
2724 	rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
2725   ckAssertReturnValueOK(env, rv, __FUNCTION__);
2726 
2727 	if(ckMechanism.pParameter != NULL_PTR) {
2728 		freeCKMechanismParameter(&ckMechanism);
2729 	}
2730 
2731   TRACE0(tag_call, __FUNCTION__, "exiting ");
2732 }
2733 
2734 /*
2735  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2736  * Method:    C_VerifyRecover
2737  * Signature: (J[B)[B
2738  * Parametermapping:                    *PKCS11*
2739  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2740  * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
2741  *                                      CK_ULONG ulSignatureLen
2742  * @return  jbyteArray jData            CK_BYTE_PTR pData
2743  *                                      CK_ULONG_PTR pulDataLen
2744  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyRecover(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jSignature)2745 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1VerifyRecover
2746   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature)
2747 {
2748 	CK_SESSION_HANDLE ckSessionHandle;
2749 	CK_BYTE_PTR ckpData;
2750 	CK_BYTE_PTR ckpSignature = NULL_PTR;
2751 	CK_ULONG ckDataLength = 0;
2752 	CK_ULONG ckSignatureLength;
2753 	jbyteArray jData;
2754 	CK_RV rv;
2755   ModuleData *moduleData;
2756   CK_FUNCTION_LIST_PTR ckpFunctions;
2757 
2758   TRACE0(tag_call, __FUNCTION__, "entering");
2759 
2760   moduleData = getModuleEntry(env, obj);
2761   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2762   ckpFunctions = getFunctionList(env, moduleData);
2763   if (ckpFunctions == NULL_PTR) { return NULL; }
2764 
2765 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2766 	if (jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength)) { return NULL; }
2767 
2768 	/* first determine the length of the signature */
2769 	rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, ckpSignature, ckSignatureLength, NULL_PTR, &ckDataLength);
2770 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2771 
2772 	ckpData = (CK_BYTE_PTR) malloc(ckDataLength * sizeof(CK_BYTE));
2773   if (ckpData == NULL && ckDataLength!=0) { free(ckpSignature); throwOutOfMemoryError(env); return NULL; }
2774 
2775 	/* now get the signature */
2776 	rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, ckpSignature, ckSignatureLength, ckpData, &ckDataLength);
2777   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2778     jData = ckByteArrayToJByteArray(env, ckpData, ckDataLength);
2779   else
2780     jData = NULL;
2781 
2782 	free(ckpData);
2783 	free(ckpSignature);
2784 
2785   TRACE0(tag_call, __FUNCTION__, "exiting ");
2786 	return jData ;
2787 }
2788 
2789 /*
2790  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2791  * Method:    C_DigestEncryptUpdate
2792  * Signature: (J[B)[B
2793  * Parametermapping:                    *PKCS11*
2794  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2795  * @param   jbyteArray jPart            CK_BYTE_PTR pPart
2796  *                                      CK_ULONG ulPartLen
2797  * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
2798  *                                      CK_ULONG_PTR pulEncryptedPartLen
2799  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestEncryptUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jPart)2800 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DigestEncryptUpdate
2801   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
2802 {
2803 	CK_SESSION_HANDLE ckSessionHandle;
2804 	CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
2805 	CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
2806 	jbyteArray jEncryptedPart;
2807 	CK_RV rv;
2808   ModuleData *moduleData;
2809   CK_FUNCTION_LIST_PTR ckpFunctions;
2810 
2811   TRACE0(tag_call, __FUNCTION__, "entering");
2812 
2813   moduleData = getModuleEntry(env, obj);
2814   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2815   ckpFunctions = getFunctionList(env, moduleData);
2816   if (ckpFunctions == NULL_PTR) { return NULL; }
2817 
2818 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2819 	if (jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength)) { return NULL; }
2820 
2821 	rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
2822 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2823 
2824 	ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
2825   if (ckpEncryptedPart == NULL && ckEncryptedPartLength!=0) { free(ckpPart); throwOutOfMemoryError(env); return NULL; }
2826 
2827 	rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
2828   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2829     jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
2830   else
2831     jEncryptedPart = NULL;
2832 
2833 	free(ckpPart);
2834 	free(ckpEncryptedPart);
2835 
2836   TRACE0(tag_call, __FUNCTION__, "exiting ");
2837 	return jEncryptedPart ;
2838 }
2839 
2840 /*
2841  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2842  * Method:    C_DecryptDigestUpdate
2843  * Signature: (J[B)[B
2844  * Parametermapping:                    *PKCS11*
2845  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2846  * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
2847  *                                      CK_ULONG ulEncryptedPartLen
2848  * @return  jbyteArray jPart            CK_BYTE_PTR pPart
2849  *                                      CK_ULONG_PTR pulPartLen
2850  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptDigestUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jEncryptedPart)2851 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptDigestUpdate
2852   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
2853 {
2854 	CK_SESSION_HANDLE ckSessionHandle;
2855 	CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
2856 	CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
2857 	jbyteArray jPart;
2858 	CK_RV rv;
2859   ModuleData *moduleData;
2860   CK_FUNCTION_LIST_PTR ckpFunctions;
2861 
2862   TRACE0(tag_call, __FUNCTION__, "entering");
2863 
2864   moduleData = getModuleEntry(env, obj);
2865   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2866   ckpFunctions = getFunctionList(env, moduleData);
2867   if (ckpFunctions == NULL_PTR) { return NULL; }
2868 
2869 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2870 	if (jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength)) { return NULL; }
2871 
2872 	rv = (*ckpFunctions->C_DecryptDigestUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
2873 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL; }
2874 
2875 	ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
2876   if (ckpPart == NULL && ckPartLength!=0) { free(ckpEncryptedPart); throwOutOfMemoryError(env); return NULL; }
2877 
2878 	rv = (*ckpFunctions->C_DecryptDigestUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
2879   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2880     jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
2881   else
2882     jPart = NULL;
2883 
2884 	free(ckpPart);
2885 	free(ckpEncryptedPart);
2886 
2887   TRACE0(tag_call, __FUNCTION__, "exiting ");
2888 	return jPart ;
2889 }
2890 
2891 /*
2892  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2893  * Method:    C_SignEncryptUpdate
2894  * Signature: (J[B)[B
2895  * Parametermapping:                    *PKCS11*
2896  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2897  * @param   jbyteArray jPart            CK_BYTE_PTR pPart
2898  *                                      CK_ULONG ulPartLen
2899  * @return  jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
2900  *                                      CK_ULONG_PTR pulEncryptedPartLen
2901  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignEncryptUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jPart)2902 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SignEncryptUpdate
2903   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart)
2904 {
2905 	CK_SESSION_HANDLE ckSessionHandle;
2906 	CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart;
2907 	CK_ULONG ckPartLength, ckEncryptedPartLength = 0;
2908 	jbyteArray jEncryptedPart;
2909 	CK_RV rv;
2910   ModuleData *moduleData;
2911   CK_FUNCTION_LIST_PTR ckpFunctions;
2912 
2913   TRACE0(tag_call, __FUNCTION__, "entering");
2914 
2915   moduleData = getModuleEntry(env, obj);
2916   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2917   ckpFunctions = getFunctionList(env, moduleData);
2918   if (ckpFunctions == NULL_PTR) { return NULL; }
2919 
2920 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2921 	if (jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength)) { return NULL; }
2922 
2923 	rv = (*ckpFunctions->C_SignEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength);
2924 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2925 
2926 	ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE));
2927   if (ckpEncryptedPart == NULL && ckEncryptedPartLength!=0) { free(ckpPart); throwOutOfMemoryError(env); return NULL; }
2928 
2929 	rv = (*ckpFunctions->C_SignEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength);
2930   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2931     jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength);
2932   else
2933     jEncryptedPart = NULL;
2934 
2935 	free(ckpPart);
2936 	free(ckpEncryptedPart);
2937 
2938   TRACE0(tag_call, __FUNCTION__, "exiting ");
2939 	return jEncryptedPart ;
2940 }
2941 
2942 /*
2943  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2944  * Method:    C_DecryptVerifyUpdate
2945  * Signature: (J[B)[B
2946  * Parametermapping:                    *PKCS11*
2947  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2948  * @param   jbyteArray jEncryptedPart   CK_BYTE_PTR pEncryptedPart
2949  *                                      CK_ULONG ulEncryptedPartLen
2950  * @return  jbyteArray jPart            CK_BYTE_PTR pPart
2951  *                                      CK_ULONG_PTR pulPartLen
2952  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptVerifyUpdate(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jEncryptedPart)2953 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DecryptVerifyUpdate
2954   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jEncryptedPart)
2955 {
2956 	CK_SESSION_HANDLE ckSessionHandle;
2957 	CK_BYTE_PTR ckpPart, ckpEncryptedPart = NULL_PTR;
2958 	CK_ULONG ckPartLength = 0, ckEncryptedPartLength;
2959 	jbyteArray jPart;
2960 	CK_RV rv;
2961   ModuleData *moduleData;
2962   CK_FUNCTION_LIST_PTR ckpFunctions;
2963 
2964   TRACE0(tag_call, __FUNCTION__, "entering");
2965 
2966   moduleData = getModuleEntry(env, obj);
2967   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
2968   ckpFunctions = getFunctionList(env, moduleData);
2969   if (ckpFunctions == NULL_PTR) { return NULL; }
2970 
2971 	ckSessionHandle = jLongToCKULong(jSessionHandle);
2972 	if (jByteArrayToCKByteArray(env, jEncryptedPart, &ckpEncryptedPart, &ckEncryptedPartLength)) { return NULL; }
2973 
2974 	rv = (*ckpFunctions->C_DecryptVerifyUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, NULL_PTR, &ckPartLength);
2975 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL ; }
2976 
2977 	ckpPart = (CK_BYTE_PTR) malloc(ckPartLength * sizeof(CK_BYTE));
2978   if (ckpPart == NULL && ckPartLength!=0) { free(ckpEncryptedPart); throwOutOfMemoryError(env); return NULL; }
2979 
2980 	rv = (*ckpFunctions->C_DecryptVerifyUpdate)(ckSessionHandle, ckpEncryptedPart, ckEncryptedPartLength, ckpPart, &ckPartLength);
2981   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
2982     jPart = ckByteArrayToJByteArray(env, ckpPart, ckPartLength);
2983   else
2984     jPart = NULL;
2985 
2986 	free(ckpPart);
2987 	free(ckpEncryptedPart);
2988 
2989   TRACE0(tag_call, __FUNCTION__, "exiting ");
2990 	return jPart ;
2991 }
2992 
2993 /*
2994  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
2995  * Method:    C_GenerateKey
2996  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)J
2997  * Parametermapping:                    *PKCS11*
2998  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
2999  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
3000  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
3001  *                                      CK_ULONG ulCount
3002  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
3003  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GenerateKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jobjectArray jTemplate)3004 JNIEXPORT jlong JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GenerateKey
3005   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jobjectArray jTemplate)
3006 {
3007 	CK_SESSION_HANDLE ckSessionHandle;
3008 	CK_MECHANISM ckMechanism;
3009 	CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR, ckAttributeArray;
3010 	CK_ULONG ckAttributesLength;
3011 	CK_OBJECT_HANDLE ckKeyHandle;
3012 	jlong jKeyHandle;
3013 	CK_ULONG i, j, length;
3014 	CK_RV rv;
3015   ModuleData *moduleData;
3016   CK_FUNCTION_LIST_PTR ckpFunctions;
3017 
3018   TRACE0(tag_call, __FUNCTION__, "entering");
3019 
3020   moduleData = getModuleEntry(env, obj);
3021   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return 0L; }
3022   ckpFunctions = getFunctionList(env, moduleData);
3023   if (ckpFunctions == NULL_PTR) { return 0L; }
3024 
3025 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3026 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
3027   if ((*env)->ExceptionOccurred(env)) { return 0L ; }
3028 	if (jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength)) { return 0L; }
3029 
3030 	rv = (*ckpFunctions->C_GenerateKey)(ckSessionHandle, &ckMechanism, ckpAttributes, ckAttributesLength, &ckKeyHandle);
3031   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
3032     jKeyHandle = ckULongToJLong(ckKeyHandle);
3033   else
3034     jKeyHandle = 0L;
3035 
3036 	for(i=0; i<ckAttributesLength; i++) {
3037 		if(ckpAttributes[i].pValue != NULL_PTR) {
3038 			if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
3039 				ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
3040 				length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
3041 				for (j=0; j<length; j++){
3042 					free(ckAttributeArray[j].pValue);
3043 				}
3044 			}
3045 			free(ckpAttributes[i].pValue);
3046 		}
3047 	}
3048 	free(ckpAttributes);
3049 
3050   /* cheack, if we must give a initialization vector back to Java */
3051   switch (ckMechanism.mechanism) {
3052     case CKM_PBE_MD2_DES_CBC:
3053     case CKM_PBE_MD5_DES_CBC:
3054     case CKM_PBE_MD5_CAST_CBC:
3055     case CKM_PBE_MD5_CAST3_CBC:
3056     case CKM_PBE_MD5_CAST128_CBC:
3057     /* case CKM_PBE_MD5_CAST5_CBC:  the same as CKM_PBE_MD5_CAST128_CBC */
3058     case CKM_PBE_SHA1_CAST128_CBC:
3059     /* case CKM_PBE_SHA1_CAST5_CBC: the same as CKM_PBE_SHA1_CAST128_CBC */
3060       /* we must copy back the initialization vector to the jMechanism object */
3061       copyBackPBEInitializationVector(env, &ckMechanism, jMechanism);
3062       break;
3063   }
3064 
3065 	if(ckMechanism.pParameter != NULL_PTR) {
3066 		freeCKMechanismParameter(&ckMechanism);
3067 	}
3068 
3069   TRACE0(tag_call, __FUNCTION__, "exiting ");
3070 	return jKeyHandle ;
3071 }
3072 
3073 /*
3074  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3075  * Method:    C_GenerateKeyPair
3076  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)[J
3077  * Parametermapping:                          *PKCS11*
3078  * @param   jlong jSessionHandle              CK_SESSION_HANDLE hSession
3079  * @param   jobject jMechanism                CK_MECHANISM_PTR pMechanism
3080  * @param   jobjectArray jPublicKeyTemplate   CK_ATTRIBUTE_PTR pPublicKeyTemplate
3081  *                                            CK_ULONG ulPublicKeyAttributeCount
3082  * @param   jobjectArray jPrivateKeyTemplate  CK_ATTRIBUTE_PTR pPrivateKeyTemplate
3083  *                                            CK_ULONG ulPrivateKeyAttributeCount
3084  * @return  jlongArray jKeyHandles            CK_OBJECT_HANDLE_PTR phPublicKey
3085  *                                            CK_OBJECT_HANDLE_PTR phPublicKey
3086  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GenerateKeyPair(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jobjectArray jPublicKeyTemplate,jobjectArray jPrivateKeyTemplate)3087 JNIEXPORT jlongArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GenerateKeyPair
3088   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism,
3089    jobjectArray jPublicKeyTemplate, jobjectArray jPrivateKeyTemplate)
3090 {
3091 	CK_SESSION_HANDLE ckSessionHandle;
3092 	CK_MECHANISM ckMechanism;
3093 	CK_ATTRIBUTE_PTR ckpPublicKeyAttributes = NULL_PTR;
3094 	CK_ATTRIBUTE_PTR ckpPrivateKeyAttributes = NULL_PTR;
3095 	CK_ATTRIBUTE_PTR ckAttributeArray;
3096 	CK_ULONG ckPublicKeyAttributesLength;
3097 	CK_ULONG ckPrivateKeyAttributesLength;
3098 	CK_OBJECT_HANDLE_PTR ckpPublicKeyHandle;	/* pointer to Public Key */
3099 	CK_OBJECT_HANDLE_PTR ckpPrivateKeyHandle;	/* pointer to Private Key */
3100 	CK_OBJECT_HANDLE_PTR ckpKeyHandles;			/* pointer to array with Public and Private Key */
3101 	CK_ULONG i, j, length;
3102 	jlongArray jKeyHandles;
3103 	CK_RV rv;
3104   ModuleData *moduleData;
3105   CK_FUNCTION_LIST_PTR ckpFunctions;
3106 
3107   TRACE0(tag_call, __FUNCTION__, "entering");
3108 
3109   moduleData = getModuleEntry(env, obj);
3110   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
3111   ckpFunctions = getFunctionList(env, moduleData);
3112   if (ckpFunctions == NULL_PTR) { return NULL; }
3113 
3114 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3115 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
3116 	if (jAttributeArrayToCKAttributeArray(env, jPublicKeyTemplate, &ckpPublicKeyAttributes, &ckPublicKeyAttributesLength)) { return NULL; }
3117 	if (jAttributeArrayToCKAttributeArray(env, jPrivateKeyTemplate, &ckpPrivateKeyAttributes, &ckPrivateKeyAttributesLength)) { return NULL; }
3118 	ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) malloc(2 * sizeof(CK_OBJECT_HANDLE));
3119   if (ckpKeyHandles == NULL) { free(ckpPublicKeyAttributes); free(ckpPrivateKeyAttributes); throwOutOfMemoryError(env); return NULL; }
3120 	ckpPublicKeyHandle = ckpKeyHandles;		/* first element of array is Public Key */
3121 	ckpPrivateKeyHandle = (ckpKeyHandles + 1);	/* second element of array is Private Key */
3122 
3123 	rv = (*ckpFunctions->C_GenerateKeyPair)(ckSessionHandle, &ckMechanism,
3124 									   ckpPublicKeyAttributes, ckPublicKeyAttributesLength,
3125 									   ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength,
3126 									   ckpPublicKeyHandle, ckpPrivateKeyHandle);
3127 
3128   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
3129     jKeyHandles = ckULongArrayToJLongArray(env, ckpKeyHandles, 2);
3130   else
3131     jKeyHandles = NULL;
3132 
3133 	for(i=0; i<ckPublicKeyAttributesLength; i++) {
3134 		if(ckpPublicKeyAttributes[i].pValue != NULL_PTR) {
3135 			if ((ckpPublicKeyAttributes[i].type == 0x40000211) || (ckpPublicKeyAttributes[i].type == 0x40000212)){
3136 				ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpPublicKeyAttributes[i].pValue;
3137 				length = ckpPublicKeyAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
3138 	 			for (j=0; j<length; j++){
3139 					free(ckAttributeArray[j].pValue);
3140 				}
3141 			}
3142 			free(ckpPublicKeyAttributes[i].pValue);
3143 		}
3144 	}
3145 	free(ckpPublicKeyAttributes);
3146 
3147 	for(i=0; i<ckPrivateKeyAttributesLength; i++) {
3148 		if(ckpPrivateKeyAttributes[i].pValue != NULL_PTR) {
3149 			if ((ckpPrivateKeyAttributes[i].type == 0x40000211) || (ckpPrivateKeyAttributes[i].type == 0x40000212)){
3150 				ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpPrivateKeyAttributes[i].pValue;
3151 				length = ckpPrivateKeyAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
3152 	 			for (j=0; j<length; j++){
3153 					free(ckAttributeArray[j].pValue);
3154 				}
3155 			}
3156 			free(ckpPrivateKeyAttributes[i].pValue);
3157 		}
3158 	}
3159 	free(ckpPrivateKeyAttributes);
3160 
3161 	if(ckMechanism.pParameter != NULL_PTR) {
3162 		freeCKMechanismParameter(&ckMechanism);
3163 	}
3164 
3165 	free(ckpKeyHandles);
3166 
3167   TRACE0(tag_call, __FUNCTION__, "exiting ");
3168 	return jKeyHandles ;
3169 }
3170 
3171 /*
3172  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3173  * Method:    C_WrapKey
3174  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;JJ)[B
3175  * Parametermapping:                    *PKCS11*
3176  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
3177  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
3178  * @param   jlong jWrappingKeyHandle    CK_OBJECT_HANDLE hWrappingKey
3179  * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
3180  * @return  jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
3181  *                                      CK_ULONG_PTR pulWrappedKeyLen
3182  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1WrapKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jWrappingKeyHandle,jlong jKeyHandle)3183 JNIEXPORT jbyteArray JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1WrapKey
3184   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jWrappingKeyHandle, jlong jKeyHandle)
3185 {
3186 	CK_SESSION_HANDLE ckSessionHandle;
3187 	CK_MECHANISM ckMechanism;
3188 	CK_OBJECT_HANDLE ckWrappingKeyHandle;
3189 	CK_OBJECT_HANDLE ckKeyHandle;
3190 	CK_BYTE_PTR ckpWrappedKey;
3191 	CK_ULONG ckWrappedKeyLength = 0;
3192 	jbyteArray jWrappedKey;
3193 	CK_RV rv;
3194   ModuleData *moduleData;
3195   CK_FUNCTION_LIST_PTR ckpFunctions;
3196 
3197   TRACE0(tag_call, __FUNCTION__, "entering");
3198 
3199   moduleData = getModuleEntry(env, obj);
3200   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return NULL; }
3201   ckpFunctions = getFunctionList(env, moduleData);
3202   if (ckpFunctions == NULL_PTR) { return NULL; }
3203 
3204 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3205 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
3206 	ckWrappingKeyHandle = jLongToCKULong(jWrappingKeyHandle);
3207 	ckKeyHandle = jLongToCKULong(jKeyHandle);
3208 
3209 	rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, NULL_PTR, &ckWrappedKeyLength);
3210 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return NULL_PTR; }
3211 
3212 	ckpWrappedKey = (CK_BYTE_PTR) malloc(ckWrappedKeyLength * sizeof(CK_BYTE));
3213   if (ckpWrappedKey == NULL && ckWrappedKeyLength!=0) {
3214     if(ckMechanism.pParameter != NULL_PTR) {
3215 		  free(ckMechanism.pParameter);
3216     }
3217     throwOutOfMemoryError(env);
3218     return NULL;
3219   }
3220 
3221 	rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
3222   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
3223     jWrappedKey = ckByteArrayToJByteArray(env, ckpWrappedKey, ckWrappedKeyLength);
3224   else
3225     jWrappedKey = NULL;
3226 
3227 	free(ckpWrappedKey);
3228   if(ckMechanism.pParameter != NULL_PTR) {
3229 		freeCKMechanismParameter(&ckMechanism);
3230   }
3231 
3232   TRACE0(tag_call, __FUNCTION__, "exiting ");
3233 	return jWrappedKey ;
3234 }
3235 
3236 /*
3237  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3238  * Method:    C_UnwrapKey
3239  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;J[B[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)J
3240  * Parametermapping:                    *PKCS11*
3241  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
3242  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
3243  * @param   jlong jUnwrappingKeyHandle  CK_OBJECT_HANDLE hUnwrappingKey
3244  * @param   jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
3245  *                                      CK_ULONG_PTR pulWrappedKeyLen
3246  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
3247  *                                      CK_ULONG ulCount
3248  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
3249  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1UnwrapKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jUnwrappingKeyHandle,jbyteArray jWrappedKey,jobjectArray jTemplate)3250 JNIEXPORT jlong JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1UnwrapKey
3251   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jUnwrappingKeyHandle,
3252    jbyteArray jWrappedKey, jobjectArray jTemplate)
3253 {
3254 	CK_SESSION_HANDLE ckSessionHandle;
3255 	CK_MECHANISM ckMechanism;
3256 	CK_OBJECT_HANDLE ckUnwrappingKeyHandle;
3257 	CK_BYTE_PTR ckpWrappedKey = NULL_PTR;
3258 	CK_ULONG ckWrappedKeyLength;
3259 	CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR, ckAttributeArray;
3260 	CK_ULONG ckAttributesLength;
3261 	CK_OBJECT_HANDLE ckKeyHandle;
3262 	jlong jKeyHandle;
3263 	CK_ULONG i, j, length;
3264 	CK_RV rv;
3265   ModuleData *moduleData;
3266   CK_FUNCTION_LIST_PTR ckpFunctions;
3267 
3268   TRACE0(tag_call, __FUNCTION__, "entering");
3269 
3270   moduleData = getModuleEntry(env, obj);
3271   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return 0L; }
3272   ckpFunctions = getFunctionList(env, moduleData);
3273   if (ckpFunctions == NULL_PTR) { return 0L; }
3274 
3275 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3276 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
3277 	ckUnwrappingKeyHandle = jLongToCKULong(jUnwrappingKeyHandle);
3278 	if (jByteArrayToCKByteArray(env, jWrappedKey, &ckpWrappedKey, &ckWrappedKeyLength)) { return 0L; }
3279 	if (jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength)) { return 0L; }
3280 
3281 	rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism, ckUnwrappingKeyHandle,
3282 								 ckpWrappedKey, ckWrappedKeyLength,
3283 								 ckpAttributes, ckAttributesLength, &ckKeyHandle);
3284 
3285   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK)
3286     jKeyHandle = ckLongToJLong(ckKeyHandle);
3287   else
3288     jKeyHandle = 0L;
3289 
3290   for(i=0; i<ckAttributesLength; i++) {
3291     if(ckpAttributes[i].pValue != NULL_PTR) {
3292 		if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
3293 			ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
3294 			length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
3295 			for (j=0; j<length; j++){
3296 				free(ckAttributeArray[j].pValue);
3297 			}
3298 		}
3299 		free(ckpAttributes[i].pValue);
3300     }
3301   }
3302 	free(ckpAttributes);
3303 
3304   /* cheack, if we must give a initialization vector back to Java */
3305   if (ckMechanism.mechanism == CKM_KEY_WRAP_SET_OAEP) {
3306     /* we must copy back the unwrapped key info to the jMechanism object */
3307     copyBackSetUnwrappedKey(env, &ckMechanism, jMechanism);
3308   }
3309 
3310 	free(ckpWrappedKey);
3311   if(ckMechanism.pParameter != NULL_PTR) {
3312 		freeCKMechanismParameter(&ckMechanism);
3313   }
3314 
3315   TRACE0(tag_call, __FUNCTION__, "exiting ");
3316 	return jKeyHandle ;
3317 }
3318 
3319 /*
3320  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3321  * Method:    C_DeriveKey
3322  * Signature: (JLiaik/pkcs/pkcs11/wrapper/CK_MECHANISM;J[Liaik/pkcs/pkcs11/wrapper/CK_ATTRIBUTE;)J
3323  * Parametermapping:                    *PKCS11*
3324  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
3325  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
3326  * @param   jlong jBaseKeyHandle        CK_OBJECT_HANDLE hBaseKey
3327  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
3328  *                                      CK_ULONG ulCount
3329  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
3330  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DeriveKey(JNIEnv * env,jobject obj,jlong jSessionHandle,jobject jMechanism,jlong jBaseKeyHandle,jobjectArray jTemplate)3331 JNIEXPORT jlong JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1DeriveKey
3332   (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jBaseKeyHandle, jobjectArray jTemplate)
3333 {
3334 	CK_SESSION_HANDLE ckSessionHandle;
3335 	CK_MECHANISM ckMechanism;
3336 	CK_OBJECT_HANDLE ckBaseKeyHandle;
3337 	CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR, ckAttributeArray;
3338 	CK_ULONG ckAttributesLength;
3339 	CK_OBJECT_HANDLE ckKeyHandle;
3340 	jlong jKeyHandle;
3341 	CK_ULONG i, j, length;
3342 	CK_RV rv;
3343   ModuleData *moduleData;
3344   CK_FUNCTION_LIST_PTR ckpFunctions;
3345 
3346   TRACE0(tag_call, __FUNCTION__, "entering");
3347 
3348   moduleData = getModuleEntry(env, obj);
3349   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return 0L; }
3350   ckpFunctions = getFunctionList(env, moduleData);
3351   if (ckpFunctions == NULL_PTR) { return 0L; }
3352 
3353 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3354 	ckMechanism = jMechanismToCKMechanism(env, jMechanism);
3355 	ckBaseKeyHandle = jLongToCKULong(jBaseKeyHandle);
3356 	if (jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength)) { return 0L; }
3357 
3358 	rv = (*ckpFunctions->C_DeriveKey)(ckSessionHandle, &ckMechanism, ckBaseKeyHandle,
3359 								 ckpAttributes, ckAttributesLength, &ckKeyHandle);
3360 
3361   if(ckAssertReturnValueOK(env, rv, __FUNCTION__) == CK_ASSERT_OK) {
3362     jKeyHandle = ckLongToJLong(ckKeyHandle);
3363 		if (ckMechanism.mechanism == CKM_SSL3_MASTER_KEY_DERIVE) {
3364 			/* we must copy back the client version */
3365 			copyBackClientVersion(env, &ckMechanism, jMechanism);
3366 		}
3367 		if (ckMechanism.mechanism == CKM_SSL3_KEY_AND_MAC_DERIVE) {
3368 			/* we must copy back the unwrapped key info to the jMechanism object */
3369 			copyBackSSLKeyMatParams(env, &ckMechanism, jMechanism);
3370 		}
3371   }
3372   else
3373     jKeyHandle = 0L;
3374 
3375 	for(i=0; i<ckAttributesLength; i++) {
3376 		if(ckpAttributes[i].pValue != NULL_PTR) {
3377 			if ((ckpAttributes[i].type == 0x40000211) || (ckpAttributes[i].type == 0x40000212)){
3378 				ckAttributeArray = (CK_ATTRIBUTE_PTR)ckpAttributes[i].pValue;
3379 				length = ckpAttributes[i].ulValueLen/sizeof(CK_ATTRIBUTE);
3380 				for (j=0; j<length; j++){
3381 					free(ckAttributeArray[j].pValue);
3382 				}
3383 			}
3384 			free(ckpAttributes[i].pValue);
3385 		}
3386 	}
3387 	free(ckpAttributes);
3388 
3389 	if(ckMechanism.pParameter != NULL_PTR) {
3390 		freeCKMechanismParameter(&ckMechanism);
3391 	}
3392 
3393   TRACE0(tag_call, __FUNCTION__, "exiting ");
3394 	return jKeyHandle ;
3395 }
3396 
3397 /*
3398  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3399  * Method:    C_SeedRandom
3400  * Signature: (J[B)V
3401  * Parametermapping:                    *PKCS11*
3402  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
3403  * @param   jbyteArray jSeed            CK_BYTE_PTR pSeed
3404  *                                      CK_ULONG ulSeedLen
3405  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SeedRandom(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jSeed)3406 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1SeedRandom
3407   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSeed)
3408 {
3409 	CK_SESSION_HANDLE ckSessionHandle;
3410 	CK_BYTE_PTR ckpSeed = NULL_PTR;
3411 	CK_ULONG ckSeedLength;
3412 	CK_RV rv;
3413   ModuleData *moduleData;
3414   CK_FUNCTION_LIST_PTR ckpFunctions;
3415 
3416   TRACE0(tag_call, __FUNCTION__, "entering");
3417 
3418   moduleData = getModuleEntry(env, obj);
3419   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
3420   ckpFunctions = getFunctionList(env, moduleData);
3421   if (ckpFunctions == NULL_PTR) { return; }
3422 
3423 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3424 	if (jByteArrayToCKByteArray(env, jSeed, &ckpSeed, &ckSeedLength)) { return; }
3425 
3426 	rv = (*ckpFunctions->C_SeedRandom)(ckSessionHandle, ckpSeed, ckSeedLength);
3427   ckAssertReturnValueOK(env, rv, __FUNCTION__);
3428 
3429 	free(ckpSeed);
3430 
3431   TRACE0(tag_call, __FUNCTION__, "exiting ");
3432 }
3433 
3434 /*
3435  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3436  * Method:    C_GenerateRandom
3437  * Signature: (J[B)V
3438  * Parametermapping:                    *PKCS11*
3439  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
3440  * @param   jbyteArray jRandomData      CK_BYTE_PTR pRandomData
3441  *                                      CK_ULONG ulRandomDataLen
3442  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GenerateRandom(JNIEnv * env,jobject obj,jlong jSessionHandle,jbyteArray jRandomData)3443 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GenerateRandom
3444   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jRandomData)
3445 {
3446 	CK_SESSION_HANDLE ckSessionHandle;
3447   jbyte *jRandomBuffer;
3448   jlong jRandomBufferLength;
3449 	CK_RV rv;
3450   ModuleData *moduleData;
3451   CK_FUNCTION_LIST_PTR ckpFunctions;
3452 
3453   TRACE0(tag_call, __FUNCTION__, "entering");
3454 
3455   moduleData = getModuleEntry(env, obj);
3456   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
3457   ckpFunctions = getFunctionList(env, moduleData);
3458   if (ckpFunctions == NULL_PTR) { return; }
3459 
3460 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3461 
3462 	jRandomBufferLength = (*env)->GetArrayLength(env, jRandomData);
3463 	jRandomBuffer = (*env)->GetByteArrayElements(env, jRandomData, NULL);
3464 
3465 	rv = (*ckpFunctions->C_GenerateRandom)(ckSessionHandle,
3466                                          (CK_BYTE_PTR) jRandomBuffer,
3467                                          jLongToCKULong(jRandomBufferLength));
3468   ckAssertReturnValueOK(env, rv, __FUNCTION__);
3469 
3470   /* copy back generated bytes */
3471 	(*env)->ReleaseByteArrayElements(env, jRandomData, jRandomBuffer, 0);
3472 
3473   TRACE0(tag_call, __FUNCTION__, "exiting ");
3474 }
3475 
3476 /*
3477  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3478  * Method:    C_GetFunctionStatus
3479  * Signature: (J)V
3480  * Parametermapping:                    *PKCS11*
3481  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
3482  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetFunctionStatus(JNIEnv * env,jobject obj,jlong jSessionHandle)3483 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1GetFunctionStatus
3484   (JNIEnv *env, jobject obj, jlong jSessionHandle)
3485 {
3486 	CK_SESSION_HANDLE ckSessionHandle;
3487 	CK_RV rv;
3488   ModuleData *moduleData;
3489   CK_FUNCTION_LIST_PTR ckpFunctions;
3490 
3491   TRACE0(tag_call, __FUNCTION__, "entering");
3492 
3493   moduleData = getModuleEntry(env, obj);
3494   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
3495   ckpFunctions = getFunctionList(env, moduleData);
3496   if (ckpFunctions == NULL_PTR) { return; }
3497 
3498 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3499 
3500 	/* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */
3501 	rv = (*ckpFunctions->C_GetFunctionStatus)(ckSessionHandle);
3502   ckAssertReturnValueOK(env, rv, __FUNCTION__);
3503 
3504   TRACE0(tag_call, __FUNCTION__, "exiting ");
3505 }
3506 
3507 /*
3508  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3509  * Method:    C_CancelFunction
3510  * Signature: (J)V
3511  * Parametermapping:                    *PKCS11*
3512  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
3513  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CancelFunction(JNIEnv * env,jobject obj,jlong jSessionHandle)3514 JNIEXPORT void JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1CancelFunction
3515   (JNIEnv *env, jobject obj, jlong jSessionHandle)
3516 {
3517 	CK_SESSION_HANDLE ckSessionHandle;
3518 	CK_RV rv;
3519   ModuleData *moduleData;
3520   CK_FUNCTION_LIST_PTR ckpFunctions;
3521 
3522   TRACE0(tag_call, __FUNCTION__, "entering");
3523 
3524   moduleData = getModuleEntry(env, obj);
3525   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return; }
3526   ckpFunctions = getFunctionList(env, moduleData);
3527   if (ckpFunctions == NULL_PTR) { return; }
3528 
3529 	ckSessionHandle = jLongToCKULong(jSessionHandle);
3530 
3531 	/* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */
3532 	rv = (*ckpFunctions->C_CancelFunction)(ckSessionHandle);
3533   ckAssertReturnValueOK(env, rv, __FUNCTION__);
3534 
3535   TRACE0(tag_call, __FUNCTION__, "exiting ");
3536 }
3537 
3538 /*
3539  * Class:     iaik_pkcs_pkcs11_wrapper_PKCS11Implementation
3540  * Method:    C_WaitForSlotEvent
3541  * Signature: (JLjava/lang/Object;)J
3542  * Parametermapping:                    *PKCS11*
3543  * @param   jlong jFlags                CK_FLAGS flags
3544  * @param   jobject jReserved           CK_VOID_PTR pReserved
3545  * @return  jlong jSlotID               CK_SLOT_ID_PTR pSlot
3546  */
Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1WaitForSlotEvent(JNIEnv * env,jobject obj,jlong jFlags,jobject jReserved)3547 JNIEXPORT jlong JNICALL Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_C_1WaitForSlotEvent
3548   (JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved)
3549 {
3550 	CK_FLAGS ckFlags;
3551 	CK_SLOT_ID ckSlotID;
3552 	jlong jSlotID;
3553 	CK_RV rv;
3554   ModuleData *moduleData;
3555   CK_FUNCTION_LIST_PTR ckpFunctions;
3556 
3557   TRACE0(tag_call, __FUNCTION__, "entering");
3558 
3559   moduleData = getModuleEntry(env, obj);
3560   if (moduleData == NULL) { throwDisconnectedRuntimeException(env); return 0L; }
3561   ckpFunctions = getFunctionList(env, moduleData);
3562   if (ckpFunctions == NULL_PTR) { return 0L; }
3563 
3564 	ckFlags = jLongToCKULong(jFlags);
3565 
3566 	rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR);
3567 	if(ckAssertReturnValueOK(env, rv, __FUNCTION__) != CK_ASSERT_OK) { return 0L; }
3568 
3569 	jSlotID = ckULongToJLong(ckSlotID);
3570 
3571   TRACE0(tag_call, __FUNCTION__, "exiting ");
3572 	return jSlotID ;
3573 }
3574 
3575 /* ************************************************************************** */
3576 /* Now come the functions for mutex handling and notification callbacks       */
3577 /* ************************************************************************** */
3578 
3579 /*
3580  * converts the InitArgs object to a CK_C_INITIALIZE_ARGS structure and sets the functions
3581  * that will call the right Java mutex functions
3582  *
3583  * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
3584  * @param pInitArgs - the InitArgs object with the Java mutex functions to call
3585  * @return - the pointer to the CK_C_INITIALIZE_ARGS structure with the functions that will call
3586  *           the corresponding Java functions
3587  */
makeCKInitArgsAdapter(JNIEnv * env,jobject jInitArgs)3588 CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject jInitArgs)
3589 {
3590 	CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
3591 	jclass jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
3592 	jfieldID fieldID;
3593 	jlong jFlags;
3594 	jobject jReserved;
3595   CK_ULONG ckReservedLength;
3596 #ifndef NO_CALLBACKS
3597 	jobject jMutexHandler;
3598 #endif /* NO_CALLBACKS */
3599 
3600 	if(jInitArgs == NULL) {
3601 		return NULL_PTR;
3602 	}
3603 
3604 	/* convert the Java InitArgs object to a pointer to a CK_C_INITIALIZE_ARGS structure */
3605 	ckpInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS));
3606   if (ckpInitArgs == NULL) { throwOutOfMemoryError(env); return NULL; }
3607 
3608 	/* Set the mutex functions that will call the Java mutex functions, but
3609    * only set it, if the field is not null.
3610    */
3611 #ifdef NO_CALLBACKS
3612   ckpInitArgs->CreateMutex = NULL_PTR;
3613   ckpInitArgs->DestroyMutex = NULL_PTR;
3614   ckpInitArgs->LockMutex = NULL_PTR;
3615   ckpInitArgs->UnlockMutex = NULL_PTR;
3616 #else
3617 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", CLASS_NAME(CLASS_CREATEMUTEX));
3618 	assert(fieldID != 0);
3619 	jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
3620   ckpInitArgs->CreateMutex = (jMutexHandler != NULL) ? &callJCreateMutex : NULL_PTR;
3621 
3622 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", CLASS_NAME(CLASS_DESTROYMUTEX));
3623 	assert(fieldID != 0);
3624 	jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
3625   ckpInitArgs->DestroyMutex = (jMutexHandler != NULL) ? &callJDestroyMutex : NULL_PTR;
3626 
3627 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", CLASS_NAME(CLASS_LOCKMUTEX));
3628 	assert(fieldID != 0);
3629 	jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
3630   ckpInitArgs->LockMutex = (jMutexHandler != NULL) ? &callJLockMutex : NULL_PTR;
3631 
3632 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", CLASS_NAME(CLASS_UNLOCKMUTEX));
3633 	assert(fieldID != 0);
3634 	jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID);
3635   ckpInitArgs->UnlockMutex = (jMutexHandler != NULL) ? &callJUnlockMutex : NULL_PTR;
3636 
3637   if ((ckpInitArgs->CreateMutex != NULL_PTR)
3638       || (ckpInitArgs->DestroyMutex != NULL_PTR)
3639       || (ckpInitArgs->LockMutex != NULL_PTR)
3640       || (ckpInitArgs->UnlockMutex != NULL_PTR)) {
3641     /* we only need to keep a global copy, if we need callbacks */
3642     /* set the global object jInitArgs so that the right Java mutex functions will be called */
3643   	jInitArgsObject = (*env)->NewGlobalRef(env, jInitArgs);
3644     ckpGlobalInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS));
3645     if (ckpGlobalInitArgs == NULL) { free(ckpInitArgs); throwOutOfMemoryError(env); return NULL; }
3646     memcpy(ckpGlobalInitArgs, ckpInitArgs, sizeof(CK_C_INITIALIZE_ARGS));
3647   }
3648 #endif /* NO_CALLBACKS */
3649 
3650 	/* convert and set the flags field */
3651 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "flags", "J");
3652 	assert(fieldID != 0);
3653 	jFlags = (*env)->GetLongField(env, jInitArgs, fieldID);
3654 	ckpInitArgs->flags = jLongToCKULong(jFlags);
3655 
3656 	/* pReserved should be NULL_PTR in this version */
3657 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "pReserved", "Ljava/lang/Object;");
3658 	assert(fieldID != 0);
3659 	jReserved = (*env)->GetObjectField(env, jInitArgs, fieldID);
3660 
3661   /* we try to convert the reserved parameter also */
3662   jObjectToPrimitiveCKObjectPtrPtr(env, jReserved, &(ckpInitArgs->pReserved), &ckReservedLength);
3663 
3664 	return ckpInitArgs ;
3665 }
3666 
3667 #ifndef NO_CALLBACKS
3668 
3669 /*
3670  * is the function that gets called by PKCS#11 to create a mutex and calls the Java
3671  * CreateMutex function
3672  *
3673  * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
3674  * @param ppMutex - the new created mutex
3675  * @return - should return CKR_OK if the mutex creation was ok
3676  */
callJCreateMutex(CK_VOID_PTR_PTR ppMutex)3677 CK_RV callJCreateMutex(CK_VOID_PTR_PTR ppMutex)
3678 {
3679   JavaVM *jvm;
3680   JNIEnv *env;
3681   jsize actualNumberVMs;
3682   jint returnValue;
3683   jthrowable pkcs11Exception;
3684   jclass pkcs11ExceptionClass;
3685   jlong errorCode;
3686   CK_RV rv = CKR_OK;
3687   int wasAttached = 1;
3688 	jclass jCreateMutexClass;
3689 	jclass jInitArgsClass;
3690 	jmethodID methodID;
3691 	jfieldID fieldID;
3692 	jobject jCreateMutex;
3693 	jobject jMutex;
3694 
3695 
3696   /* Get the currently running Java VM */
3697   returnValue = JNI_GetCreatedJavaVMs(&jvm, (jsize) 1, &actualNumberVMs);
3698   if ((returnValue != 0) || (actualNumberVMs <= 0)) { return rv ;} /* there is no VM running */
3699 
3700   /* Determine, if current thread is already attached */
3701   returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
3702   if (returnValue == JNI_EDETACHED) {
3703     /* thread detached, so attach it */
3704     wasAttached = 0;
3705     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
3706   } else if (returnValue == JNI_EVERSION) {
3707     /* this version of JNI is not supported, so just try to attach */
3708     /* we assume it was attached to ensure that this thread is not detached
3709      * afterwards even though it should not
3710      */
3711     wasAttached = 1;
3712     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
3713   } else {
3714     /* attached */
3715     wasAttached = 1;
3716   }
3717 
3718 
3719   jCreateMutexClass = (*env)->FindClass(env, CLASS_CREATEMUTEX);
3720 	jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
3721 
3722   /* get the CreateMutex object out of the jInitArgs object */
3723 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", CLASS_NAME(CLASS_CREATEMUTEX));
3724 	assert(fieldID != 0);
3725 	jCreateMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
3726 	assert(jCreateMutex != 0);
3727 
3728 	/* call the CK_CREATEMUTEX function of the CreateMutex object */
3729 	/* and get the new Java mutex object */
3730 	methodID = (*env)->GetMethodID(env, jCreateMutexClass, "CK_CREATEMUTEX", "()Ljava/lang/Object;");
3731 	assert(methodID != 0);
3732 	jMutex = (*env)->CallObjectMethod(env, jCreateMutex, methodID);
3733 
3734 	/* set a global reference on the Java mutex */
3735 	jMutex = (*env)->NewGlobalRef(env, jMutex);
3736 	/* convert the Java mutex to a CK mutex */
3737 	*ppMutex = jObjectToCKVoidPtr(jMutex);
3738 
3739 
3740   /* check, if callback threw an exception */
3741   pkcs11Exception = (*env)->ExceptionOccurred(env);
3742 
3743   if (pkcs11Exception != NULL) {
3744     /* The was an exception thrown, now we get the error-code from it */
3745     pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
3746 	  methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
3747 	  assert(methodID != 0);
3748     errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
3749     rv = jLongToCKULong(errorCode);
3750   }
3751 
3752   /* if we attached this thread to the VM just for callback, we detach it now */
3753   if (wasAttached) {
3754     returnValue = (*jvm)->DetachCurrentThread(jvm);
3755   }
3756 
3757 	return rv ;
3758 }
3759 
3760 /*
3761  * is the function that gets called by PKCS#11 to destroy a mutex and calls the Java
3762  * DestroyMutex function
3763  *
3764  * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
3765  * @param pMutex - the mutex to destroy
3766  * @return - should return CKR_OK if the mutex was destroyed
3767  */
callJDestroyMutex(CK_VOID_PTR pMutex)3768 CK_RV callJDestroyMutex(CK_VOID_PTR pMutex)
3769 {
3770   JavaVM *jvm;
3771   JNIEnv *env;
3772   jsize actualNumberVMs;
3773   jint returnValue;
3774   jthrowable pkcs11Exception;
3775   jclass pkcs11ExceptionClass;
3776   jlong errorCode;
3777   CK_RV rv = CKR_OK;
3778   int wasAttached = 1;
3779 	jclass jDestroyMutexClass;
3780 	jclass jInitArgsClass;
3781 	jmethodID methodID;
3782 	jfieldID fieldID;
3783 	jobject jDestroyMutex;
3784 	jobject jMutex;
3785 
3786 
3787   /* Get the currently running Java VM */
3788   returnValue = JNI_GetCreatedJavaVMs(&jvm, (jsize) 1, &actualNumberVMs);
3789   if ((returnValue != 0) || (actualNumberVMs <= 0)) { return rv ; } /* there is no VM running */
3790 
3791   /* Determine, if current thread is already attached */
3792   returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
3793   if (returnValue == JNI_EDETACHED) {
3794     /* thread detached, so attach it */
3795     wasAttached = 0;
3796     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
3797   } else if (returnValue == JNI_EVERSION) {
3798     /* this version of JNI is not supported, so just try to attach */
3799     /* we assume it was attached to ensure that this thread is not detached
3800      * afterwards even though it should not
3801      */
3802     wasAttached = 1;
3803     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
3804   } else {
3805     /* attached */
3806     wasAttached = 1;
3807   }
3808 
3809 
3810   jDestroyMutexClass = (*env)->FindClass(env, CLASS_DESTROYMUTEX);
3811 	jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
3812 
3813   /* convert the CK mutex to a Java mutex */
3814 	jMutex = ckVoidPtrToJObject(pMutex);
3815 
3816 	/* get the DestroyMutex object out of the jInitArgs object */
3817 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", CLASS_NAME(CLASS_DESTROYMUTEX));
3818 	assert(fieldID != 0);
3819 	jDestroyMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
3820 	assert(jDestroyMutex != 0);
3821 
3822 	/* call the CK_DESTROYMUTEX method of the DestroyMutex object */
3823 	methodID = (*env)->GetMethodID(env, jDestroyMutexClass, "CK_DESTROYMUTEX", "(Ljava/lang/Object;)V");
3824 	assert(methodID != 0);
3825 	(*env)->CallVoidMethod(env, jDestroyMutex, methodID, jMutex);
3826 
3827 	/* delete the global reference on the Java mutex */
3828 	(*env)->DeleteGlobalRef(env, jMutex);
3829 
3830 
3831   /* check, if callback threw an exception */
3832   pkcs11Exception = (*env)->ExceptionOccurred(env);
3833 
3834   if (pkcs11Exception != NULL) {
3835     /* The was an exception thrown, now we get the error-code from it */
3836     pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
3837 	  methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
3838 	  assert(methodID != 0);
3839     errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
3840     rv = jLongToCKULong(errorCode);
3841   }
3842 
3843   /* if we attached this thread to the VM just for callback, we detach it now */
3844   if (wasAttached) {
3845     returnValue = (*jvm)->DetachCurrentThread(jvm);
3846   }
3847 
3848 	return rv ;
3849 }
3850 
3851 /*
3852  * is the function that gets called by PKCS#11 to lock a mutex and calls the Java
3853  * LockMutex function
3854  *
3855  * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
3856  * @param pMutex - the mutex to lock
3857  * @return - should return CKR_OK if the mutex was not locked already
3858  */
callJLockMutex(CK_VOID_PTR pMutex)3859 CK_RV callJLockMutex(CK_VOID_PTR pMutex)
3860 {
3861   JavaVM *jvm;
3862   JNIEnv *env;
3863   jsize actualNumberVMs;
3864   jint returnValue;
3865   jthrowable pkcs11Exception;
3866   jclass pkcs11ExceptionClass;
3867   jlong errorCode;
3868   CK_RV rv = CKR_OK;
3869   int wasAttached = 1;
3870 	jclass jLockMutexClass;
3871 	jclass jInitArgsClass;
3872 	jmethodID methodID;
3873 	jfieldID fieldID;
3874 	jobject jLockMutex;
3875 	jobject jMutex;
3876 
3877 
3878   /* Get the currently running Java VM */
3879   returnValue = JNI_GetCreatedJavaVMs(&jvm, (jsize) 1, &actualNumberVMs);
3880   if ((returnValue != 0) || (actualNumberVMs <= 0)) { return rv ; } /* there is no VM running */
3881 
3882   /* Determine, if current thread is already attached */
3883   returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
3884   if (returnValue == JNI_EDETACHED) {
3885     /* thread detached, so attach it */
3886     wasAttached = 0;
3887     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
3888   } else if (returnValue == JNI_EVERSION) {
3889     /* this version of JNI is not supported, so just try to attach */
3890     /* we assume it was attached to ensure that this thread is not detached
3891      * afterwards even though it should not
3892      */
3893     wasAttached = 1;
3894     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
3895   } else {
3896     /* attached */
3897     wasAttached = 1;
3898   }
3899 
3900 
3901   jLockMutexClass = (*env)->FindClass(env, CLASS_LOCKMUTEX);
3902 	jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
3903 
3904   /* convert the CK mutex to a Java mutex */
3905 	jMutex = ckVoidPtrToJObject(pMutex);
3906 
3907 	/* get the LockMutex object out of the jInitArgs object */
3908 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", CLASS_NAME(CLASS_LOCKMUTEX));
3909 	assert(fieldID != 0);
3910 	jLockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
3911 	assert(jLockMutex != 0);
3912 
3913 	/* call the CK_LOCKMUTEX method of the LockMutex object */
3914 	methodID = (*env)->GetMethodID(env, jLockMutexClass, "CK_LOCKMUTEX", "(Ljava/lang/Object;)V");
3915 	assert(methodID != 0);
3916 	(*env)->CallVoidMethod(env, jLockMutex, methodID, jMutex);
3917 
3918 
3919   /* check, if callback threw an exception */
3920   pkcs11Exception = (*env)->ExceptionOccurred(env);
3921 
3922   if (pkcs11Exception != NULL) {
3923     /* The was an exception thrown, now we get the error-code from it */
3924     pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
3925 	  methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
3926 	  assert(methodID != 0);
3927     errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
3928     rv = jLongToCKULong(errorCode);
3929   }
3930 
3931   /* if we attached this thread to the VM just for callback, we detach it now */
3932   if (wasAttached) {
3933     returnValue = (*jvm)->DetachCurrentThread(jvm);
3934   }
3935 
3936 	return rv ;
3937 }
3938 
3939 /*
3940  * is the function that gets called by PKCS#11 to unlock a mutex and calls the Java
3941  * UnlockMutex function
3942  *
3943  * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields
3944  * @param pMutex - the mutex to unlock
3945  * @return - should return CKR_OK if the mutex was not unlocked already
3946  */
callJUnlockMutex(CK_VOID_PTR pMutex)3947 CK_RV callJUnlockMutex(CK_VOID_PTR pMutex)
3948 {
3949   JavaVM *jvm;
3950   JNIEnv *env;
3951   jsize actualNumberVMs;
3952   jint returnValue;
3953   jthrowable pkcs11Exception;
3954   jclass pkcs11ExceptionClass;
3955   jlong errorCode;
3956   CK_RV rv = CKR_OK;
3957   int wasAttached = 1;
3958 	jclass jUnlockMutexClass;
3959 	jclass jInitArgsClass;
3960 	jmethodID methodID;
3961 	jfieldID fieldID;
3962 	jobject jUnlockMutex;
3963 	jobject jMutex;
3964 
3965 
3966   /* Get the currently running Java VM */
3967   returnValue = JNI_GetCreatedJavaVMs(&jvm, (jsize) 1, &actualNumberVMs);
3968   if ((returnValue != 0) || (actualNumberVMs <= 0)) { return rv ; } /* there is no VM running */
3969 
3970   /* Determine, if current thread is already attached */
3971   returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
3972   if (returnValue == JNI_EDETACHED) {
3973     /* thread detached, so attach it */
3974     wasAttached = 0;
3975     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
3976   } else if (returnValue == JNI_EVERSION) {
3977     /* this version of JNI is not supported, so just try to attach */
3978     /* we assume it was attached to ensure that this thread is not detached
3979      * afterwards even though it should not
3980      */
3981     wasAttached = 1;
3982     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
3983   } else {
3984     /* attached */
3985     wasAttached = 1;
3986   }
3987 
3988 
3989   jUnlockMutexClass = (*env)->FindClass(env, CLASS_UNLOCKMUTEX);
3990 	jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS);
3991 
3992   /* convert the CK-type mutex to a Java mutex */
3993 	jMutex = ckVoidPtrToJObject(pMutex);
3994 
3995 	/* get the UnlockMutex object out of the jInitArgs object */
3996 	fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", CLASS_NAME(CLASS_UNLOCKMUTEX));
3997 	assert(fieldID != 0);
3998 	jUnlockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID);
3999 	assert(jUnlockMutex != 0);
4000 
4001 	/* call the CK_UNLOCKMUTEX method of the UnLockMutex object */
4002 	methodID = (*env)->GetMethodID(env, jUnlockMutexClass, "CK_UNLOCKMUTEX", "(Ljava/lang/Object;)V");
4003 	assert(methodID != 0);
4004 	(*env)->CallVoidMethod(env, jUnlockMutex, methodID, jMutex);
4005 
4006 
4007   /* check, if callback threw an exception */
4008   pkcs11Exception = (*env)->ExceptionOccurred(env);
4009 
4010   if (pkcs11Exception != NULL) {
4011     /* The was an exception thrown, now we get the error-code from it */
4012     pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
4013 	  methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
4014 	  assert(methodID != 0);
4015     errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID);
4016     rv = jLongToCKULong(errorCode);
4017   }
4018 
4019   /* if we attached this thread to the VM just for callback, we detach it now */
4020   if (wasAttached) {
4021     returnValue = (*jvm)->DetachCurrentThread(jvm);
4022   }
4023 
4024 	return rv ;
4025 }
4026 
4027 
4028 /*
4029  * The function handling notify callbacks. It casts the pApplication paramter
4030  * back to a NotifyEncapsulation structure and retrieves the Notify object and
4031  * the application data from it.
4032  *
4033  * @param hSession The session, this callback is comming from.
4034  * @param event The type of event that occurred.
4035  * @param pApplication The application data as passed in upon OpenSession. In
4036                        this wrapper we always pass in a NotifyEncapsulation
4037                        object, which holds necessary information for delegating
4038                        the callback to the Java VM.
4039  * @return
4040  */
notifyCallback(CK_SESSION_HANDLE hSession,CK_NOTIFICATION event,CK_VOID_PTR pApplication)4041 CK_RV notifyCallback(
4042   CK_SESSION_HANDLE hSession,     /* the session's handle */
4043   CK_NOTIFICATION   event,
4044   CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
4045 )
4046 {
4047 	NotifyEncapsulation *notifyEncapsulation;
4048   JavaVM *jvm;
4049   JNIEnv *env;
4050   jsize actualNumberVMs;
4051   jint returnValue;
4052   jlong jSessionHandle;
4053   jlong jEvent;
4054   jclass ckNotifyClass;
4055   jmethodID jmethod;
4056   jthrowable pkcs11Exception;
4057   jclass pkcs11ExceptionClass;
4058   jlong errorCode;
4059   CK_RV rv = CKR_OK;
4060   int wasAttached = 1;
4061 
4062   if (pApplication == NULL) { return rv ; } /* This should not occur in this wrapper. */
4063 
4064   notifyEncapsulation = (NotifyEncapsulation *) pApplication;
4065 
4066   /* Get the currently running Java VM */
4067   returnValue = JNI_GetCreatedJavaVMs(&jvm, (jsize) 1, &actualNumberVMs);
4068   if ((returnValue != 0) || (actualNumberVMs <= 0)) { return rv ; } /* there is no VM running */
4069 
4070   /* Determine, if current thread is already attached */
4071   returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2);
4072   if (returnValue == JNI_EDETACHED) {
4073     /* thread detached, so attach it */
4074     wasAttached = 0;
4075     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
4076   } else if (returnValue == JNI_EVERSION) {
4077     /* this version of JNI is not supported, so just try to attach */
4078     /* we assume it was attached to ensure that this thread is not detached
4079      * afterwards even though it should not
4080      */
4081     wasAttached = 1;
4082     returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL);
4083   } else {
4084     /* attached */
4085     wasAttached = 1;
4086   }
4087 
4088   jSessionHandle = ckULongToJLong(hSession);
4089   jEvent = ckULongToJLong(event);
4090 
4091 	ckNotifyClass = (*env)->FindClass(env, CLASS_NOTIFY);
4092 	assert(ckNotifyClass != 0);
4093 	jmethod = (*env)->GetMethodID(env, ckNotifyClass, "CK_NOTIFY", "(JJLjava/lang/Object;)V");
4094 	assert(jmethod != 0);
4095   (*env)->CallVoidMethod(env, notifyEncapsulation->jNotifyObject, jmethod,
4096                          jSessionHandle, jEvent, notifyEncapsulation->jApplicationData);
4097 
4098   /* check, if callback threw an exception */
4099   pkcs11Exception = (*env)->ExceptionOccurred(env);
4100 
4101   if (pkcs11Exception != NULL) {
4102     /* The was an exception thrown, now we get the error-code from it */
4103     pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
4104 	  jmethod = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J");
4105 	  assert(jmethod != 0);
4106     errorCode = (*env)->CallLongMethod(env, pkcs11Exception, jmethod);
4107     rv = jLongToCKULong(errorCode);
4108   }
4109 
4110   /* if we attached this thread to the VM just for callback, we detach it now */
4111   if (wasAttached) {
4112     returnValue = (*jvm)->DetachCurrentThread(jvm);
4113   }
4114 
4115 	return rv ;
4116 }
4117 
4118 #endif /* NO_CALLBACKS */
4119 
4120 
4121 /* ************************************************************************** */
4122 /* Below there follow the helper functions to support conversions between     */
4123 /* Java and Cryptoki types                                                    */
4124 /* ************************************************************************** */
4125 
4126 /*
4127  * function to convert a PKCS#11 return value into a PKCS#11Exception
4128  *
4129  * This function generates a PKCS#11Exception with the returnValue as the errorcode
4130  * if the returnValue is not CKR_OK. The functin returns 0, if the returnValue is
4131  * CKR_OK. Otherwise, it returns the returnValue as a jLong.
4132  *
4133  * @param env - used to call JNI funktions and to get the Exception class
4134  * @param returnValue - of the PKCS#11 function
4135  */
ckAssertReturnValueOK(JNIEnv * env,CK_RV returnValue,char * callerMethodName)4136 jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue, char* callerMethodName)
4137 {
4138 	jclass jPKCS11ExceptionClass;
4139 	jmethodID jConstructor;
4140 	jthrowable jPKCS11Exception;
4141 	jlong jErrorCode;
4142 
4143 	if (returnValue == CKR_OK) {
4144 		return 0L ;
4145 	} else {
4146 		jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
4147 		assert(jPKCS11ExceptionClass != 0);
4148 		jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass, "<init>", "(J)V");
4149 		assert(jConstructor != 0);
4150 		jErrorCode = ckULongToJLong(returnValue);
4151 		jPKCS11Exception = (jthrowable) (*env)->NewObject(env, jPKCS11ExceptionClass, jConstructor, jErrorCode);
4152 		(*env)->Throw(env, jPKCS11Exception);
4153 		TRACE1(tag_error, callerMethodName, "got %u instead of CKR_OK, going to raise an exception", returnValue);
4154 		return jErrorCode ;
4155 	}
4156 }
4157 
4158 /*
4159  * this function throws an OutOfMemoryError, e.g. in case a malloc did fail to
4160  * allocate memory.
4161  *
4162  * @param env Used to call JNI funktions and to get the Exception class.
4163  */
throwOutOfMemoryError(JNIEnv * env)4164 void throwOutOfMemoryError(JNIEnv *env)
4165 {
4166 	jclass jOutOfMemoryErrorClass;
4167 	jmethodID jConstructor;
4168 	jthrowable jOutOfMemoryError;
4169 
4170 	jOutOfMemoryErrorClass = (*env)->FindClass(env, CLASS_OUT_OF_MEMORY_ERROR);
4171 	assert(jOutOfMemoryErrorClass != 0);
4172 
4173 	jConstructor = (*env)->GetMethodID(env, jOutOfMemoryErrorClass, "<init>", "()V");
4174 	assert(jConstructor != 0);
4175 	jOutOfMemoryError = (jthrowable) (*env)->NewObject(env, jOutOfMemoryErrorClass, jConstructor);
4176 	(*env)->Throw(env, jOutOfMemoryError);
4177 }
4178 
4179 /*
4180  * this function simply throws a FileNotFoundException
4181  *
4182  * @param env Used to call JNI funktions and to get the Exception class.
4183  * @param jmessage The message string of the Exception object.
4184  */
throwFileNotFoundException(JNIEnv * env,jstring jmessage)4185 void throwFileNotFoundException(JNIEnv *env, jstring jmessage)
4186 {
4187 	jclass jFileNotFoundExceptionClass;
4188 	jmethodID jConstructor;
4189 	jthrowable jFileNotFoundException;
4190 
4191 	jFileNotFoundExceptionClass = (*env)->FindClass(env, CLASS_FILE_NOT_FOUND_EXCEPTION);
4192 	assert(jFileNotFoundExceptionClass != 0);
4193 
4194 	jConstructor = (*env)->GetMethodID(env, jFileNotFoundExceptionClass, "<init>", "(Ljava/lang/String;)V");
4195 	assert(jConstructor != 0);
4196 	jFileNotFoundException = (jthrowable) (*env)->NewObject(env, jFileNotFoundExceptionClass, jConstructor, jmessage);
4197 	(*env)->Throw(env, jFileNotFoundException);
4198 }
4199 
4200 /*
4201  * this function simply throws an IOException
4202  *
4203  * @param env Used to call JNI funktions and to get the Exception class.
4204  * @param message The message string of the Exception object.
4205  */
throwIOException(JNIEnv * env,const char * message)4206 void throwIOException(JNIEnv *env, const char * message)
4207 {
4208 	jclass jIOExceptionClass;
4209 
4210 	jIOExceptionClass = (*env)->FindClass(env, CLASS_IO_EXCEPTION);
4211 	assert(jIOExceptionClass != 0);
4212 
4213   (*env)->ThrowNew(env, jIOExceptionClass, message);
4214 }
4215 
4216 /*
4217  * this function simply throws an IOException and takes a unicode
4218  * messge.
4219  *
4220  * @param env Used to call JNI funktions and to get the Exception class.
4221  * @param message The unicode message string of the Exception object.
4222  */
throwIOExceptionUnicodeMessage(JNIEnv * env,const unsigned short * message)4223 void throwIOExceptionUnicodeMessage(JNIEnv *env, const unsigned short *message)
4224 {
4225 	jclass jIOExceptionClass;
4226 	jmethodID jConstructor;
4227 	jthrowable jIOException;
4228   jstring jmessage;
4229   jsize length;
4230   short *currentCharacter;
4231 
4232 	jIOExceptionClass = (*env)->FindClass(env, CLASS_IO_EXCEPTION);
4233 	assert(jIOExceptionClass != 0);
4234 
4235   length = 0;
4236   if (message != NULL) {
4237     currentCharacter = (short *) message;
4238     while (*(currentCharacter++) != 0) length++;
4239   }
4240 
4241   jmessage = (*env)->NewString(env, message, length);
4242 
4243 	jConstructor = (*env)->GetMethodID(env, jIOExceptionClass, "<init>", "(Ljava/lang/String;)V");
4244 	assert(jConstructor != 0);
4245 	jIOException = (jthrowable) (*env)->NewObject(env, jIOExceptionClass, jConstructor, jmessage);
4246 	(*env)->Throw(env, jIOException);
4247 }
4248 
4249 /*
4250  * This function simply throws a PKCS#11RuntimeException with the given
4251  * string as its message. If the message is NULL, the exception is created
4252  * using the default constructor.
4253  *
4254  * @param env Used to call JNI funktions and to get the Exception class.
4255  * @param jmessage The message string of the Exception object.
4256  */
throwPKCS11RuntimeException(JNIEnv * env,jstring jmessage)4257 void throwPKCS11RuntimeException(JNIEnv *env, jstring jmessage)
4258 {
4259 	jclass jPKCS11RuntimeExceptionClass;
4260 	jmethodID jConstructor;
4261 	jthrowable jPKCS11RuntimeException;
4262 
4263 	jPKCS11RuntimeExceptionClass = (*env)->FindClass(env, CLASS_PKCS11RUNTIMEEXCEPTION);
4264 	assert(jPKCS11RuntimeExceptionClass != 0);
4265 
4266   if (jmessage == NULL) {
4267 	  jConstructor = (*env)->GetMethodID(env, jPKCS11RuntimeExceptionClass, "<init>", "()V");
4268 	  assert(jConstructor != 0);
4269 	  jPKCS11RuntimeException = (jthrowable) (*env)->NewObject(env, jPKCS11RuntimeExceptionClass, jConstructor);
4270 	  (*env)->Throw(env, jPKCS11RuntimeException);
4271   } else {
4272 	  jConstructor = (*env)->GetMethodID(env, jPKCS11RuntimeExceptionClass, "<init>", "(Ljava/lang/String;)V");
4273 	  assert(jConstructor != 0);
4274 	  jPKCS11RuntimeException = (jthrowable) (*env)->NewObject(env, jPKCS11RuntimeExceptionClass, jConstructor, jmessage);
4275 	  (*env)->Throw(env, jPKCS11RuntimeException);
4276   }
4277 }
4278 
4279 /*
4280  * This function simply throws a PKCS#11RuntimeException. The message says that
4281  * the object is not connected to the module.
4282  *
4283  * @param env Used to call JNI funktions and to get the Exception class.
4284  */
throwDisconnectedRuntimeException(JNIEnv * env)4285 void throwDisconnectedRuntimeException(JNIEnv *env)
4286 {
4287 	jstring jExceptionMessage = (*env)->NewStringUTF(env, "This object is not connected to a module.");
4288 
4289   throwPKCS11RuntimeException(env, jExceptionMessage);
4290 }
4291 
4292 /*
4293  * the following functions convert Java arrays to PKCS#11 array pointers and
4294  * their array length and vice versa
4295  *
4296  * void j<Type>ArrayToCK<Type>Array(JNIEnv *env,
4297  *                                  const j<Type>Array jArray,
4298  *                                  CK_<Type>_PTR *ckpArray,
4299  *                                  CK_ULONG_PTR ckLength);
4300  *
4301  * j<Type>Array ck<Type>ArrayToJ<Type>Array(JNIEnv *env,
4302  *                                          const CK_<Type>_PTR ckpArray,
4303  *                                          CK_ULONG ckLength);
4304  *
4305  * PKCS#11 arrays consist always of a pointer to the beginning of the array and
4306  * the array length whereas Java arrays carry their array length.
4307  *
4308  * The Functions to convert a Java array to a PKCS#11 array are void functions.
4309  * Their arguments are the Java array object to convert, the reference to the
4310  * array pointer, where the new PKCS#11 array should be stored and the reference
4311  * to the array length where the PKCS#11 array length should be stored. These two
4312  * references must not be NULL_PTR.
4313  *
4314  * The functions first obtain the array length of the Java array and then allocate
4315  * the memory for the PKCS#11 array and set the array length. Then each element
4316  * gets converted depending on their type. After use the allocated memory of the
4317  * PKCS#11 array has to be explicitly freed.
4318  *
4319  * The Functions to convert a PKCS#11 array to a Java array get the PKCS#11 array
4320  * pointer and the array length and they return the new Java array object. The
4321  * Java array does not need to get freed after use.
4322  */
4323 
4324 /*
4325  * converts a jbooleanArray to a CK_BBOOL array. The allocated memory has to be freed after use!
4326  *
4327  * @param env - used to call JNI funktions to get the array informtaion
4328  * @param jArray - the Java array to convert
4329  * @param ckpArray - the reference, where the pointer to the new CK_BBOOL array will be stored
4330  * @param ckpLength - the reference, where the array length will be stored
4331  * @return 0 is successful
4332  */
jBooleanArrayToCKBBoolArray(JNIEnv * env,const jbooleanArray jArray,CK_BBOOL ** ckpArray,CK_ULONG_PTR ckpLength)4333 int jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckpLength)
4334 {
4335 	jboolean* jpTemp;
4336 	CK_ULONG i;
4337 
4338 	if(jArray == NULL) {
4339 		*ckpArray = NULL_PTR;
4340 		*ckpLength = 0L;
4341 		return 0;
4342 	}
4343 	*ckpLength = (*env)->GetArrayLength(env, jArray);
4344 	jpTemp = (jboolean*) malloc((*ckpLength) * sizeof(jboolean));
4345   if (jpTemp == NULL && (*ckpLength)!=0) { *ckpArray = NULL_PTR; throwOutOfMemoryError(env); return 1; }
4346 	(*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
4347 	*ckpArray = (CK_BBOOL*) malloc ((*ckpLength) * sizeof(CK_BBOOL));
4348   if (*ckpArray == NULL && (*ckpLength)!=0) { free(jpTemp); throwOutOfMemoryError(env); return 2; }
4349 	for (i=0; i<(*ckpLength); i++) {
4350 		(*ckpArray)[i] = jBooleanToCKBBool(jpTemp[i]);
4351 	}
4352 	free(jpTemp);
4353   return 0;
4354 }
4355 
4356 /*
4357  * converts a jbyteArray to a CK_BYTE array. The allocated memory has to be freed after use!
4358  *
4359  * @param env - used to call JNI funktions to get the array informtaion
4360  * @param jArray - the Java array to convert
4361  * @param ckpArray - the reference, where the pointer to the new CK_BYTE array will be stored
4362  * @param ckpLength - the reference, where the array length will be stored
4363  * @return 0 is successful
4364  */
jByteArrayToCKByteArray(JNIEnv * env,const jbyteArray jArray,CK_BYTE_PTR * ckpArray,CK_ULONG_PTR ckpLength)4365 int jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
4366 {
4367 	jbyte* jpTemp;
4368 	CK_ULONG i;
4369 
4370 	if(jArray == NULL) {
4371 		*ckpArray = NULL_PTR;
4372 		*ckpLength = 0L;
4373 		return 0;
4374 	}
4375 	*ckpLength = (*env)->GetArrayLength(env, jArray);
4376 	jpTemp = (jbyte*) malloc((*ckpLength) * sizeof(jbyte));
4377   if (jpTemp == NULL && (*ckpLength)!=0) { *ckpArray = NULL_PTR; throwOutOfMemoryError(env); return 1; }
4378 	(*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
4379 
4380   /* if CK_BYTE is the same size as jbyte, we save an additional copy */
4381   if (sizeof(CK_BYTE) == sizeof(jbyte)) {
4382     *ckpArray = (CK_BYTE_PTR) jpTemp;
4383   } else {
4384 	  *ckpArray = (CK_BYTE_PTR) malloc ((*ckpLength) * sizeof(CK_BYTE));
4385     if (*ckpArray == NULL && (*ckpLength)!=0) { free(jpTemp); throwOutOfMemoryError(env); return 2; }
4386 	  for (i=0; i<(*ckpLength); i++) {
4387 		  (*ckpArray)[i] = jByteToCKByte(jpTemp[i]);
4388 	  }
4389 	  free(jpTemp);
4390   }
4391   return 0;
4392 }
4393 
4394 /*
4395  * converts a jlongArray to a CK_ULONG array. The allocated memory has to be freed after use!
4396  *
4397  * @param env - used to call JNI funktions to get the array informtaion
4398  * @param jArray - the Java array to convert
4399  * @param ckpArray - the reference, where the pointer to the new CK_ULONG array will be stored
4400  * @param ckpLength - the reference, where the array length will be stored
4401  * @return 0 is successful
4402  */
jLongArrayToCKULongArray(JNIEnv * env,const jlongArray jArray,CK_ULONG_PTR * ckpArray,CK_ULONG_PTR ckpLength)4403 int jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckpLength)
4404 {
4405 	jlong* jpTemp;
4406 	CK_ULONG i;
4407 
4408 	if(jArray == NULL) {
4409 		*ckpArray = NULL_PTR;
4410 		*ckpLength = 0L;
4411 		return 0;
4412 	}
4413 	*ckpLength = (*env)->GetArrayLength(env, jArray);
4414 	jpTemp = (jlong*) malloc((*ckpLength) * sizeof(jlong));
4415   if (jpTemp == NULL && (*ckpLength)!=0) { *ckpArray = NULL_PTR; throwOutOfMemoryError(env); return 1; }
4416 	(*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
4417 	*ckpArray = (CK_ULONG_PTR) malloc (*ckpLength * sizeof(CK_ULONG));
4418   if (*ckpArray == NULL && (*ckpLength)!=0) { free(jpTemp); throwOutOfMemoryError(env); return 2; }
4419 	for (i=0; i<(*ckpLength); i++) {
4420 		(*ckpArray)[i] = jLongToCKULong(jpTemp[i]);
4421 	}
4422 	free(jpTemp);
4423 	return 0;
4424 }
4425 
4426 /*
4427  * converts a jcharArray to a CK_CHAR array. The allocated memory has to be freed after use!
4428  *
4429  * @param env - used to call JNI funktions to get the array informtaion
4430  * @param jArray - the Java array to convert
4431  * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
4432  * @param ckpLength - the reference, where the array length will be stored
4433  * @return 0 is successful
4434  */
jCharArrayToCKCharArray(JNIEnv * env,const jcharArray jArray,CK_CHAR_PTR * ckpArray,CK_ULONG_PTR ckpLength)4435 int jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
4436 {
4437 	jchar* jpTemp;
4438 	CK_ULONG i;
4439 
4440 	if(jArray == NULL) {
4441 		*ckpArray = NULL_PTR;
4442 		*ckpLength = 0L;
4443 		return 0;
4444 	}
4445 	*ckpLength = (*env)->GetArrayLength(env, jArray);
4446 	jpTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
4447   if (jpTemp == NULL && (*ckpLength)!=0) { *ckpArray = NULL_PTR; throwOutOfMemoryError(env); return 1; }
4448 	(*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
4449 	*ckpArray = (CK_CHAR_PTR) malloc (*ckpLength * sizeof(CK_CHAR));
4450   if (*ckpArray == NULL && (*ckpLength)!=0) { free(jpTemp); throwOutOfMemoryError(env); return 2; }
4451 	for (i=0; i<(*ckpLength); i++) {
4452 		(*ckpArray)[i] = jCharToCKChar(jpTemp[i]);
4453 	}
4454 	free(jpTemp);
4455   return 0;
4456 }
4457 
4458 /*
4459  * converts a jcharArray to a CK_UTF8CHAR array. The allocated memory has to be freed after use!
4460  *
4461  * @param env - used to call JNI funktions to get the array informtaion
4462  * @param jArray - the Java array to convert
4463  * @param ckpArray - the reference, where the pointer to the new CK_UTF8CHAR array will be stored
4464  * @param ckpLength - the reference, where the array length will be stored
4465  * @return 0 is successful
4466  */
jCharArrayToCKUTF8CharArray(JNIEnv * env,const jcharArray jArray,CK_UTF8CHAR_PTR * ckpArray,CK_ULONG_PTR ckpLength)4467 int jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
4468 {
4469 	jchar* jpTemp;
4470 	CK_ULONG i;
4471 
4472 	if(jArray == NULL) {
4473 		*ckpArray = NULL_PTR;
4474 		*ckpLength = 0L;
4475 		return 0;
4476 	}
4477 	*ckpLength = (*env)->GetArrayLength(env, jArray);
4478 	jpTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
4479   if (jpTemp == NULL && (*ckpLength)!=0) { *ckpArray = NULL_PTR; throwOutOfMemoryError(env); return 1; }
4480 	(*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
4481 	*ckpArray = (CK_UTF8CHAR_PTR) malloc ((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
4482   if (*ckpArray == NULL && (*ckpLength)!=0) { free(jpTemp); throwOutOfMemoryError(env); return 2; }
4483 	for (i=0; i<(*ckpLength); i++) {
4484 		(*ckpArray)[i] = jCharToCKUTF8Char(jpTemp[i]);
4485 	}
4486 	(*ckpArray)[*ckpLength] = NULL_PTR;
4487 	free(jpTemp);
4488   return 0;
4489 }
4490 
4491 /*
4492  * converts a jstring to a CK_CHAR array. The allocated memory has to be freed after use!
4493  *
4494  * @param env - used to call JNI funktions to get the array informtaion
4495  * @param jArray - the Java array to convert
4496  * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
4497  * @param ckpLength - the reference, where the array length will be stored
4498  * @return 0 is successful
4499  */
jStringToCKUTF8CharArray(JNIEnv * env,const jstring jArray,CK_UTF8CHAR_PTR * ckpArray,CK_ULONG_PTR ckpLength)4500 int jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
4501 {
4502 	const char* pCharArray;
4503 	jboolean isCopy;
4504 
4505 	if(jArray == NULL) {
4506 		*ckpArray = NULL_PTR;
4507 		*ckpLength = 0L;
4508 		return 0;
4509 	}
4510 
4511 	pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
4512 	*ckpLength = strlen(pCharArray);
4513 	*ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
4514   if (*ckpArray == NULL && (*ckpLength + 1)!=0) { throwOutOfMemoryError(env); return 1; }
4515 	strcpy((char *) *ckpArray, pCharArray);
4516 	(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
4517   return 0;
4518 }
4519 
4520 /*
4521  * converts a jobjectArray with Java Attributes to a CK_ATTRIBUTE array. The allocated memory
4522  * has to be freed after use!
4523  *
4524  * @param env - used to call JNI funktions to get the array informtaion
4525  * @param jArray - the Java Attribute array (template) to convert
4526  * @param ckpArray - the reference, where the pointer to the new CK_ATTRIBUTE array will be
4527  *                   stored
4528  * @param ckpLength - the reference, where the array length will be stored
4529  * @return 0 is successful
4530  */
jAttributeArrayToCKAttributeArray(JNIEnv * env,jobjectArray jArray,CK_ATTRIBUTE_PTR * ckpArray,CK_ULONG_PTR ckpLength)4531 int jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
4532 {
4533 	CK_ULONG i;
4534 	jlong jLength;
4535 	jobject jAttribute;
4536 
4537 	TRACE0(tag_call, __FUNCTION__,"entering");
4538 	if (jArray == NULL) {
4539 		*ckpArray = NULL_PTR;
4540 		*ckpLength = 0L;
4541 	  TRACE0(tag_call, __FUNCTION__, "exiting ");
4542 		return 0;
4543 	}
4544 	jLength = (*env)->GetArrayLength(env, jArray);
4545 	*ckpLength = jLongToCKULong(jLength);
4546 	*ckpArray = (CK_ATTRIBUTE_PTR) malloc(*ckpLength * sizeof(CK_ATTRIBUTE));
4547   if (*ckpArray == NULL && (*ckpLength)!=0) { throwOutOfMemoryError(env); return 1; }
4548 	TRACE1(tag_debug, __FUNCTION__,"converting %d attributes", jLength);
4549 	for (i=0; i<(*ckpLength); i++) {
4550 		TRACE1(tag_debug, __FUNCTION__,", getting %d. attribute", i);
4551 		jAttribute = (*env)->GetObjectArrayElement(env, jArray, i);
4552 		TRACE2(tag_debug, __FUNCTION__,", jAttribute = %d, converting %d. attribute", jAttribute, i);
4553 		(*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute);
4554 	}
4555 	TRACE0(tag_debug, __FUNCTION__,"Converted template with following types: ");
4556 	for (i=0; i<(*ckpLength); i++) {
4557 		TRACE1(tag_debug, __FUNCTION__,"0x%X", (*ckpArray)[i].type);
4558 	}
4559   TRACE0(tag_call, __FUNCTION__, "exiting ");
4560   return 0;
4561 }
4562 
4563 /*
4564  * converts a jobjectArray to a CK_VOID_PTR array. The allocated memory has to be freed after
4565  * use!
4566  * NOTE: this function does not work and is not used yet
4567  *
4568  * @param env - used to call JNI funktions to get the array informtaion
4569  * @param jArray - the Java object array to convert
4570  * @param ckpArray - the reference, where the pointer to the new CK_VOID_PTR array will be stored
4571  * @param ckpLength - the reference, where the array length will be stored
4572  * @return 0 is successful
4573  */
4574 /*
4575 int jObjectArrayToCKVoidPtrArray(JNIEnv *env, const jobjectArray jArray, CK_VOID_PTR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
4576 {
4577 	jobject jTemp;
4578 	CK_ULONG i;
4579 
4580 	if(jArray == NULL) {
4581 		*ckpArray = NULL_PTR;
4582 		*ckpLength = 0L;
4583 		return 0;
4584 	}
4585 	*ckpLength = (*env)->GetArrayLength(env, jArray);
4586 	*ckpArray = (CK_VOID_PTR_PTR) malloc (*ckpLength * sizeof(CK_VOID_PTR));
4587   if (*ckpArray == NULL && (*ckpLength)!=0) { throwOutOfMemoryError(env); return 1; }
4588 	for (i=0; i<(*ckpLength); i++) {
4589 		jTemp = (*env)->GetObjectArrayElement(env, jArray, i);
4590 		(*ckpArray)[i] = jObjectToCKVoidPtr(jTemp);
4591 	}
4592 	free(jTemp);
4593   return 0;
4594 }
4595 */
4596 
4597 /*
4598  * converts a CK_BYTE array and its length to a jbyteArray.
4599  *
4600  * @param env - used to call JNI funktions to create the new Java array
4601  * @param ckpArray - the pointer to the CK_BYTE array to convert
4602  * @param ckpLength - the length of the array to convert
4603  * @return - the new Java byte array
4604  */
ckByteArrayToJByteArray(JNIEnv * env,const CK_BYTE_PTR ckpArray,CK_ULONG ckLength)4605 jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength)
4606 {
4607 	CK_ULONG i;
4608 	jbyte* jpTemp;
4609 	jbyteArray jArray;
4610 
4611   /* if CK_BYTE is the same size as jbyte, we save an additional copy */
4612   if (sizeof(CK_BYTE) == sizeof(jbyte)) {
4613     jpTemp = (jbyte*) ckpArray;
4614   } else {
4615 	  jpTemp = (jbyte*) malloc((ckLength) * sizeof(jbyte));
4616     if (jpTemp == NULL && ckLength!=0) { throwOutOfMemoryError(env); return NULL; }
4617 	  for (i=0; i<ckLength; i++) {
4618 		  jpTemp[i] = ckByteToJByte(ckpArray[i]);
4619 	  }
4620   }
4621 
4622 	jArray = (*env)->NewByteArray(env, ckULongToJSize(ckLength));
4623 	(*env)->SetByteArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
4624 
4625   if (sizeof(CK_BYTE) != sizeof(jbyte)) {
4626     free(jpTemp);
4627   }
4628 
4629 	return jArray ;
4630 }
4631 
4632 /*
4633  * converts a CK_ULONG array and its length to a jlongArray.
4634  *
4635  * @param env - used to call JNI funktions to create the new Java array
4636  * @param ckpArray - the pointer to the CK_ULONG array to convert
4637  * @param ckpLength - the length of the array to convert
4638  * @return - the new Java long array
4639  */
ckULongArrayToJLongArray(JNIEnv * env,const CK_ULONG_PTR ckpArray,CK_ULONG ckLength)4640 jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength)
4641 {
4642 	CK_ULONG i;
4643 	jlong* jpTemp;
4644 	jlongArray jArray;
4645 
4646 	jpTemp = (jlong*) malloc((ckLength) * sizeof(jlong));
4647   if (jpTemp == NULL && ckLength!=0) { throwOutOfMemoryError(env); return NULL; }
4648 	for (i=0; i<ckLength; i++) {
4649 		jpTemp[i] = ckLongToJLong(ckpArray[i]);
4650 	}
4651 	jArray = (*env)->NewLongArray(env, ckULongToJSize(ckLength));
4652 	(*env)->SetLongArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
4653 	free(jpTemp);
4654 
4655 	return jArray ;
4656 }
4657 
4658 /*
4659  * converts a CK_CHAR array and its length to a jcharArray.
4660  *
4661  * @param env - used to call JNI funktions to create the new Java array
4662  * @param ckpArray - the pointer to the CK_CHAR array to convert
4663  * @param ckpLength - the length of the array to convert
4664  * @return - the new Java char array
4665  */
ckCharArrayToJCharArray(JNIEnv * env,const CK_CHAR_PTR ckpArray,CK_ULONG ckLength)4666 jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG ckLength)
4667 {
4668 	CK_ULONG i;
4669 	jchar* jpTemp;
4670 	jcharArray jArray;
4671 
4672 	jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
4673   if (jpTemp == NULL && ckLength!=0) { throwOutOfMemoryError(env); return NULL; }
4674 	for (i=0; i<ckLength; i++) {
4675 		jpTemp[i] = ckCharToJChar(ckpArray[i]);
4676 	}
4677 	jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
4678 	(*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
4679 	free(jpTemp);
4680 
4681 	return jArray ;
4682 }
4683 
4684 /*
4685  * converts a CK_UTF8CHAR array and its length to a jcharArray.
4686  *
4687  * @param env - used to call JNI funktions to create the new Java array
4688  * @param ckpArray - the pointer to the CK_UTF8CHAR array to convert
4689  * @param ckpLength - the length of the array to convert
4690  * @return - the new Java char array
4691  */
ckUTF8CharArrayToJCharArray(JNIEnv * env,const CK_UTF8CHAR_PTR ckpArray,CK_ULONG ckLength)4692 jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength)
4693 {
4694 	CK_ULONG i;
4695 	jchar* jpTemp;
4696 	jcharArray jArray;
4697 
4698 	jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
4699   if (jpTemp == NULL && ckLength!=0) { throwOutOfMemoryError(env); return NULL; }
4700 	for (i=0; i<ckLength; i++) {
4701 		jpTemp[i] = ckUTF8CharToJChar(ckpArray[i]);
4702 	}
4703 	jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
4704 	(*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
4705 	free(jpTemp);
4706 
4707 	return jArray ;
4708 }
4709 
ckAttributeArrayToJAttributeArray(JNIEnv * env,const CK_ATTRIBUTE_PTR ckpArray,CK_ULONG ckLength)4710 jobject ckAttributeArrayToJAttributeArray(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpArray, CK_ULONG ckLength)
4711 {
4712 	jclass jAttributeClass;
4713 	jobjectArray jAttributeArray;
4714 	CK_ULONG i;
4715 	CK_ULONG length;
4716 	jobject jAttribute;
4717 	jsize jlength;
4718 
4719 	length = ckLength/sizeof(CK_ATTRIBUTE);
4720 	jlength = ckULongToJSize(length);
4721 	jAttributeClass = (*env)->FindClass(env, CLASS_ATTRIBUTE);
4722 	assert(jAttributeClass != 0);
4723 	/* allocate array, all elements null per default */
4724 	jAttributeArray = (*env)->NewObjectArray(env, jlength, jAttributeClass, NULL);
4725 	assert(jAttributeArray != 0);
4726 
4727 	for (i=0; i<length; i++) {
4728 		jAttribute = ckAttributePtrToJAttribute(env, &(ckpArray[i]));
4729 		(*env)->SetObjectArrayElement(env, jAttributeArray, i, jAttribute);
4730 	}
4731 
4732 	return jAttributeArray ;
4733 }
4734 
4735 /*
4736  * the following functions convert Java objects to PKCS#11 pointers and the
4737  * length in bytes and vice versa
4738  *
4739  * CK_<Type>_PTR j<Object>ToCK<Type>Ptr(JNIEnv *env, jobject jObject);
4740  *
4741  * jobject ck<Type>PtrToJ<Object>(JNIEnv *env, const CK_<Type>_PTR ckpValue);
4742  *
4743  * The functions that convert a Java object to a PKCS#11 pointer first allocate
4744  * the memory for the PKCS#11 pointer. Then they set each element corresponding
4745  * to the fields in the Java object to convert. After use the allocated memory of
4746  * the PKCS#11 pointer has to be explicitly freed.
4747  *
4748  * The functions to convert a PKCS#11 pointer to a Java object create a new Java
4749  * object first and than they set all fields in the object depending on the values
4750  * of the type or structure where the PKCS#11 pointer points to.
4751  */
4752 
4753 /*
4754  * converts a CK_BBOOL pointer to a Java boolean Object.
4755  *
4756  * @param env - used to call JNI funktions to create the new Java object
4757  * @param ckpValue - the pointer to the CK_BBOOL value
4758  * @return - the new Java boolean object with the boolean value
4759  */
ckBBoolPtrToJBooleanObject(JNIEnv * env,const CK_BBOOL * ckpValue)4760 jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL *ckpValue)
4761 {
4762 	jclass jValueObjectClass;
4763 	jmethodID jConstructor;
4764 	jobject jValueObject;
4765 	jboolean jValue;
4766 
4767 	jValueObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
4768 	assert(jValueObjectClass != 0);
4769 	jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(Z)V");
4770 	assert(jConstructor != 0);
4771 	jValue = ckBBoolToJBoolean(*ckpValue);
4772 	jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
4773 	assert(jValueObject != 0);
4774 
4775 	return jValueObject ;
4776 }
4777 
4778 /*
4779  * converts a CK_ULONG pointer to a Java long Object.
4780  *
4781  * @param env - used to call JNI funktions to create the new Java object
4782  * @param ckpValue - the pointer to the CK_ULONG value
4783  * @return - the new Java long object with the long value
4784  */
ckULongPtrToJLongObject(JNIEnv * env,const CK_ULONG_PTR ckpValue)4785 jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue)
4786 {
4787 	jclass jValueObjectClass;
4788 	jmethodID jConstructor;
4789 	jobject jValueObject;
4790 	jlong jValue;
4791 
4792 	jValueObjectClass = (*env)->FindClass(env, "java/lang/Long");
4793 	assert(jValueObjectClass != 0);
4794 	jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V");
4795 	assert(jConstructor != 0);
4796 	jValue = ckULongToJLong(*ckpValue);
4797 	jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
4798 	assert(jValueObject != 0);
4799 
4800 	return jValueObject ;
4801 }
4802 
4803 /*
4804  * converts a pointer to a CK_DATE structure into a Java CK_DATE Object.
4805  *
4806  * @param env - used to call JNI funktions to create the new Java object
4807  * @param ckpValue - the pointer to the CK_DATE structure
4808  * @return - the new Java CK_DATE object
4809  */
ckDatePtrToJDateObject(JNIEnv * env,const CK_DATE * ckpValue)4810 jobject ckDatePtrToJDateObject(JNIEnv *env, const CK_DATE *ckpValue)
4811 {
4812 	jclass jValueObjectClass;
4813 	jobject jValueObject;
4814 	jcharArray jTempCharArray;
4815 	jfieldID fieldID;
4816 
4817 	/* load CK_DATE class */
4818 	jValueObjectClass = (*env)->FindClass(env, CLASS_DATE);
4819 	assert(jValueObjectClass != 0);
4820 	/* create new CK_DATE jObject */
4821 	jValueObject = (*env)->AllocObject(env, jValueObjectClass);
4822 	assert(jValueObject != 0);
4823 
4824 	/* set year */
4825 	fieldID = (*env)->GetFieldID(env, jValueObjectClass, "year", "[C");
4826 	assert(fieldID != 0);
4827 	jTempCharArray = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpValue->year), 4);
4828 	(*env)->SetObjectField(env, jValueObject, fieldID, jTempCharArray);
4829 
4830 	/* set month */
4831 	fieldID = (*env)->GetFieldID(env, jValueObjectClass, "month", "[C");
4832 	assert(fieldID != 0);
4833 	jTempCharArray = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpValue->month), 2);
4834 	(*env)->SetObjectField(env, jValueObject, fieldID, jTempCharArray);
4835 
4836 	/* set day */
4837 	fieldID = (*env)->GetFieldID(env, jValueObjectClass, "day", "[C");
4838 	assert(fieldID != 0);
4839 	jTempCharArray = ckCharArrayToJCharArray(env, (CK_CHAR_PTR)(ckpValue->day), 2);
4840 	(*env)->SetObjectField(env, jValueObject, fieldID, jTempCharArray);
4841 
4842 	return jValueObject ;
4843 }
4844 
4845 /*
4846  * converts a pointer to a CK_VERSION structure into a Java CK_VERSION Object.
4847  *
4848  * @param env - used to call JNI funktions to create the new Java object
4849  * @param ckpVersion - the pointer to the CK_VERSION structure
4850  * @return - the new Java CK_VERSION object
4851  */
ckVersionPtrToJVersion(JNIEnv * env,const CK_VERSION_PTR ckpVersion)4852 jobject ckVersionPtrToJVersion(JNIEnv *env, const CK_VERSION_PTR ckpVersion)
4853 {
4854 	jclass jVersionClass;
4855 	jobject jVersionObject;
4856 	jfieldID jFieldID;
4857 
4858 	/* load CK_VERSION class */
4859 	jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
4860 	assert(jVersionClass != 0);
4861 	/* create new CK_VERSION object */
4862 	jVersionObject = (*env)->AllocObject(env, jVersionClass);
4863 	assert(jVersionObject != 0);
4864 	/* set major */
4865 	jFieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
4866 	assert(jFieldID != 0);
4867 	(*env)->SetByteField(env, jVersionObject, jFieldID, (jbyte) (ckpVersion->major));
4868 	/* set minor */
4869 	jFieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
4870 	assert(jFieldID != 0);
4871 	(*env)->SetByteField(env, jVersionObject, jFieldID, (jbyte) (ckpVersion->minor));
4872 
4873 	return jVersionObject ;
4874 }
4875 
4876 /*
4877  * converts a pointer to a CK_INFO structure into a Java CK_INFO Object.
4878  *
4879  * @param env - used to call JNI funktions to create the new Java object
4880  * @param ckpInfo - the pointer to the CK_INFO structure
4881  * @return - the new Java CK_INFO object
4882  */
ckInfoPtrToJInfo(JNIEnv * env,const CK_INFO_PTR ckpInfo)4883 jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo)
4884 {
4885 	jclass jInfoClass;
4886 	jobject jInfoObject;
4887 	jcharArray jTempCharArray;
4888 	jfieldID jFieldID;
4889 	jobject jTempVersion;
4890 
4891 	/* load CK_INFO class */
4892 	jInfoClass = (*env)->FindClass(env, CLASS_INFO);
4893 	assert(jInfoClass != 0);
4894 	/* create new CK_INFO object */
4895 	jInfoObject = (*env)->AllocObject(env, jInfoClass);
4896 	assert(jInfoObject != 0);
4897 
4898 	/* set cryptokiVersion */
4899 	jFieldID = (*env)->GetFieldID(env, jInfoClass, "cryptokiVersion", CLASS_NAME(CLASS_VERSION));
4900 	assert(jFieldID != 0);
4901 	jTempVersion = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion));
4902 	(*env)->SetObjectField(env, jInfoObject, jFieldID, jTempVersion);
4903 
4904 	/* set manufacturerID */
4905 	jFieldID = (*env)->GetFieldID(env, jInfoClass, "manufacturerID", "[C");
4906 	assert(jFieldID != 0);
4907 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32);
4908 	(*env)->SetObjectField(env, jInfoObject, jFieldID, jTempCharArray);
4909 
4910 	/* set flags */
4911 	jFieldID = (*env)->GetFieldID(env, jInfoClass, "flags", "J");
4912 	assert(jFieldID != 0);
4913 	(*env)->SetLongField(env, jInfoObject, jFieldID, ckULongToJLong(ckpInfo->flags));
4914 
4915 	/* set libraryDescription */
4916 	jFieldID = (*env)->GetFieldID(env, jInfoClass, "libraryDescription", "[C");
4917 	assert(jFieldID != 0);
4918 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]) ,32);
4919 	(*env)->SetObjectField(env, jInfoObject, jFieldID, jTempCharArray);
4920 
4921 	/* set libraryVersion */
4922 	jFieldID = (*env)->GetFieldID(env, jInfoClass, "libraryVersion", CLASS_NAME(CLASS_VERSION));
4923 	assert(jFieldID != 0);
4924 	jTempVersion = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion));
4925 	(*env)->SetObjectField(env, jInfoObject, jFieldID, jTempVersion);
4926 
4927 	return jInfoObject ;
4928 }
4929 
4930 /*
4931  * converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO Object.
4932  *
4933  * @param env - used to call JNI funktions to create the new Java object
4934  * @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure
4935  * @return - the new Java CK_SLOT_INFO object
4936  */
ckSlotInfoPtrToJSlotInfo(JNIEnv * env,const CK_SLOT_INFO_PTR ckpSlotInfo)4937 jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo)
4938 {
4939 	jclass jSlotInfoClass;
4940 	jobject jSlotInfoObject;
4941 	jcharArray jTempCharArray;
4942 	jfieldID jFieldID;
4943 	jobject jTempVersion;
4944 
4945 	/* load CK_SLOT_INFO class */
4946 	jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO);
4947 	assert(jSlotInfoClass != 0);
4948 	/* create new CK_SLOT_INFO object */
4949 	jSlotInfoObject = (*env)->AllocObject(env, jSlotInfoClass);
4950 	assert(jSlotInfoObject != 0);
4951 
4952 
4953 	/* set slotDescription */
4954 	jFieldID = (*env)->GetFieldID(env, jSlotInfoClass, "slotDescription", "[C");
4955 	assert(jFieldID != 0);
4956 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]) ,64);
4957 	(*env)->SetObjectField(env, jSlotInfoObject, jFieldID, jTempCharArray);
4958 
4959 	/* set manufacturerID */
4960 	jFieldID = (*env)->GetFieldID(env, jSlotInfoClass, "manufacturerID", "[C");
4961 	assert(jFieldID != 0);
4962 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]) ,32);
4963 	(*env)->SetObjectField(env, jSlotInfoObject, jFieldID, jTempCharArray);
4964 
4965 	/* set flags */
4966 	jFieldID = (*env)->GetFieldID(env, jSlotInfoClass, "flags", "J");
4967 	assert(jFieldID != 0);
4968 	(*env)->SetLongField(env, jSlotInfoObject, jFieldID, ckULongToJLong(ckpSlotInfo->flags));
4969 
4970 	/* set hardwareVersion */
4971 	jFieldID = (*env)->GetFieldID(env, jSlotInfoClass, "hardwareVersion", CLASS_NAME(CLASS_VERSION));
4972 	assert(jFieldID != 0);
4973 	jTempVersion = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion));
4974 	(*env)->SetObjectField(env, jSlotInfoObject, jFieldID, jTempVersion);
4975 
4976 	/* set firmwareVersion */
4977 	jFieldID = (*env)->GetFieldID(env, jSlotInfoClass, "firmwareVersion", CLASS_NAME(CLASS_VERSION));
4978 	assert(jFieldID != 0);
4979 	jTempVersion = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion));
4980 	(*env)->SetObjectField(env, jSlotInfoObject, jFieldID, jTempVersion);
4981 
4982 	return jSlotInfoObject ;
4983 }
4984 
4985 /*
4986  * converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO Object.
4987  *
4988  * @param env - used to call JNI funktions to create the new Java object
4989  * @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure
4990  * @return - the new Java CK_TOKEN_INFO object
4991  */
ckTokenInfoPtrToJTokenInfo(JNIEnv * env,const CK_TOKEN_INFO_PTR ckpTokenInfo)4992 jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo)
4993 {
4994 	jclass jTokenInfoClass;
4995 	jobject jTokenInfoObject;
4996 	jcharArray jTempCharArray;
4997 	jfieldID jFieldID;
4998 	jobject jTempVersion;
4999 
5000 	/* load CK_SLOT_INFO class */
5001 	jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO);
5002 	assert(jTokenInfoClass != 0);
5003 	/* create new CK_SLOT_INFO object */
5004 	jTokenInfoObject = (*env)->AllocObject(env, jTokenInfoClass);
5005 	assert(jTokenInfoObject != 0);
5006 
5007 
5008 	/* set label */
5009 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "label", "[C");
5010 	assert(jFieldID != 0);
5011 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]) ,32);
5012 	(*env)->SetObjectField(env, jTokenInfoObject, jFieldID, jTempCharArray);
5013 
5014 	/* set manufacturerID */
5015 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "manufacturerID", "[C");
5016 	assert(jFieldID != 0);
5017 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]) ,32);
5018 	(*env)->SetObjectField(env, jTokenInfoObject, jFieldID, jTempCharArray);
5019 
5020 	/* set model */
5021 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "model", "[C");
5022 	assert(jFieldID != 0);
5023 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]) ,16);
5024 	(*env)->SetObjectField(env, jTokenInfoObject, jFieldID, jTempCharArray);
5025 
5026 	/* set serialNumber */
5027 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "serialNumber", "[C");
5028 	assert(jFieldID != 0);
5029 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]) ,16);
5030 	(*env)->SetObjectField(env, jTokenInfoObject, jFieldID, jTempCharArray);
5031 
5032 	/* set flags */
5033 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "flags", "J");
5034 	assert(jFieldID != 0);
5035 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->flags));
5036 
5037 	/* set ulMaxSessionCount */
5038 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulMaxSessionCount", "J");
5039 	assert(jFieldID != 0);
5040 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulMaxSessionCount));
5041 
5042 	/* set ulSessionCount */
5043 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulSessionCount", "J");
5044 	assert(jFieldID != 0);
5045 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulSessionCount));
5046 
5047 	/* set ulMaxRwSessionCount */
5048 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulMaxRwSessionCount", "J");
5049 	assert(jFieldID != 0);
5050 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulMaxRwSessionCount));
5051 
5052 	/* set ulRwSessionCount */
5053 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulRwSessionCount", "J");
5054 	assert(jFieldID != 0);
5055 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulRwSessionCount));
5056 
5057 	/* set ulMaxPinLen */
5058 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulMaxPinLen", "J");
5059 	assert(jFieldID != 0);
5060 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulMaxPinLen));
5061 
5062 	/* set ulMinPinLen */
5063 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulMinPinLen", "J");
5064 	assert(jFieldID != 0);
5065 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulMinPinLen));
5066 
5067 	/* set ulTotalPublicMemory */
5068 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulTotalPublicMemory", "J");
5069 	assert(jFieldID != 0);
5070 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulTotalPublicMemory));
5071 
5072 	/* set ulFreePublicMemory */
5073 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulFreePublicMemory", "J");
5074 	assert(jFieldID != 0);
5075 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulFreePublicMemory));
5076 
5077 	/* set ulTotalPrivateMemory */
5078 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulTotalPrivateMemory", "J");
5079 	assert(jFieldID != 0);
5080 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulTotalPrivateMemory));
5081 
5082 	/* set ulFreePrivateMemory */
5083 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "ulFreePrivateMemory", "J");
5084 	assert(jFieldID != 0);
5085 	(*env)->SetLongField(env, jTokenInfoObject, jFieldID, ckULongToJLong(ckpTokenInfo->ulFreePrivateMemory));
5086 
5087 
5088 	/* set hardwareVersion */
5089 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "hardwareVersion", CLASS_NAME(CLASS_VERSION));
5090 	assert(jFieldID != 0);
5091 	jTempVersion = ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion));
5092 	(*env)->SetObjectField(env, jTokenInfoObject, jFieldID, jTempVersion);
5093 
5094 	/* set firmwareVersion */
5095 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "firmwareVersion", CLASS_NAME(CLASS_VERSION));
5096 	assert(jFieldID != 0);
5097 	jTempVersion = ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion));
5098 	(*env)->SetObjectField(env, jTokenInfoObject, jFieldID, jTempVersion);
5099 
5100 	/* set utcTime */
5101 	jFieldID = (*env)->GetFieldID(env, jTokenInfoClass, "utcTime", "[C");
5102 	assert(jFieldID != 0);
5103 	jTempCharArray = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]) ,16);
5104 	(*env)->SetObjectField(env, jTokenInfoObject, jFieldID, jTempCharArray);
5105 
5106 	return jTokenInfoObject ;
5107 }
5108 
5109 /*
5110  * converts a pointer to a CK_SESSION_INFO structure into a Java CK_SESSION_INFO Object.
5111  *
5112  * @param env - used to call JNI funktions to create the new Java object
5113  * @param ckpSessionInfo - the pointer to the CK_SESSION_INFO structure
5114  * @return - the new Java CK_SESSION_INFO object
5115  */
ckSessionInfoPtrToJSessionInfo(JNIEnv * env,const CK_SESSION_INFO_PTR ckpSessionInfo)5116 jobject ckSessionInfoPtrToJSessionInfo(JNIEnv *env, const CK_SESSION_INFO_PTR ckpSessionInfo)
5117 {
5118 	jclass jSessionInfoClass;
5119 	jobject jSessionInfoObject;
5120 	jfieldID jFieldID;
5121 
5122 	/* load CK_SESSION_INFO class */
5123 	jSessionInfoClass = (*env)->FindClass(env, CLASS_SESSION_INFO);
5124 	assert(jSessionInfoClass != 0);
5125 	/* create new CK_SESSION_INFO object */
5126 	jSessionInfoObject = (*env)->AllocObject(env, jSessionInfoClass);
5127 	assert(jSessionInfoObject != 0);
5128 
5129 	/* set slotID */
5130 	jFieldID = (*env)->GetFieldID(env, jSessionInfoClass, "slotID", "J");
5131 	assert(jFieldID != 0);
5132 	(*env)->SetLongField(env, jSessionInfoObject, jFieldID, ckULongToJLong(ckpSessionInfo->slotID));
5133 
5134 	/* set state */
5135 	jFieldID = (*env)->GetFieldID(env, jSessionInfoClass, "state", "J");
5136 	assert(jFieldID != 0);
5137 	(*env)->SetLongField(env, jSessionInfoObject, jFieldID, ckULongToJLong(ckpSessionInfo->state));
5138 
5139 	/* set flags */
5140 	jFieldID = (*env)->GetFieldID(env, jSessionInfoClass, "flags", "J");
5141 	assert(jFieldID != 0);
5142 	(*env)->SetLongField(env, jSessionInfoObject, jFieldID, ckULongToJLong(ckpSessionInfo->flags));
5143 
5144 	/* set ulDeviceError */
5145 	jFieldID = (*env)->GetFieldID(env, jSessionInfoClass, "ulDeviceError", "J");
5146 	assert(jFieldID != 0);
5147 	(*env)->SetLongField(env, jSessionInfoObject, jFieldID, ckULongToJLong(ckpSessionInfo->ulDeviceError));
5148 
5149 	return jSessionInfoObject ;
5150 }
5151 
5152 /*
5153  * converts a pointer to a CK_MECHANISM_INFO structure into a Java CK_MECHANISM_INFO Object.
5154  *
5155  * @param env - used to call JNI funktions to create the new Java object
5156  * @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure
5157  * @return - the new Java CK_MECHANISM_INFO object
5158  */
ckMechanismInfoPtrToJMechanismInfo(JNIEnv * env,const CK_MECHANISM_INFO_PTR ckpMechanismInfo)5159 jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo)
5160 {
5161 	jclass jMechanismInfoClass;
5162 	jobject jMechanismInfoObject;
5163 	jfieldID jFieldID;
5164 
5165 	/* load CK_MECHANISM_INFO class */
5166 	jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO);
5167 	assert(jMechanismInfoClass != 0);
5168 	/* create new CK_MECHANISM_INFO object */
5169 	jMechanismInfoObject = (*env)->AllocObject(env, jMechanismInfoClass);
5170 	assert(jMechanismInfoObject != 0);
5171 
5172 
5173 	/* set ulMinKeySize */
5174 	jFieldID = (*env)->GetFieldID(env, jMechanismInfoClass, "ulMinKeySize", "J");
5175 	assert(jFieldID != 0);
5176 	(*env)->SetLongField(env, jMechanismInfoObject, jFieldID, ckULongToJLong(ckpMechanismInfo->ulMinKeySize));
5177 
5178 	/* set ulMaxKeySize */
5179 	jFieldID = (*env)->GetFieldID(env, jMechanismInfoClass, "ulMaxKeySize", "J");
5180 	assert(jFieldID != 0);
5181 	(*env)->SetLongField(env, jMechanismInfoObject, jFieldID, ckULongToJLong(ckpMechanismInfo->ulMaxKeySize));
5182 
5183 	/* set flags */
5184 	jFieldID = (*env)->GetFieldID(env, jMechanismInfoClass, "flags", "J");
5185 	assert(jFieldID != 0);
5186 	(*env)->SetLongField(env, jMechanismInfoObject, jFieldID, ckULongToJLong(ckpMechanismInfo->flags));
5187 
5188 	return jMechanismInfoObject ;
5189 }
5190 
5191 /*
5192  * converts a pointer to a CK_ATTRIBUTE structure into a Java CK_ATTRIBUTE Object.
5193  *
5194  * @param env - used to call JNI funktions to create the new Java object
5195  * @param ckpAttribute - the pointer to the CK_ATTRIBUTE structure
5196  * @return - the new Java CK_ATTRIBUTE object
5197  */
ckAttributePtrToJAttribute(JNIEnv * env,const CK_ATTRIBUTE_PTR ckpAttribute)5198 jobject ckAttributePtrToJAttribute(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute)
5199 {
5200 	jclass jAttributeClass;
5201 	jobject jAttribute;
5202 	jfieldID jFieldID;
5203 	jobject jPValue = NULL;
5204 
5205 	jAttributeClass = (*env)->FindClass(env, CLASS_ATTRIBUTE);
5206 	assert(jAttributeClass != 0);
5207 	jAttribute = (*env)->AllocObject(env, jAttributeClass);
5208 	assert(jAttribute != 0);
5209 
5210 	/* set type */
5211 	jFieldID = (*env)->GetFieldID(env, jAttributeClass, "type", "J");
5212 	assert(jFieldID != 0);
5213 	(*env)->SetLongField(env, jAttribute, jFieldID, ckULongToJLong(ckpAttribute->type));
5214 
5215 	/* set pValue */
5216 	jFieldID = (*env)->GetFieldID(env, jAttributeClass, "pValue", "Ljava/lang/Object;");
5217 	assert(jFieldID != 0);
5218 
5219 	jPValue = ckAttributeValueToJObject(env, ckpAttribute);
5220 	(*env)->SetObjectField(env, jAttribute, jFieldID, jPValue);
5221 
5222 	return jAttribute ;
5223 }
5224 
5225 /*
5226  * converts a Java boolean object into a pointer to a CK_BBOOL value. The memory has to be
5227  * freed after use!
5228  *
5229  * @param env - used to call JNI funktions to get the value out of the Java object
5230  * @param jObject - the "java/lang/Boolean" object to convert
5231  * @return - the pointer to the new CK_BBOOL value
5232  */
jBooleanObjectToCKBBoolPtr(JNIEnv * env,jobject jObject)5233 CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject)
5234 {
5235 	jclass jObjectClass;
5236 	jmethodID jValueMethod;
5237 	jboolean jValue;
5238 	CK_BBOOL *ckpValue;
5239 
5240 	jObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
5241 	assert(jObjectClass != 0);
5242 	jValueMethod = (*env)->GetMethodID(env, jObjectClass, "booleanValue", "()Z");
5243 	assert(jValueMethod != 0);
5244 	jValue = (*env)->CallBooleanMethod(env, jObject, jValueMethod);
5245 	ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL));
5246   if (ckpValue == NULL) { throwOutOfMemoryError(env); return NULL; }
5247 	*ckpValue = jBooleanToCKBBool(jValue);
5248 
5249 	return ckpValue ;
5250 }
5251 
5252 /*
5253  * converts a Java byte object into a pointer to a CK_BYTE value. The memory has to be
5254  * freed after use!
5255  *
5256  * @param env - used to call JNI funktions to get the value out of the Java object
5257  * @param jObject - the "java/lang/Byte" object to convert
5258  * @return - the pointer to the new CK_BYTE value
5259  */
jByteObjectToCKBytePtr(JNIEnv * env,jobject jObject)5260 CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject)
5261 {
5262 	jclass jObjectClass;
5263 	jmethodID jValueMethod;
5264 	jbyte jValue;
5265 	CK_BYTE_PTR ckpValue;
5266 
5267 	jObjectClass = (*env)->FindClass(env, "java/lang/Byte");
5268 	assert(jObjectClass != 0);
5269 	jValueMethod = (*env)->GetMethodID(env, jObjectClass, "byteValue", "()B");
5270 	assert(jValueMethod != 0);
5271 	jValue = (*env)->CallByteMethod(env, jObject, jValueMethod);
5272 	ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE));
5273   if (ckpValue == NULL) { throwOutOfMemoryError(env); return NULL; }
5274 	*ckpValue = jByteToCKByte(jValue);
5275 
5276 	return ckpValue ;
5277 }
5278 
5279 /*
5280  * converts a Java integer object into a pointer to a CK_ULONG value. The memory has to be
5281  * freed after use!
5282  *
5283  * @param env - used to call JNI funktions to get the value out of the Java object
5284  * @param jObject - the "java/lang/Integer" object to convert
5285  * @return - the pointer to the new CK_ULONG value
5286  */
jIntegerObjectToCKULongPtr(JNIEnv * env,jobject jObject)5287 CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject)
5288 {
5289 	jclass jObjectClass;
5290 	jmethodID jValueMethod;
5291 	jint jValue;
5292 	CK_ULONG *ckpValue;
5293 
5294 	jObjectClass = (*env)->FindClass(env, "java/lang/Integer");
5295 	assert(jObjectClass != 0);
5296 	jValueMethod = (*env)->GetMethodID(env, jObjectClass, "intValue", "()I");
5297 	assert(jValueMethod != 0);
5298 	jValue = (*env)->CallIntMethod(env, jObject, jValueMethod);
5299 	ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
5300   if (ckpValue == NULL) { throwOutOfMemoryError(env); return NULL; }
5301 	*ckpValue = jLongToCKLong(jValue);
5302 
5303 	return ckpValue ;
5304 }
5305 
5306 /*
5307  * converts a Java long object into a pointer to a CK_ULONG value. The memory has to be
5308  * freed after use!
5309  *
5310  * @param env - used to call JNI funktions to get the value out of the Java object
5311  * @param jObject - the "java/lang/Long" object to convert
5312  * @return - the pointer to the new CK_ULONG value
5313  */
jLongObjectToCKULongPtr(JNIEnv * env,jobject jObject)5314 CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject)
5315 {
5316 	jclass jObjectClass;
5317 	jmethodID jValueMethod;
5318 	jlong jValue;
5319 	CK_ULONG *ckpValue;
5320 
5321 	jObjectClass = (*env)->FindClass(env, "java/lang/Long");
5322 	assert(jObjectClass != 0);
5323 	jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J");
5324 	assert(jValueMethod != 0);
5325 	jValue = (*env)->CallLongMethod(env, jObject, jValueMethod);
5326 	ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
5327   if (ckpValue == NULL) { throwOutOfMemoryError(env); return NULL; }
5328 	*ckpValue = jLongToCKULong(jValue);
5329 
5330 	return ckpValue ;
5331 }
5332 
5333 /*
5334  * converts a Java char object into a pointer to a CK_CHAR value. The memory has to be
5335  * freed after use!
5336  *
5337  * @param env - used to call JNI funktions to get the value out of the Java object
5338  * @param jObject - the "java/lang/Char" object to convert
5339  * @return - the pointer to the new CK_CHAR value
5340  */
jCharObjectToCKCharPtr(JNIEnv * env,jobject jObject)5341 CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject)
5342 {
5343 	jclass jObjectClass;
5344 	jmethodID jValueMethod;
5345 	jchar jValue;
5346 	CK_CHAR_PTR ckpValue;
5347 
5348 	jObjectClass = (*env)->FindClass(env, "java/lang/Char");
5349 	assert(jObjectClass != 0);
5350 	jValueMethod = (*env)->GetMethodID(env, jObjectClass, "charValue", "()C");
5351 	assert(jValueMethod != 0);
5352 	jValue = (*env)->CallCharMethod(env, jObject, jValueMethod);
5353 	ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR));
5354   if (ckpValue == NULL) { throwOutOfMemoryError(env); return NULL; }
5355 	*ckpValue = jCharToCKChar(jValue);
5356 
5357 	return ckpValue ;
5358 }
5359 
5360 /*
5361  * converts a Java CK_VERSION object into a pointer to a CK_VERSION structure
5362  *
5363  * @param env - used to call JNI funktions to get the values out of the Java object
5364  * @param jVersion - the Java CK_VERSION object to convert
5365  * @return - the pointer to the new CK_VERSION structure
5366  */
jVersionToCKVersionPtr(JNIEnv * env,jobject jVersion)5367 CK_VERSION_PTR jVersionToCKVersionPtr(JNIEnv *env, jobject jVersion)
5368 {
5369 	CK_VERSION_PTR ckpVersion;
5370 	jclass jVersionClass;
5371 	jfieldID jFieldID;
5372 	jbyte jMajor, jMinor;
5373 
5374 	/* allocate memory for CK_VERSION pointer */
5375 	ckpVersion = (CK_VERSION_PTR) malloc(sizeof(CK_VERSION));
5376   if (ckpVersion == NULL) { throwOutOfMemoryError(env); return NULL; }
5377 
5378 	/* get CK_VERSION class */
5379 	jVersionClass = (*env)->GetObjectClass(env, jVersion);
5380 	assert(jVersionClass != 0);
5381 
5382 	/* get Major */
5383 	jFieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
5384 	assert(jFieldID != 0);
5385 	jMajor = (*env)->GetByteField(env, jVersion, jFieldID);
5386 	ckpVersion->major = jByteToCKByte(jMajor);
5387 
5388 	/* get Minor */
5389 	jFieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
5390 	assert(jFieldID != 0);
5391 	jMinor = (*env)->GetByteField(env, jVersion, jFieldID);
5392 	ckpVersion->minor = jByteToCKByte(jMinor);
5393 
5394 	return ckpVersion ;
5395 }
5396 
5397 
5398 /*
5399  * converts a Java CK_DATE object into a pointer to a CK_DATE structure
5400  *
5401  * @param env - used to call JNI funktions to get the values out of the Java object
5402  * @param jVersion - the Java CK_DATE object to convert
5403  * @return - the pointer to the new CK_DATE structure
5404  */
jDateObjectPtrToCKDatePtr(JNIEnv * env,jobject jDate)5405 CK_DATE * jDateObjectPtrToCKDatePtr(JNIEnv *env, jobject jDate)
5406 {
5407 	CK_DATE * ckpDate;
5408   CK_ULONG ckLength;
5409 	jclass jDateClass;
5410 	jfieldID jFieldID;
5411 	jobject jYear, jMonth, jDay;
5412   jchar *jTempChars;
5413   CK_ULONG i;
5414 
5415 	/* allocate memory for CK_DATE pointer */
5416 	ckpDate = (CK_DATE *) malloc(sizeof(CK_DATE));
5417   if (ckpDate == NULL) { throwOutOfMemoryError(env); return NULL; }
5418 
5419 	/* get CK_DATE class */
5420 	jDateClass = (*env)->FindClass(env, CLASS_DATE);
5421 	assert(jDateClass != 0);
5422 
5423 	/* get Year */
5424 	jFieldID = (*env)->GetFieldID(env, jDateClass, "year", "[C");
5425 	assert(jFieldID != 0);
5426 	jYear = (*env)->GetObjectField(env, jDate, jFieldID);
5427 
5428   if (jYear == NULL) {
5429     ckpDate->year[0] = 0;
5430     ckpDate->year[1] = 0;
5431     ckpDate->year[2] = 0;
5432     ckpDate->year[3] = 0;
5433   } else {
5434   	ckLength = (*env)->GetArrayLength(env, jYear);
5435 	  jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
5436     if (jTempChars == NULL && ckLength!=0) { free(ckpDate); throwOutOfMemoryError(env); return NULL; }
5437   	(*env)->GetCharArrayRegion(env, jYear, 0, ckLength, jTempChars);
5438     for (i = 0; (i < ckLength) && (i < 4) ; i++) {
5439       ckpDate->year[i] = jCharToCKChar(jTempChars[i]);
5440     }
5441 	  free(jTempChars);
5442   }
5443 
5444 	/* get Month */
5445 	jFieldID = (*env)->GetFieldID(env, jDateClass, "month", "[C");
5446 	assert(jFieldID != 0);
5447 	jMonth = (*env)->GetObjectField(env, jDate, jFieldID);
5448 
5449   if (jMonth == NULL) {
5450     ckpDate->month[0] = 0;
5451     ckpDate->month[1] = 0;
5452   } else {
5453   	ckLength = (*env)->GetArrayLength(env, jMonth);
5454 	  jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
5455     if (jTempChars == NULL && ckLength!=0) { free(ckpDate); throwOutOfMemoryError(env); return NULL; }
5456   	(*env)->GetCharArrayRegion(env, jMonth, 0, ckLength, jTempChars);
5457     for (i = 0; (i < ckLength) && (i < 4) ; i++) {
5458       ckpDate->month[i] = jCharToCKChar(jTempChars[i]);
5459     }
5460 	  free(jTempChars);
5461   }
5462 
5463 	/* get Day */
5464 	jFieldID = (*env)->GetFieldID(env, jDateClass, "day", "[C");
5465 	assert(jFieldID != 0);
5466 	jDay = (*env)->GetObjectField(env, jDate, jFieldID);
5467 
5468   if (jDay == NULL) {
5469     ckpDate->day[0] = 0;
5470     ckpDate->day[1] = 0;
5471   } else {
5472   	ckLength = (*env)->GetArrayLength(env, jDay);
5473 	  jTempChars = (jchar*) malloc((ckLength) * sizeof(jchar));
5474     if (jTempChars == NULL && ckLength!=0) { free(ckpDate); throwOutOfMemoryError(env); return NULL; }
5475   	(*env)->GetCharArrayRegion(env, jDay, 0, ckLength, jTempChars);
5476     for (i = 0; (i < ckLength) && (i < 4) ; i++) {
5477       ckpDate->day[i] = jCharToCKChar(jTempChars[i]);
5478     }
5479 	  free(jTempChars);
5480   }
5481 
5482 	return ckpDate ;
5483 }
5484 
5485 
5486 /*
5487  * converts a Java CK_ATTRIBUTE object into a CK_ATTRIBUTE structure
5488  *
5489  * @param env - used to call JNI funktions to get the values out of the Java object
5490  * @param jAttribute - the Java CK_ATTRIBUTE object to convert
5491  * @return - the new CK_ATTRIBUTE structure
5492  */
jAttributeToCKAttribute(JNIEnv * env,jobject jAttribute)5493 CK_ATTRIBUTE jAttributeToCKAttribute(JNIEnv *env, jobject jAttribute)
5494 {
5495 	CK_ATTRIBUTE ckAttribute;
5496 	jclass jAttributeClass;
5497 	jfieldID jFieldID;
5498 	jlong jType;
5499 	jobject jPValue;
5500 
5501   TRACE0(tag_call, __FUNCTION__,"entering");
5502 
5503   /* get CK_ATTRIBUTE class */
5504 	TRACE0(tag_debug, __FUNCTION__,"- getting attribute object class");
5505 	jAttributeClass = (*env)->GetObjectClass(env, jAttribute);
5506 	assert(jAttributeClass != 0);
5507 
5508 	/* get type */
5509 	TRACE0(tag_debug, __FUNCTION__,"- getting type field");
5510 	jFieldID = (*env)->GetFieldID(env, jAttributeClass, "type", "J");
5511 	assert(jFieldID != 0);
5512 	jType = (*env)->GetLongField(env, jAttribute, jFieldID);
5513 	TRACE1(tag_debug, __FUNCTION__,"  type=0x%X", jType);
5514 
5515 	/* get pValue */
5516 	TRACE0(tag_debug, __FUNCTION__,"- getting pValue field");
5517 	jFieldID = (*env)->GetFieldID(env, jAttributeClass, "pValue", "Ljava/lang/Object;");
5518 	assert(jFieldID != 0);
5519 	jPValue = (*env)->GetObjectField(env, jAttribute, jFieldID);
5520 	TRACE1(tag_debug, __FUNCTION__,"  pValue=%p", jPValue);
5521 
5522 	ckAttribute.type = jLongToCKULong(jType);
5523 	TRACE0(tag_debug, __FUNCTION__,"- converting pValue to primitive object");
5524 
5525 	if ((ckAttribute.type == 0x40000211) || (ckAttribute.type == 0x40000212)){
5526 		TRACE0(tag_debug, __FUNCTION__,"  CKF_ARRAY_ATTRIBUTE:");
5527 		if (jAttributeArrayToCKAttributeArray(env, jPValue, &(ckAttribute.pValue), &(ckAttribute.ulValueLen))) {
5528 			throwOutOfMemoryError(env);
5529 		}
5530 		ckAttribute.ulValueLen *= sizeof(CK_ATTRIBUTE);
5531 	} else {
5532 		/* convert the Java pValue object to a CK-type pValue pointer */
5533 		jObjectToPrimitiveCKObjectPtrPtr(env, jPValue, &(ckAttribute.pValue), &(ckAttribute.ulValueLen));
5534 	}
5535 
5536   TRACE0(tag_call, __FUNCTION__,"exiting ");
5537 
5538 	return ckAttribute ;
5539 }
5540 
5541 /*
5542  * converts a Java CK_MECHANISM object into a CK_MECHANISM structure
5543  *
5544  * @param env - used to call JNI funktions to get the values out of the Java object
5545  * @param jMechanism - the Java CK_MECHANISM object to convert
5546  * @return - the new CK_MECHANISM structure
5547  */
jMechanismToCKMechanism(JNIEnv * env,jobject jMechanism)5548 CK_MECHANISM jMechanismToCKMechanism(JNIEnv *env, jobject jMechanism)
5549 {
5550 	CK_MECHANISM ckMechanism;
5551 	jclass jMechanismClass;
5552 	jfieldID fieldID;
5553 	jlong jMechanismType;
5554 	jobject jParameter;
5555 
5556 	/* get CK_MECHANISM class */
5557 	jMechanismClass = (*env)->GetObjectClass(env, jMechanism);
5558 	assert(jMechanismClass != 0);
5559 
5560 	/* get mechanism */
5561 	fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
5562 	assert(fieldID != 0);
5563 	jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
5564 
5565 	/* get pParameter */
5566 	fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
5567 	assert(fieldID != 0);
5568 	jParameter = (*env)->GetObjectField(env, jMechanism, fieldID);
5569 
5570 	ckMechanism.mechanism = jLongToCKULong(jMechanismType);
5571 
5572 	/* convert the specific Java mechanism parameter object to a pointer to a CK-type mechanism
5573 	 * structure
5574    */
5575 	jMechanismParameterToCKMechanismParameter(env, jParameter, &(ckMechanism.pParameter), &(ckMechanism.ulParameterLen));
5576 
5577 	return ckMechanism ;
5578 }
5579 
freeCKMechanismParameter(CK_MECHANISM_PTR mechanism)5580 void freeCKMechanismParameter(CK_MECHANISM_PTR mechanism) {
5581   void *value;
5582 
5583   /* free pointers inside parameter structures, see jMechanismParameterToCKMechanismParameter */
5584   switch (mechanism->mechanism) {
5585     case CKM_RSA_PKCS_OAEP:
5586       value = ((CK_RSA_PKCS_OAEP_PARAMS_PTR) mechanism->pParameter)->pSourceData;
5587       if (value != NULL) free(value);
5588       break;
5589     case CKM_KEA_KEY_DERIVE:
5590       value = ((CK_KEA_DERIVE_PARAMS_PTR) mechanism->pParameter)->pRandomA;
5591       if (value != NULL) free(value);
5592       value = ((CK_KEA_DERIVE_PARAMS_PTR) mechanism->pParameter)->pRandomB;
5593       if (value != NULL) free(value);
5594       value = ((CK_KEA_DERIVE_PARAMS_PTR) mechanism->pParameter)->pPublicData;
5595       if (value != NULL) free(value);
5596       break;
5597     case CKM_RC5_CBC:
5598     case CKM_RC5_CBC_PAD:
5599       value = ((CK_RC5_CBC_PARAMS_PTR) mechanism->pParameter)->pIv;
5600       if (value != NULL) free(value);
5601       break;
5602     case CKM_SKIPJACK_PRIVATE_WRAP:
5603       value = ((CK_SKIPJACK_PRIVATE_WRAP_PTR) mechanism->pParameter)->pPassword;
5604       if (value != NULL) free(value);
5605       value = ((CK_SKIPJACK_PRIVATE_WRAP_PTR) mechanism->pParameter)->pPublicData;
5606       if (value != NULL) free(value);
5607       value = ((CK_SKIPJACK_PRIVATE_WRAP_PTR) mechanism->pParameter)->pRandomA;
5608       if (value != NULL) free(value);
5609       value = ((CK_SKIPJACK_PRIVATE_WRAP_PTR) mechanism->pParameter)->pPrimeP;
5610       if (value != NULL) free(value);
5611       value = ((CK_SKIPJACK_PRIVATE_WRAP_PTR) mechanism->pParameter)->pBaseG;
5612       if (value != NULL) free(value);
5613       value = ((CK_SKIPJACK_PRIVATE_WRAP_PTR) mechanism->pParameter)->pSubprimeQ;
5614       if (value != NULL) free(value);
5615       break;
5616     case CKM_SKIPJACK_RELAYX:
5617       value = ((CK_SKIPJACK_RELAYX_PARAMS_PTR) mechanism->pParameter)->pOldWrappedX;
5618       if (value != NULL) free(value);
5619       value = ((CK_SKIPJACK_RELAYX_PARAMS_PTR) mechanism->pParameter)->pOldPassword;
5620       if (value != NULL) free(value);
5621       value = ((CK_SKIPJACK_RELAYX_PARAMS_PTR) mechanism->pParameter)->pOldPublicData;
5622       if (value != NULL) free(value);
5623       value = ((CK_SKIPJACK_RELAYX_PARAMS_PTR) mechanism->pParameter)->pOldRandomA;
5624       if (value != NULL) free(value);
5625       value = ((CK_SKIPJACK_RELAYX_PARAMS_PTR) mechanism->pParameter)->pNewPassword;
5626       if (value != NULL) free(value);
5627       value = ((CK_SKIPJACK_RELAYX_PARAMS_PTR) mechanism->pParameter)->pNewPublicData;
5628       if (value != NULL) free(value);
5629       value = ((CK_SKIPJACK_RELAYX_PARAMS_PTR) mechanism->pParameter)->pNewRandomA;
5630       if (value != NULL) free(value);
5631       break;
5632     case CKM_PBE_MD2_DES_CBC:
5633     case CKM_PBE_MD5_DES_CBC:
5634     case CKM_PBE_MD5_CAST_CBC:
5635     case CKM_PBE_MD5_CAST3_CBC:
5636     case CKM_PBE_MD5_CAST128_CBC:
5637     /* case CKM_PBE_MD5_CAST5_CBC: */
5638     case CKM_PBE_SHA1_CAST128_CBC:
5639     /* case CKM_PBE_SHA1_CAST5_CBC: */
5640     case CKM_PBE_SHA1_RC4_128:
5641     case CKM_PBE_SHA1_RC4_40:
5642     case CKM_PBE_SHA1_DES3_EDE_CBC:
5643     case CKM_PBE_SHA1_DES2_EDE_CBC:
5644     case CKM_PBE_SHA1_RC2_128_CBC:
5645     case CKM_PBE_SHA1_RC2_40_CBC:
5646     case CKM_PBA_SHA1_WITH_SHA1_HMAC:
5647       value = ((CK_PBE_PARAMS_PTR) mechanism->pParameter)->pInitVector;
5648       if (value != NULL) free(value);
5649       value = ((CK_PBE_PARAMS_PTR) mechanism->pParameter)->pPassword;
5650       if (value != NULL) free(value);
5651       value = ((CK_PBE_PARAMS_PTR) mechanism->pParameter)->pSalt;
5652       if (value != NULL) free(value);
5653       break;
5654     case CKM_PKCS5_PBKD2:
5655       value = ((CK_PKCS5_PBKD2_PARAMS_PTR) mechanism->pParameter)->pSaltSourceData;
5656       if (value != NULL) free(value);
5657       value = ((CK_PKCS5_PBKD2_PARAMS_PTR) mechanism->pParameter)->pPrfData;
5658       if (value != NULL) free(value);
5659       break;
5660     case CKM_CONCATENATE_BASE_AND_DATA:
5661     case CKM_XOR_BASE_AND_DATA:
5662     case CKM_DES_ECB_ENCRYPT_DATA:
5663     case CKM_DES3_ECB_ENCRYPT_DATA:
5664     case CKM_AES_ECB_ENCRYPT_DATA:
5665       value = ((CK_KEY_DERIVATION_STRING_DATA_PTR) mechanism->pParameter)->pData;
5666       if (value != NULL) free(value);
5667       break;
5668     case CKM_KEY_WRAP_SET_OAEP:
5669       value = ((CK_KEY_WRAP_SET_OAEP_PARAMS_PTR) mechanism->pParameter)->pX;
5670       if (value != NULL) free(value);
5671       break;
5672     case CKM_SSL3_MASTER_KEY_DERIVE:
5673     case CKM_SSL3_MASTER_KEY_DERIVE_DH:
5674     case CKM_TLS_MASTER_KEY_DERIVE:
5675     case CKM_TLS_MASTER_KEY_DERIVE_DH:
5676       value = ((CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR) mechanism->pParameter)->RandomInfo.pClientRandom;
5677       if (value != NULL) free(value);
5678       value = ((CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR) mechanism->pParameter)->RandomInfo.pServerRandom;
5679       if (value != NULL) free(value);
5680       value = ((CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR) mechanism->pParameter)->pVersion;
5681       if (value != NULL) free(value);
5682       break;
5683     case CKM_SSL3_KEY_AND_MAC_DERIVE:
5684     case CKM_TLS_KEY_AND_MAC_DERIVE:
5685       value = ((CK_SSL3_KEY_MAT_PARAMS_PTR) mechanism->pParameter)->RandomInfo.pClientRandom;
5686       if (value != NULL) free(value);
5687       value = ((CK_SSL3_KEY_MAT_PARAMS_PTR) mechanism->pParameter)->RandomInfo.pServerRandom;
5688       if (value != NULL) free(value);
5689       value = ((CK_SSL3_KEY_MAT_PARAMS_PTR) mechanism->pParameter)->pReturnedKeyMaterial->pIVClient;
5690       if (value != NULL) free(value);
5691       value = ((CK_SSL3_KEY_MAT_PARAMS_PTR) mechanism->pParameter)->pReturnedKeyMaterial->pIVServer;
5692       if (value != NULL) free(value);
5693       break;
5694     case CKM_ECDH1_DERIVE:
5695     case CKM_ECDH1_COFACTOR_DERIVE:
5696       value = ((CK_ECDH1_DERIVE_PARAMS_PTR) mechanism->pParameter)->pSharedData;
5697       if (value != NULL) free(value);
5698       value = ((CK_ECDH1_DERIVE_PARAMS_PTR) mechanism->pParameter)->pPublicData;
5699       if (value != NULL) free(value);
5700       break;
5701     case CKM_ECMQV_DERIVE:
5702       value = ((CK_ECDH2_DERIVE_PARAMS_PTR) mechanism->pParameter)->pSharedData;
5703       if (value != NULL) free(value);
5704       value = ((CK_ECDH2_DERIVE_PARAMS_PTR) mechanism->pParameter)->pPublicData;
5705       if (value != NULL) free(value);
5706       value = ((CK_ECDH2_DERIVE_PARAMS_PTR) mechanism->pParameter)->pPublicData2;
5707       if (value != NULL) free(value);
5708       break;
5709     case CKM_X9_42_DH_DERIVE:
5710       value = ((CK_X9_42_DH1_DERIVE_PARAMS_PTR) mechanism->pParameter)->pOtherInfo;
5711       if (value != NULL) free(value);
5712       value = ((CK_X9_42_DH1_DERIVE_PARAMS_PTR) mechanism->pParameter)->pPublicData;
5713       if (value != NULL) free(value);
5714       break;
5715     case CKM_X9_42_DH_HYBRID_DERIVE:
5716     case CKM_X9_42_MQV_DERIVE:
5717       value = ((CK_X9_42_DH2_DERIVE_PARAMS_PTR) mechanism->pParameter)->pOtherInfo;
5718       if (value != NULL) free(value);
5719       value = ((CK_X9_42_DH2_DERIVE_PARAMS_PTR) mechanism->pParameter)->pPublicData;
5720       if (value != NULL) free(value);
5721       value = ((CK_X9_42_DH2_DERIVE_PARAMS_PTR) mechanism->pParameter)->pPublicData2;
5722       if (value != NULL) free(value);
5723       break;
5724   }
5725 
5726   /* free parameter structure itself */
5727   free(mechanism->pParameter);
5728 }
5729 
5730 /*
5731  * the following functions convert Attribute and Mechanism value pointers
5732  *
5733  * jobject ckAttributeValueToJObject(JNIEnv *env,
5734  *                                   const CK_ATTRIBUTE_PTR ckpAttribute);
5735  *
5736  * void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env,
5737  *                                       jobject jObject,
5738  *                                       CK_VOID_PTR *ckpObjectPtr,
5739  *                                       CK_ULONG *pLength);
5740  *
5741  * void jMechanismParameterToCKMechanismParameter(JNIEnv *env,
5742  *                                                jobject jParam,
5743  *                                                CK_VOID_PTR *ckpParamPtr,
5744  *                                                CK_ULONG *ckpLength);
5745  *
5746  * These functions are used if a PKCS#11 mechanism or attribute structure gets
5747  * convertet to a Java attribute or mechanism object or vice versa.
5748  *
5749  * ckAttributeValueToJObject converts a PKCS#11 attribute value pointer to a Java
5750  * object depending on the type of the Attribute. A PKCS#11 attribute value can
5751  * be a CK_ULONG, CK_BYTE[], CK_CHAR[], big integer, CK_BBOOL, CK_UTF8CHAR[],
5752  * CK_DATE or CK_FLAGS that gets converted to a corresponding Java object.
5753  *
5754  * jObjectToPrimitiveCKObjectPtrPtr is used by jAttributeToCKAttributePtr for
5755  * converting the Java attribute value to a PKCS#11 attribute value pointer.
5756  * For now only primitive datatypes and arrays of primitive datatypes can get
5757  * converted. Otherwise this function throws a PKCS#11Exception with the
5758  * errorcode CKR_VENDOR_DEFINED.
5759  *
5760  * jMechanismParameterToCKMechanismParameter converts a Java mechanism parameter
5761  * to a PKCS#11 mechanism parameter. First this function determines what mechanism
5762  * parameter the Java object is, then it allocates the memory for the new PKCS#11
5763  * structure and calls the corresponding function to convert the Java object to
5764  * a PKCS#11 mechanism parameter structure.
5765  */
5766 
5767 /*
5768  * converts the pValue of a CK_ATTRIBUTE structure into a Java Object by checking the type
5769  * of the attribute.
5770  *
5771  * @param env - used to call JNI funktions to create the new Java object
5772  * @param ckpAttribute - the pointer to the CK_ATTRIBUTE structure that contains the type
5773  *                       and the pValue to convert
5774  * @return - the new Java object of the CK-type pValue
5775  */
ckAttributeValueToJObject(JNIEnv * env,const CK_ATTRIBUTE_PTR ckpAttribute)5776 jobject ckAttributeValueToJObject(JNIEnv *env, const CK_ATTRIBUTE_PTR ckpAttribute)
5777 {
5778 	jint jValueLength;
5779 	jobject jValueObject = NULL;
5780 
5781 	jValueLength = ckULongToJInt(ckpAttribute->ulValueLen);
5782 
5783 	if ((jValueLength <= 0) || (ckpAttribute->pValue == NULL)) {
5784 		return NULL ;
5785 	}
5786 
5787 	switch(ckpAttribute->type) {
5788 		case CKA_CLASS:
5789 			/* value CK_OBJECT_CLASS, defacto a CK_ULONG */
5790 		case CKA_KEY_TYPE:
5791 			/* value CK_KEY_TYPE, defacto a CK_ULONG */
5792 		case CKA_CERTIFICATE_TYPE:
5793 			/* value CK_CERTIFICATE_TYPE, defacto a CK_ULONG */
5794 		case CKA_HW_FEATURE_TYPE:
5795 			/* value CK_HW_FEATURE_TYPE, defacto a CK_ULONG */
5796 		case CKA_MODULUS_BITS:
5797 		case CKA_VALUE_BITS:
5798 		case CKA_VALUE_LEN:
5799 		case CKA_KEY_GEN_MECHANISM:
5800 		case CKA_PRIME_BITS:
5801 		case CKA_SUB_PRIME_BITS:
5802 		case CKA_CERTIFICATE_CATEGORY:
5803 		case CKA_JAVA_MIDP_SECURITY_DOMAIN:
5804 			/* value CK_ULONG */
5805 			jValueObject = ckULongPtrToJLongObject(env, (CK_ULONG*) ckpAttribute->pValue);
5806 			break;
5807 
5808 			/* can be CK_BYTE[],CK_CHAR[] or big integer; defacto always CK_BYTE[] */
5809 		case CKA_VALUE:
5810 		case CKA_OBJECT_ID:
5811 		case CKA_SUBJECT:
5812 		case CKA_ID:
5813 		case CKA_ISSUER:
5814 		case CKA_SERIAL_NUMBER:
5815 		case CKA_OWNER:
5816 		case CKA_AC_ISSUER:
5817 		case CKA_ATTR_TYPES:
5818 		case CKA_ECDSA_PARAMS:
5819       /* CKA_EC_PARAMS is the same, these two are equivalent */
5820 		case CKA_EC_POINT:
5821 		case CKA_PRIVATE_EXPONENT:
5822 		case CKA_PRIME_1:
5823 		case CKA_PRIME_2:
5824 		case CKA_EXPONENT_1:
5825 		case CKA_EXPONENT_2:
5826 		case CKA_COEFFICIENT:
5827 		case CKA_CHECK_VALUE:
5828 		case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
5829 		case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
5830 			/* value CK_BYTE[] */
5831 			jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
5832 			break;
5833 
5834 		case CKA_RESET_ON_INIT:
5835 		case CKA_HAS_RESET:
5836 		case CKA_TOKEN:
5837 		case CKA_PRIVATE:
5838 		case CKA_MODIFIABLE:
5839 		case CKA_DERIVE:
5840 		case CKA_LOCAL:
5841 		case CKA_ENCRYPT:
5842 		case CKA_VERIFY:
5843 		case CKA_VERIFY_RECOVER:
5844 		case CKA_WRAP:
5845 		case CKA_SENSITIVE:
5846 		case CKA_SECONDARY_AUTH:
5847 		case CKA_DECRYPT:
5848 		case CKA_SIGN:
5849 		case CKA_SIGN_RECOVER:
5850 		case CKA_UNWRAP:
5851 		case CKA_EXTRACTABLE:
5852 		case CKA_ALWAYS_SENSITIVE:
5853 		case CKA_NEVER_EXTRACTABLE:
5854 		case CKA_TRUSTED:
5855 		case CKA_WRAP_WITH_TRUSTED:
5856 		case CKA_ALWAYS_AUTHENTICATE:
5857 			/* value CK_BBOOL */
5858 			jValueObject = ckBBoolPtrToJBooleanObject(env, (CK_BBOOL*) ckpAttribute->pValue);
5859 			break;
5860 
5861 		case CKA_LABEL:
5862 		case CKA_APPLICATION:
5863 		case CKA_URL:
5864 			/* value RFC 2279 (UTF-8) string */
5865 			jValueObject = ckUTF8CharArrayToJCharArray(env, (CK_UTF8CHAR*) ckpAttribute->pValue, jValueLength);
5866 			break;
5867 
5868 		case CKA_START_DATE:
5869 		case CKA_END_DATE:
5870 			/* value CK_DATE */
5871 			jValueObject = ckDatePtrToJDateObject(env, (CK_DATE*) ckpAttribute->pValue);
5872 			break;
5873 
5874 		case CKA_MODULUS:
5875 		case CKA_PUBLIC_EXPONENT:
5876 		case CKA_PRIME:
5877 		case CKA_SUBPRIME:
5878 		case CKA_BASE:
5879 			/* value big integer, i.e. CK_BYTE[] */
5880 			jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
5881 			break;
5882 
5883 		case CKA_AUTH_PIN_FLAGS:
5884 			jValueObject = ckULongPtrToJLongObject(env, (CK_ULONG*) ckpAttribute->pValue);
5885 			/* value FLAGS, defacto a CK_ULONG */
5886 			break;
5887 
5888 		case CKA_ALLOWED_MECHANISMS:
5889 			jValueLength = jValueLength / sizeof(CK_MECHANISM_TYPE);
5890 			jValueObject = ckULongArrayToJLongArray(env, (CK_ULONG*) ckpAttribute->pValue, jValueLength);
5891 			break;
5892 
5893 		case CKA_WRAP_TEMPLATE:
5894 		case CKA_UNWRAP_TEMPLATE:
5895 			jValueObject = ckAttributeArrayToJAttributeArray(env, (CK_ATTRIBUTE*) ckpAttribute->pValue, jValueLength);
5896 			break;
5897 
5898 		case CKA_VENDOR_DEFINED:
5899 			/* we make a CK_BYTE[] out of this */
5900 			jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
5901 			break;
5902 
5903 		default:
5904 			/* we make a CK_BYTE[] out of this */
5905 			jValueObject = ckByteArrayToJByteArray(env, (CK_BYTE*) ckpAttribute->pValue, jValueLength);
5906 			break;
5907 	}
5908 
5909 	return jValueObject ;
5910 }
5911 
5912 /*
5913  * converts a Java object into a pointer to CK-type or a CK-structure with the length in Bytes.
5914  * The memory of *ckpObjectPtr to be freed after use! This function is only used by
5915  * jAttributeToCKAttribute by now.
5916  *
5917  * @param env - used to call JNI funktions to get the Java classes and objects
5918  * @param jObject - the Java object to convert
5919  * @param ckpObjectPtr - the reference of the new pointer to the new CK-value or CK-structure
5920  * @param ckpLength - the reference of the length in bytes of the new CK-value or CK-structure
5921  */
jObjectToPrimitiveCKObjectPtrPtr(JNIEnv * env,jobject jObject,CK_VOID_PTR * ckpObjectPtr,CK_ULONG * ckpLength)5922 void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *ckpLength)
5923 {
5924 	jclass jBooleanClass     = (*env)->FindClass(env, "java/lang/Boolean");
5925 	jclass jByteClass        = (*env)->FindClass(env, "java/lang/Byte");
5926 	jclass jCharacterClass   = (*env)->FindClass(env, "java/lang/Character");
5927 	jclass jClassClass = (*env)->FindClass(env, "java/lang/Class");
5928 	/* jclass jShortClass       = (*env)->FindClass(env, "java/lang/Short"); */
5929 	jclass jIntegerClass     = (*env)->FindClass(env, "java/lang/Integer");
5930 	jclass jLongClass        = (*env)->FindClass(env, "java/lang/Long");
5931 	/* jclass jFloatClass       = (*env)->FindClass(env, "java/lang/Float"); */
5932 	/* jclass jDoubleClass      = (*env)->FindClass(env, "java/lang/Double"); */
5933 	jclass jDateClass      = (*env)->FindClass(env, CLASS_DATE);
5934 	jclass jStringClass      = (*env)->FindClass(env, "java/lang/String");
5935 	jclass jStringBufferClass      = (*env)->FindClass(env, "java/lang/StringBuffer");
5936 	jclass jBooleanArrayClass = (*env)->FindClass(env, "[Z");
5937 	jclass jByteArrayClass    = (*env)->FindClass(env, "[B");
5938 	jclass jCharArrayClass    = (*env)->FindClass(env, "[C");
5939 	/* jclass jShortArrayClass   = (*env)->FindClass(env, "[S"); */
5940 	jclass jIntArrayClass     = (*env)->FindClass(env, "[I");
5941 	jclass jLongArrayClass    = (*env)->FindClass(env, "[J");
5942 	/* jclass jFloatArrayClass   = (*env)->FindClass(env, "[F"); */
5943 	/* jclass jDoubleArrayClass  = (*env)->FindClass(env, "[D"); */
5944 	jclass jObjectClass = (*env)->FindClass(env, "java/lang/Object");
5945   /*  jclass jObjectArrayClass = (*env)->FindClass(env, "[java/lang/Object"); */
5946   /* ATTENTION: jObjectArrayClass is always NULL !! */
5947   /* CK_ULONG ckArrayLength; */
5948 	/* CK_VOID_PTR *ckpElementObject; */
5949 	/* CK_ULONG ckElementLength; */
5950 	/* CK_ULONG i; */
5951   CK_VOID_PTR ckpVoid = *ckpObjectPtr;
5952 	jmethodID jMethod;
5953   jobject jClassObject;
5954   jstring jClassNameString;
5955   jstring jExceptionMessagePrefix;
5956   jobject jExceptionMessageStringBuffer;
5957   jstring jExceptionMessage;
5958 /*#if DEBUG
5959   char buffer[buffer_size];
5960   int i = 0;
5961   for(i; i < buffer_size; i++)
5962   	buffer[i] = '\0';
5963 #endif*/
5964 
5965   TRACE0(tag_call, __FUNCTION__,"entering");
5966 
5967 	if (jObject == NULL) {
5968 		*ckpObjectPtr = NULL;
5969 		*ckpLength = 0;
5970 		TRACE0(tag_debug, __FUNCTION__, "- converted NULL value");
5971 	} else if ((*env)->IsInstanceOf(env, jObject, jLongClass)) {
5972 		*ckpObjectPtr = jLongObjectToCKULongPtr(env, jObject);
5973 		*ckpLength = sizeof(CK_ULONG);
5974 		TRACE1(tag_debug, __FUNCTION__,"- converted long value %X", *((CK_ULONG *) *ckpObjectPtr));
5975 	} else if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) {
5976 		*ckpObjectPtr = jBooleanObjectToCKBBoolPtr(env, jObject);
5977 		*ckpLength = sizeof(CK_BBOOL);
5978 		TRACE0(tag_debug, __FUNCTION__,(*((CK_BBOOL *) *ckpObjectPtr) == TRUE) ? "- converted boolean value TRUE>" : "- converted boolean value FALSE>");
5979 	} else if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) {
5980 		jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*)ckpObjectPtr, ckpLength);
5981 /*#if DEBUG
5982 		byteArrayToHexString((char *)(*ckpObjectPtr), *ckpLength, buffer, buffer_size);
5983 		TRACE1(tag_debug, __FUNCTION__, "- converted byte array: %s", buffer);
5984 #endif*/
5985 	} else if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) {
5986 		jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength);
5987 		TRACE0(tag_debug, __FUNCTION__, "- converted char array");
5988 	} else if ((*env)->IsInstanceOf(env, jObject, jByteClass)) {
5989 		*ckpObjectPtr = jByteObjectToCKBytePtr(env, jObject);
5990 		*ckpLength = sizeof(CK_BYTE);
5991 		TRACE1(tag_debug, __FUNCTION__,"- converted byte value %X", *((CK_BYTE *) *ckpObjectPtr));
5992 	} else if ((*env)->IsInstanceOf(env, jObject, jDateClass)) {
5993 		*ckpObjectPtr = jDateObjectPtrToCKDatePtr(env, jObject);
5994 		*ckpLength = sizeof(CK_DATE);
5995 		TRACE3(tag_debug, __FUNCTION__,"- converted date value %.4s-%.2s-%.2s", (*((CK_DATE *) *ckpObjectPtr)).year,
5996                                                     (*((CK_DATE *) *ckpObjectPtr)).month,
5997                                                     (*((CK_DATE *) *ckpObjectPtr)).day);
5998 	} else if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) {
5999 		*ckpObjectPtr = jCharObjectToCKCharPtr(env, jObject);
6000 		*ckpLength = sizeof(CK_UTF8CHAR);
6001 		TRACE1(tag_debug, __FUNCTION__,"- converted char value %c", *((CK_CHAR *) *ckpObjectPtr));
6002 	} else if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) {
6003 		*ckpObjectPtr = jIntegerObjectToCKULongPtr(env, jObject);
6004 		*ckpLength = sizeof(CK_ULONG);
6005 		TRACE1(tag_debug, __FUNCTION__,"- converted integer value %X", *((CK_ULONG *) *ckpObjectPtr));
6006 	} else if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) {
6007 		jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**)ckpObjectPtr, ckpLength);
6008 		TRACE0(tag_debug, __FUNCTION__, "- converted boolean array");
6009 	} else if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) {
6010 		jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength);
6011 		TRACE0(tag_debug, __FUNCTION__, "- converted int array");
6012 } else if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) {
6013 		jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength);
6014 		*ckpLength = *ckpLength * sizeof(CK_MECHANISM_TYPE);
6015 		TRACE0(tag_debug, __FUNCTION__, "- converted long array");
6016 } else if ((*env)->IsInstanceOf(env, jObject, jStringClass)) {
6017 		jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength);
6018 		TRACE0(tag_debug, __FUNCTION__, "- converted string");
6019 
6020     /* a Java object array is not used by CK_ATTRIBUTE by now... */
6021 /*	} else if ((*env)->IsInstanceOf(env, jObject, jObjectArrayClass)) {
6022 		ckArrayLength = (*env)->GetArrayLength(env, (jarray) jObject);
6023 		ckpObjectPtr = (CK_VOID_PTR_PTR) malloc(sizeof(CK_VOID_PTR) * ckArrayLength);
6024     if (ckpObjectPtr == NULL && ckArrayLength!=0) { *ckpObjectPtr = NULL_PTR; throwOutOfMemoryError(env); return NULL; }
6025 		*ckpLength = 0;
6026 		for (i = 0; i < ckArrayLength; i++) {
6027 			jObjectToPrimitiveCKObjectPtrPtr(env, (*env)->GetObjectArrayElement(env, (jarray) jObject, i),
6028 									   ckpElementObject, &ckElementLength);
6029 			(*ckpObjectPtr)[i] = *ckpElementObject;
6030 			*ckpLength += ckElementLength;
6031 		}
6032 */
6033 	} else {
6034 		/* type of jObject unknown, throw PKCS11RuntimeException */
6035 	  jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;");
6036 	  assert(jMethod != 0);
6037     jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod);
6038 	  assert(jClassObject != 0);
6039 	  jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;");
6040 	  assert(jMethod != 0);
6041     jClassNameString = (jstring)
6042         (*env)->CallObjectMethod(env, jClassObject, jMethod);
6043 	  assert(jClassNameString != 0);
6044     jExceptionMessagePrefix = (*env)->NewStringUTF(env, "Java object of this class cannot be converted to native PKCS#11 type: ");
6045 	  jMethod = (*env)->GetMethodID(env, jStringBufferClass, "<init>", "(Ljava/lang/String;)V");
6046 	  assert(jMethod != 0);
6047     jExceptionMessageStringBuffer = (*env)->NewObject(env, jStringBufferClass, jMethod, jExceptionMessagePrefix);
6048 	  assert(jClassNameString != 0);
6049 	  jMethod = (*env)->GetMethodID(env, jStringBufferClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
6050 	  assert(jMethod != 0);
6051     jExceptionMessage = (jstring)
6052          (*env)->CallObjectMethod(env, jExceptionMessageStringBuffer, jMethod, jClassNameString);
6053 	  assert(jExceptionMessage != 0);
6054 
6055 	  throwPKCS11RuntimeException(env, jExceptionMessage);
6056 
6057 		*ckpObjectPtr = NULL;
6058 		*ckpLength = 0;
6059 	}
6060 
6061   TRACE0(tag_call, __FUNCTION__,"exiting ");
6062 }
6063 
6064 /*
6065  * the following functions convert a Java mechanism parameter object to a PKCS#11
6066  * mechanism parameter structure
6067  *
6068  * CK_<Param>_PARAMS j<Param>ParamToCK<Param>Param(JNIEnv *env,
6069  *                                                 jobject jParam);
6070  *
6071  * These functions get a Java object, that must be the right Java mechanism
6072  * object and they return the new PKCS#11 mechanism parameter structure.
6073  * Every field of the Java object is retrieved, gets converted to a corresponding
6074  * PKCS#11 type and is set in the new PKCS#11 structure.
6075  */
6076 
6077 /*
6078  * converts the given Java mechanism parameter to a CK mechanism parameter structure
6079  * and store the length in bytes in the length variable.
6080  * The memory of *ckpParamPtr has to be freed after use!
6081  *
6082  * @param env - used to call JNI funktions to get the Java classes and objects
6083  * @param jParam - the Java mechanism parameter object to convert
6084  * @param ckpParamPtr - the reference of the new pointer to the new CK mechanism parameter
6085  *                      structure
6086  * @param ckpLength - the reference of the length in bytes of the new CK mechanism parameter
6087  *                    structure
6088  */
jMechanismParameterToCKMechanismParameter(JNIEnv * env,jobject jParam,CK_VOID_PTR * ckpParamPtr,CK_ULONG * ckpLength)6089 void jMechanismParameterToCKMechanismParameter(JNIEnv *env, jobject jParam, CK_VOID_PTR *ckpParamPtr, CK_ULONG *ckpLength)
6090 {
6091 	/* get all Java mechanism parameter classes */
6092 	jclass jByteArrayClass    = (*env)->FindClass(env, "[B");
6093 	jclass jLongClass        = (*env)->FindClass(env, "java/lang/Long");
6094 	jclass jVersionClass    = (*env)->FindClass(env, CLASS_VERSION);
6095 	jclass jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS);
6096 	jclass jKeaDeriveParamsClass = (*env)->FindClass(env, CLASS_KEA_DERIVE_PARAMS);
6097   jclass jRc2CbcParamsClass = (*env)->FindClass(env, CLASS_RC2_CBC_PARAMS);
6098 	jclass jRc2MacGeneralParamsClass = (*env)->FindClass(env, CLASS_RC2_MAC_GENERAL_PARAMS);
6099 	jclass jRc5ParamsClass = (*env)->FindClass(env, CLASS_RC5_PARAMS);
6100   jclass jRc5CbcParamsClass = (*env)->FindClass(env, CLASS_RC5_CBC_PARAMS);
6101 	jclass jRc5MacGeneralParamsClass = (*env)->FindClass(env, CLASS_RC5_MAC_GENERAL_PARAMS);
6102 	jclass jSkipjackPrivateWrapParamsClass = (*env)->FindClass(env, CLASS_SKIPJACK_PRIVATE_WRAP_PARAMS);
6103 	jclass jSkipjackRelayxParamsClass = (*env)->FindClass(env, CLASS_SKIPJACK_RELAYX_PARAMS);
6104 	jclass jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
6105 	jclass jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS);
6106 	jclass jKeyWrapSetOaepParamsClass = (*env)->FindClass(env, CLASS_KEY_WRAP_SET_OAEP_PARAMS);
6107   jclass jKeyDerivationStringDataClass = (*env)->FindClass(env, CLASS_KEY_DERIVATION_STRING_DATA);
6108 	jclass jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
6109 	jclass jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
6110 
6111 	jclass jRsaPkcsPssParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_PSS_PARAMS);
6112 	jclass jEcdh1DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH1_DERIVE_PARAMS);
6113 	jclass jEcdh2DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH2_DERIVE_PARAMS);
6114 	jclass jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS);
6115 	jclass jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS);
6116 	jclass jDesCbcEncryptDataParamsClass = (*env)->FindClass(env, CLASS_DES_CBC_ENCRYPT_DATA_PARAMS);
6117 	jclass jAesCbcEncryptDataParamsClass = (*env)->FindClass(env, CLASS_AES_CBC_ENCRYPT_DATA_PARAMS);
6118 
6119   /* first check the most common cases */
6120 	if (jParam == NULL) {
6121 		*ckpParamPtr = NULL;
6122 		*ckpLength = 0;
6123   } else if ((*env)->IsInstanceOf(env, jParam, jByteArrayClass)) {
6124     jByteArrayToCKByteArray(env, jParam, (CK_BYTE_PTR *)ckpParamPtr, ckpLength);
6125   } else if ((*env)->IsInstanceOf(env, jParam, jLongClass)) {
6126 		*ckpParamPtr = jLongObjectToCKULongPtr(env, jParam);
6127 		*ckpLength = sizeof(CK_ULONG);
6128   } else if ((*env)->IsInstanceOf(env, jParam, jVersionClass)) {
6129 		/*
6130 		 * CK_VERSION used by CKM_SSL3_PRE_MASTER_KEY_GEN
6131 		 */
6132 
6133 		CK_VERSION_PTR ckpParam;
6134 
6135 		/* convert jParameter to CKParameter */
6136 		ckpParam = jVersionToCKVersionPtr(env, jParam);
6137 
6138 		/* get length and pointer of parameter */
6139 		*ckpLength = sizeof(CK_VERSION);
6140 		*ckpParamPtr = ckpParam;
6141 
6142   } else if ((*env)->IsInstanceOf(env, jParam, jRsaPkcsOaepParamsClass)) {
6143 		/*
6144 		 * CK_RSA_PKCS_OAEP_PARAMS
6145 		 */
6146 
6147 		CK_RSA_PKCS_OAEP_PARAMS_PTR ckpParam;
6148 
6149 		ckpParam = (CK_RSA_PKCS_OAEP_PARAMS_PTR) malloc(sizeof(CK_RSA_PKCS_OAEP_PARAMS));
6150     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6151 
6152 		/* convert jParameter to CKParameter */
6153 		*ckpParam = jRsaPkcsOaepParamToCKRsaPkcsOaepParam(env, jParam);
6154 
6155 		/* get length and pointer of parameter */
6156 		*ckpLength = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
6157 		*ckpParamPtr = ckpParam;
6158 
6159 	} else if ((*env)->IsInstanceOf(env, jParam, jKeaDeriveParamsClass)) {
6160 		/*
6161 		 * CK_KEA_DERIVE_PARAMS
6162 		 */
6163 
6164 		CK_KEA_DERIVE_PARAMS_PTR ckpParam;
6165 
6166 		ckpParam = (CK_KEA_DERIVE_PARAMS_PTR) malloc(sizeof(CK_KEA_DERIVE_PARAMS));
6167     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6168 
6169 		/* convert jParameter to CKParameter */
6170 		*ckpParam = jKeaDeriveParamToCKKeaDeriveParam(env, jParam);
6171 
6172 		/* get length and pointer of parameter */
6173 		*ckpLength = sizeof(CK_KEA_DERIVE_PARAMS);
6174 		*ckpParamPtr = ckpParam;
6175 
6176 	} else if ((*env)->IsInstanceOf(env, jParam, jRc2CbcParamsClass)) {
6177 		/*
6178 		 * CK_RC2_CBC_PARAMS
6179 		 */
6180 
6181 		CK_RC2_CBC_PARAMS_PTR ckpParam;
6182 
6183 		ckpParam = (CK_RC2_CBC_PARAMS_PTR) malloc(sizeof(CK_RC2_CBC_PARAMS));
6184     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6185 
6186 		/* convert jParameter to CKParameter */
6187 		*ckpParam = jRc2CbcParamToCKRc2CbcParam(env, jParam);
6188 
6189 		/* get length and pointer of parameter */
6190 		*ckpLength = sizeof(CK_RC2_CBC_PARAMS);
6191 		*ckpParamPtr = ckpParam;
6192 
6193 	} else if ((*env)->IsInstanceOf(env, jParam, jRc2MacGeneralParamsClass)) {
6194 		/*
6195 		 * CK_RC2_MAC_GENERAL_PARAMS
6196 		 */
6197 
6198 		CK_RC2_MAC_GENERAL_PARAMS_PTR ckpParam;
6199 
6200 		ckpParam = (CK_RC2_MAC_GENERAL_PARAMS_PTR) malloc(sizeof(CK_RC2_MAC_GENERAL_PARAMS));
6201     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6202 
6203 		/* convert jParameter to CKParameter */
6204 		*ckpParam = jRc2MacGeneralParamToCKRc2MacGeneralParam(env, jParam);
6205 
6206 		/* get length and pointer of parameter */
6207 		*ckpLength = sizeof(CK_RC2_MAC_GENERAL_PARAMS);
6208 		*ckpParamPtr = ckpParam;
6209 
6210 	} else if ((*env)->IsInstanceOf(env, jParam, jRc5ParamsClass)) {
6211 		/*
6212 		 * CK_RC5_PARAMS
6213 		 */
6214 
6215 		CK_RC5_PARAMS_PTR ckpParam;
6216 
6217 		ckpParam = (CK_RC5_PARAMS_PTR) malloc(sizeof(CK_RC5_PARAMS));
6218     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6219 
6220 		/* convert jParameter to CKParameter */
6221 		*ckpParam = jRc5ParamToCKRc5Param(env, jParam);
6222 
6223 		/* get length and pointer of parameter */
6224 		*ckpLength = sizeof(CK_RC5_PARAMS);
6225 		*ckpParamPtr = ckpParam;
6226 
6227 	} else if ((*env)->IsInstanceOf(env, jParam, jRc5CbcParamsClass)) {
6228 		/*
6229 		 * CK_RC5_CBC_PARAMS
6230 		 */
6231 
6232 		CK_RC5_CBC_PARAMS_PTR ckpParam;
6233 
6234 		ckpParam = (CK_RC5_CBC_PARAMS_PTR) malloc(sizeof(CK_RC5_CBC_PARAMS));
6235     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6236 
6237 		/* convert jParameter to CKParameter */
6238 		*ckpParam = jRc5CbcParamToCKRc5CbcParam(env, jParam);
6239 
6240 		/* get length and pointer of parameter */
6241 		*ckpLength = sizeof(CK_RC5_CBC_PARAMS);
6242 		*ckpParamPtr = ckpParam;
6243 
6244 	} else if ((*env)->IsInstanceOf(env, jParam, jRc5MacGeneralParamsClass)) {
6245 		/*
6246 		 * CK_RC5_MAC_GENERAL_PARAMS
6247 		 */
6248 
6249 		CK_RC5_MAC_GENERAL_PARAMS_PTR ckpParam;
6250 
6251 		ckpParam = (CK_RC5_MAC_GENERAL_PARAMS_PTR) malloc(sizeof(CK_RC5_MAC_GENERAL_PARAMS));
6252     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6253 
6254 		/* convert jParameter to CKParameter */
6255 		*ckpParam = jRc5MacGeneralParamToCKRc5MacGeneralParam(env, jParam);
6256 
6257 		/* get length and pointer of parameter */
6258 		*ckpLength = sizeof(CK_RC5_MAC_GENERAL_PARAMS);
6259 
6260 		*ckpParamPtr = ckpParam;
6261 
6262 	} else if ((*env)->IsInstanceOf(env, jParam, jSkipjackPrivateWrapParamsClass)) {
6263 		/*
6264 		 * CK_SKIPJACK_PRIVATE_WRAP_PARAMS
6265 		 */
6266 
6267 		CK_SKIPJACK_PRIVATE_WRAP_PTR ckpParam;
6268 
6269 		ckpParam = (CK_SKIPJACK_PRIVATE_WRAP_PTR) malloc(sizeof(CK_SKIPJACK_PRIVATE_WRAP_PARAMS));
6270     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6271 
6272 		/* convert jParameter to CKParameter */
6273 		*ckpParam = jSkipjackPrivateWrapParamToCKSkipjackPrivateWrapParam(env, jParam);
6274 
6275 		/* get length and pointer of parameter */
6276 		*ckpLength = sizeof(CK_SKIPJACK_PRIVATE_WRAP_PARAMS);
6277 		*ckpParamPtr = ckpParam;
6278 
6279 	} else if ((*env)->IsInstanceOf(env, jParam, jSkipjackRelayxParamsClass)) {
6280 		/*
6281 		 * CK_SKIPJACK_RELAYX_PARAMS
6282 		 */
6283 
6284 		CK_SKIPJACK_RELAYX_PARAMS_PTR ckpParam;
6285 
6286 		ckpParam = (CK_SKIPJACK_RELAYX_PARAMS_PTR) malloc(sizeof(CK_SKIPJACK_RELAYX_PARAMS));
6287     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6288 
6289 		/* convert jParameter to CKParameter */
6290 		*ckpParam = jSkipjackRelayxParamToCKSkipjackRelayxParam(env, jParam);
6291 
6292 		/* get length and pointer of parameter */
6293 		*ckpLength = sizeof(CK_SKIPJACK_RELAYX_PARAMS);
6294 		*ckpParamPtr = ckpParam;
6295 
6296 	} else if ((*env)->IsInstanceOf(env, jParam, jPbeParamsClass)) {
6297 		/*
6298 		 * CK_PBE_PARAMS
6299 		 */
6300 
6301 		CK_PBE_PARAMS_PTR ckpParam;
6302 
6303 		ckpParam = (CK_PBE_PARAMS_PTR) malloc(sizeof(CK_PBE_PARAMS));
6304     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6305 
6306 		/* convert jParameter to CKParameter */
6307 		*ckpParam = jPbeParamToCKPbeParam(env, jParam);
6308 
6309 		/* get length and pointer of parameter */
6310 		*ckpLength = sizeof(CK_PBE_PARAMS);
6311 		*ckpParamPtr = ckpParam;
6312 
6313 	} else if ((*env)->IsInstanceOf(env, jParam, jPkcs5Pbkd2ParamsClass)) {
6314 		/*
6315 		 * CK_PKCS5_PBKD2_PARAMS
6316 		 */
6317 
6318 		CK_PKCS5_PBKD2_PARAMS_PTR ckpParam;
6319 
6320 		ckpParam = (CK_PKCS5_PBKD2_PARAMS_PTR) malloc(sizeof(CK_PKCS5_PBKD2_PARAMS));
6321     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6322 
6323 		/* convert jParameter to CKParameter */
6324 		*ckpParam = jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(env, jParam);
6325 
6326 		/* get length and pointer of parameter */
6327 		*ckpLength = sizeof(CK_PKCS5_PBKD2_PARAMS);
6328 		*ckpParamPtr = ckpParam;
6329 
6330 	} else if ((*env)->IsInstanceOf(env, jParam, jKeyDerivationStringDataClass)) {
6331 		/*
6332 		 * CK_KEY_DERIVATION_STRING_DATA
6333 		 */
6334 
6335 		CK_KEY_DERIVATION_STRING_DATA_PTR ckpParam;
6336 
6337 		ckpParam = (CK_KEY_DERIVATION_STRING_DATA_PTR) malloc(sizeof(CK_KEY_DERIVATION_STRING_DATA));
6338     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6339 
6340 		/* convert jParameter to CKParameter */
6341 		*ckpParam = jKeyDerivationStringDataToCKKeyDerivationStringData(env, jParam);
6342 
6343 		/* get length and pointer of parameter */
6344 		*ckpLength = sizeof(CK_KEY_DERIVATION_STRING_DATA);
6345 		*ckpParamPtr = ckpParam;
6346 
6347 	} else if ((*env)->IsInstanceOf(env, jParam, jKeyWrapSetOaepParamsClass)) {
6348 		/*
6349 		 * CK_KEY_WRAP_SET_OAEP_PARAMS
6350 		 */
6351 
6352 		CK_KEY_WRAP_SET_OAEP_PARAMS_PTR ckpParam;
6353 
6354 		ckpParam = (CK_KEY_WRAP_SET_OAEP_PARAMS_PTR) malloc(sizeof(CK_KEY_WRAP_SET_OAEP_PARAMS));
6355     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6356 
6357 		/* convert jParameter to CKParameter */
6358 		*ckpParam = jKeyWrapSetOaepParamToCKKeyWrapSetOaepParam(env, jParam);
6359 
6360 		/* get length and pointer of parameter */
6361 		*ckpLength = sizeof(CK_KEY_WRAP_SET_OAEP_PARAMS);
6362 		*ckpParamPtr = ckpParam;
6363 
6364 	} else if ((*env)->IsInstanceOf(env, jParam, jSsl3MasterKeyDeriveParamsClass)) {
6365 		/*
6366 		 * CK_SSL3_MASTER_KEY_DERIVE_PARAMS
6367 		 */
6368 
6369 		CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR ckpParam;
6370 
6371 		ckpParam = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR) malloc(sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS));
6372     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6373 
6374 		/* convert jParameter to CKParameter */
6375 		*ckpParam = jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(env, jParam);
6376 
6377 		/* get length and pointer of parameter */
6378 		*ckpLength = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS);
6379 		*ckpParamPtr = ckpParam;
6380 
6381 	} else if ((*env)->IsInstanceOf(env, jParam, jSsl3KeyMatParamsClass)) {
6382 		/*
6383 		 * CK_SSL3_KEY_MAT_PARAMS
6384 		 */
6385 
6386 		CK_SSL3_KEY_MAT_PARAMS_PTR ckpParam;
6387 
6388 		ckpParam = (CK_SSL3_KEY_MAT_PARAMS_PTR) malloc(sizeof(CK_SSL3_KEY_MAT_PARAMS));
6389     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6390 
6391 		/* convert jParameter to CKParameter */
6392 		*ckpParam = jSsl3KeyMatParamToCKSsl3KeyMatParam(env, jParam);
6393 
6394 		/* get length and pointer of parameter */
6395 		*ckpLength = sizeof(CK_SSL3_KEY_MAT_PARAMS);
6396 		*ckpParamPtr = ckpParam;
6397 
6398 	} else if ((*env)->IsInstanceOf(env, jParam, jRsaPkcsPssParamsClass)) {
6399 		/*
6400 		 * CK_RSA_PKCS_PSS_PARAMS
6401 		 */
6402 
6403 		CK_RSA_PKCS_PSS_PARAMS_PTR ckpParam;
6404 
6405 		ckpParam = (CK_RSA_PKCS_PSS_PARAMS_PTR) malloc(sizeof(CK_RSA_PKCS_PSS_PARAMS));
6406     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6407 
6408 		/* convert jParameter to CKParameter */
6409 		*ckpParam = jRsaPkcsPssParamToCKRsaPkcsPssParam(env, jParam);
6410 
6411 		/* get length and pointer of parameter */
6412 		*ckpLength = sizeof(CK_RSA_PKCS_PSS_PARAMS);
6413 		*ckpParamPtr = ckpParam;
6414 
6415 	} else if ((*env)->IsInstanceOf(env, jParam, jEcdh1DeriveParamsClass)) {
6416 		/*
6417 		 * CK_ECDH1_DERIVE_PARAMS
6418 		 */
6419 
6420 		CK_ECDH1_DERIVE_PARAMS_PTR ckpParam;
6421 
6422 		ckpParam = (CK_ECDH1_DERIVE_PARAMS_PTR) malloc(sizeof(CK_ECDH1_DERIVE_PARAMS));
6423     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6424 
6425 		/* convert jParameter to CKParameter */
6426 		*ckpParam = jEcdh1DeriveParamToCKEcdh1DeriveParam(env, jParam);
6427 
6428 		/* get length and pointer of parameter */
6429 		*ckpLength = sizeof(CK_ECDH1_DERIVE_PARAMS);
6430 		*ckpParamPtr = ckpParam;
6431 
6432 	} else if ((*env)->IsInstanceOf(env, jParam, jEcdh2DeriveParamsClass)) {
6433 		/*
6434 		 * CK_ECDH2_DERIVE_PARAMS
6435 		 */
6436 
6437 		CK_ECDH2_DERIVE_PARAMS_PTR ckpParam;
6438 
6439 		ckpParam = (CK_ECDH2_DERIVE_PARAMS_PTR) malloc(sizeof(CK_ECDH2_DERIVE_PARAMS));
6440     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6441 
6442 		/* convert jParameter to CKParameter */
6443 		*ckpParam = jEcdh2DeriveParamToCKEcdh2DeriveParam(env, jParam);
6444 
6445 		/* get length and pointer of parameter */
6446 		*ckpLength = sizeof(CK_ECDH2_DERIVE_PARAMS);
6447 		*ckpParamPtr = ckpParam;
6448 
6449 	} else if ((*env)->IsInstanceOf(env, jParam, jX942Dh1DeriveParamsClass)) {
6450 		/*
6451 		 * CK_X9_42_DH1_DERIVE_PARAMS
6452 		 */
6453 
6454 		CK_X9_42_DH1_DERIVE_PARAMS_PTR ckpParam;
6455 
6456 		ckpParam = (CK_X9_42_DH1_DERIVE_PARAMS_PTR) malloc(sizeof(CK_X9_42_DH1_DERIVE_PARAMS));
6457     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6458 
6459 		/* convert jParameter to CKParameter */
6460 		*ckpParam = jX942Dh1DeriveParamToCKX942Dh1DeriveParam(env, jParam);
6461 
6462 		/* get length and pointer of parameter */
6463 		*ckpLength = sizeof(CK_X9_42_DH1_DERIVE_PARAMS);
6464 		*ckpParamPtr = ckpParam;
6465 
6466 	} else if ((*env)->IsInstanceOf(env, jParam, jX942Dh2DeriveParamsClass)) {
6467 		/*
6468 		 * CK_X9_42_DH2_DERIVE_PARAMS
6469 		 */
6470 
6471 		CK_X9_42_DH2_DERIVE_PARAMS_PTR ckpParam;
6472 
6473 		ckpParam = (CK_X9_42_DH2_DERIVE_PARAMS_PTR) malloc(sizeof(CK_X9_42_DH2_DERIVE_PARAMS));
6474     if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6475 
6476 		/* convert jParameter to CKParameter */
6477 		*ckpParam = jX942Dh2DeriveParamToCKX942Dh2DeriveParam(env, jParam);
6478 
6479 		/* get length and pointer of parameter */
6480 		*ckpLength = sizeof(CK_X9_42_DH2_DERIVE_PARAMS);
6481 		*ckpParamPtr = ckpParam;
6482 
6483 	} else if ((*env)->IsInstanceOf(env, jParam, jDesCbcEncryptDataParamsClass)) {
6484 		/*
6485 		* CK_DES_CBC_ENCRYPT_DATA_PARAMS
6486 		*/
6487 
6488 		CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR ckpParam;
6489 
6490 		ckpParam = (CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR) malloc(sizeof(CK_DES_CBC_ENCRYPT_DATA_PARAMS));
6491 		if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6492 
6493 		/* convert jParameter to CKParameter */
6494 		*ckpParam = jDesCbcEncryptDataParamToCKDesCbcEncryptData(env, jParam);
6495 
6496 		/* get length and pointer of parameter */
6497 		*ckpLength = sizeof(CK_DES_CBC_ENCRYPT_DATA_PARAMS);
6498 		*ckpParamPtr = ckpParam;
6499 
6500 	} else if ((*env)->IsInstanceOf(env, jParam, jAesCbcEncryptDataParamsClass)) {
6501 		/*
6502 		* CK_AES_CBC_ENCRYPT_DATA_PARAMS
6503 		*/
6504 
6505 		CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR ckpParam;
6506 
6507 		ckpParam = (CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR) malloc(sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS));
6508 		if (ckpParam == NULL) { *ckpParamPtr = NULL_PTR; throwOutOfMemoryError(env); return; }
6509 
6510 		/* convert jParameter to CKParameter */
6511 		*ckpParam = jAesCbcEncryptDataParamToCKAesCbcEncryptData(env, jParam);
6512 
6513 		/* get length and pointer of parameter */
6514 		*ckpLength = sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS);
6515 		*ckpParamPtr = ckpParam;
6516 
6517 	} else {
6518     /* if everything faild up to here */
6519     /* try if the parameter is a primitive Java type */
6520     jObjectToPrimitiveCKObjectPtrPtr(env, jParam, ckpParamPtr, ckpLength);
6521 		/* *ckpParamPtr = jObjectToCKVoidPtr(jParam); */
6522 		/* *ckpLength = 1; */
6523 	}
6524 }
6525 
6526 
6527 /* the mechanism parameter convertion functions: */
6528 
6529 /*
6530  * converts the Java CK_DES_CBC_ENCRYPT_DATA_PARAMS object to a CK_DES_CBC_ENCRYPT_DATA_PARAMS structure
6531  *
6532  * @param env - used to call JNI funktions to get the Java classes and objects
6533  * @param jParam - the Java CK_DES_CBC_ENCRYPT_DATA_PARAMS object to convert
6534  * @return - the new CK_DES_CBC_ENCRYPT_DATA_PARAMS structure
6535  */
jDesCbcEncryptDataParamToCKDesCbcEncryptData(JNIEnv * env,jobject jParam)6536 CK_DES_CBC_ENCRYPT_DATA_PARAMS jDesCbcEncryptDataParamToCKDesCbcEncryptData(JNIEnv *env, jobject jParam)
6537 {
6538 	jclass jDesCbcEncryptDataParamsClass = (*env)->FindClass(env, CLASS_DES_CBC_ENCRYPT_DATA_PARAMS);
6539 	CK_DES_CBC_ENCRYPT_DATA_PARAMS ckParam;
6540 	jfieldID fieldID;
6541 	jobject jObject;
6542 	CK_BYTE_PTR ckpByte;
6543 	CK_LONG ivLength;
6544 
6545 	/* get iv */
6546 	fieldID = (*env)->GetFieldID(env, jDesCbcEncryptDataParamsClass, "iv", "[B");
6547 	assert(fieldID != 0);
6548 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6549 	jByteArrayToCKByteArray(env, jObject, &ckpByte, &ivLength);
6550 	memcpy(ckParam.iv, ckpByte, ivLength);
6551 	free(ckpByte);
6552 
6553 	/* get pData and length */
6554 	fieldID = (*env)->GetFieldID(env, jDesCbcEncryptDataParamsClass, "pData", "[B");
6555 	assert(fieldID != 0);
6556 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6557 	jByteArrayToCKByteArray(env, jObject, &ckpByte, &(ckParam.length));
6558 	ckParam.pData = (CK_VOID_PTR) ckpByte;
6559 
6560 	return ckParam ;
6561 }
6562 
6563 
6564 /*
6565  * converts the Java CK_AES_CBC_ENCRYPT_DATA_PARAMS object to a CK_AES_CBC_ENCRYPT_DATA_PARAMS structure
6566  *
6567  * @param env - used to call JNI funktions to get the Java classes and objects
6568  * @param jParam - the Java CK_AES_CBC_ENCRYPT_DATA_PARAMS object to convert
6569  * @return - the new CK_AES_CBC_ENCRYPT_DATA_PARAMS structure
6570  */
jAesCbcEncryptDataParamToCKAesCbcEncryptData(JNIEnv * env,jobject jParam)6571 CK_AES_CBC_ENCRYPT_DATA_PARAMS jAesCbcEncryptDataParamToCKAesCbcEncryptData(JNIEnv *env, jobject jParam)
6572 {
6573 	jclass jAesCbcEncryptDataParamsClass = (*env)->FindClass(env, CLASS_AES_CBC_ENCRYPT_DATA_PARAMS);
6574 	CK_AES_CBC_ENCRYPT_DATA_PARAMS ckParam;
6575 	jfieldID fieldID;
6576 	jobject jObject;
6577 	CK_BYTE_PTR ckpByte;
6578 	CK_LONG ivLength;
6579 
6580 	/* get iv */
6581 	fieldID = (*env)->GetFieldID(env, jAesCbcEncryptDataParamsClass, "iv", "[B");
6582 	assert(fieldID != 0);
6583 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6584 	jByteArrayToCKByteArray(env, jObject, &ckpByte, &ivLength);
6585 	memcpy(ckParam.iv, ckpByte, ivLength);
6586 	free(ckpByte);
6587 
6588 	/* get pData and length */
6589 	fieldID = (*env)->GetFieldID(env, jAesCbcEncryptDataParamsClass, "pData", "[B");
6590 	assert(fieldID != 0);
6591 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6592 	jByteArrayToCKByteArray(env, jObject, &ckpByte, &(ckParam.length));
6593 	ckParam.pData = (CK_VOID_PTR) ckpByte;
6594 
6595 	return ckParam ;
6596 }
6597 
6598 /*
6599  * converts the Java CK_RSA_PKCS_OAEP_PARAMS object to a CK_RSA_PKCS_OAEP_PARAMS structure
6600  *
6601  * @param env - used to call JNI funktions to get the Java classes and objects
6602  * @param jParam - the Java CK_RSA_PKCS_OAEP_PARAMS object to convert
6603  * @return - the new CK_RSA_PKCS_OAEP_PARAMS structure
6604  */
jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv * env,jobject jParam)6605 CK_RSA_PKCS_OAEP_PARAMS jRsaPkcsOaepParamToCKRsaPkcsOaepParam(JNIEnv *env, jobject jParam)
6606 {
6607 	jclass jRsaPkcsOaepParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_OAEP_PARAMS);
6608 	CK_RSA_PKCS_OAEP_PARAMS ckParam;
6609 	jfieldID fieldID;
6610 	jlong jLong;
6611 	jobject jObject;
6612 	CK_BYTE_PTR ckpByte;
6613 
6614 	/* get hashAlg */
6615 	fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "hashAlg", "J");
6616 	assert(fieldID != 0);
6617 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6618 	ckParam.hashAlg = jLongToCKULong(jLong);
6619 
6620 	/* get mgf */
6621 	fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "mgf", "J");
6622 	assert(fieldID != 0);
6623 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6624 	ckParam.mgf = jLongToCKULong(jLong);
6625 
6626 	/* get source */
6627 	fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "source", "J");
6628 	assert(fieldID != 0);
6629 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6630 	ckParam.source = jLongToCKULong(jLong);
6631 
6632 	/* get sourceData and sourceDataLength */
6633 	fieldID = (*env)->GetFieldID(env, jRsaPkcsOaepParamsClass, "pSourceData", "[B");
6634 	assert(fieldID != 0);
6635 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6636 	jByteArrayToCKByteArray(env, jObject, &ckpByte, &(ckParam.ulSourceDataLen));
6637 	ckParam.pSourceData = (CK_VOID_PTR) ckpByte;
6638 
6639 	return ckParam ;
6640 }
6641 
6642 /*
6643  * converts the Java CK_KEA_DERIVE_PARAMS object to a CK_KEA_DERIVE_PARAMS structure
6644  *
6645  * @param env - used to call JNI funktions to get the Java classes and objects
6646  * @param jParam - the Java CK_KEA_DERIVE_PARAMS object to convert
6647  * @return - the new CK_KEA_DERIVE_PARAMS structure
6648  */
jKeaDeriveParamToCKKeaDeriveParam(JNIEnv * env,jobject jParam)6649 CK_KEA_DERIVE_PARAMS jKeaDeriveParamToCKKeaDeriveParam(JNIEnv *env, jobject jParam)
6650 {
6651 	jclass jKeaDeriveParamsClass = (*env)->FindClass(env, CLASS_KEA_DERIVE_PARAMS);
6652 	CK_KEA_DERIVE_PARAMS ckParam;
6653 	jfieldID fieldID;
6654 	jboolean jBoolean;
6655 	jobject jObject;
6656 	CK_ULONG ckTemp;
6657 
6658 	/* get isSender */
6659 	fieldID = (*env)->GetFieldID(env, jKeaDeriveParamsClass, "isSender", "Z");
6660 	assert(fieldID != 0);
6661 	jBoolean = (*env)->GetBooleanField(env, jParam, fieldID);
6662 	ckParam.isSender = jBooleanToCKBBool(jBoolean);
6663 
6664 	/* get pRandomA and ulRandomLength */
6665 	fieldID = (*env)->GetFieldID(env, jKeaDeriveParamsClass, "pRandomA", "[B");
6666 	assert(fieldID != 0);
6667 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6668 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pRandomA), &ckTemp);
6669 
6670 	/* get pRandomB and ulRandomLength */
6671 	fieldID = (*env)->GetFieldID(env, jKeaDeriveParamsClass, "pRandomB", "[B");
6672 	assert(fieldID != 0);
6673 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6674 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pRandomB), &(ckParam.ulRandomLen));
6675 	/* pRandomA and pRandomB must have the same length */
6676 	assert(ckTemp == ckParam.ulRandomLen);		/* pRandomALength == pRandomBLength */
6677 
6678 	/* get pPublicData and ulPublicDataLength */
6679 	fieldID = (*env)->GetFieldID(env, jKeaDeriveParamsClass, "pPublicData", "[B");
6680 	assert(fieldID != 0);
6681 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6682 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
6683 
6684 	return ckParam ;
6685 }
6686 
6687 /*
6688  * converts the Java CK_RC2_CBC_PARAMS object to a CK_RC2_CBC_PARAMS structure
6689  *
6690  * @param env - used to call JNI funktions to get the Java classes and objects
6691  * @param jParam - the Java CK_RC2_CBC_PARAMS object to convert
6692  * @return - the new CK_RC2_CBC_PARAMS structure
6693  */
jRc2CbcParamToCKRc2CbcParam(JNIEnv * env,jobject jParam)6694 CK_RC2_CBC_PARAMS jRc2CbcParamToCKRc2CbcParam(JNIEnv *env, jobject jParam)
6695 {
6696 	jclass jRc2CbcParamsClass = (*env)->FindClass(env, CLASS_RC2_CBC_PARAMS);
6697 	CK_RC2_CBC_PARAMS ckParam;
6698 	jfieldID fieldID;
6699 	jlong jLong;
6700 	jbyte* jpTemp;
6701 	CK_ULONG i;
6702   jbyteArray jArray;
6703   jint jLength;
6704   CK_ULONG ckLength;
6705 
6706 	/* get ulEffectiveBits */
6707 	fieldID = (*env)->GetFieldID(env, jRc2CbcParamsClass, "ulEffectiveBits", "J");
6708 	assert(fieldID != 0);
6709 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6710 	ckParam.ulEffectiveBits = jLongToCKULong(jLong);
6711 
6712 	/* get iv[8] */
6713 	fieldID = (*env)->GetFieldID(env, jRc2CbcParamsClass, "iv", "[B");
6714 	assert(fieldID != 0);
6715 	jArray = (jbyteArray) (*env)->GetObjectField(env, jParam, fieldID);
6716 	assert(jArray != NULL);
6717 
6718 	jLength = (*env)->GetArrayLength(env, jArray);
6719   assert(jLength == 8); /*  iv is a BYTE[8] array */
6720   ckLength = jIntToCKULong(jLength);
6721 	jpTemp = (jbyte *) malloc(ckLength * sizeof(jbyte));
6722   if (jpTemp == NULL && ckLength!=0) { throwOutOfMemoryError(env); return ckParam; }
6723 	(*env)->GetByteArrayRegion(env, jArray, 0, ckLength, jpTemp);
6724 	for (i=0; i < ckLength; i++) {
6725 		(ckParam.iv)[i] = jByteToCKByte(jpTemp[i]);
6726 	}
6727 	free(jpTemp);
6728 
6729 	return ckParam ;
6730 }
6731 
6732 /*
6733  * converts the Java CK_RC2_MAC_GENERAL_PARAMS object to a CK_RC2_MAC_GENERAL_PARAMS structure
6734  *
6735  * @param env - used to call JNI funktions to get the Java classes and objects
6736  * @param jParam - the Java CK_RC2_MAC_GENERAL_PARAMS object to convert
6737  * @return - the new CK_RC2_MAC_GENERAL_PARAMS structure
6738  */
jRc2MacGeneralParamToCKRc2MacGeneralParam(JNIEnv * env,jobject jParam)6739 CK_RC2_MAC_GENERAL_PARAMS jRc2MacGeneralParamToCKRc2MacGeneralParam(JNIEnv *env, jobject jParam)
6740 {
6741 	jclass jRc2MacGeneralParamsClass = (*env)->FindClass(env, CLASS_RC2_MAC_GENERAL_PARAMS);
6742 	CK_RC2_MAC_GENERAL_PARAMS ckParam;
6743 	jfieldID fieldID;
6744 	jlong jLong;
6745 
6746 	/* get ulEffectiveBits */
6747 	fieldID = (*env)->GetFieldID(env, jRc2MacGeneralParamsClass, "ulEffectiveBits", "J");
6748 	assert(fieldID != 0);
6749 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6750 	ckParam.ulEffectiveBits = jLongToCKULong(jLong);
6751 
6752 	/* get ulMacLength */
6753 	fieldID = (*env)->GetFieldID(env, jRc2MacGeneralParamsClass, "ulMacLength", "J");
6754 	assert(fieldID != 0);
6755 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6756 	ckParam.ulMacLength = jLongToCKULong(jLong);
6757 
6758 	return ckParam ;
6759 }
6760 
6761 /*
6762  * converts the Java CK_RC5_PARAMS object to a CK_RC5_PARAMS structure
6763  *
6764  * @param env - used to call JNI funktions to get the Java classes and objects
6765  * @param jParam - the Java CK_RC5_PARAMS object to convert
6766  * @return - the new CK_RC5_PARAMS structure
6767  */
jRc5ParamToCKRc5Param(JNIEnv * env,jobject jParam)6768 CK_RC5_PARAMS jRc5ParamToCKRc5Param(JNIEnv *env, jobject jParam)
6769 {
6770 	jclass jRc5ParamsClass = (*env)->FindClass(env, CLASS_RC5_PARAMS);
6771 	CK_RC5_PARAMS ckParam;
6772 	jfieldID fieldID;
6773 	jlong jLong;
6774 
6775 	/* get ulWordsize */
6776 	fieldID = (*env)->GetFieldID(env, jRc5ParamsClass, "ulWordsize", "J");
6777 	assert(fieldID != 0);
6778 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6779 	ckParam.ulWordsize = jLongToCKULong(jLong);
6780 
6781 	/* get ulRounds */
6782 	fieldID = (*env)->GetFieldID(env, jRc5ParamsClass, "ulRounds", "J");
6783 	assert(fieldID != 0);
6784 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6785 	ckParam.ulRounds = jLongToCKULong(jLong);
6786 
6787 	return ckParam ;
6788 }
6789 
6790 /*
6791  * converts the Java CK_RC5_CBC_PARAMS object to a CK_RC5_CBC_PARAMS structure
6792  *
6793  * @param env - used to call JNI funktions to get the Java classes and objects
6794  * @param jParam - the Java CK_RC5_CBC_PARAMS object to convert
6795  * @return - the new CK_RC5_CBC_PARAMS structure
6796  */
jRc5CbcParamToCKRc5CbcParam(JNIEnv * env,jobject jParam)6797 CK_RC5_CBC_PARAMS jRc5CbcParamToCKRc5CbcParam(JNIEnv *env, jobject jParam)
6798 {
6799 	jclass jRc5CbcParamsClass = (*env)->FindClass(env, CLASS_RC5_CBC_PARAMS);
6800 	CK_RC5_CBC_PARAMS ckParam;
6801 	jfieldID fieldID;
6802 	jlong jLong;
6803 	jobject jObject;
6804 
6805 	/* get ulWordsize */
6806 	fieldID = (*env)->GetFieldID(env, jRc5CbcParamsClass, "ulWordsize", "J");
6807 	assert(fieldID != 0);
6808 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6809 	ckParam.ulWordsize = jLongToCKULong(jLong);
6810 
6811 	/* get ulRounds */
6812 	fieldID = (*env)->GetFieldID(env, jRc5CbcParamsClass, "ulRounds", "J");
6813 	assert(fieldID != 0);
6814 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6815 	ckParam.ulRounds = jLongToCKULong(jLong);
6816 
6817 	/* get pIv and ulIvLen */
6818 	fieldID = (*env)->GetFieldID(env, jRc5CbcParamsClass, "pIv", "[B");
6819 	assert(fieldID != 0);
6820 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6821 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pIv), &(ckParam.ulIvLen));
6822 
6823 	return ckParam ;
6824 }
6825 
6826 /*
6827  * converts the Java CK_RC5_MAC_GENERAL_PARAMS object to a CK_RC5_MAC_GENERAL_PARAMS structure
6828  *
6829  * @param env - used to call JNI funktions to get the Java classes and objects
6830  * @param jParam - the Java CK_RC5_MAC_GENERAL_PARAMS object to convert
6831  * @return - the new CK_RC5_MAC_GENERAL_PARAMS structure
6832  */
jRc5MacGeneralParamToCKRc5MacGeneralParam(JNIEnv * env,jobject jParam)6833 CK_RC5_MAC_GENERAL_PARAMS jRc5MacGeneralParamToCKRc5MacGeneralParam(JNIEnv *env, jobject jParam)
6834 {
6835 	jclass jRc5MacGeneralParamsClass = (*env)->FindClass(env, CLASS_RC5_MAC_GENERAL_PARAMS);
6836 	CK_RC5_MAC_GENERAL_PARAMS ckParam;
6837 	jfieldID fieldID;
6838 	jlong jLong;
6839 
6840 	/* get ulWordsize */
6841 	fieldID = (*env)->GetFieldID(env, jRc5MacGeneralParamsClass, "ulWordsize", "J");
6842 	assert(fieldID != 0);
6843 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6844 	ckParam.ulWordsize = jLongToCKULong(jLong);
6845 
6846 	/* get ulRounds */
6847 	fieldID = (*env)->GetFieldID(env, jRc5MacGeneralParamsClass, "ulRounds", "J");
6848 	assert(fieldID != 0);
6849 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6850 	ckParam.ulRounds = jLongToCKULong(jLong);
6851 
6852 	/* get ulMacLength */
6853 	fieldID = (*env)->GetFieldID(env, jRc5MacGeneralParamsClass, "ulMacLength", "J");
6854 	assert(fieldID != 0);
6855 	jLong = (*env)->GetLongField(env, jParam, fieldID);
6856 	ckParam.ulMacLength = jLongToCKULong(jLong);
6857 
6858 	return ckParam ;
6859 }
6860 
6861 /*
6862  * converts the Java CK_SKIPJACK_PRIVATE_WRAP_PARAMS object to a CK_SKIPJACK_PRIVATE_WRAP_PARAMS structure
6863  *
6864  * @param env - used to call JNI funktions to get the Java classes and objects
6865  * @param jParam - the Java CK_SKIPJACK_PRIVATE_WRAP_PARAMS object to convert
6866  * @return - the new CK_SKIPJACK_PRIVATE_WRAP_PARAMS structure
6867  */
jSkipjackPrivateWrapParamToCKSkipjackPrivateWrapParam(JNIEnv * env,jobject jParam)6868 CK_SKIPJACK_PRIVATE_WRAP_PARAMS jSkipjackPrivateWrapParamToCKSkipjackPrivateWrapParam(JNIEnv *env, jobject jParam)
6869 {
6870 	jclass jSkipjackPrivateWrapParamsClass = (*env)->FindClass(env, CLASS_SKIPJACK_PRIVATE_WRAP_PARAMS);
6871 	CK_SKIPJACK_PRIVATE_WRAP_PARAMS ckParam;
6872 	jfieldID fieldID;
6873 	jobject jObject;
6874 	CK_ULONG ckTemp;
6875 
6876 	/* get pPassword and ulPasswordLength */
6877 	fieldID = (*env)->GetFieldID(env, jSkipjackPrivateWrapParamsClass, "pPassword", "[B");
6878 	assert(fieldID != 0);
6879 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6880 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPassword), &(ckParam.ulPasswordLen));
6881 
6882 	/* get pPublicData and ulPublicDataLength */
6883 	fieldID = (*env)->GetFieldID(env, jSkipjackPrivateWrapParamsClass, "pPublicData", "[B");
6884 	assert(fieldID != 0);
6885 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6886 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
6887 
6888 	/* get pRandomA and ulRandomLength */
6889 	fieldID = (*env)->GetFieldID(env, jSkipjackPrivateWrapParamsClass, "pRandomA", "[B");
6890 	assert(fieldID != 0);
6891 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6892 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pRandomA), &(ckParam.ulRandomLen));
6893 
6894 	/* get pPrimeP and ulPandGLength */
6895 	fieldID = (*env)->GetFieldID(env, jSkipjackPrivateWrapParamsClass, "pPrimeP", "[B");
6896 	assert(fieldID != 0);
6897 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6898 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPrimeP), &ckTemp);
6899 
6900 	/* get pBaseG and ulPAndGLength */
6901 	fieldID = (*env)->GetFieldID(env, jSkipjackPrivateWrapParamsClass, "pBaseG", "[B");
6902 	assert(fieldID != 0);
6903 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6904 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pBaseG), &(ckParam.ulPAndGLen));
6905 	/* pPrimeP and pBaseG must have the same length */
6906 	assert(ckTemp == ckParam.ulPAndGLen);
6907 
6908 	/* get pSubprimeQ and ulQLength */
6909 	fieldID = (*env)->GetFieldID(env, jSkipjackPrivateWrapParamsClass, "pSubprimeQ", "[B");
6910 	assert(fieldID != 0);
6911 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6912 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pSubprimeQ), &(ckParam.ulQLen));
6913 
6914 	return ckParam ;
6915 }
6916 
6917 /*
6918  * converts the Java CK_SKIPJACK_RELAYX_PARAMS object to a CK_SKIPJACK_RELAYX_PARAMS structure
6919  *
6920  * @param env - used to call JNI funktions to get the Java classes and objects
6921  * @param jParam - the Java CK_SKIPJACK_RELAYX_PARAMS object to convert
6922  * @return - the new CK_SKIPJACK_RELAYX_PARAMS structure
6923  */
jSkipjackRelayxParamToCKSkipjackRelayxParam(JNIEnv * env,jobject jParam)6924 CK_SKIPJACK_RELAYX_PARAMS jSkipjackRelayxParamToCKSkipjackRelayxParam(JNIEnv *env, jobject jParam)
6925 {
6926 	jclass jSkipjackRelayxParamsClass = (*env)->FindClass(env, CLASS_SKIPJACK_RELAYX_PARAMS);
6927 	CK_SKIPJACK_RELAYX_PARAMS ckParam;
6928 	jfieldID fieldID;
6929 	jobject jObject;
6930 
6931 	/* get pOldWrappedX and ulOldWrappedXLength */
6932 	fieldID = (*env)->GetFieldID(env, jSkipjackRelayxParamsClass, "pOldWrappedX", "[B");
6933 	assert(fieldID != 0);
6934 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6935 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pOldWrappedX), &(ckParam.ulOldWrappedXLen));
6936 
6937 	/* get pOldPassword and ulOldPasswordLength */
6938 	fieldID = (*env)->GetFieldID(env, jSkipjackRelayxParamsClass, "pOldPassword", "[B");
6939 	assert(fieldID != 0);
6940 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6941 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pOldPassword), &(ckParam.ulOldPasswordLen));
6942 
6943 	/* get pOldPublicData and ulOldPublicDataLength */
6944 	fieldID = (*env)->GetFieldID(env, jSkipjackRelayxParamsClass, "pOldPublicData", "[B");
6945 	assert(fieldID != 0);
6946 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6947 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pOldPublicData), &(ckParam.ulOldPublicDataLen));
6948 
6949 	/* get pOldRandomA and ulOldRandomLength */
6950 	fieldID = (*env)->GetFieldID(env, jSkipjackRelayxParamsClass, "pOldRandomA", "[B");
6951 	assert(fieldID != 0);
6952 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6953 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pOldRandomA), &(ckParam.ulOldRandomLen));
6954 
6955 	/* get pNewPassword and ulNewPasswordLength */
6956 	fieldID = (*env)->GetFieldID(env, jSkipjackRelayxParamsClass, "pNewPassword", "[B");
6957 	assert(fieldID != 0);
6958 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6959 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pNewPassword), &(ckParam.ulNewPasswordLen));
6960 
6961 	/* get pNewPublicData and ulNewPublicDataLength */
6962 	fieldID = (*env)->GetFieldID(env, jSkipjackRelayxParamsClass, "pNewPublicData", "[B");
6963 	assert(fieldID != 0);
6964 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6965 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pNewPublicData), &(ckParam.ulNewPublicDataLen));
6966 
6967 	/* get pNewRandomA and ulNewRandomLength */
6968 	fieldID = (*env)->GetFieldID(env, jSkipjackRelayxParamsClass, "pNewRandomA", "[B");
6969 	assert(fieldID != 0);
6970 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6971 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pNewRandomA), &(ckParam.ulNewRandomLen));
6972 
6973 	return ckParam ;
6974 }
6975 
6976 /*
6977  * converts the Java CK_PBE_PARAMS object to a CK_PBE_PARAMS structure
6978  *
6979  * @param env - used to call JNI funktions to get the Java classes and objects
6980  * @param jParam - the Java CK_PBE_PARAMS object to convert
6981  * @return - the new CK_PBE_PARAMS structure
6982  */
jPbeParamToCKPbeParam(JNIEnv * env,jobject jParam)6983 CK_PBE_PARAMS jPbeParamToCKPbeParam(JNIEnv *env, jobject jParam)
6984 {
6985 	jclass jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
6986 	CK_PBE_PARAMS ckParam;
6987 	jfieldID fieldID;
6988 	jlong jLong;
6989 	jobject jObject;
6990 	CK_ULONG ckTemp;
6991 
6992 	/* get pInitVector */
6993 	fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVector", "[C");
6994 	assert(fieldID != 0);
6995 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
6996 	jCharArrayToCKCharArray(env, jObject, &(ckParam.pInitVector), &ckTemp);
6997 
6998 	/* get pPassword and ulPasswordLength */
6999 	fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pPassword", "[C");
7000 	assert(fieldID != 0);
7001 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7002 	jCharArrayToCKCharArray(env, jObject, &(ckParam.pPassword), &(ckParam.ulPasswordLen));
7003 
7004 	/* get pSalt and ulSaltLength */
7005 	fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pSalt", "[C");
7006 	assert(fieldID != 0);
7007 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7008 	jCharArrayToCKCharArray(env, jObject, &(ckParam.pSalt), &(ckParam.ulSaltLen));
7009 
7010 	/* get ulIteration */
7011 	fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "ulIteration", "J");
7012 	assert(fieldID != 0);
7013 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7014 	ckParam.ulIteration = jLongToCKULong(jLong);
7015 
7016 	return ckParam ;
7017 }
7018 
7019 /*
7020  * Copy back the initialization vector from the native structure to the
7021  * Java object. This is only used for CKM_PBE_* mechanisms and their
7022  * CK_PBE_PARAMS parameters.
7023  *
7024  */
copyBackPBEInitializationVector(JNIEnv * env,CK_MECHANISM * ckMechanism,jobject jMechanism)7025 void copyBackPBEInitializationVector(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
7026 {
7027 	jclass jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
7028 	jclass jPbeParamsClass = (*env)->FindClass(env, CLASS_PBE_PARAMS);
7029 	CK_PBE_PARAMS *ckParam;
7030 	jfieldID fieldID;
7031   CK_MECHANISM_TYPE ckMechanismType;
7032 	jlong jMechanismType;
7033 	jobject jParameter;
7034 	jobject jInitVector;
7035 	jint jInitVectorLength;
7036   CK_CHAR_PTR initVector;
7037 	int i;
7038 	jchar* jInitVectorChars;
7039 
7040 	/* get mechanism */
7041 	fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
7042 	assert(fieldID != 0);
7043 	jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
7044   ckMechanismType = jLongToCKULong(jMechanismType);
7045   if (ckMechanismType != ckMechanism->mechanism) {
7046     /* we do not have maching types, this should not occur */
7047     return;
7048   }
7049 
7050   ckParam = (CK_PBE_PARAMS *) ckMechanism->pParameter;
7051   if (ckParam != NULL_PTR) {
7052     initVector = ckParam->pInitVector;
7053     if (initVector != NULL_PTR) {
7054 	    /* get pParameter */
7055 	    fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
7056 	    assert(fieldID != 0);
7057 	    jParameter = (*env)->GetObjectField(env, jMechanism, fieldID);
7058 	    fieldID = (*env)->GetFieldID(env, jPbeParamsClass, "pInitVektor", "[C");
7059 	    assert(fieldID != 0);
7060       jInitVector = (*env)->GetObjectField(env, jParameter, fieldID);
7061 
7062       if (jInitVector != NULL) {
7063         jInitVectorLength = (*env)->GetArrayLength(env, jInitVector);
7064         jInitVectorChars = (*env)->GetCharArrayElements(env, jInitVector, NULL);
7065         /* copy the chars to the Java buffer */
7066 	      for (i=0; i < jInitVectorLength; i++) {
7067 		      jInitVectorChars[i] = ckCharToJChar(initVector[i]);
7068 	      }
7069         /* copy back the Java buffer to the object */
7070 	      (*env)->ReleaseCharArrayElements(env, jInitVector, jInitVectorChars, 0);
7071       }
7072     }
7073   }
7074 }
7075 
7076 /*
7077  * converts the Java CK_PKCS5_PBKD2_PARAMS object to a CK_PKCS5_PBKD2_PARAMS structure
7078  *
7079  * @param env - used to call JNI funktions to get the Java classes and objects
7080  * @param jParam - the Java CK_PKCS5_PBKD2_PARAMS object to convert
7081  * @return - the new CK_PKCS5_PBKD2_PARAMS structure
7082  */
jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv * env,jobject jParam)7083 CK_PKCS5_PBKD2_PARAMS jPkcs5Pbkd2ParamToCKPkcs5Pbkd2Param(JNIEnv *env, jobject jParam)
7084 {
7085 	jclass jPkcs5Pbkd2ParamsClass = (*env)->FindClass(env, CLASS_PKCS5_PBKD2_PARAMS);
7086 	CK_PKCS5_PBKD2_PARAMS ckParam;
7087 	jfieldID fieldID;
7088 	jlong jLong;
7089 	jobject jObject;
7090 
7091 	/* get saltSource */
7092 	fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "saltSource", "J");
7093 	assert(fieldID != 0);
7094 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7095 	ckParam.saltSource = jLongToCKULong(jLong);
7096 
7097 	/* get pSaltSourceData */
7098 	fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pSaltSourceData", "[B");
7099 	assert(fieldID != 0);
7100 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7101 	jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR *) &(ckParam.pSaltSourceData), &(ckParam.ulSaltSourceDataLen));
7102 
7103 	/* get iterations */
7104 	fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "iterations", "J");
7105 	assert(fieldID != 0);
7106 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7107 	ckParam.iterations = jLongToCKULong(jLong);
7108 
7109 	/* get prf */
7110 	fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "prf", "J");
7111 	assert(fieldID != 0);
7112 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7113 	ckParam.prf = jLongToCKULong(jLong);
7114 
7115 	/* get pPrfData and ulPrfDataLength in byte */
7116 	fieldID = (*env)->GetFieldID(env, jPkcs5Pbkd2ParamsClass, "pPrfData", "[B");
7117 	assert(fieldID != 0);
7118 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7119 	jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR *) &(ckParam.pPrfData), &(ckParam.ulPrfDataLen));
7120 
7121 	return ckParam ;
7122 }
7123 
7124 /*
7125  * converts the Java CK_KEY_WRAP_SET_OAEP_PARAMS object to a CK_KEY_WRAP_SET_OAEP_PARAMS structure
7126  *
7127  * @param env - used to call JNI funktions to get the Java classes and objects
7128  * @param jParam - the Java CK_KEY_WRAP_SET_OAEP_PARAMS object to convert
7129  * @return - the new CK_KEY_WRAP_SET_OAEP_PARAMS structure
7130  */
jKeyWrapSetOaepParamToCKKeyWrapSetOaepParam(JNIEnv * env,jobject jParam)7131 CK_KEY_WRAP_SET_OAEP_PARAMS jKeyWrapSetOaepParamToCKKeyWrapSetOaepParam(JNIEnv *env, jobject jParam)
7132 {
7133 	jclass jKeyWrapSetOaepParamsClass = (*env)->FindClass(env, CLASS_KEY_WRAP_SET_OAEP_PARAMS);
7134 	CK_KEY_WRAP_SET_OAEP_PARAMS ckParam;
7135 	jfieldID fieldID;
7136 	jbyte jByte;
7137 	jobject jObject;
7138 
7139 	/* get bBC */
7140 	fieldID = (*env)->GetFieldID(env, jKeyWrapSetOaepParamsClass, "bBC", "B");
7141 	assert(fieldID != 0);
7142 	jByte = (*env)->GetByteField(env, jParam, fieldID);
7143 	ckParam.bBC = jByteToCKByte(jByte);
7144 
7145 	/* get pX and ulXLength */
7146 	fieldID = (*env)->GetFieldID(env, jKeyWrapSetOaepParamsClass, "pX", "[B");
7147 	assert(fieldID != 0);
7148 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7149 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pX), &(ckParam.ulXLen));
7150 
7151 	return ckParam ;
7152 }
7153 
7154 /*
7155  * Copy back the unwrapped key info from the native structure to the
7156  * Java object. This is only used for the CK_KEY_WRAP_SET_OAEP_PARAMS
7157  * mechanism when used for unwrapping a key.
7158  *
7159  */
copyBackSetUnwrappedKey(JNIEnv * env,CK_MECHANISM * ckMechanism,jobject jMechanism)7160 void copyBackSetUnwrappedKey(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
7161 {
7162 	jclass jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
7163 	jclass jSetParamsClass = (*env)->FindClass(env, CLASS_KEY_WRAP_SET_OAEP_PARAMS);
7164 	CK_KEY_WRAP_SET_OAEP_PARAMS *ckKeyWrapSetOaepParams;
7165 	jfieldID fieldID;
7166   CK_MECHANISM_TYPE ckMechanismType;
7167 	jlong jMechanismType;
7168   CK_BYTE_PTR x;
7169 	jobject jParameter;
7170 	jobject jx;
7171 	jint jxLength;
7172 	jbyte* jxBytes;
7173 	int i;
7174 
7175 	/* get mechanism */
7176 	fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
7177 	assert(fieldID != 0);
7178 	jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
7179   ckMechanismType = jLongToCKULong(jMechanismType);
7180   if (ckMechanismType != ckMechanism->mechanism) {
7181     /* we do not have maching types, this should not occur */
7182     return;
7183   }
7184 
7185   ckKeyWrapSetOaepParams = (CK_KEY_WRAP_SET_OAEP_PARAMS *) ckMechanism->pParameter;
7186   if (ckKeyWrapSetOaepParams != NULL_PTR) {
7187     x = ckKeyWrapSetOaepParams->pX;
7188     if (x != NULL_PTR) {
7189 	    /* get pParameter */
7190 	    fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
7191 	    assert(fieldID != 0);
7192 	    jParameter = (*env)->GetObjectField(env, jMechanism, fieldID);
7193 
7194       /* copy back the bBC */
7195 	    fieldID = (*env)->GetFieldID(env, jSetParamsClass, "bBC", "B");
7196 	    assert(fieldID != 0);
7197       (*env)->SetByteField(env, jParameter, fieldID, ckKeyWrapSetOaepParams->bBC);
7198 
7199       /* copy back the pX */
7200 	    fieldID = (*env)->GetFieldID(env, jSetParamsClass, "pX", "[B");
7201 	    assert(fieldID != 0);
7202       jx = (*env)->GetObjectField(env, jParameter, fieldID);
7203 
7204       if (jx != NULL) {
7205         jxLength = (*env)->GetArrayLength(env, jx);
7206         jxBytes = (*env)->GetByteArrayElements(env, jx, NULL);
7207         /* copy the bytes to the Java buffer */
7208 	      for (i=0; i < jxLength; i++) {
7209 		      jxBytes[i] = ckByteToJByte(x[i]);
7210 	      }
7211         /* copy back the Java buffer to the object */
7212 	      (*env)->ReleaseByteArrayElements(env, jx, jxBytes, 0);
7213       }
7214     }
7215   }
7216 }
7217 
7218 
7219 /*
7220  * Copy back the client version information from the native
7221  * structure to the Java object. This is only used for the
7222  * CKM_SSL3_MASTER_KEY_DERIVE mechanism when used for deriving a key.
7223  *
7224  */
copyBackClientVersion(JNIEnv * env,CK_MECHANISM * ckMechanism,jobject jMechanism)7225 void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
7226 {
7227 	jclass jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
7228 	jclass jSSL3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
7229 	jclass jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
7230 	CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams;
7231 	CK_VERSION *ckVersion;
7232 	jfieldID fieldID;
7233   CK_MECHANISM_TYPE ckMechanismType;
7234 	jlong jMechanismType;
7235 	jobject jSSL3MasterKeyDeriveParams;
7236 	jobject jVersion;
7237 
7238 	/* get mechanism */
7239 	fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
7240 	assert(fieldID != 0);
7241 	jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
7242   ckMechanismType = jLongToCKULong(jMechanismType);
7243   if (ckMechanismType != ckMechanism->mechanism) {
7244     /* we do not have maching types, this should not occur */
7245     return;
7246   }
7247 
7248   /* get the native CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
7249   ckSSL3MasterKeyDeriveParams = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
7250   if (ckSSL3MasterKeyDeriveParams != NULL_PTR) {
7251     /* get the native CK_VERSION */
7252     ckVersion = ckSSL3MasterKeyDeriveParams->pVersion;
7253     if (ckVersion != NULL_PTR) {
7254       /* get the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS (pParameter) */
7255 	    fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
7256 	    assert(fieldID != 0);
7257 	    jSSL3MasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID);
7258 
7259       /* get the Java CK_VERSION */
7260 	    fieldID = (*env)->GetFieldID(env, jSSL3MasterKeyDeriveParamsClass, "pVersion", "L"CLASS_VERSION";");
7261 	    assert(fieldID != 0);
7262       jVersion = (*env)->GetObjectField(env, jSSL3MasterKeyDeriveParams, fieldID);
7263 
7264       /* now copy back the version from the native structure to the Java structure */
7265 
7266       /* copy back the major version */
7267  	    fieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
7268 	    assert(fieldID != 0);
7269       (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->major));
7270 
7271       /* copy back the minor version */
7272 	    fieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
7273 	    assert(fieldID != 0);
7274       (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->minor));
7275     }
7276   }
7277 }
7278 
7279 
7280 /*
7281  * Copy back the derived keys and initialization vectors from the native
7282  * structure to the Java object. This is only used for the
7283  * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key.
7284  *
7285  */
copyBackSSLKeyMatParams(JNIEnv * env,CK_MECHANISM * ckMechanism,jobject jMechanism)7286 void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
7287 {
7288 	jclass jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
7289 	jclass jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
7290 	jclass jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
7291 	CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam;
7292 	CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut;
7293 	jfieldID fieldID;
7294   CK_MECHANISM_TYPE ckMechanismType;
7295 	jlong jMechanismType;
7296   CK_BYTE_PTR iv;
7297 	jobject jSSL3KeyMatParam;
7298 	jobject jSSL3KeyMatOut;
7299 	jobject jIV;
7300 	jint jLength;
7301 	jbyte* jBytes;
7302 	int i;
7303 
7304 	/* get mechanism */
7305 	fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
7306 	assert(fieldID != 0);
7307 	jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
7308   ckMechanismType = jLongToCKULong(jMechanismType);
7309   if (ckMechanismType != ckMechanism->mechanism) {
7310     /* we do not have maching types, this should not occur */
7311     return;
7312   }
7313 
7314   /* get the native CK_SSL3_KEY_MAT_PARAMS */
7315   ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter;
7316   if (ckSSL3KeyMatParam != NULL_PTR) {
7317     /* get the native CK_SSL3_KEY_MAT_OUT */
7318     ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial;
7319     if (ckSSL3KeyMatOut != NULL_PTR) {
7320       /* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */
7321 	    fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
7322 	    assert(fieldID != 0);
7323 	    jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID);
7324 
7325       /* get the Java CK_SSL3_KEY_MAT_OUT */
7326 	    fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";");
7327 	    assert(fieldID != 0);
7328       jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID);
7329 
7330       /* now copy back all the key handles and the initialization vectors */
7331       /* copy back client MAC secret handle */
7332 	    fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J");
7333 	    assert(fieldID != 0);
7334       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret));
7335 
7336       /* copy back server MAC secret handle */
7337 	    fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J");
7338 	    assert(fieldID != 0);
7339       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret));
7340 
7341       /* copy back client secret key handle */
7342 	    fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J");
7343 	    assert(fieldID != 0);
7344       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey));
7345 
7346       /* copy back server secret key handle */
7347 	    fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J");
7348 	    assert(fieldID != 0);
7349       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey));
7350 
7351       /* copy back the client IV */
7352 	    fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B");
7353 	    assert(fieldID != 0);
7354       jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
7355       iv = ckSSL3KeyMatOut->pIVClient;
7356 
7357       if (jIV != NULL) {
7358         jLength = (*env)->GetArrayLength(env, jIV);
7359         jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
7360         /* copy the bytes to the Java buffer */
7361 	      for (i=0; i < jLength; i++) {
7362 		      jBytes[i] = ckByteToJByte(iv[i]);
7363 	      }
7364         /* copy back the Java buffer to the object */
7365 	      (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
7366       }
7367 
7368       /* copy back the server IV */
7369 	    fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B");
7370 	    assert(fieldID != 0);
7371       jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
7372       iv = ckSSL3KeyMatOut->pIVServer;
7373 
7374       if (jIV != NULL) {
7375         jLength = (*env)->GetArrayLength(env, jIV);
7376         jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
7377         /* copy the bytes to the Java buffer */
7378 	      for (i=0; i < jLength; i++) {
7379 		      jBytes[i] = ckByteToJByte(iv[i]);
7380 	      }
7381         /* copy back the Java buffer to the object */
7382 	      (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
7383       }
7384     }
7385   }
7386 }
7387 
7388 
7389 /*
7390  * converts the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to a
7391  * CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
7392  *
7393  * @param env - used to call JNI funktions to get the Java classes and objects
7394  * @param jParam - the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS object to convert
7395  * @return - the new CK_SSL3_MASTER_KEY_DERIVE_PARAMS structure
7396  */
jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv * env,jobject jParam)7397 CK_SSL3_MASTER_KEY_DERIVE_PARAMS jSsl3MasterKeyDeriveParamToCKSsl3MasterKeyDeriveParam(JNIEnv *env, jobject jParam)
7398 {
7399 	jclass jSsl3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
7400 	CK_SSL3_MASTER_KEY_DERIVE_PARAMS ckParam;
7401 	jfieldID fieldID;
7402 	jobject jObject;
7403 	jclass jSsl3RandomDataClass;
7404 	jobject jRandomInfo;
7405 
7406 	/* get RandomInfo */
7407 	jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA);
7408 	fieldID = (*env)->GetFieldID(env, jSsl3MasterKeyDeriveParamsClass, "RandomInfo", CLASS_NAME(CLASS_SSL3_RANDOM_DATA));
7409 	assert(fieldID != 0);
7410 	jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID);
7411 
7412 	/* get pClientRandom and ulClientRandomLength out of RandomInfo */
7413 	fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B");
7414 	assert(fieldID != 0);
7415 	jObject = (*env)->GetObjectField(env, jRandomInfo, fieldID);
7416 	jByteArrayToCKByteArray(env, jObject, &(ckParam.RandomInfo.pClientRandom), &(ckParam.RandomInfo.ulClientRandomLen));
7417 
7418 	/* get pServerRandom and ulServerRandomLength out of RandomInfo */
7419 	fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B");
7420 	assert(fieldID != 0);
7421 	jObject = (*env)->GetObjectField(env, jRandomInfo, fieldID);
7422 	jByteArrayToCKByteArray(env, jObject, &(ckParam.RandomInfo.pServerRandom), &(ckParam.RandomInfo.ulServerRandomLen));
7423 
7424 	/* get pVersion */
7425 	fieldID = (*env)->GetFieldID(env, jSsl3MasterKeyDeriveParamsClass, "pVersion", CLASS_NAME(CLASS_VERSION));
7426 	assert(fieldID != 0);
7427 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7428 	ckParam.pVersion = jVersionToCKVersionPtr(env, jObject);
7429 
7430 	return ckParam ;
7431 }
7432 
7433 /*
7434  * converts the Java CK_SSL3_KEY_MAT_PARAMS object to a CK_SSL3_KEY_MAT_PARAMS structure
7435  *
7436  * @param env - used to call JNI funktions to get the Java classes and objects
7437  * @param jParam - the Java CK_SSL3_KEY_MAT_PARAMS object to convert
7438  * @return - the new CK_SSL3_KEY_MAT_PARAMS structure
7439  */
jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv * env,jobject jParam)7440 CK_SSL3_KEY_MAT_PARAMS jSsl3KeyMatParamToCKSsl3KeyMatParam(JNIEnv *env, jobject jParam)
7441 {
7442 	jclass jSsl3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
7443 	CK_SSL3_KEY_MAT_PARAMS ckParam;
7444 	jfieldID fieldID;
7445 	jlong jLong;
7446 	jboolean jBoolean;
7447 	jobject jObject;
7448 	jobject jRandomInfo;
7449 	jobject jReturnedKeyMaterial;
7450 	jclass jSsl3RandomDataClass;
7451 	jclass jSsl3KeyMatOutClass;
7452 	CK_ULONG ckTemp;
7453 
7454 	/* get ulMacSizeInBits */
7455 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulMacSizeInBits", "J");
7456 	assert(fieldID != 0);
7457 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7458 	ckParam.ulMacSizeInBits = jLongToCKULong(jLong);
7459 
7460 	/* get ulKeySizeInBits */
7461 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulKeySizeInBits", "J");
7462 	assert(fieldID != 0);
7463 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7464 	ckParam.ulKeySizeInBits = jLongToCKULong(jLong);
7465 
7466 	/* get ulIVSizeInBits */
7467 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "ulIVSizeInBits", "J");
7468 	assert(fieldID != 0);
7469 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7470 	ckParam.ulIVSizeInBits = jLongToCKULong(jLong);
7471 
7472 	/* get bIsExport */
7473 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "bIsExport", "Z");
7474 	assert(fieldID != 0);
7475 	jBoolean = (*env)->GetBooleanField(env, jParam, fieldID);
7476 	ckParam.bIsExport = jBooleanToCKBBool(jBoolean);
7477 
7478 	/* get RandomInfo */
7479 	jSsl3RandomDataClass = (*env)->FindClass(env, CLASS_SSL3_RANDOM_DATA);
7480 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "RandomInfo", CLASS_NAME(CLASS_SSL3_RANDOM_DATA));
7481 	assert(fieldID != 0);
7482 	jRandomInfo = (*env)->GetObjectField(env, jParam, fieldID);
7483 
7484 	/* get pClientRandom and ulClientRandomLength out of RandomInfo */
7485 	fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pClientRandom", "[B");
7486 	assert(fieldID != 0);
7487 	jObject = (*env)->GetObjectField(env, jRandomInfo, fieldID);
7488 	jByteArrayToCKByteArray(env, jObject, &(ckParam.RandomInfo.pClientRandom), &(ckParam.RandomInfo.ulClientRandomLen));
7489 
7490 	/* get pServerRandom and ulServerRandomLength out of RandomInfo */
7491 	fieldID = (*env)->GetFieldID(env, jSsl3RandomDataClass, "pServerRandom", "[B");
7492 	assert(fieldID != 0);
7493 	jObject = (*env)->GetObjectField(env, jRandomInfo, fieldID);
7494 	jByteArrayToCKByteArray(env, jObject, &(ckParam.RandomInfo.pServerRandom), &(ckParam.RandomInfo.ulServerRandomLen));
7495 
7496 	/* get pReturnedKeyMaterial */
7497 	jSsl3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
7498 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatParamsClass, "pReturnedKeyMaterial", CLASS_NAME(CLASS_SSL3_KEY_MAT_OUT));
7499 	assert(fieldID != 0);
7500 	jReturnedKeyMaterial = (*env)->GetObjectField(env, jParam, fieldID);
7501 
7502 	/* allocate memory for pRetrunedKeyMaterial */
7503 	ckParam.pReturnedKeyMaterial = (CK_SSL3_KEY_MAT_OUT_PTR) malloc(sizeof(CK_SSL3_KEY_MAT_OUT));
7504   if (ckParam.pReturnedKeyMaterial == NULL) { throwOutOfMemoryError(env); return ckParam; }
7505 
7506 	/* get hClientMacSecret out of pReturnedKeyMaterial */
7507 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "hClientMacSecret", "J");
7508 	assert(fieldID != 0);
7509 	jLong = (*env)->GetLongField(env, jReturnedKeyMaterial, fieldID);
7510 	ckParam.pReturnedKeyMaterial->hClientMacSecret = jLongToCKULong(jLong);
7511 
7512 	/* get hServerMacSecret out of pReturnedKeyMaterial */
7513 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "hServerMacSecret", "J");
7514 	assert(fieldID != 0);
7515 	jLong = (*env)->GetLongField(env, jReturnedKeyMaterial, fieldID);
7516 	ckParam.pReturnedKeyMaterial->hServerMacSecret = jLongToCKULong(jLong);
7517 
7518 	/* get hClientKey out of pReturnedKeyMaterial */
7519 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "hClientKey", "J");
7520 	assert(fieldID != 0);
7521 	jLong = (*env)->GetLongField(env, jReturnedKeyMaterial, fieldID);
7522 	ckParam.pReturnedKeyMaterial->hClientKey = jLongToCKULong(jLong);
7523 
7524 	/* get hServerKey out of pReturnedKeyMaterial */
7525 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "hServerKey", "J");
7526 	assert(fieldID != 0);
7527 	jLong = (*env)->GetLongField(env, jReturnedKeyMaterial, fieldID);
7528 	ckParam.pReturnedKeyMaterial->hServerKey = jLongToCKULong(jLong);
7529 
7530 	/* get pIVClient out of pReturnedKeyMaterial */
7531 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVClient", "[B");
7532 	assert(fieldID != 0);
7533 	jObject = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID);
7534 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pReturnedKeyMaterial->pIVClient), &ckTemp);
7535 
7536 	/* get pIVServer out of pReturnedKeyMaterial */
7537 	fieldID = (*env)->GetFieldID(env, jSsl3KeyMatOutClass, "pIVServer", "[B");
7538 	assert(fieldID != 0);
7539 	jObject = (*env)->GetObjectField(env, jReturnedKeyMaterial, fieldID);
7540 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pReturnedKeyMaterial->pIVServer), &ckTemp);
7541 
7542 	return ckParam ;
7543 }
7544 
7545 /*
7546  * converts the Java CK_KEY_DERIVATION_STRING_DATA object to a
7547  * CK_KEY_DERIVATION_STRING_DATA structure
7548  *
7549  * @param env - used to call JNI funktions to get the Java classes and objects
7550  * @param jParam - the Java CK_KEY_DERIVATION_STRING_DATA object to convert
7551  * @return - the new CK_KEY_DERIVATION_STRING_DATA structure
7552  */
jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv * env,jobject jParam)7553 CK_KEY_DERIVATION_STRING_DATA jKeyDerivationStringDataToCKKeyDerivationStringData(JNIEnv *env, jobject jParam)
7554 {
7555 	jclass jKeyDerivationStringDataClass = (*env)->FindClass(env, CLASS_KEY_DERIVATION_STRING_DATA);
7556 	CK_KEY_DERIVATION_STRING_DATA ckParam;
7557 	jfieldID fieldID;
7558 	jobject jObject;
7559 
7560   /* get pData */
7561 	fieldID = (*env)->GetFieldID(env, jKeyDerivationStringDataClass, "pData", "[B");
7562 	assert(fieldID != 0);
7563 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7564 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pData), &(ckParam.ulLen));
7565 
7566 	return ckParam ;
7567 }
7568 
7569 /*
7570  * converts the Java CK_RSA_PKCS_PSS_PARAMS object to a CK_RSA_PKCS_PSS_PARAMS structure
7571  *
7572  * @param env - used to call JNI funktions to get the Java classes and objects
7573  * @param jParam - the Java CK_RSA_PKCS_PSS_PARAMS object to convert
7574  * @return - the new CK_RSA_PKCS_PSS_PARAMS structure
7575  */
jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv * env,jobject jParam)7576 CK_RSA_PKCS_PSS_PARAMS jRsaPkcsPssParamToCKRsaPkcsPssParam(JNIEnv *env, jobject jParam)
7577 {
7578 	jclass jRsaPkcsPssParamsClass = (*env)->FindClass(env, CLASS_RSA_PKCS_PSS_PARAMS);
7579 	CK_RSA_PKCS_PSS_PARAMS ckParam;
7580 	jfieldID fieldID;
7581 	jlong jLong;
7582 
7583 	/* get hashAlg */
7584 	fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "hashAlg", "J");
7585 	assert(fieldID != 0);
7586 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7587 	ckParam.hashAlg = jLongToCKULong(jLong);
7588 
7589 	/* get mgf */
7590 	fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "mgf", "J");
7591 	assert(fieldID != 0);
7592 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7593 	ckParam.mgf = jLongToCKULong(jLong);
7594 
7595 	/* get sLen */
7596 	fieldID = (*env)->GetFieldID(env, jRsaPkcsPssParamsClass, "sLen", "J");
7597 	assert(fieldID != 0);
7598 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7599 	ckParam.sLen = jLongToCKULong(jLong);
7600 
7601 	return ckParam ;
7602 }
7603 
7604 /*
7605  * converts the Java CK_ECDH1_DERIVE_PARAMS object to a CK_ECDH1_DERIVE_PARAMS structure
7606  *
7607  * @param env - used to call JNI funktions to get the Java classes and objects
7608  * @param jParam - the Java CK_ECDH1_DERIVE_PARAMS object to convert
7609  * @return - the new CK_ECDH1_DERIVE_PARAMS structure
7610  */
jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv * env,jobject jParam)7611 CK_ECDH1_DERIVE_PARAMS jEcdh1DeriveParamToCKEcdh1DeriveParam(JNIEnv *env, jobject jParam)
7612 {
7613 	jclass jEcdh1DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH1_DERIVE_PARAMS);
7614 	CK_ECDH1_DERIVE_PARAMS ckParam;
7615 	jfieldID fieldID;
7616 	jlong jLong;
7617 	jobject jObject;
7618 
7619 	/* get kdf */
7620 	fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "kdf", "J");
7621 	assert(fieldID != 0);
7622 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7623 	ckParam.kdf = jLongToCKULong(jLong);
7624 
7625 	/* get pSharedData and ulSharedDataLen */
7626 	fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "pSharedData", "[B");
7627 	assert(fieldID != 0);
7628 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7629 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pSharedData), &(ckParam.ulSharedDataLen));
7630 
7631 	/* get pPublicData and ulPublicDataLen */
7632 	fieldID = (*env)->GetFieldID(env, jEcdh1DeriveParamsClass, "pPublicData", "[B");
7633 	assert(fieldID != 0);
7634 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7635 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
7636 
7637 	return ckParam ;
7638 }
7639 
7640 /*
7641  * converts the Java CK_ECDH2_DERIVE_PARAMS object to a CK_ECDH2_DERIVE_PARAMS structure
7642  *
7643  * @param env - used to call JNI funktions to get the Java classes and objects
7644  * @param jParam - the Java CK_ECDH2_DERIVE_PARAMS object to convert
7645  * @return - the new CK_ECDH2_DERIVE_PARAMS structure
7646  */
jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv * env,jobject jParam)7647 CK_ECDH2_DERIVE_PARAMS jEcdh2DeriveParamToCKEcdh2DeriveParam(JNIEnv *env, jobject jParam)
7648 {
7649 	jclass jEcdh2DeriveParamsClass = (*env)->FindClass(env, CLASS_ECDH2_DERIVE_PARAMS);
7650 	CK_ECDH2_DERIVE_PARAMS ckParam;
7651 	jfieldID fieldID;
7652 	jlong jLong;
7653 	jobject jObject;
7654 
7655 	/* get kdf */
7656 	fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "kdf", "J");
7657 	assert(fieldID != 0);
7658 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7659 	ckParam.kdf = jLongToCKULong(jLong);
7660 
7661 	/* get pSharedData and ulSharedDataLen */
7662 	fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pSharedData", "[B");
7663 	assert(fieldID != 0);
7664 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7665 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pSharedData), &(ckParam.ulSharedDataLen));
7666 
7667 	/* get pPublicData and ulPublicDataLen */
7668 	fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pPublicData", "[B");
7669 	assert(fieldID != 0);
7670 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7671 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
7672 
7673 	/* get ulPrivateDataLen */
7674 	fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "ulPrivateDataLen", "J");
7675 	assert(fieldID != 0);
7676 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7677 	ckParam.ulPrivateDataLen = jLongToCKULong(jLong);
7678 
7679 	/* get hPrivateData */
7680 	fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "hPrivateData", "J");
7681 	assert(fieldID != 0);
7682 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7683 	ckParam.hPrivateData = jLongToCKULong(jLong);
7684 
7685 	/* get pPublicData2 and ulPublicDataLen2 */
7686 	fieldID = (*env)->GetFieldID(env, jEcdh2DeriveParamsClass, "pPublicData2", "[B");
7687 	assert(fieldID != 0);
7688 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7689 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPublicData2), &(ckParam.ulPublicDataLen2));
7690 
7691 	return ckParam ;
7692 }
7693 
7694 /*
7695  * converts the Java CK_X9_42_DH1_DERIVE_PARAMS object to a CK_X9_42_DH1_DERIVE_PARAMS structure
7696  *
7697  * @param env - used to call JNI funktions to get the Java classes and objects
7698  * @param jParam - the Java CK_X9_42_DH1_DERIVE_PARAMS object to convert
7699  * @return - the new CK_X9_42_DH1_DERIVE_PARAMS structure
7700  */
jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv * env,jobject jParam)7701 CK_X9_42_DH1_DERIVE_PARAMS jX942Dh1DeriveParamToCKX942Dh1DeriveParam(JNIEnv *env, jobject jParam)
7702 {
7703 	jclass jX942Dh1DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH1_DERIVE_PARAMS);
7704 	CK_X9_42_DH1_DERIVE_PARAMS ckParam;
7705 	jfieldID fieldID;
7706 	jlong jLong;
7707 	jobject jObject;
7708 
7709 	/* get kdf */
7710 	fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "kdf", "J");
7711 	assert(fieldID != 0);
7712 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7713 	ckParam.kdf = jLongToCKULong(jLong);
7714 
7715 	/* get pOtherInfo and ulOtherInfoLen */
7716 	fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "pOtherInfo", "[B");
7717 	assert(fieldID != 0);
7718 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7719 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pOtherInfo), &(ckParam.ulOtherInfoLen));
7720 
7721 	/* get pPublicData and ulPublicDataLen */
7722 	fieldID = (*env)->GetFieldID(env, jX942Dh1DeriveParamsClass, "pPublicData", "[B");
7723 	assert(fieldID != 0);
7724 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7725 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
7726 
7727 	return ckParam ;
7728 }
7729 
7730 /*
7731  * converts the Java CK_X9_42_DH2_DERIVE_PARAMS object to a CK_X9_42_DH2_DERIVE_PARAMS structure
7732  *
7733  * @param env - used to call JNI funktions to get the Java classes and objects
7734  * @param jParam - the Java CK_X9_42_DH2_DERIVE_PARAMS object to convert
7735  * @return - the new CK_X9_42_DH2_DERIVE_PARAMS structure
7736  */
jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv * env,jobject jParam)7737 CK_X9_42_DH2_DERIVE_PARAMS jX942Dh2DeriveParamToCKX942Dh2DeriveParam(JNIEnv *env, jobject jParam)
7738 {
7739 	jclass jX942Dh2DeriveParamsClass = (*env)->FindClass(env, CLASS_X9_42_DH2_DERIVE_PARAMS);
7740 	CK_X9_42_DH2_DERIVE_PARAMS ckParam;
7741 	jfieldID fieldID;
7742 	jlong jLong;
7743 	jobject jObject;
7744 
7745 	/* get kdf */
7746 	fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "kdf", "J");
7747 	assert(fieldID != 0);
7748 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7749 	ckParam.kdf = jLongToCKULong(jLong);
7750 
7751 	/* get pOtherInfo and ulOtherInfoLen */
7752 	fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pOtherInfo", "[B");
7753 	assert(fieldID != 0);
7754 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7755 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pOtherInfo), &(ckParam.ulOtherInfoLen));
7756 
7757 	/* get pPublicData and ulPublicDataLen */
7758 	fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pPublicData", "[B");
7759 	assert(fieldID != 0);
7760 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7761 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPublicData), &(ckParam.ulPublicDataLen));
7762 
7763 	/* get ulPrivateDataLen */
7764 	fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "ulPrivateDataLen", "J");
7765 	assert(fieldID != 0);
7766 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7767 	ckParam.ulPrivateDataLen = jLongToCKULong(jLong);
7768 
7769 	/* get hPrivateData */
7770 	fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "hPrivateData", "J");
7771 	assert(fieldID != 0);
7772 	jLong = (*env)->GetLongField(env, jParam, fieldID);
7773 	ckParam.hPrivateData = jLongToCKULong(jLong);
7774 
7775 	/* get pPublicData2 and ulPublicDataLen2 */
7776 	fieldID = (*env)->GetFieldID(env, jX942Dh2DeriveParamsClass, "pPublicData2", "[B");
7777 	assert(fieldID != 0);
7778 	jObject = (*env)->GetObjectField(env, jParam, fieldID);
7779 	jByteArrayToCKByteArray(env, jObject, &(ckParam.pPublicData2), &(ckParam.ulPublicDataLen2));
7780 
7781 	return ckParam ;
7782 }
7783 
7784 
7785 
7786 
7787 /* ************************************************************************** */
7788 /* Functions for keeping track of currently active and loaded modules         */
7789 /* ************************************************************************** */
7790 
7791 
7792 /*
7793  * Create a new object for locking.
7794  */
createLockObject(JNIEnv * env)7795 jobject createLockObject(JNIEnv *env) {
7796 	jclass jObjectClass;
7797   jobject jLockObject;
7798   jmethodID jConstructor;
7799 
7800   jObjectClass = (*env)->FindClass(env, "java/lang/Object");
7801 	assert(jObjectClass != 0);
7802 	jConstructor = (*env)->GetMethodID(env, jObjectClass, "<init>", "()V");
7803 	assert(jConstructor != 0);
7804 	jLockObject = (*env)->NewObject(env, jObjectClass, jConstructor);
7805 	assert(jLockObject != 0);
7806   jLockObject = (*env)->NewGlobalRef(env, jLockObject);
7807 
7808   return jLockObject ;
7809 }
7810 
7811 /*
7812  * Create a new object for locking.
7813  */
destroyLockObject(JNIEnv * env,jobject jLockObject)7814 void destroyLockObject(JNIEnv *env, jobject jLockObject) {
7815 	if (jLockObject != NULL) {
7816 		(*env)->DeleteGlobalRef(env, jLockObject);
7817 	}
7818 }
7819 
7820 /*
7821  * Add the given pkcs11Implementation object to the list of present modules.
7822  * Attach the given data to the entry. If the given pkcs11Implementation is
7823  * already in the lsit, just override its old module data with the new one.
7824  * None of the arguments can be NULL. If one of the arguments is NULL, this
7825  * function does nothing.
7826  */
putModuleEntry(JNIEnv * env,jobject pkcs11Implementation,ModuleData * moduleData)7827 void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData) {
7828   ModuleListNode *currentNode, *newNode;
7829 
7830   if (pkcs11Implementation == NULL_PTR) {
7831     return ;
7832   }
7833   if (moduleData == NULL) {
7834     return ;
7835   }
7836 
7837   (*env)->MonitorEnter(env, moduleListLock); /* synchronize access to list */
7838 
7839   if (moduleListHead == NULL) {
7840     /* this is the first entry */
7841     newNode = (ModuleListNode *) malloc(sizeof(ModuleListNode));
7842     if (newNode == NULL) { throwOutOfMemoryError(env); return; }
7843     newNode->pkcs11Implementation = pkcs11Implementation;
7844     newNode->moduleData = moduleData;
7845     newNode->next = NULL;
7846 
7847     moduleListHead = newNode;
7848   } else {
7849     /* go to the last entry; i.e. the first node which's 'next' is NULL.
7850      * we also stop, when we the pkcs11Implementation object is already in the list.
7851      * then we override the old moduleData with the new one
7852      */
7853     currentNode = moduleListHead;
7854     while ((currentNode->next != NULL) && (!equals(env, pkcs11Implementation, currentNode->pkcs11Implementation))) {
7855       currentNode = currentNode->next;
7856     }
7857     if (!equals(env, pkcs11Implementation, currentNode->pkcs11Implementation)) {
7858       /* this pkcs11Implementation is not present yet, append the new node */
7859       newNode = (ModuleListNode *) malloc(sizeof(ModuleListNode));
7860       if (newNode == NULL) { throwOutOfMemoryError(env); return; }
7861       newNode->pkcs11Implementation = pkcs11Implementation;
7862       newNode->moduleData = moduleData;
7863       newNode->next = NULL;
7864 
7865       currentNode->next = newNode;
7866     } else {
7867       /* this pkcs11Implementation is already present, set the new moduleData */
7868       currentNode->moduleData = moduleData;
7869     }
7870   }
7871 
7872   (*env)->MonitorExit(env, moduleListLock); /* synchronize access to list */
7873 }
7874 
7875 
7876 /*
7877  * Get the module data of the entry for the given pkcs11Implementation. Returns
7878  * NULL, if the pkcs11Implementation is not in the list.
7879  */
getModuleEntry(JNIEnv * env,jobject pkcs11Implementation)7880 ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
7881   ModuleListNode *currentNode;
7882   ModuleData *moduleDataOfFoundNode;
7883 
7884   moduleDataOfFoundNode = NULL;
7885 
7886   if (pkcs11Implementation == NULL) {
7887     /* Nothing to do. */
7888     return NULL ;
7889   }
7890 
7891   /* We stop, when we the pkcs11Implementation object is already in the list.
7892    * We also stop, when we reach the end; i.e. the first node which's 'next'
7893    * is NULL.
7894    */
7895   (*env)->MonitorEnter(env, moduleListLock); /* synchronize access to list */
7896 
7897   if (moduleListHead != NULL) {
7898     currentNode = moduleListHead;
7899     while ((currentNode->next != NULL) && (!equals(env, pkcs11Implementation, currentNode->pkcs11Implementation))) {
7900       currentNode = currentNode->next;
7901     }
7902     if (equals(env, pkcs11Implementation, currentNode->pkcs11Implementation)) {
7903       /* we found the entry */
7904       moduleDataOfFoundNode = currentNode->moduleData;
7905     } else {
7906       /* the entry is not in the list */
7907       moduleDataOfFoundNode = NULL;
7908     }
7909   }
7910 
7911   (*env)->MonitorExit(env, moduleListLock); /* synchronize access to list */
7912 
7913   return moduleDataOfFoundNode ;
7914 }
7915 
7916 
7917 /*
7918  * Returns 1, if the given pkcs11Implementation is in the list.
7919  * 0, otherwise.
7920  */
isModulePresent(JNIEnv * env,jobject pkcs11Implementation)7921 int isModulePresent(JNIEnv *env, jobject pkcs11Implementation) {
7922   int present;
7923 
7924   ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
7925 
7926   present = (moduleData != NULL) ? 1 : 0;
7927 
7928   return present ;
7929 }
7930 
7931 
7932 /*
7933  * Removes the entry for the given pkcs11Implementation from the list. Returns
7934  * the module's data, after the node was removed. If this function returns NULL
7935  * the pkcs11Implementation was not in the list.
7936  */
removeModuleEntry(JNIEnv * env,jobject pkcs11Implementation)7937 ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
7938   ModuleListNode *currentNode, *previousNode;
7939   ModuleData *moduleDataOfFoundNode;
7940 
7941   moduleDataOfFoundNode = NULL;
7942 
7943   if (pkcs11Implementation == NULL) {
7944     /* Nothing to do. */
7945     return NULL ;
7946   }
7947 
7948   /* We stop, when we the pkcs11Implementation object is already in the list.
7949    * We also stop, when we reach the end; i.e. the first node which's 'next'
7950    * is NULL. We remember the previous node the be able to remove the node
7951    * later.
7952    */
7953   (*env)->MonitorEnter(env, moduleListLock); /* synchronize access to list */
7954 
7955   if (moduleListHead != NULL) {
7956     currentNode = moduleListHead;
7957     previousNode = NULL;
7958     while ((currentNode->next != NULL) && (!equals(env, pkcs11Implementation, currentNode->pkcs11Implementation))) {
7959       previousNode = currentNode;
7960       currentNode = currentNode->next;
7961     }
7962     if (equals(env, pkcs11Implementation, currentNode->pkcs11Implementation)) {
7963       /* we found the entry, so remove it */
7964       if (previousNode == NULL) {
7965         /* it's the first node */
7966         moduleListHead = currentNode->next;
7967       } else {
7968         previousNode->next = currentNode->next;
7969       }
7970       moduleDataOfFoundNode = currentNode->moduleData;
7971       (*env)->DeleteGlobalRef(env, currentNode->pkcs11Implementation);
7972       free(currentNode);
7973     } else {
7974       /* the entry is not in the list */
7975       moduleDataOfFoundNode = NULL ;
7976     }
7977   }
7978 
7979   (*env)->MonitorExit(env, moduleListLock); /* synchronize access to list */
7980 
7981   return moduleDataOfFoundNode ;
7982 }
7983 
7984 /*
7985  * Removes all present entries from the list of modules and frees all
7986  * associated resources. This function is used for clean-up.
7987  */
removeAllModuleEntries(JNIEnv * env)7988 void removeAllModuleEntries(JNIEnv *env) {
7989   ModuleListNode *currentNode, *nextNode;
7990 
7991   (*env)->MonitorEnter(env, moduleListLock); /* synchronize access to list */
7992 
7993   currentNode = moduleListHead;
7994   while (currentNode != NULL) {
7995     nextNode = currentNode->next;
7996     (*env)->DeleteGlobalRef(env, currentNode->pkcs11Implementation);
7997     free(currentNode);
7998     currentNode = nextNode;
7999   }
8000   moduleListHead = NULL;
8001 
8002   (*env)->MonitorExit(env, moduleListLock); /* synchronize access to list */
8003 }
8004 
8005 
8006 /*
8007  * This function compares the two given objects using the equals method as
8008  * implemented by the Object class; i.e. it checks, if both refereces refer
8009  * to the same object. If both references are NULL, this functions also regards
8010  * them as equal.
8011  */
equals(JNIEnv * env,jobject thisObject,jobject otherObject)8012 int equals(JNIEnv *env, jobject thisObject, jobject otherObject) {
8013 	jclass jObjectClass;
8014 	jmethodID jequals;
8015 	jboolean jequal = JNI_FALSE;
8016   int returnValue;
8017 
8018   if (thisObject != NULL) {
8019 	  jObjectClass = (*env)->FindClass(env, "java/lang/Object");
8020 	  assert(jObjectClass != 0);
8021 	  jequals = (*env)->GetMethodID(env, jObjectClass, "equals", "(Ljava/lang/Object;)Z");
8022 	  assert(jequals != 0);
8023     /* We must call the equals method as implemented by the Object class. This
8024      * method compares if both references refer to the same object. This is what
8025      * we want.
8026      */
8027     jequal = (*env)->CallNonvirtualBooleanMethod(env, thisObject, jObjectClass, jequals, otherObject);
8028   } else if (otherObject == NULL) {
8029     jequal = JNI_TRUE; /* both NULL, we regard equal */
8030   }
8031 
8032   returnValue = (jequal == JNI_TRUE) ? 1 : 0;
8033 
8034   return returnValue ;
8035 }
8036 
8037 
8038 /* ************************************************************************** */
8039 /* Functions for keeping track of notify callbacks                            */
8040 /* ************************************************************************** */
8041 
8042 #ifndef NO_CALLBACKS
8043 
8044 /*
8045  * Add the given notify encapsulation object to the list of active notify
8046  * objects.
8047  * If notifyEncapsulation is NULL, this function does nothing.
8048  */
putNotifyEntry(JNIEnv * env,CK_SESSION_HANDLE hSession,NotifyEncapsulation * notifyEncapsulation)8049 void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation *notifyEncapsulation) {
8050   NotifyListNode *currentNode, *newNode;
8051 
8052   if (notifyEncapsulation == NULL) {
8053     return ;
8054   }
8055 
8056   newNode = (NotifyListNode *) malloc(sizeof(NotifyListNode));
8057   if (newNode == NULL) { throwOutOfMemoryError(env); return; }
8058   newNode->hSession = hSession;
8059   newNode->notifyEncapsulation = notifyEncapsulation;
8060   newNode->next = NULL;
8061 
8062   (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
8063 
8064   if (notifyListHead == NULL) {
8065     /* this is the first entry */
8066     notifyListHead = newNode;
8067   } else {
8068     /* go to the last entry; i.e. the first node which's 'next' is NULL.
8069      */
8070     currentNode = notifyListHead;
8071     while (currentNode->next != NULL) {
8072       currentNode = currentNode->next;
8073     }
8074     currentNode->next = newNode;
8075   }
8076 
8077   (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
8078 }
8079 
8080 
8081 /*
8082  * Removes the active notifyEncapsulation object used with the given session and
8083  * returns it. If there is no notifyEncapsulation active for this session, this
8084  * function returns NULL.
8085  */
removeNotifyEntry(JNIEnv * env,CK_SESSION_HANDLE hSession)8086 NotifyEncapsulation * removeNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession) {
8087   NotifyEncapsulation *notifyEncapsulation;
8088   NotifyListNode *currentNode, *previousNode;
8089 
8090   (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
8091 
8092   if (notifyListHead == NULL) {
8093     /* this is the first entry */
8094     notifyEncapsulation = NULL;
8095   } else {
8096     /* Find the node with the wanted session handle. Also stop, when we reach
8097      * the last entry; i.e. the first node which's 'next' is NULL.
8098      */
8099     currentNode = notifyListHead;
8100     previousNode = NULL;
8101 
8102     while ((currentNode->hSession != hSession) && (currentNode->next != NULL)) {
8103       previousNode = currentNode;
8104       currentNode = currentNode->next;
8105     }
8106 
8107     if (currentNode->hSession == hSession) {
8108       /* We found a entry for the wanted session, now remove it. */
8109       if (previousNode == NULL) {
8110         /* it's the first node */
8111         notifyListHead = currentNode->next;
8112       } else {
8113         previousNode->next = currentNode->next;
8114       }
8115       notifyEncapsulation = currentNode->notifyEncapsulation;
8116       free(currentNode);
8117     } else {
8118       /* We did not find a entry for this session */
8119       notifyEncapsulation = NULL;
8120     }
8121   }
8122 
8123   (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
8124 
8125   return notifyEncapsulation ;
8126 }
8127 
8128 /*
8129 
8130  * Removes the first notifyEncapsulation object. If there is no notifyEncapsulation,
8131  * this function returns NULL.
8132  */
removeFirstNotifyEntry(JNIEnv * env)8133 NotifyEncapsulation * removeFirstNotifyEntry(JNIEnv *env) {
8134   NotifyEncapsulation *notifyEncapsulation;
8135   NotifyListNode *currentNode;
8136 
8137   (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */
8138 
8139   if (notifyListHead == NULL) {
8140     /* this is the first entry */
8141     notifyEncapsulation = NULL;
8142   } else {
8143     /* Remove the first entry. */
8144     currentNode = notifyListHead;
8145     notifyListHead = notifyListHead->next;
8146     notifyEncapsulation = currentNode->notifyEncapsulation;
8147     free(currentNode);
8148   }
8149 
8150   (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */
8151 
8152   return notifyEncapsulation ;
8153 }
8154 
8155 #endif /* NO_CALLBACKS */
8156