jdk
1378 строк · 49.7 Кб
1/*
2* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
3*/
4
5/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
6*
7* Redistribution and use in source and binary forms, with or without
8* modification, are permitted provided that the following conditions are met:
9*
10* 1. Redistributions of source code must retain the above copyright notice,
11* this list of conditions and the following disclaimer.
12*
13* 2. Redistributions in binary form must reproduce the above copyright notice,
14* this list of conditions and the following disclaimer in the documentation
15* and/or other materials provided with the distribution.
16*
17* 3. The end-user documentation included with the redistribution, if any, must
18* include the following acknowledgment:
19*
20* "This product includes software developed by IAIK of Graz University of
21* Technology."
22*
23* Alternately, this acknowledgment may appear in the software itself, if
24* and wherever such third-party acknowledgments normally appear.
25*
26* 4. The names "Graz University of Technology" and "IAIK of Graz University of
27* Technology" must not be used to endorse or promote products derived from
28* this software without prior written permission.
29*
30* 5. Products derived from this software may not be called
31* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
32* written permission of Graz University of Technology.
33*
34* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
35* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
38* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
41* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
43* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
45* POSSIBILITY OF SUCH DAMAGE.
46*/
47
48#include "pkcs11wrapper.h"
49
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <assert.h>
54
55/* declare file private functions */
56
57ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
58int isModulePresent(JNIEnv *env, jobject pkcs11Implementation);
59void removeAllModuleEntries(JNIEnv *env);
60
61/*
62* This function simply throws a PKCS#11RuntimeException. The message says that
63* the object is not connected to the module.
64*
65* @param env Used to call JNI functions and to get the Exception class.
66*/
67static void throwDisconnectedRuntimeException(JNIEnv *env)
68{
69p11ThrowPKCS11RuntimeException(env, "This object is not connected to a module.");
70}
71
72/* ************************************************************************** */
73/* Functions for keeping track of currently active and loaded modules */
74/* ************************************************************************** */
75
76
77/*
78* Create a new object for locking.
79*/
80jobject createLockObject(JNIEnv *env) {
81jclass jObjectClass;
82jobject jLockObject;
83jmethodID jConstructor;
84
85jObjectClass = (*env)->FindClass(env, "java/lang/Object");
86if (jObjectClass == NULL) { return NULL; }
87jConstructor = (*env)->GetMethodID(env, jObjectClass, "<init>", "()V");
88if (jConstructor == NULL) { return NULL; }
89jLockObject = (*env)->NewObject(env, jObjectClass, jConstructor);
90if (jLockObject == NULL) { return NULL; }
91jLockObject = (*env)->NewGlobalRef(env, jLockObject);
92
93return jLockObject ;
94}
95
96/*
97* Create a new object for locking.
98*/
99void destroyLockObject(JNIEnv *env, jobject jLockObject) {
100if (jLockObject != NULL) {
101(*env)->DeleteGlobalRef(env, jLockObject);
102}
103}
104
105/*
106* Add the given pkcs11Implementation object to the list of present modules.
107* Attach the given data to the entry. If the given pkcs11Implementation is
108* already in the list, just override its old module data with the new one.
109* None of the arguments can be NULL. If one of the arguments is NULL, this
110* function does nothing.
111*/
112void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData) {
113if (pkcs11Implementation == NULL_PTR) {
114return ;
115}
116if (moduleData == NULL) {
117return ;
118}
119(*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, ptr_to_jlong(moduleData));
120}
121
122
123/*
124* Get the module data of the entry for the given pkcs11Implementation. Returns
125* NULL, if the pkcs11Implementation is not in the list.
126*/
127ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
128jlong jData;
129if (pkcs11Implementation == NULL) {
130return NULL;
131}
132jData = (*env)->GetLongField(env, pkcs11Implementation, pNativeDataID);
133return (ModuleData*)jlong_to_ptr(jData);
134}
135
136CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation) {
137ModuleData *moduleData;
138CK_FUNCTION_LIST_PTR ckpFunctions;
139
140moduleData = getModuleEntry(env, pkcs11Implementation);
141if (moduleData == NULL) {
142throwDisconnectedRuntimeException(env);
143return NULL;
144}
145ckpFunctions = moduleData->ckFunctionListPtr;
146return ckpFunctions;
147}
148
149CK_FUNCTION_LIST_3_0_PTR getFunctionList30(JNIEnv *env, jobject
150pkcs11Implementation) {
151ModuleData *moduleData;
152CK_FUNCTION_LIST_3_0_PTR ckpFunctions30;
153
154moduleData = getModuleEntry(env, pkcs11Implementation);
155if (moduleData == NULL) {
156throwDisconnectedRuntimeException(env);
157return NULL;
158}
159ckpFunctions30 = moduleData->ckFunctionList30Ptr;
160return ckpFunctions30;
161}
162
163
164/*
165* Returns 1, if the given pkcs11Implementation is in the list.
166* 0, otherwise.
167*/
168int isModulePresent(JNIEnv *env, jobject pkcs11Implementation) {
169int present;
170
171ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
172
173present = (moduleData != NULL) ? 1 : 0;
174
175return present ;
176}
177
178/*
179* Removes all present entries from the list of modules and frees all
180* associated resources. This function is used for clean-up.
181*/
182void removeAllModuleEntries(JNIEnv *env) {
183/* XXX empty */
184}
185
186/* ************************************************************************** */
187/* Below there follow the helper functions to support conversions between */
188/* Java and Cryptoki types */
189/* ************************************************************************** */
190
191/*
192* function to convert a PKCS#11 return value into a PKCS#11Exception
193*
194* This function generates a PKCS#11Exception with the returnValue as the
195* errorcode. If the returnValue is not CKR_OK. The function returns 0, if the
196* returnValue is CKR_OK. Otherwise, it returns the returnValue as a jLong.
197*
198* @param env - used to call JNI functions and to get the Exception class
199* @param returnValue - of the PKCS#11 function
200*/
201jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue) {
202return ckAssertReturnValueOK2(env, returnValue, NULL);
203}
204
205/*
206* function to convert a PKCS#11 return value and additional message into a
207* PKCS#11Exception
208*
209* This function generates a PKCS#11Exception with the returnValue as the
210* errorcode. If the returnValue is not CKR_OK. The function returns 0, if the
211* returnValue is CKR_OK. Otherwise, it returns the returnValue as a jLong.
212*
213* @param env - used to call JNI functions and to get the Exception class
214* @param returnValue - of the PKCS#11 function
215* @param msg - additional message for the generated PKCS11Exception
216*/
217jlong ckAssertReturnValueOK2(JNIEnv *env, CK_RV returnValue, const char* msg) {
218jclass jPKCS11ExceptionClass;
219jmethodID jConstructor;
220jthrowable jPKCS11Exception;
221jlong jErrorCode = 0L;
222jstring jMsg = NULL;
223
224if (returnValue != CKR_OK) {
225jErrorCode = ckULongToJLong(returnValue);
226jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
227if (jPKCS11ExceptionClass != NULL) {
228jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass,
229"<init>", "(JLjava/lang/String;)V");
230if (jConstructor != NULL) {
231if (msg != NULL) {
232jMsg = (*env)->NewStringUTF(env, msg);
233}
234jPKCS11Exception = (jthrowable) (*env)->NewObject(env,
235jPKCS11ExceptionClass, jConstructor, jErrorCode, jMsg);
236if (jPKCS11Exception != NULL) {
237(*env)->Throw(env, jPKCS11Exception);
238}
239}
240}
241(*env)->DeleteLocalRef(env, jPKCS11ExceptionClass);
242}
243return jErrorCode;
244}
245
246
247/*
248* Throws a Java Exception by name
249*/
250static void throwByName(JNIEnv *env, const char *name, const char *msg)
251{
252jclass cls = (*env)->FindClass(env, name);
253
254if (cls != 0) /* Otherwise an exception has already been thrown */
255(*env)->ThrowNew(env, cls, msg);
256}
257
258/*
259* Throws java.lang.OutOfMemoryError
260*/
261void p11ThrowOutOfMemoryError(JNIEnv *env, const char *msg)
262{
263throwByName(env, "java/lang/OutOfMemoryError", msg);
264}
265
266/*
267* Throws java.lang.NullPointerException
268*/
269void p11ThrowNullPointerException(JNIEnv *env, const char *msg)
270{
271throwByName(env, "java/lang/NullPointerException", msg);
272}
273
274/*
275* Throws java.io.IOException
276*/
277void p11ThrowIOException(JNIEnv *env, const char *msg)
278{
279throwByName(env, "java/io/IOException", msg);
280}
281
282/*
283* This function simply throws a PKCS#11RuntimeException with the given
284* string as its message.
285*
286* @param env Used to call JNI functions and to get the Exception class.
287* @param jmessage The message string of the Exception object.
288*/
289void p11ThrowPKCS11RuntimeException(JNIEnv *env, const char *message)
290{
291throwByName(env, CLASS_PKCS11RUNTIMEEXCEPTION, message);
292}
293
294/* This function frees the specified CK_ATTRIBUTE array.
295*
296* @param attrPtr pointer to the to-be-freed CK_ATTRIBUTE array.
297* @param len the length of the array
298*/
299void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len) {
300if (attrPtr != NULL) {
301int i;
302for (i=0; i<len; i++) {
303if (attrPtr[i].pValue != NULL_PTR) {
304free(attrPtr[i].pValue);
305}
306}
307free(attrPtr);
308}
309}
310
311/* This function frees the specified CK_MECHANISM_PTR pointer and its
312* pParameter including mechanism-specific memory allocations.
313*
314* @param mechPtr pointer to the to-be-freed CK_MECHANISM structure.
315*/
316void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) {
317void *tmp;
318CK_SSL3_MASTER_KEY_DERIVE_PARAMS *sslMkdTmp;
319CK_SSL3_KEY_MAT_PARAMS* sslKmTmp;
320CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tlsMkdTmp;
321CK_TLS12_KEY_MAT_PARAMS* tlsKmTmp;
322
323if (mechPtr != NULL) {
324TRACE2("DEBUG freeCKMechanismPtr: free pMech %p (mech 0x%lX)\n",
325mechPtr, mechPtr->mechanism);
326if (mechPtr->pParameter != NULL) {
327tmp = mechPtr->pParameter;
328switch (mechPtr->mechanism) {
329case CKM_AES_GCM:
330if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS)) {
331TRACE0("[ GCM_PARAMS ]\n");
332free(((CK_GCM_PARAMS*)tmp)->pIv);
333free(((CK_GCM_PARAMS*)tmp)->pAAD);
334} else if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {
335TRACE0("[ GCM_PARAMS w/o ulIvBits ]\n");
336free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pIv);
337free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pAAD);
338}
339break;
340case CKM_AES_CCM:
341TRACE0("[ CK_CCM_PARAMS ]\n");
342free(((CK_CCM_PARAMS*)tmp)->pNonce);
343free(((CK_CCM_PARAMS*)tmp)->pAAD);
344break;
345case CKM_CHACHA20_POLY1305:
346TRACE0("[ CK_SALSA20_CHACHA20_POLY1305_PARAMS ]\n");
347free(((CK_SALSA20_CHACHA20_POLY1305_PARAMS*)tmp)->pNonce);
348free(((CK_SALSA20_CHACHA20_POLY1305_PARAMS*)tmp)->pAAD);
349break;
350case CKM_TLS_PRF:
351case CKM_NSS_TLS_PRF_GENERAL:
352TRACE0("[ CK_TLS_PRF_PARAMS ]\n");
353free(((CK_TLS_PRF_PARAMS*)tmp)->pSeed);
354free(((CK_TLS_PRF_PARAMS*)tmp)->pLabel);
355free(((CK_TLS_PRF_PARAMS*)tmp)->pulOutputLen);
356free(((CK_TLS_PRF_PARAMS*)tmp)->pOutput);
357break;
358case CKM_SSL3_MASTER_KEY_DERIVE:
359case CKM_TLS_MASTER_KEY_DERIVE:
360case CKM_SSL3_MASTER_KEY_DERIVE_DH:
361case CKM_TLS_MASTER_KEY_DERIVE_DH:
362sslMkdTmp = tmp;
363TRACE0("[ CK_SSL3_MASTER_KEY_DERIVE_PARAMS ]\n");
364free(sslMkdTmp->RandomInfo.pClientRandom);
365free(sslMkdTmp->RandomInfo.pServerRandom);
366free(sslMkdTmp->pVersion);
367break;
368case CKM_SSL3_KEY_AND_MAC_DERIVE:
369case CKM_TLS_KEY_AND_MAC_DERIVE:
370sslKmTmp = tmp;
371TRACE0("[ CK_SSL3_KEY_MAT_PARAMS ]\n");
372free(sslKmTmp->RandomInfo.pClientRandom);
373free(sslKmTmp->RandomInfo.pServerRandom);
374if (sslKmTmp->pReturnedKeyMaterial != NULL) {
375free(sslKmTmp->pReturnedKeyMaterial->pIVClient);
376free(sslKmTmp->pReturnedKeyMaterial->pIVServer);
377free(sslKmTmp->pReturnedKeyMaterial);
378}
379break;
380case CKM_TLS12_MASTER_KEY_DERIVE:
381case CKM_TLS12_MASTER_KEY_DERIVE_DH:
382tlsMkdTmp = tmp;
383TRACE0("[ CK_TLS12_MASTER_KEY_DERIVE_PARAMS ]\n");
384free(tlsMkdTmp->RandomInfo.pClientRandom);
385free(tlsMkdTmp->RandomInfo.pServerRandom);
386free(tlsMkdTmp->pVersion);
387break;
388case CKM_TLS12_KEY_AND_MAC_DERIVE:
389tlsKmTmp = tmp;
390TRACE0("[ CK_TLS12_KEY_MAT_PARAMS ]\n");
391free(tlsKmTmp->RandomInfo.pClientRandom);
392free(tlsKmTmp->RandomInfo.pServerRandom);
393if (tlsKmTmp->pReturnedKeyMaterial != NULL) {
394free(tlsKmTmp->pReturnedKeyMaterial->pIVClient);
395free(tlsKmTmp->pReturnedKeyMaterial->pIVServer);
396free(tlsKmTmp->pReturnedKeyMaterial);
397}
398break;
399case CKM_ECDH1_DERIVE:
400case CKM_ECDH1_COFACTOR_DERIVE:
401TRACE0("[ CK_ECDH1_DERIVE_PARAMS ]\n");
402free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pSharedData);
403free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pPublicData);
404break;
405case CKM_TLS_MAC:
406case CKM_AES_CTR:
407case CKM_RSA_PKCS_PSS:
408case CKM_CAMELLIA_CTR:
409// params do not contain pointers
410break;
411case CKM_PKCS5_PBKD2:
412// get the versioned structure from behind memory
413TRACE0(((VersionedPbkd2ParamsPtr)tmp)->version == PARAMS ?
414"[ CK_PKCS5_PBKD2_PARAMS ]\n" :
415"[ CK_PKCS5_PBKD2_PARAMS2 ]\n");
416FREE_VERSIONED_PBKD2_MEMBERS((VersionedPbkd2ParamsPtr)tmp);
417break;
418case CKM_PBA_SHA1_WITH_SHA1_HMAC:
419case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
420case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
421case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
422case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
423TRACE0("[ CK_PBE_PARAMS ]\n");
424free(((CK_PBE_PARAMS_PTR)tmp)->pInitVector);
425if (((CK_PBE_PARAMS_PTR)tmp)->pPassword != NULL) {
426memset(((CK_PBE_PARAMS_PTR)tmp)->pPassword, 0,
427((CK_PBE_PARAMS_PTR)tmp)->ulPasswordLen);
428}
429free(((CK_PBE_PARAMS_PTR)tmp)->pPassword);
430free(((CK_PBE_PARAMS_PTR)tmp)->pSalt);
431break;
432default:
433// currently unsupported mechs by SunPKCS11 provider
434// CKM_RSA_PKCS_OAEP, CKM_ECMQV_DERIVE,
435// CKM_X9_42_*, CKM_KEA_DERIVE, CKM_RC2_*, CKM_RC5_*,
436// CKM_SKIPJACK_*, CKM_KEY_WRAP_SET_OAEP,
437// PBE mechs, WTLS mechs, CMS mechs,
438// CKM_EXTRACT_KEY_FROM_KEY, CKM_OTP, CKM_KIP,
439// CKM_DSA_PARAMETER_GEN?, CKM_GOSTR3410_*
440// CK_any_CBC_ENCRYPT_DATA?
441TRACE0("ERROR: UNSUPPORTED CK_MECHANISM\n");
442break;
443}
444TRACE1("\t=> freed param %p\n", tmp);
445free(tmp);
446} else {
447TRACE0("\t=> param NULL\n");
448}
449free(mechPtr);
450TRACE0("FINISHED\n");
451}
452}
453
454/* This function updates the specified CK_MECHANISM structure
455* and its GCM parameter structure switching between CK_GCM_PARAMS and
456* CK_GCM_PARAMS_NO_IVBITS.
457*
458* @param mechPtr pointer to the CK_MECHANISM structure containing
459* the to-be-converted CK_GCM_PARAMS / CK_GCM_PARAMS_NO_IVBITS structure.
460* @return pointer to the CK_MECHANISM structure containing the
461* converted structure or NULL if no conversion is done.
462*/
463CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr) {
464CK_GCM_PARAMS_PTR pParams;
465CK_GCM_PARAMS_NO_IVBITS_PTR pParamsNoIvBits;
466CK_ULONG paramLen;
467
468if (mechPtr != NULL) {
469paramLen = mechPtr->ulParameterLen;
470if (paramLen == sizeof(CK_GCM_PARAMS)) {
471// CK_GCM_PARAMS => CK_GCM_PARAMS_NO_IVBITS
472pParams = (CK_GCM_PARAMS*) mechPtr->pParameter;
473pParamsNoIvBits = calloc(1, sizeof(CK_GCM_PARAMS_NO_IVBITS));
474pParamsNoIvBits->pIv = pParams->pIv;
475pParamsNoIvBits->ulIvLen = pParams->ulIvLen;
476pParamsNoIvBits->pAAD = pParams->pAAD;
477pParamsNoIvBits->ulAADLen = pParams->ulAADLen;
478pParamsNoIvBits->ulTagBits = pParams->ulTagBits;
479mechPtr->pParameter = pParamsNoIvBits;
480mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS_NO_IVBITS);
481free(pParams);
482TRACE0("DEBUG update CK_GCM_PARAMS to CK_GCM_PARAMS_NO_IVBITS\n");
483return mechPtr;
484} else if (paramLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {
485// CK_GCM_PARAMS_NO_IVBITS => CK_GCM_PARAMS
486pParamsNoIvBits = (CK_GCM_PARAMS_NO_IVBITS*) mechPtr->pParameter;
487pParams = calloc(1, sizeof(CK_GCM_PARAMS));
488pParams->pIv = pParamsNoIvBits->pIv;
489pParams->ulIvLen = pParamsNoIvBits->ulIvLen;
490pParams->ulIvBits = pParamsNoIvBits->ulIvLen << 3;
491pParams->pAAD = pParamsNoIvBits->pAAD;
492pParams->ulAADLen = pParamsNoIvBits->ulAADLen;
493pParams->ulTagBits = pParamsNoIvBits->ulTagBits;
494mechPtr->pParameter = pParams;
495mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS);
496free(pParamsNoIvBits);
497TRACE0("DEBUG update CK_GCM_PARAMS_NO_IVBITS to CK_GCM_PARAMS\n");
498return mechPtr;
499}
500}
501TRACE0("DEBUG updateGCMParams: no conversion done\n");
502return NULL;
503}
504
505/*
506* the following functions convert Java arrays to PKCS#11 array pointers and
507* their array length and vice versa
508*
509* void j<Type>ArrayToCK<Type>Array(JNIEnv *env,
510* const j<Type>Array jArray,
511* CK_<Type>_PTR *ckpArray,
512* CK_ULONG_PTR ckLength);
513*
514* j<Type>Array ck<Type>ArrayToJ<Type>Array(JNIEnv *env,
515* const CK_<Type>_PTR ckpArray,
516* CK_ULONG ckLength);
517*
518* PKCS#11 arrays consist always of a pointer to the beginning of the array and
519* the array length whereas Java arrays carry their array length.
520*
521* The Functions to convert a Java array to a PKCS#11 array are void functions.
522* Their arguments are the Java array object to convert, the reference to the
523* array pointer, where the new PKCS#11 array should be stored and the reference
524* to the array length where the PKCS#11 array length should be stored. These two
525* references must not be NULL_PTR.
526*
527* The functions first obtain the array length of the Java array and then allocate
528* the memory for the PKCS#11 array and set the array length. Then each element
529* gets converted depending on their type. After use the allocated memory of the
530* PKCS#11 array has to be explicitly freed.
531*
532* The Functions to convert a PKCS#11 array to a Java array get the PKCS#11 array
533* pointer and the array length and they return the new Java array object. The
534* Java array does not need to get freed after use.
535*/
536
537/*
538* converts a jbooleanArray to a CK_BBOOL array. The allocated memory has to be freed after use!
539*
540* @param env - used to call JNI functions to get the array informtaion
541* @param jArray - the Java array to convert
542* @param ckpArray - the reference, where the pointer to the new CK_BBOOL array will be stored
543* @param ckpLength - the reference, where the array length will be stored
544*/
545void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckpLength)
546{
547jboolean* jpTemp;
548CK_ULONG i;
549
550if (jArray == NULL) {
551*ckpArray = NULL_PTR;
552*ckpLength = 0UL;
553return;
554}
555*ckpLength = (*env)->GetArrayLength(env, jArray);
556jpTemp = (jboolean*) calloc(*ckpLength, sizeof(jboolean));
557if (jpTemp == NULL && *ckpLength != 0UL) {
558p11ThrowOutOfMemoryError(env, 0);
559return;
560}
561(*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
562if ((*env)->ExceptionCheck(env)) {
563free(jpTemp);
564return;
565}
566
567*ckpArray = (CK_BBOOL*) calloc(*ckpLength, sizeof(CK_BBOOL));
568if (*ckpArray == NULL && *ckpLength != 0UL) {
569free(jpTemp);
570p11ThrowOutOfMemoryError(env, 0);
571return;
572}
573for (i=0; i<(*ckpLength); i++) {
574(*ckpArray)[i] = jBooleanToCKBBool(jpTemp[i]);
575}
576free(jpTemp);
577}
578
579/*
580* converts a jbyteArray to a CK_BYTE array. The allocated memory has to be freed after use!
581*
582* @param env - used to call JNI functions to get the array informtaion
583* @param jArray - the Java array to convert
584* @param ckpArray - the reference, where the pointer to the new CK_BYTE array will be stored
585* @param ckpLength - the reference, where the array length will be stored
586*/
587void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
588{
589jbyte* jpTemp;
590CK_ULONG i;
591
592if (jArray == NULL) {
593*ckpArray = NULL_PTR;
594*ckpLength = 0UL;
595return;
596}
597*ckpLength = (*env)->GetArrayLength(env, jArray);
598jpTemp = (jbyte*) calloc(*ckpLength, sizeof(jbyte));
599if (jpTemp == NULL && *ckpLength != 0UL) {
600p11ThrowOutOfMemoryError(env, 0);
601return;
602}
603(*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
604if ((*env)->ExceptionCheck(env)) {
605free(jpTemp);
606return;
607}
608
609/* if CK_BYTE is the same size as jbyte, we save an additional copy */
610if (sizeof(CK_BYTE) == sizeof(jbyte)) {
611*ckpArray = (CK_BYTE_PTR) jpTemp;
612} else {
613*ckpArray = (CK_BYTE_PTR) calloc(*ckpLength, sizeof(CK_BYTE));
614if (*ckpArray == NULL && *ckpLength != 0UL) {
615free(jpTemp);
616p11ThrowOutOfMemoryError(env, 0);
617return;
618}
619for (i=0; i<(*ckpLength); i++) {
620(*ckpArray)[i] = jByteToCKByte(jpTemp[i]);
621}
622free(jpTemp);
623}
624}
625
626/*
627* converts a jlongArray to a CK_ULONG array. The allocated memory has to be freed after use!
628*
629* @param env - used to call JNI functions to get the array informtaion
630* @param jArray - the Java array to convert
631* @param ckpArray - the reference, where the pointer to the new CK_ULONG array will be stored
632* @param ckpLength - the reference, where the array length will be stored
633*/
634void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckpLength)
635{
636jlong* jTemp;
637CK_ULONG i;
638
639if (jArray == NULL) {
640*ckpArray = NULL_PTR;
641*ckpLength = 0UL;
642return;
643}
644*ckpLength = (*env)->GetArrayLength(env, jArray);
645jTemp = (jlong*) calloc(*ckpLength, sizeof(jlong));
646if (jTemp == NULL && *ckpLength != 0UL) {
647p11ThrowOutOfMemoryError(env, 0);
648return;
649}
650(*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jTemp);
651if ((*env)->ExceptionCheck(env)) {
652free(jTemp);
653return;
654}
655
656*ckpArray = (CK_ULONG_PTR) calloc(*ckpLength, sizeof(CK_ULONG));
657if (*ckpArray == NULL && *ckpLength != 0UL) {
658free(jTemp);
659p11ThrowOutOfMemoryError(env, 0);
660return;
661}
662for (i=0; i<(*ckpLength); i++) {
663(*ckpArray)[i] = jLongToCKULong(jTemp[i]);
664}
665free(jTemp);
666}
667
668/*
669* converts a jcharArray to a CK_CHAR array. The allocated memory has to be freed after use!
670*
671* @param env - used to call JNI functions to get the array informtaion
672* @param jArray - the Java array to convert
673* @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
674* @param ckpLength - the reference, where the array length will be stored
675*/
676void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
677{
678jchar* jpTemp;
679CK_ULONG i;
680
681if (jArray == NULL) {
682*ckpArray = NULL_PTR;
683*ckpLength = 0UL;
684return;
685}
686*ckpLength = (*env)->GetArrayLength(env, jArray);
687jpTemp = (jchar*) calloc(*ckpLength, sizeof(jchar));
688if (jpTemp == NULL && *ckpLength != 0UL) {
689p11ThrowOutOfMemoryError(env, 0);
690return;
691}
692(*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
693if ((*env)->ExceptionCheck(env)) {
694free(jpTemp);
695return;
696}
697
698*ckpArray = (CK_CHAR_PTR) calloc(*ckpLength, sizeof(CK_CHAR));
699if (*ckpArray == NULL && *ckpLength != 0UL) {
700free(jpTemp);
701p11ThrowOutOfMemoryError(env, 0);
702return;
703}
704for (i=0; i<(*ckpLength); i++) {
705(*ckpArray)[i] = jCharToCKChar(jpTemp[i]);
706}
707free(jpTemp);
708}
709
710/*
711* converts a jcharArray to a CK_UTF8CHAR array. The allocated memory has to be freed after use!
712*
713* @param env - used to call JNI functions to get the array informtaion
714* @param jArray - the Java array to convert
715* @param ckpArray - the reference, where the pointer to the new CK_UTF8CHAR array will be stored
716* @param ckpLength - the reference, where the array length will be stored
717*/
718void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
719{
720jchar* jTemp;
721CK_ULONG i;
722
723if (jArray == NULL) {
724*ckpArray = NULL_PTR;
725*ckpLength = 0UL;
726return;
727}
728*ckpLength = (*env)->GetArrayLength(env, jArray);
729jTemp = (jchar*) calloc(*ckpLength, sizeof(jchar));
730if (jTemp == NULL && *ckpLength != 0UL) {
731p11ThrowOutOfMemoryError(env, 0);
732return;
733}
734(*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jTemp);
735if ((*env)->ExceptionCheck(env)) {
736goto cleanup;
737}
738
739*ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength, sizeof(CK_UTF8CHAR));
740if (*ckpArray == NULL && *ckpLength != 0UL) {
741p11ThrowOutOfMemoryError(env, 0);
742goto cleanup;
743}
744for (i=0; i<(*ckpLength); i++) {
745(*ckpArray)[i] = jCharToCKUTF8Char(jTemp[i]);
746}
747cleanup:
748// Clean possible temporary copies of passwords.
749memset(jTemp, 0, *ckpLength * sizeof(jchar));
750free(jTemp);
751}
752
753/*
754* converts a jstring to a CK_CHAR array. The allocated memory has to be freed after use!
755*
756* @param env - used to call JNI functions to get the array informtaion
757* @param jArray - the Java array to convert
758* @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
759* @param ckpLength - the reference, where the array length will be stored
760*/
761void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
762{
763const char* pCharArray;
764jboolean isCopy;
765
766if(jArray == NULL) {
767*ckpArray = NULL_PTR;
768*ckpLength = 0L;
769return;
770}
771
772pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
773if (pCharArray == NULL) { return; }
774
775*ckpLength = (CK_ULONG) strlen(pCharArray);
776*ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength + 1, sizeof(CK_UTF8CHAR));
777if (*ckpArray == NULL) {
778(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
779p11ThrowOutOfMemoryError(env, 0);
780return;
781}
782strcpy((char*)*ckpArray, pCharArray);
783(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
784}
785
786/*
787* converts a jobjectArray with Java Attributes to a CK_ATTRIBUTE array. The allocated memory
788* has to be freed after use!
789*
790* @param env - used to call JNI functions to get the array informtaion
791* @param jArray - the Java Attribute array (template) to convert
792* @param ckpArray - the reference, where the pointer to the new CK_ATTRIBUTE array will be
793* stored
794* @param ckpLength - the reference, where the array length will be stored
795*/
796void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
797{
798CK_ULONG i;
799jlong jLength;
800jobject jAttribute;
801
802TRACE0("\nDEBUG: jAttributeArrayToCKAttributeArray");
803if (jArray == NULL) {
804*ckpArray = NULL_PTR;
805*ckpLength = 0L;
806return;
807}
808jLength = (*env)->GetArrayLength(env, jArray);
809*ckpLength = jLongToCKULong(jLength);
810*ckpArray = (CK_ATTRIBUTE_PTR) calloc(*ckpLength, sizeof(CK_ATTRIBUTE));
811if (*ckpArray == NULL && *ckpLength != 0UL) {
812p11ThrowOutOfMemoryError(env, 0);
813return;
814}
815TRACE1(", converting %lld attributes", (long long int) jLength);
816for (i=0; i<(*ckpLength); i++) {
817TRACE1(", getting %lu. attribute", i);
818jAttribute = (*env)->GetObjectArrayElement(env, jArray, i);
819if ((*env)->ExceptionCheck(env)) {
820freeCKAttributeArray(*ckpArray, i);
821return;
822}
823TRACE1(", jAttribute , converting %lu. attribute", i);
824(*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute);
825if ((*env)->ExceptionCheck(env)) {
826freeCKAttributeArray(*ckpArray, i);
827return;
828}
829}
830TRACE0("FINISHED\n");
831}
832
833/*
834* converts a CK_BYTE array and its length to a jbyteArray.
835*
836* @param env - used to call JNI functions to create the new Java array
837* @param ckpArray - the pointer to the CK_BYTE array to convert
838* @param ckpLength - the length of the array to convert
839* @return - the new Java byte array or NULL if error occurred
840*/
841jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength)
842{
843CK_ULONG i;
844jbyte* jpTemp;
845jbyteArray jArray;
846
847/* if CK_BYTE is the same size as jbyte, we save an additional copy */
848if (sizeof(CK_BYTE) == sizeof(jbyte)) {
849jpTemp = (jbyte*) ckpArray;
850} else {
851jpTemp = (jbyte*) calloc(ckLength, sizeof(jbyte));
852if (jpTemp == NULL && ckLength != 0UL) {
853p11ThrowOutOfMemoryError(env, 0);
854return NULL;
855}
856for (i=0; i<ckLength; i++) {
857jpTemp[i] = ckByteToJByte(ckpArray[i]);
858}
859}
860
861jArray = (*env)->NewByteArray(env, ckULongToJSize(ckLength));
862if (jArray != NULL) {
863(*env)->SetByteArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
864}
865
866if (sizeof(CK_BYTE) != sizeof(jbyte)) { free(jpTemp); }
867
868return jArray ;
869}
870
871/*
872* converts a CK_ULONG array and its length to a jlongArray.
873*
874* @param env - used to call JNI functions to create the new Java array
875* @param ckpArray - the pointer to the CK_ULONG array to convert
876* @param ckpLength - the length of the array to convert
877* @return - the new Java long array
878*/
879jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength)
880{
881CK_ULONG i;
882jlong* jpTemp;
883jlongArray jArray;
884
885jpTemp = (jlong*) calloc(ckLength, sizeof(jlong));
886if (jpTemp == NULL && ckLength != 0UL) {
887p11ThrowOutOfMemoryError(env, 0);
888return NULL;
889}
890for (i=0; i<ckLength; i++) {
891jpTemp[i] = ckLongToJLong(ckpArray[i]);
892}
893jArray = (*env)->NewLongArray(env, ckULongToJSize(ckLength));
894if (jArray != NULL) {
895(*env)->SetLongArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
896}
897free(jpTemp);
898
899return jArray ;
900}
901
902/*
903* converts a CK_CHAR array and its length to a jcharArray.
904*
905* @param env - used to call JNI functions to create the new Java array
906* @param ckpArray - the pointer to the CK_CHAR array to convert
907* @param ckpLength - the length of the array to convert
908* @return - the new Java char array
909*/
910jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG ckLength)
911{
912CK_ULONG i;
913jchar* jpTemp;
914jcharArray jArray;
915
916jpTemp = (jchar*) calloc(ckLength, sizeof(jchar));
917if (jpTemp == NULL && ckLength != 0UL) {
918p11ThrowOutOfMemoryError(env, 0);
919return NULL;
920}
921for (i=0; i<ckLength; i++) {
922jpTemp[i] = ckCharToJChar(ckpArray[i]);
923}
924jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
925if (jArray != NULL) {
926(*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
927}
928free(jpTemp);
929
930return jArray ;
931}
932
933/*
934* converts a CK_UTF8CHAR array and its length to a jcharArray.
935*
936* @param env - used to call JNI functions to create the new Java array
937* @param ckpArray - the pointer to the CK_UTF8CHAR array to convert
938* @param ckpLength - the length of the array to convert
939* @return - the new Java char array
940*/
941jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength)
942{
943CK_ULONG i;
944jchar* jpTemp;
945jcharArray jArray;
946
947jpTemp = (jchar*) calloc(ckLength, sizeof(jchar));
948if (jpTemp == NULL && ckLength != 0UL) {
949p11ThrowOutOfMemoryError(env, 0);
950return NULL;
951}
952for (i=0; i<ckLength; i++) {
953jpTemp[i] = ckUTF8CharToJChar(ckpArray[i]);
954}
955jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
956if (jArray != NULL) {
957(*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
958}
959free(jpTemp);
960
961return jArray ;
962}
963
964/*
965* the following functions convert Java objects to PKCS#11 pointers and the
966* length in bytes and vice versa
967*
968* CK_<Type>_PTR j<Object>ToCK<Type>Ptr(JNIEnv *env, jobject jObject);
969*
970* jobject ck<Type>PtrToJ<Object>(JNIEnv *env, const CK_<Type>_PTR ckpValue);
971*
972* The functions that convert a Java object to a PKCS#11 pointer first allocate
973* the memory for the PKCS#11 pointer. Then they set each element corresponding
974* to the fields in the Java object to convert. After use the allocated memory of
975* the PKCS#11 pointer has to be explicitly freed.
976*
977* The functions to convert a PKCS#11 pointer to a Java object create a new Java
978* object first and than they set all fields in the object depending on the values
979* of the type or structure where the PKCS#11 pointer points to.
980*/
981
982/*
983* converts a CK_BBOOL pointer to a Java boolean Object.
984*
985* @param env - used to call JNI functions to create the new Java object
986* @param ckpValue - the pointer to the CK_BBOOL value
987* @return - the new Java boolean object with the boolean value
988*/
989jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL *ckpValue)
990{
991jclass jValueObjectClass;
992jmethodID jConstructor;
993jobject jValueObject;
994jboolean jValue;
995
996jValueObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
997if (jValueObjectClass == NULL) { return NULL; }
998jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(Z)V");
999if (jConstructor == NULL) { return NULL; }
1000jValue = ckBBoolToJBoolean(*ckpValue);
1001jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
1002
1003return jValueObject ;
1004}
1005
1006/*
1007* converts a CK_ULONG pointer to a Java long Object.
1008*
1009* @param env - used to call JNI functions to create the new Java object
1010* @param ckpValue - the pointer to the CK_ULONG value
1011* @return - the new Java long object with the long value
1012*/
1013jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue)
1014{
1015jclass jValueObjectClass;
1016jmethodID jConstructor;
1017jobject jValueObject;
1018jlong jValue;
1019
1020jValueObjectClass = (*env)->FindClass(env, "java/lang/Long");
1021if (jValueObjectClass == NULL) { return NULL; }
1022jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V");
1023if (jConstructor == NULL) { return NULL; }
1024jValue = ckULongToJLong(*ckpValue);
1025jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
1026
1027return jValueObject ;
1028}
1029
1030/*
1031* converts a Java boolean object into a pointer to a CK_BBOOL value. The memory has to be
1032* freed after use!
1033*
1034* @param env - used to call JNI functions to get the value out of the Java object
1035* @param jObject - the "java/lang/Boolean" object to convert
1036* @return - the pointer to the new CK_BBOOL value
1037*/
1038CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject)
1039{
1040jclass jObjectClass;
1041jmethodID jValueMethod;
1042jboolean jValue;
1043CK_BBOOL *ckpValue;
1044
1045jObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
1046if (jObjectClass == NULL) { return NULL; }
1047jValueMethod = (*env)->GetMethodID(env, jObjectClass, "booleanValue", "()Z");
1048if (jValueMethod == NULL) { return NULL; }
1049jValue = (*env)->CallBooleanMethod(env, jObject, jValueMethod);
1050ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL));
1051if (ckpValue == NULL) {
1052p11ThrowOutOfMemoryError(env, 0);
1053return NULL;
1054}
1055*ckpValue = jBooleanToCKBBool(jValue);
1056
1057return ckpValue ;
1058}
1059
1060/*
1061* converts a Java byte object into a pointer to a CK_BYTE value. The memory has to be
1062* freed after use!
1063*
1064* @param env - used to call JNI functions to get the value out of the Java object
1065* @param jObject - the "java/lang/Byte" object to convert
1066* @return - the pointer to the new CK_BYTE value
1067*/
1068CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject)
1069{
1070jclass jObjectClass;
1071jmethodID jValueMethod;
1072jbyte jValue;
1073CK_BYTE_PTR ckpValue;
1074
1075jObjectClass = (*env)->FindClass(env, "java/lang/Byte");
1076if (jObjectClass == NULL) { return NULL; }
1077jValueMethod = (*env)->GetMethodID(env, jObjectClass, "byteValue", "()B");
1078if (jValueMethod == NULL) { return NULL; }
1079jValue = (*env)->CallByteMethod(env, jObject, jValueMethod);
1080ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE));
1081if (ckpValue == NULL) {
1082p11ThrowOutOfMemoryError(env, 0);
1083return NULL;
1084}
1085*ckpValue = jByteToCKByte(jValue);
1086return ckpValue ;
1087}
1088
1089/*
1090* converts a Java integer object into a pointer to a CK_ULONG value. The memory has to be
1091* freed after use!
1092*
1093* @param env - used to call JNI functions to get the value out of the Java object
1094* @param jObject - the "java/lang/Integer" object to convert
1095* @return - the pointer to the new CK_ULONG value
1096*/
1097CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject)
1098{
1099jclass jObjectClass;
1100jmethodID jValueMethod;
1101jint jValue;
1102CK_ULONG *ckpValue;
1103
1104jObjectClass = (*env)->FindClass(env, "java/lang/Integer");
1105if (jObjectClass == NULL) { return NULL; }
1106jValueMethod = (*env)->GetMethodID(env, jObjectClass, "intValue", "()I");
1107if (jValueMethod == NULL) { return NULL; }
1108jValue = (*env)->CallIntMethod(env, jObject, jValueMethod);
1109ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
1110if (ckpValue == NULL) {
1111p11ThrowOutOfMemoryError(env, 0);
1112return NULL;
1113}
1114*ckpValue = jLongToCKLong(jValue);
1115return ckpValue ;
1116}
1117
1118/*
1119* converts a Java long object into a pointer to a CK_ULONG value. The memory has to be
1120* freed after use!
1121*
1122* @param env - used to call JNI functions to get the value out of the Java object
1123* @param jObject - the "java/lang/Long" object to convert
1124* @return - the pointer to the new CK_ULONG value
1125*/
1126CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject)
1127{
1128jclass jObjectClass;
1129jmethodID jValueMethod;
1130jlong jValue;
1131CK_ULONG *ckpValue;
1132
1133jObjectClass = (*env)->FindClass(env, "java/lang/Long");
1134if (jObjectClass == NULL) { return NULL; }
1135jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J");
1136if (jValueMethod == NULL) { return NULL; }
1137jValue = (*env)->CallLongMethod(env, jObject, jValueMethod);
1138ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
1139if (ckpValue == NULL) {
1140p11ThrowOutOfMemoryError(env, 0);
1141return NULL;
1142}
1143*ckpValue = jLongToCKULong(jValue);
1144
1145return ckpValue ;
1146}
1147
1148/*
1149* converts a Java char object into a pointer to a CK_CHAR value. The memory has to be
1150* freed after use!
1151*
1152* @param env - used to call JNI functions to get the value out of the Java object
1153* @param jObject - the "java/lang/Char" object to convert
1154* @return - the pointer to the new CK_CHAR value
1155*/
1156CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject)
1157{
1158jclass jObjectClass;
1159jmethodID jValueMethod;
1160jchar jValue;
1161CK_CHAR_PTR ckpValue;
1162
1163jObjectClass = (*env)->FindClass(env, "java/lang/Char");
1164if (jObjectClass == NULL) { return NULL; }
1165jValueMethod = (*env)->GetMethodID(env, jObjectClass, "charValue", "()C");
1166if (jValueMethod == NULL) { return NULL; }
1167jValue = (*env)->CallCharMethod(env, jObject, jValueMethod);
1168ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR));
1169if (ckpValue == NULL) {
1170p11ThrowOutOfMemoryError(env, 0);
1171return NULL;
1172}
1173*ckpValue = jCharToCKChar(jValue);
1174
1175return ckpValue ;
1176}
1177
1178/*
1179* converts a Java object into a pointer to CK-type or a CK-structure with the length in Bytes.
1180* The memory of the returned pointer MUST BE FREED BY CALLER!
1181*
1182* @param env - used to call JNI functions to get the Java classes and objects
1183* @param jObject - the Java object to convert
1184* @param ckpLength - pointer to the length (bytes) of the newly-allocated CK-value or CK-structure
1185* @return ckpObject - pointer to the newly-allocated CK-value or CK-structure
1186*/
1187CK_VOID_PTR jObjectToPrimitiveCKObjectPtr(JNIEnv *env, jobject jObject, CK_ULONG *ckpLength)
1188{
1189jclass jLongClass, jBooleanClass, jByteArrayClass, jCharArrayClass;
1190jclass jByteClass, jDateClass, jCharacterClass, jIntegerClass;
1191jclass jBooleanArrayClass, jIntArrayClass, jLongArrayClass;
1192jclass jStringClass;
1193jclass jObjectClass, jClassClass;
1194CK_VOID_PTR ckpObject;
1195jmethodID jMethod;
1196jobject jClassObject;
1197jstring jClassNameString;
1198char *classNameString, *exceptionMsgPrefix, *exceptionMsg;
1199
1200TRACE0("\nDEBUG: jObjectToPrimitiveCKObjectPtr");
1201if (jObject == NULL) {
1202*ckpLength = 0;
1203return NULL;
1204}
1205
1206jLongClass = (*env)->FindClass(env, "java/lang/Long");
1207if (jLongClass == NULL) { return NULL; }
1208if ((*env)->IsInstanceOf(env, jObject, jLongClass)) {
1209ckpObject = jLongObjectToCKULongPtr(env, jObject);
1210*ckpLength = sizeof(CK_ULONG);
1211TRACE1("<converted long value %lu>", *((CK_ULONG *) ckpObject));
1212return ckpObject;
1213}
1214
1215jBooleanClass = (*env)->FindClass(env, "java/lang/Boolean");
1216if (jBooleanClass == NULL) { return NULL; }
1217if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) {
1218ckpObject = jBooleanObjectToCKBBoolPtr(env, jObject);
1219*ckpLength = sizeof(CK_BBOOL);
1220TRACE0(" <converted boolean value ");
1221TRACE0((*((CK_BBOOL *) ckpObject) == TRUE) ? "TRUE>" : "FALSE>");
1222return ckpObject;
1223}
1224
1225jByteArrayClass = (*env)->FindClass(env, "[B");
1226if (jByteArrayClass == NULL) { return NULL; }
1227if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) {
1228jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*) &ckpObject, ckpLength);
1229return ckpObject;
1230}
1231
1232jCharArrayClass = (*env)->FindClass(env, "[C");
1233if (jCharArrayClass == NULL) { return NULL; }
1234if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) {
1235jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*) &ckpObject, ckpLength);
1236return ckpObject;
1237}
1238
1239jByteClass = (*env)->FindClass(env, "java/lang/Byte");
1240if (jByteClass == NULL) { return NULL; }
1241if ((*env)->IsInstanceOf(env, jObject, jByteClass)) {
1242ckpObject = jByteObjectToCKBytePtr(env, jObject);
1243*ckpLength = sizeof(CK_BYTE);
1244TRACE1("<converted byte value %X>", *((CK_BYTE *) ckpObject));
1245return ckpObject;
1246}
1247
1248jDateClass = (*env)->FindClass(env, CLASS_DATE);
1249if (jDateClass == NULL) { return NULL; }
1250if ((*env)->IsInstanceOf(env, jObject, jDateClass)) {
1251ckpObject = jDateObjectToCKDatePtr(env, jObject);
1252*ckpLength = sizeof(CK_DATE);
1253TRACE3("<converted date value %.4s-%.2s-%.2s>", ((CK_DATE *) ckpObject)->year,
1254((CK_DATE *) ckpObject)->month, ((CK_DATE *) ckpObject)->day);
1255return ckpObject;
1256}
1257
1258jCharacterClass = (*env)->FindClass(env, "java/lang/Character");
1259if (jCharacterClass == NULL) { return NULL; }
1260if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) {
1261ckpObject = jCharObjectToCKCharPtr(env, jObject);
1262*ckpLength = sizeof(CK_UTF8CHAR);
1263TRACE1("<converted char value %c>", *((CK_CHAR *) ckpObject));
1264return ckpObject;
1265}
1266
1267jIntegerClass = (*env)->FindClass(env, "java/lang/Integer");
1268if (jIntegerClass == NULL) { return NULL; }
1269if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) {
1270ckpObject = jIntegerObjectToCKULongPtr(env, jObject);
1271*ckpLength = sizeof(CK_ULONG);
1272TRACE1("<converted integer value %lu>", *((CK_ULONG *) ckpObject));
1273return ckpObject;
1274}
1275
1276jBooleanArrayClass = (*env)->FindClass(env, "[Z");
1277if (jBooleanArrayClass == NULL) { return NULL; }
1278if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) {
1279jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**) &ckpObject, ckpLength);
1280return ckpObject;
1281}
1282
1283jIntArrayClass = (*env)->FindClass(env, "[I");
1284if (jIntArrayClass == NULL) { return NULL; }
1285if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) {
1286jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*) &ckpObject, ckpLength);
1287return ckpObject;
1288}
1289
1290jLongArrayClass = (*env)->FindClass(env, "[J");
1291if (jLongArrayClass == NULL) { return NULL; }
1292if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) {
1293jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*) &ckpObject, ckpLength);
1294return ckpObject;
1295}
1296
1297jStringClass = (*env)->FindClass(env, "java/lang/String");
1298if (jStringClass == NULL) { return NULL; }
1299if ((*env)->IsInstanceOf(env, jObject, jStringClass)) {
1300jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*) &ckpObject, ckpLength);
1301return ckpObject;
1302}
1303
1304/* type of jObject unknown, throw PKCS11RuntimeException */
1305jObjectClass = (*env)->FindClass(env, "java/lang/Object");
1306if (jObjectClass == NULL) { return NULL; }
1307jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;");
1308if (jMethod == NULL) { return NULL; }
1309jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod);
1310assert(jClassObject != 0);
1311jClassClass = (*env)->FindClass(env, "java/lang/Class");
1312if (jClassClass == NULL) { return NULL; }
1313jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;");
1314if (jMethod == NULL) { return NULL; }
1315jClassNameString = (jstring)
1316(*env)->CallObjectMethod(env, jClassObject, jMethod);
1317assert(jClassNameString != 0);
1318classNameString = (char*)
1319(*env)->GetStringUTFChars(env, jClassNameString, NULL);
1320if (classNameString == NULL) { return NULL; }
1321exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: ";
1322exceptionMsg = (char *)
1323malloc(strlen(exceptionMsgPrefix) + strlen(classNameString) + 1);
1324if (exceptionMsg == NULL) {
1325(*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
1326p11ThrowOutOfMemoryError(env, 0);
1327return NULL;
1328}
1329strcpy(exceptionMsg, exceptionMsgPrefix);
1330strcat(exceptionMsg, classNameString);
1331(*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
1332p11ThrowPKCS11RuntimeException(env, exceptionMsg);
1333free(exceptionMsg);
1334*ckpLength = 0;
1335
1336TRACE0("FINISHED\n");
1337return NULL;
1338}
1339
1340#ifdef P11_MEMORYDEBUG
1341
1342#undef malloc
1343#undef calloc
1344#undef free
1345
1346void *p11malloc(size_t c, char *file, int line) {
1347void *p = malloc(c);
1348fprintf(stdout, "malloc\t%08lX\t%lX\t%s:%d\n", ptr_to_jlong(p), c, file, line);
1349fflush(stdout);
1350return p;
1351}
1352
1353void *p11calloc(size_t c, size_t s, char *file, int line) {
1354void *p = calloc(c, s);
1355fprintf(stdout, "calloc\t%08lX\t%lX\t%lX\t%s:%d\n", ptr_to_jlong(p), c, s, file, line);
1356fflush(stdout);
1357return p;
1358}
1359
1360void p11free(void *p, char *file, int line) {
1361fprintf(stdout, "free\t%08lX\t\t%s:%d\n", ptr_to_jlong(p), file, line);
1362fflush(stdout);
1363free(p);
1364}
1365
1366#endif
1367
1368// prints a message to stdout if debug output is enabled
1369void printDebug(const char *format, ...) {
1370if (debug_j2pkcs11 == JNI_TRUE) {
1371va_list args;
1372fprintf(stdout, "sunpkcs11: ");
1373va_start(args, format);
1374vfprintf(stdout, format, args);
1375va_end(args);
1376fflush(stdout);
1377}
1378}
1379
1380