jdk

Форк
0
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

57
ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
58
int isModulePresent(JNIEnv *env, jobject pkcs11Implementation);
59
void 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
 */
67
static void throwDisconnectedRuntimeException(JNIEnv *env)
68
{
69
    p11ThrowPKCS11RuntimeException(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
 */
80
jobject createLockObject(JNIEnv *env) {
81
    jclass jObjectClass;
82
    jobject jLockObject;
83
    jmethodID jConstructor;
84

85
    jObjectClass = (*env)->FindClass(env, "java/lang/Object");
86
    if (jObjectClass == NULL) { return NULL; }
87
    jConstructor = (*env)->GetMethodID(env, jObjectClass, "<init>", "()V");
88
    if (jConstructor == NULL) { return NULL; }
89
    jLockObject = (*env)->NewObject(env, jObjectClass, jConstructor);
90
    if (jLockObject == NULL) { return NULL; }
91
    jLockObject = (*env)->NewGlobalRef(env, jLockObject);
92

93
    return jLockObject ;
94
}
95

96
/*
97
 * Create a new object for locking.
98
 */
99
void destroyLockObject(JNIEnv *env, jobject jLockObject) {
100
    if (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
 */
112
void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData) {
113
    if (pkcs11Implementation == NULL_PTR) {
114
        return ;
115
    }
116
    if (moduleData == NULL) {
117
        return ;
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
 */
127
ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
128
    jlong jData;
129
    if (pkcs11Implementation == NULL) {
130
        return NULL;
131
    }
132
    jData = (*env)->GetLongField(env, pkcs11Implementation, pNativeDataID);
133
    return (ModuleData*)jlong_to_ptr(jData);
134
}
135

136
CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation) {
137
    ModuleData *moduleData;
138
    CK_FUNCTION_LIST_PTR ckpFunctions;
139

140
    moduleData = getModuleEntry(env, pkcs11Implementation);
141
    if (moduleData == NULL) {
142
        throwDisconnectedRuntimeException(env);
143
        return NULL;
144
    }
145
    ckpFunctions = moduleData->ckFunctionListPtr;
146
    return ckpFunctions;
147
}
148

149
CK_FUNCTION_LIST_3_0_PTR getFunctionList30(JNIEnv *env, jobject
150
        pkcs11Implementation) {
151
    ModuleData *moduleData;
152
    CK_FUNCTION_LIST_3_0_PTR ckpFunctions30;
153

154
    moduleData = getModuleEntry(env, pkcs11Implementation);
155
    if (moduleData == NULL) {
156
        throwDisconnectedRuntimeException(env);
157
        return NULL;
158
    }
159
    ckpFunctions30 = moduleData->ckFunctionList30Ptr;
160
    return ckpFunctions30;
161
}
162

163

164
/*
165
 * Returns 1, if the given pkcs11Implementation is in the list.
166
 * 0, otherwise.
167
 */
168
int isModulePresent(JNIEnv *env, jobject pkcs11Implementation) {
169
    int present;
170

171
    ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
172

173
    present = (moduleData != NULL) ? 1 : 0;
174

175
    return 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
 */
182
void 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
 */
201
jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue) {
202
    return 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
 */
217
jlong ckAssertReturnValueOK2(JNIEnv *env, CK_RV returnValue, const char* msg) {
218
    jclass jPKCS11ExceptionClass;
219
    jmethodID jConstructor;
220
    jthrowable jPKCS11Exception;
221
    jlong jErrorCode = 0L;
222
    jstring jMsg = NULL;
223

224
    if (returnValue != CKR_OK) {
225
        jErrorCode = ckULongToJLong(returnValue);
226
        jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
227
        if (jPKCS11ExceptionClass != NULL) {
228
            jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass,
229
                    "<init>", "(JLjava/lang/String;)V");
230
            if (jConstructor != NULL) {
231
                if (msg != NULL) {
232
                    jMsg = (*env)->NewStringUTF(env, msg);
233
                }
234
                jPKCS11Exception = (jthrowable) (*env)->NewObject(env,
235
                        jPKCS11ExceptionClass, jConstructor, jErrorCode, jMsg);
236
                if (jPKCS11Exception != NULL) {
237
                    (*env)->Throw(env, jPKCS11Exception);
238
                }
239
            }
240
        }
241
        (*env)->DeleteLocalRef(env, jPKCS11ExceptionClass);
242
    }
243
    return jErrorCode;
244
}
245

246

247
/*
248
 * Throws a Java Exception by name
249
 */
250
static void throwByName(JNIEnv *env, const char *name, const char *msg)
251
{
252
    jclass cls = (*env)->FindClass(env, name);
253

254
    if (cls != 0) /* Otherwise an exception has already been thrown */
255
        (*env)->ThrowNew(env, cls, msg);
256
}
257

258
/*
259
 * Throws java.lang.OutOfMemoryError
260
 */
261
void p11ThrowOutOfMemoryError(JNIEnv *env, const char *msg)
262
{
263
    throwByName(env, "java/lang/OutOfMemoryError", msg);
264
}
265

266
/*
267
 * Throws java.lang.NullPointerException
268
 */
269
void p11ThrowNullPointerException(JNIEnv *env, const char *msg)
270
{
271
    throwByName(env, "java/lang/NullPointerException", msg);
272
}
273

274
/*
275
 * Throws java.io.IOException
276
 */
277
void p11ThrowIOException(JNIEnv *env, const char *msg)
278
{
279
    throwByName(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
 */
289
void p11ThrowPKCS11RuntimeException(JNIEnv *env, const char *message)
290
{
291
    throwByName(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
 */
299
void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len) {
300
    if (attrPtr != NULL) {
301
        int i;
302
        for (i=0; i<len; i++) {
303
            if (attrPtr[i].pValue != NULL_PTR) {
304
                free(attrPtr[i].pValue);
305
            }
306
        }
307
        free(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
 */
316
void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) {
317
     void *tmp;
318
     CK_SSL3_MASTER_KEY_DERIVE_PARAMS *sslMkdTmp;
319
     CK_SSL3_KEY_MAT_PARAMS* sslKmTmp;
320
     CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tlsMkdTmp;
321
     CK_TLS12_KEY_MAT_PARAMS* tlsKmTmp;
322

323
     if (mechPtr != NULL) {
324
         TRACE2("DEBUG freeCKMechanismPtr: free pMech %p (mech 0x%lX)\n",
325
                 mechPtr,  mechPtr->mechanism);
326
         if (mechPtr->pParameter != NULL) {
327
             tmp = mechPtr->pParameter;
328
             switch (mechPtr->mechanism) {
329
                 case CKM_AES_GCM:
330
                     if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS)) {
331
                         TRACE0("[ GCM_PARAMS ]\n");
332
                         free(((CK_GCM_PARAMS*)tmp)->pIv);
333
                         free(((CK_GCM_PARAMS*)tmp)->pAAD);
334
                     } else if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {
335
                         TRACE0("[ GCM_PARAMS w/o ulIvBits ]\n");
336
                         free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pIv);
337
                         free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pAAD);
338
                     }
339
                     break;
340
                 case CKM_AES_CCM:
341
                     TRACE0("[ CK_CCM_PARAMS ]\n");
342
                     free(((CK_CCM_PARAMS*)tmp)->pNonce);
343
                     free(((CK_CCM_PARAMS*)tmp)->pAAD);
344
                     break;
345
                 case CKM_CHACHA20_POLY1305:
346
                     TRACE0("[ CK_SALSA20_CHACHA20_POLY1305_PARAMS ]\n");
347
                     free(((CK_SALSA20_CHACHA20_POLY1305_PARAMS*)tmp)->pNonce);
348
                     free(((CK_SALSA20_CHACHA20_POLY1305_PARAMS*)tmp)->pAAD);
349
                     break;
350
                 case CKM_TLS_PRF:
351
                 case CKM_NSS_TLS_PRF_GENERAL:
352
                     TRACE0("[ CK_TLS_PRF_PARAMS ]\n");
353
                     free(((CK_TLS_PRF_PARAMS*)tmp)->pSeed);
354
                     free(((CK_TLS_PRF_PARAMS*)tmp)->pLabel);
355
                     free(((CK_TLS_PRF_PARAMS*)tmp)->pulOutputLen);
356
                     free(((CK_TLS_PRF_PARAMS*)tmp)->pOutput);
357
                     break;
358
                 case CKM_SSL3_MASTER_KEY_DERIVE:
359
                 case CKM_TLS_MASTER_KEY_DERIVE:
360
                 case CKM_SSL3_MASTER_KEY_DERIVE_DH:
361
                 case CKM_TLS_MASTER_KEY_DERIVE_DH:
362
                     sslMkdTmp = tmp;
363
                     TRACE0("[ CK_SSL3_MASTER_KEY_DERIVE_PARAMS ]\n");
364
                     free(sslMkdTmp->RandomInfo.pClientRandom);
365
                     free(sslMkdTmp->RandomInfo.pServerRandom);
366
                     free(sslMkdTmp->pVersion);
367
                     break;
368
                 case CKM_SSL3_KEY_AND_MAC_DERIVE:
369
                 case CKM_TLS_KEY_AND_MAC_DERIVE:
370
                     sslKmTmp = tmp;
371
                     TRACE0("[ CK_SSL3_KEY_MAT_PARAMS ]\n");
372
                     free(sslKmTmp->RandomInfo.pClientRandom);
373
                     free(sslKmTmp->RandomInfo.pServerRandom);
374
                     if (sslKmTmp->pReturnedKeyMaterial != NULL) {
375
                         free(sslKmTmp->pReturnedKeyMaterial->pIVClient);
376
                         free(sslKmTmp->pReturnedKeyMaterial->pIVServer);
377
                         free(sslKmTmp->pReturnedKeyMaterial);
378
                     }
379
                     break;
380
                 case CKM_TLS12_MASTER_KEY_DERIVE:
381
                 case CKM_TLS12_MASTER_KEY_DERIVE_DH:
382
                     tlsMkdTmp = tmp;
383
                     TRACE0("[ CK_TLS12_MASTER_KEY_DERIVE_PARAMS ]\n");
384
                     free(tlsMkdTmp->RandomInfo.pClientRandom);
385
                     free(tlsMkdTmp->RandomInfo.pServerRandom);
386
                     free(tlsMkdTmp->pVersion);
387
                     break;
388
                 case CKM_TLS12_KEY_AND_MAC_DERIVE:
389
                     tlsKmTmp = tmp;
390
                     TRACE0("[ CK_TLS12_KEY_MAT_PARAMS ]\n");
391
                     free(tlsKmTmp->RandomInfo.pClientRandom);
392
                     free(tlsKmTmp->RandomInfo.pServerRandom);
393
                     if (tlsKmTmp->pReturnedKeyMaterial != NULL) {
394
                         free(tlsKmTmp->pReturnedKeyMaterial->pIVClient);
395
                         free(tlsKmTmp->pReturnedKeyMaterial->pIVServer);
396
                         free(tlsKmTmp->pReturnedKeyMaterial);
397
                     }
398
                     break;
399
                 case CKM_ECDH1_DERIVE:
400
                 case CKM_ECDH1_COFACTOR_DERIVE:
401
                     TRACE0("[ CK_ECDH1_DERIVE_PARAMS ]\n");
402
                     free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pSharedData);
403
                     free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pPublicData);
404
                     break;
405
                 case CKM_TLS_MAC:
406
                 case CKM_AES_CTR:
407
                 case CKM_RSA_PKCS_PSS:
408
                 case CKM_CAMELLIA_CTR:
409
                     // params do not contain pointers
410
                     break;
411
                 case CKM_PKCS5_PBKD2:
412
                     // get the versioned structure from behind memory
413
                     TRACE0(((VersionedPbkd2ParamsPtr)tmp)->version == PARAMS ?
414
                             "[ CK_PKCS5_PBKD2_PARAMS ]\n" :
415
                             "[ CK_PKCS5_PBKD2_PARAMS2 ]\n");
416
                     FREE_VERSIONED_PBKD2_MEMBERS((VersionedPbkd2ParamsPtr)tmp);
417
                     break;
418
                 case CKM_PBA_SHA1_WITH_SHA1_HMAC:
419
                 case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
420
                 case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
421
                 case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
422
                 case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
423
                     TRACE0("[ CK_PBE_PARAMS ]\n");
424
                     free(((CK_PBE_PARAMS_PTR)tmp)->pInitVector);
425
                     if (((CK_PBE_PARAMS_PTR)tmp)->pPassword != NULL) {
426
                         memset(((CK_PBE_PARAMS_PTR)tmp)->pPassword, 0,
427
                                 ((CK_PBE_PARAMS_PTR)tmp)->ulPasswordLen);
428
                     }
429
                     free(((CK_PBE_PARAMS_PTR)tmp)->pPassword);
430
                     free(((CK_PBE_PARAMS_PTR)tmp)->pSalt);
431
                     break;
432
                 default:
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?
441
                     TRACE0("ERROR: UNSUPPORTED CK_MECHANISM\n");
442
                     break;
443
             }
444
             TRACE1("\t=> freed param %p\n", tmp);
445
             free(tmp);
446
         } else {
447
             TRACE0("\t=> param NULL\n");
448
         }
449
         free(mechPtr);
450
         TRACE0("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
 */
463
CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr) {
464
    CK_GCM_PARAMS_PTR pParams;
465
    CK_GCM_PARAMS_NO_IVBITS_PTR pParamsNoIvBits;
466
    CK_ULONG paramLen;
467

468
    if (mechPtr != NULL) {
469
        paramLen = mechPtr->ulParameterLen;
470
        if (paramLen == sizeof(CK_GCM_PARAMS)) {
471
            // CK_GCM_PARAMS => CK_GCM_PARAMS_NO_IVBITS
472
            pParams = (CK_GCM_PARAMS*) mechPtr->pParameter;
473
            pParamsNoIvBits = calloc(1, sizeof(CK_GCM_PARAMS_NO_IVBITS));
474
            pParamsNoIvBits->pIv = pParams->pIv;
475
            pParamsNoIvBits->ulIvLen = pParams->ulIvLen;
476
            pParamsNoIvBits->pAAD = pParams->pAAD;
477
            pParamsNoIvBits->ulAADLen = pParams->ulAADLen;
478
            pParamsNoIvBits->ulTagBits = pParams->ulTagBits;
479
            mechPtr->pParameter = pParamsNoIvBits;
480
            mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS_NO_IVBITS);
481
            free(pParams);
482
            TRACE0("DEBUG update CK_GCM_PARAMS to CK_GCM_PARAMS_NO_IVBITS\n");
483
            return mechPtr;
484
        } else if (paramLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {
485
            // CK_GCM_PARAMS_NO_IVBITS => CK_GCM_PARAMS
486
            pParamsNoIvBits = (CK_GCM_PARAMS_NO_IVBITS*) mechPtr->pParameter;
487
            pParams = calloc(1, sizeof(CK_GCM_PARAMS));
488
            pParams->pIv = pParamsNoIvBits->pIv;
489
            pParams->ulIvLen = pParamsNoIvBits->ulIvLen;
490
            pParams->ulIvBits = pParamsNoIvBits->ulIvLen << 3;
491
            pParams->pAAD = pParamsNoIvBits->pAAD;
492
            pParams->ulAADLen = pParamsNoIvBits->ulAADLen;
493
            pParams->ulTagBits = pParamsNoIvBits->ulTagBits;
494
            mechPtr->pParameter = pParams;
495
            mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS);
496
            free(pParamsNoIvBits);
497
            TRACE0("DEBUG update CK_GCM_PARAMS_NO_IVBITS to CK_GCM_PARAMS\n");
498
            return mechPtr;
499
        }
500
    }
501
    TRACE0("DEBUG updateGCMParams: no conversion done\n");
502
    return 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
 */
545
void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckpLength)
546
{
547
    jboolean* jpTemp;
548
    CK_ULONG i;
549

550
    if (jArray == NULL) {
551
        *ckpArray = NULL_PTR;
552
        *ckpLength = 0UL;
553
        return;
554
    }
555
    *ckpLength = (*env)->GetArrayLength(env, jArray);
556
    jpTemp = (jboolean*) calloc(*ckpLength, sizeof(jboolean));
557
    if (jpTemp == NULL && *ckpLength != 0UL) {
558
        p11ThrowOutOfMemoryError(env, 0);
559
        return;
560
    }
561
    (*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
562
    if ((*env)->ExceptionCheck(env)) {
563
        free(jpTemp);
564
        return;
565
    }
566

567
    *ckpArray = (CK_BBOOL*) calloc(*ckpLength, sizeof(CK_BBOOL));
568
    if (*ckpArray == NULL && *ckpLength != 0UL) {
569
        free(jpTemp);
570
        p11ThrowOutOfMemoryError(env, 0);
571
        return;
572
    }
573
    for (i=0; i<(*ckpLength); i++) {
574
        (*ckpArray)[i] = jBooleanToCKBBool(jpTemp[i]);
575
    }
576
    free(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
 */
587
void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
588
{
589
    jbyte* jpTemp;
590
    CK_ULONG i;
591

592
    if (jArray == NULL) {
593
        *ckpArray = NULL_PTR;
594
        *ckpLength = 0UL;
595
        return;
596
    }
597
    *ckpLength = (*env)->GetArrayLength(env, jArray);
598
    jpTemp = (jbyte*) calloc(*ckpLength, sizeof(jbyte));
599
    if (jpTemp == NULL && *ckpLength != 0UL) {
600
        p11ThrowOutOfMemoryError(env, 0);
601
        return;
602
    }
603
    (*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
604
    if ((*env)->ExceptionCheck(env)) {
605
        free(jpTemp);
606
        return;
607
    }
608

609
    /* if CK_BYTE is the same size as jbyte, we save an additional copy */
610
    if (sizeof(CK_BYTE) == sizeof(jbyte)) {
611
        *ckpArray = (CK_BYTE_PTR) jpTemp;
612
    } else {
613
        *ckpArray = (CK_BYTE_PTR) calloc(*ckpLength, sizeof(CK_BYTE));
614
        if (*ckpArray == NULL && *ckpLength != 0UL) {
615
            free(jpTemp);
616
            p11ThrowOutOfMemoryError(env, 0);
617
            return;
618
        }
619
        for (i=0; i<(*ckpLength); i++) {
620
            (*ckpArray)[i] = jByteToCKByte(jpTemp[i]);
621
        }
622
        free(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
 */
634
void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckpLength)
635
{
636
    jlong* jTemp;
637
    CK_ULONG i;
638

639
    if (jArray == NULL) {
640
        *ckpArray = NULL_PTR;
641
        *ckpLength = 0UL;
642
        return;
643
    }
644
    *ckpLength = (*env)->GetArrayLength(env, jArray);
645
    jTemp = (jlong*) calloc(*ckpLength, sizeof(jlong));
646
    if (jTemp == NULL && *ckpLength != 0UL) {
647
        p11ThrowOutOfMemoryError(env, 0);
648
        return;
649
    }
650
    (*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jTemp);
651
    if ((*env)->ExceptionCheck(env)) {
652
        free(jTemp);
653
        return;
654
    }
655

656
    *ckpArray = (CK_ULONG_PTR) calloc(*ckpLength, sizeof(CK_ULONG));
657
    if (*ckpArray == NULL && *ckpLength != 0UL) {
658
        free(jTemp);
659
        p11ThrowOutOfMemoryError(env, 0);
660
        return;
661
    }
662
    for (i=0; i<(*ckpLength); i++) {
663
        (*ckpArray)[i] = jLongToCKULong(jTemp[i]);
664
    }
665
    free(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
 */
676
void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
677
{
678
    jchar* jpTemp;
679
    CK_ULONG i;
680

681
    if (jArray == NULL) {
682
        *ckpArray = NULL_PTR;
683
        *ckpLength = 0UL;
684
        return;
685
    }
686
    *ckpLength = (*env)->GetArrayLength(env, jArray);
687
    jpTemp = (jchar*) calloc(*ckpLength, sizeof(jchar));
688
    if (jpTemp == NULL && *ckpLength != 0UL) {
689
        p11ThrowOutOfMemoryError(env, 0);
690
        return;
691
    }
692
    (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
693
    if ((*env)->ExceptionCheck(env)) {
694
        free(jpTemp);
695
        return;
696
    }
697

698
    *ckpArray = (CK_CHAR_PTR) calloc(*ckpLength, sizeof(CK_CHAR));
699
    if (*ckpArray == NULL && *ckpLength != 0UL) {
700
        free(jpTemp);
701
        p11ThrowOutOfMemoryError(env, 0);
702
        return;
703
    }
704
    for (i=0; i<(*ckpLength); i++) {
705
        (*ckpArray)[i] = jCharToCKChar(jpTemp[i]);
706
    }
707
    free(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
 */
718
void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
719
{
720
    jchar* jTemp;
721
    CK_ULONG i;
722

723
    if (jArray == NULL) {
724
        *ckpArray = NULL_PTR;
725
        *ckpLength = 0UL;
726
        return;
727
    }
728
    *ckpLength = (*env)->GetArrayLength(env, jArray);
729
    jTemp = (jchar*) calloc(*ckpLength, sizeof(jchar));
730
    if (jTemp == NULL && *ckpLength != 0UL) {
731
        p11ThrowOutOfMemoryError(env, 0);
732
        return;
733
    }
734
    (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jTemp);
735
    if ((*env)->ExceptionCheck(env)) {
736
        goto cleanup;
737
    }
738

739
    *ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength, sizeof(CK_UTF8CHAR));
740
    if (*ckpArray == NULL && *ckpLength != 0UL) {
741
        p11ThrowOutOfMemoryError(env, 0);
742
        goto cleanup;
743
    }
744
    for (i=0; i<(*ckpLength); i++) {
745
        (*ckpArray)[i] = jCharToCKUTF8Char(jTemp[i]);
746
    }
747
cleanup:
748
    // Clean possible temporary copies of passwords.
749
    memset(jTemp, 0, *ckpLength * sizeof(jchar));
750
    free(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
 */
761
void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
762
{
763
    const char* pCharArray;
764
    jboolean isCopy;
765

766
    if(jArray == NULL) {
767
        *ckpArray = NULL_PTR;
768
        *ckpLength = 0L;
769
        return;
770
    }
771

772
    pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
773
    if (pCharArray == NULL) { return; }
774

775
    *ckpLength = (CK_ULONG) strlen(pCharArray);
776
    *ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength + 1, sizeof(CK_UTF8CHAR));
777
    if (*ckpArray == NULL) {
778
        (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
779
        p11ThrowOutOfMemoryError(env, 0);
780
        return;
781
    }
782
    strcpy((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
 */
796
void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
797
{
798
    CK_ULONG i;
799
    jlong jLength;
800
    jobject jAttribute;
801

802
    TRACE0("\nDEBUG: jAttributeArrayToCKAttributeArray");
803
    if (jArray == NULL) {
804
        *ckpArray = NULL_PTR;
805
        *ckpLength = 0L;
806
        return;
807
    }
808
    jLength = (*env)->GetArrayLength(env, jArray);
809
    *ckpLength = jLongToCKULong(jLength);
810
    *ckpArray = (CK_ATTRIBUTE_PTR) calloc(*ckpLength, sizeof(CK_ATTRIBUTE));
811
    if (*ckpArray == NULL && *ckpLength != 0UL) {
812
        p11ThrowOutOfMemoryError(env, 0);
813
        return;
814
    }
815
    TRACE1(", converting %lld attributes", (long long int) jLength);
816
    for (i=0; i<(*ckpLength); i++) {
817
        TRACE1(", getting %lu. attribute", i);
818
        jAttribute = (*env)->GetObjectArrayElement(env, jArray, i);
819
        if ((*env)->ExceptionCheck(env)) {
820
            freeCKAttributeArray(*ckpArray, i);
821
            return;
822
        }
823
        TRACE1(", jAttribute , converting %lu. attribute", i);
824
        (*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute);
825
        if ((*env)->ExceptionCheck(env)) {
826
            freeCKAttributeArray(*ckpArray, i);
827
            return;
828
        }
829
    }
830
    TRACE0("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
 */
841
jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength)
842
{
843
    CK_ULONG i;
844
    jbyte* jpTemp;
845
    jbyteArray jArray;
846

847
    /* if CK_BYTE is the same size as jbyte, we save an additional copy */
848
    if (sizeof(CK_BYTE) == sizeof(jbyte)) {
849
        jpTemp = (jbyte*) ckpArray;
850
    } else {
851
        jpTemp = (jbyte*) calloc(ckLength, sizeof(jbyte));
852
        if (jpTemp == NULL && ckLength != 0UL) {
853
            p11ThrowOutOfMemoryError(env, 0);
854
            return NULL;
855
        }
856
        for (i=0; i<ckLength; i++) {
857
            jpTemp[i] = ckByteToJByte(ckpArray[i]);
858
        }
859
    }
860

861
    jArray = (*env)->NewByteArray(env, ckULongToJSize(ckLength));
862
    if (jArray != NULL) {
863
        (*env)->SetByteArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
864
    }
865

866
    if (sizeof(CK_BYTE) != sizeof(jbyte)) { free(jpTemp); }
867

868
    return 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
 */
879
jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength)
880
{
881
    CK_ULONG i;
882
    jlong* jpTemp;
883
    jlongArray jArray;
884

885
    jpTemp = (jlong*) calloc(ckLength, sizeof(jlong));
886
    if (jpTemp == NULL && ckLength != 0UL) {
887
        p11ThrowOutOfMemoryError(env, 0);
888
        return NULL;
889
    }
890
    for (i=0; i<ckLength; i++) {
891
        jpTemp[i] = ckLongToJLong(ckpArray[i]);
892
    }
893
    jArray = (*env)->NewLongArray(env, ckULongToJSize(ckLength));
894
    if (jArray != NULL) {
895
        (*env)->SetLongArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
896
    }
897
    free(jpTemp);
898

899
    return 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
 */
910
jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG ckLength)
911
{
912
    CK_ULONG i;
913
    jchar* jpTemp;
914
    jcharArray jArray;
915

916
    jpTemp = (jchar*) calloc(ckLength, sizeof(jchar));
917
    if (jpTemp == NULL && ckLength != 0UL) {
918
        p11ThrowOutOfMemoryError(env, 0);
919
        return NULL;
920
    }
921
    for (i=0; i<ckLength; i++) {
922
        jpTemp[i] = ckCharToJChar(ckpArray[i]);
923
    }
924
    jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
925
    if (jArray != NULL) {
926
        (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
927
    }
928
    free(jpTemp);
929

930
    return 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
 */
941
jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength)
942
{
943
    CK_ULONG i;
944
    jchar* jpTemp;
945
    jcharArray jArray;
946

947
    jpTemp = (jchar*) calloc(ckLength, sizeof(jchar));
948
    if (jpTemp == NULL && ckLength != 0UL) {
949
        p11ThrowOutOfMemoryError(env, 0);
950
        return NULL;
951
    }
952
    for (i=0; i<ckLength; i++) {
953
        jpTemp[i] = ckUTF8CharToJChar(ckpArray[i]);
954
    }
955
    jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
956
    if (jArray != NULL) {
957
        (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
958
    }
959
    free(jpTemp);
960

961
    return 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
 */
989
jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL *ckpValue)
990
{
991
    jclass jValueObjectClass;
992
    jmethodID jConstructor;
993
    jobject jValueObject;
994
    jboolean jValue;
995

996
    jValueObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
997
    if (jValueObjectClass == NULL) { return NULL; }
998
    jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(Z)V");
999
    if (jConstructor == NULL) { return NULL; }
1000
    jValue = ckBBoolToJBoolean(*ckpValue);
1001
    jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
1002

1003
    return 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
 */
1013
jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue)
1014
{
1015
    jclass jValueObjectClass;
1016
    jmethodID jConstructor;
1017
    jobject jValueObject;
1018
    jlong jValue;
1019

1020
    jValueObjectClass = (*env)->FindClass(env, "java/lang/Long");
1021
    if (jValueObjectClass == NULL) { return NULL; }
1022
    jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V");
1023
    if (jConstructor == NULL) { return NULL; }
1024
    jValue = ckULongToJLong(*ckpValue);
1025
    jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
1026

1027
    return 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
 */
1038
CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject)
1039
{
1040
    jclass jObjectClass;
1041
    jmethodID jValueMethod;
1042
    jboolean jValue;
1043
    CK_BBOOL *ckpValue;
1044

1045
    jObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
1046
    if (jObjectClass == NULL) { return NULL; }
1047
    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "booleanValue", "()Z");
1048
    if (jValueMethod == NULL) { return NULL; }
1049
    jValue = (*env)->CallBooleanMethod(env, jObject, jValueMethod);
1050
    ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL));
1051
    if (ckpValue == NULL) {
1052
        p11ThrowOutOfMemoryError(env, 0);
1053
        return NULL;
1054
    }
1055
    *ckpValue = jBooleanToCKBBool(jValue);
1056

1057
    return 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
 */
1068
CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject)
1069
{
1070
    jclass jObjectClass;
1071
    jmethodID jValueMethod;
1072
    jbyte jValue;
1073
    CK_BYTE_PTR ckpValue;
1074

1075
    jObjectClass = (*env)->FindClass(env, "java/lang/Byte");
1076
    if (jObjectClass == NULL) { return NULL; }
1077
    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "byteValue", "()B");
1078
    if (jValueMethod == NULL) { return NULL; }
1079
    jValue = (*env)->CallByteMethod(env, jObject, jValueMethod);
1080
    ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE));
1081
    if (ckpValue == NULL) {
1082
        p11ThrowOutOfMemoryError(env, 0);
1083
        return NULL;
1084
    }
1085
    *ckpValue = jByteToCKByte(jValue);
1086
    return 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
 */
1097
CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject)
1098
{
1099
    jclass jObjectClass;
1100
    jmethodID jValueMethod;
1101
    jint jValue;
1102
    CK_ULONG *ckpValue;
1103

1104
    jObjectClass = (*env)->FindClass(env, "java/lang/Integer");
1105
    if (jObjectClass == NULL) { return NULL; }
1106
    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "intValue", "()I");
1107
    if (jValueMethod == NULL) { return NULL; }
1108
    jValue = (*env)->CallIntMethod(env, jObject, jValueMethod);
1109
    ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
1110
    if (ckpValue == NULL) {
1111
        p11ThrowOutOfMemoryError(env, 0);
1112
        return NULL;
1113
    }
1114
    *ckpValue = jLongToCKLong(jValue);
1115
    return 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
 */
1126
CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject)
1127
{
1128
    jclass jObjectClass;
1129
    jmethodID jValueMethod;
1130
    jlong jValue;
1131
    CK_ULONG *ckpValue;
1132

1133
    jObjectClass = (*env)->FindClass(env, "java/lang/Long");
1134
    if (jObjectClass == NULL) { return NULL; }
1135
    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J");
1136
    if (jValueMethod == NULL) { return NULL; }
1137
    jValue = (*env)->CallLongMethod(env, jObject, jValueMethod);
1138
    ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
1139
    if (ckpValue == NULL) {
1140
        p11ThrowOutOfMemoryError(env, 0);
1141
        return NULL;
1142
    }
1143
    *ckpValue = jLongToCKULong(jValue);
1144

1145
    return 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
 */
1156
CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject)
1157
{
1158
    jclass jObjectClass;
1159
    jmethodID jValueMethod;
1160
    jchar jValue;
1161
    CK_CHAR_PTR ckpValue;
1162

1163
    jObjectClass = (*env)->FindClass(env, "java/lang/Char");
1164
    if (jObjectClass == NULL) { return NULL; }
1165
    jValueMethod = (*env)->GetMethodID(env, jObjectClass, "charValue", "()C");
1166
    if (jValueMethod == NULL) { return NULL; }
1167
    jValue = (*env)->CallCharMethod(env, jObject, jValueMethod);
1168
    ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR));
1169
    if (ckpValue == NULL) {
1170
        p11ThrowOutOfMemoryError(env, 0);
1171
        return NULL;
1172
    }
1173
    *ckpValue = jCharToCKChar(jValue);
1174

1175
    return 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
 */
1187
CK_VOID_PTR jObjectToPrimitiveCKObjectPtr(JNIEnv *env, jobject jObject, CK_ULONG *ckpLength)
1188
{
1189
    jclass jLongClass, jBooleanClass, jByteArrayClass, jCharArrayClass;
1190
    jclass jByteClass, jDateClass, jCharacterClass, jIntegerClass;
1191
    jclass jBooleanArrayClass, jIntArrayClass, jLongArrayClass;
1192
    jclass jStringClass;
1193
    jclass jObjectClass, jClassClass;
1194
    CK_VOID_PTR ckpObject;
1195
    jmethodID jMethod;
1196
    jobject jClassObject;
1197
    jstring jClassNameString;
1198
    char *classNameString, *exceptionMsgPrefix, *exceptionMsg;
1199

1200
    TRACE0("\nDEBUG: jObjectToPrimitiveCKObjectPtr");
1201
    if (jObject == NULL) {
1202
        *ckpLength = 0;
1203
        return NULL;
1204
    }
1205

1206
    jLongClass = (*env)->FindClass(env, "java/lang/Long");
1207
    if (jLongClass == NULL) { return NULL; }
1208
    if ((*env)->IsInstanceOf(env, jObject, jLongClass)) {
1209
        ckpObject = jLongObjectToCKULongPtr(env, jObject);
1210
        *ckpLength = sizeof(CK_ULONG);
1211
        TRACE1("<converted long value %lu>", *((CK_ULONG *) ckpObject));
1212
        return ckpObject;
1213
    }
1214

1215
    jBooleanClass = (*env)->FindClass(env, "java/lang/Boolean");
1216
    if (jBooleanClass == NULL) { return NULL; }
1217
    if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) {
1218
        ckpObject = jBooleanObjectToCKBBoolPtr(env, jObject);
1219
        *ckpLength = sizeof(CK_BBOOL);
1220
        TRACE0(" <converted boolean value ");
1221
        TRACE0((*((CK_BBOOL *) ckpObject) == TRUE) ? "TRUE>" : "FALSE>");
1222
        return ckpObject;
1223
    }
1224

1225
    jByteArrayClass = (*env)->FindClass(env, "[B");
1226
    if (jByteArrayClass == NULL) { return NULL; }
1227
    if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) {
1228
        jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*) &ckpObject, ckpLength);
1229
        return ckpObject;
1230
    }
1231

1232
    jCharArrayClass = (*env)->FindClass(env, "[C");
1233
    if (jCharArrayClass == NULL) { return NULL; }
1234
    if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) {
1235
        jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*) &ckpObject, ckpLength);
1236
        return ckpObject;
1237
    }
1238

1239
    jByteClass = (*env)->FindClass(env, "java/lang/Byte");
1240
    if (jByteClass == NULL) { return NULL; }
1241
    if ((*env)->IsInstanceOf(env, jObject, jByteClass)) {
1242
        ckpObject = jByteObjectToCKBytePtr(env, jObject);
1243
        *ckpLength = sizeof(CK_BYTE);
1244
        TRACE1("<converted byte value %X>", *((CK_BYTE *) ckpObject));
1245
        return ckpObject;
1246
    }
1247

1248
    jDateClass = (*env)->FindClass(env, CLASS_DATE);
1249
    if (jDateClass == NULL) { return NULL; }
1250
    if ((*env)->IsInstanceOf(env, jObject, jDateClass)) {
1251
        ckpObject = jDateObjectToCKDatePtr(env, jObject);
1252
        *ckpLength = sizeof(CK_DATE);
1253
        TRACE3("<converted date value %.4s-%.2s-%.2s>", ((CK_DATE *) ckpObject)->year,
1254
                ((CK_DATE *) ckpObject)->month, ((CK_DATE *) ckpObject)->day);
1255
        return ckpObject;
1256
    }
1257

1258
    jCharacterClass = (*env)->FindClass(env, "java/lang/Character");
1259
    if (jCharacterClass == NULL) { return NULL; }
1260
    if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) {
1261
        ckpObject = jCharObjectToCKCharPtr(env, jObject);
1262
        *ckpLength = sizeof(CK_UTF8CHAR);
1263
        TRACE1("<converted char value %c>", *((CK_CHAR *) ckpObject));
1264
        return ckpObject;
1265
    }
1266

1267
    jIntegerClass = (*env)->FindClass(env, "java/lang/Integer");
1268
    if (jIntegerClass == NULL) { return NULL; }
1269
    if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) {
1270
        ckpObject = jIntegerObjectToCKULongPtr(env, jObject);
1271
        *ckpLength = sizeof(CK_ULONG);
1272
        TRACE1("<converted integer value %lu>", *((CK_ULONG *) ckpObject));
1273
        return ckpObject;
1274
    }
1275

1276
    jBooleanArrayClass = (*env)->FindClass(env, "[Z");
1277
    if (jBooleanArrayClass == NULL) { return NULL; }
1278
    if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) {
1279
        jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**) &ckpObject, ckpLength);
1280
        return ckpObject;
1281
    }
1282

1283
    jIntArrayClass = (*env)->FindClass(env, "[I");
1284
    if (jIntArrayClass == NULL) { return NULL; }
1285
    if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) {
1286
        jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*) &ckpObject, ckpLength);
1287
        return ckpObject;
1288
    }
1289

1290
    jLongArrayClass = (*env)->FindClass(env, "[J");
1291
    if (jLongArrayClass == NULL) { return NULL; }
1292
    if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) {
1293
        jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*) &ckpObject, ckpLength);
1294
        return ckpObject;
1295
    }
1296

1297
    jStringClass = (*env)->FindClass(env, "java/lang/String");
1298
    if (jStringClass == NULL) { return NULL; }
1299
    if ((*env)->IsInstanceOf(env, jObject, jStringClass)) {
1300
        jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*) &ckpObject, ckpLength);
1301
        return ckpObject;
1302
    }
1303

1304
    /* type of jObject unknown, throw PKCS11RuntimeException */
1305
    jObjectClass = (*env)->FindClass(env, "java/lang/Object");
1306
    if (jObjectClass == NULL) { return NULL; }
1307
    jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;");
1308
    if (jMethod == NULL) { return NULL; }
1309
    jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod);
1310
    assert(jClassObject != 0);
1311
    jClassClass = (*env)->FindClass(env, "java/lang/Class");
1312
    if (jClassClass == NULL) { return NULL; }
1313
    jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;");
1314
    if (jMethod == NULL) { return NULL; }
1315
    jClassNameString = (jstring)
1316
        (*env)->CallObjectMethod(env, jClassObject, jMethod);
1317
    assert(jClassNameString != 0);
1318
    classNameString = (char*)
1319
        (*env)->GetStringUTFChars(env, jClassNameString, NULL);
1320
    if (classNameString == NULL) { return NULL; }
1321
    exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: ";
1322
    exceptionMsg = (char *)
1323
        malloc(strlen(exceptionMsgPrefix) + strlen(classNameString) + 1);
1324
    if (exceptionMsg == NULL) {
1325
        (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
1326
        p11ThrowOutOfMemoryError(env, 0);
1327
        return NULL;
1328
    }
1329
    strcpy(exceptionMsg, exceptionMsgPrefix);
1330
    strcat(exceptionMsg, classNameString);
1331
    (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
1332
    p11ThrowPKCS11RuntimeException(env, exceptionMsg);
1333
    free(exceptionMsg);
1334
    *ckpLength = 0;
1335

1336
    TRACE0("FINISHED\n");
1337
    return NULL;
1338
}
1339

1340
#ifdef P11_MEMORYDEBUG
1341

1342
#undef malloc
1343
#undef calloc
1344
#undef free
1345

1346
void *p11malloc(size_t c, char *file, int line) {
1347
    void *p = malloc(c);
1348
    fprintf(stdout, "malloc\t%08lX\t%lX\t%s:%d\n", ptr_to_jlong(p), c, file, line);
1349
    fflush(stdout);
1350
    return p;
1351
}
1352

1353
void *p11calloc(size_t c, size_t s, char *file, int line) {
1354
    void *p = calloc(c, s);
1355
    fprintf(stdout, "calloc\t%08lX\t%lX\t%lX\t%s:%d\n", ptr_to_jlong(p), c, s, file, line);
1356
    fflush(stdout);
1357
    return p;
1358
}
1359

1360
void p11free(void *p, char *file, int line) {
1361
    fprintf(stdout, "free\t%08lX\t\t%s:%d\n", ptr_to_jlong(p), file, line);
1362
    fflush(stdout);
1363
    free(p);
1364
}
1365

1366
#endif
1367

1368
// prints a message to stdout if debug output is enabled
1369
void printDebug(const char *format, ...) {
1370
    if (debug_j2pkcs11 == JNI_TRUE) {
1371
        va_list args;
1372
        fprintf(stdout, "sunpkcs11: ");
1373
        va_start(args, format);
1374
        vfprintf(stdout, format, args);
1375
        va_end(args);
1376
        fflush(stdout);
1377
    }
1378
}
1379

1380

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.