1/*
2 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3 */
4
5/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * 3. The end-user documentation included with the redistribution, if any, must
18 * include the following acknowledgment:
19 *
20 * "This product includes software developed by IAIK of Graz University of
21 * Technology."
22 *
23 * Alternately, this acknowledgment may appear in the software itself, if
24 * and wherever such third-party acknowledgments normally appear.
25 *
26 * 4. The names "Graz University of Technology" and "IAIK of Graz University of
27 * Technology" must not be used to endorse or promote products derived from
28 * this software without prior written permission.
29 *
30 * 5. Products derived from this software may not be called
31 * "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
32 * written permission of Graz University of Technology.
33 *
34 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
35 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
38 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
39 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
40 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
41 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
43 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
45 * POSSIBILITY OF SUCH DAMAGE.
46 */
47
48#include "pkcs11wrapper.h"
49
50#include <stdio.h>
51#include <stdlib.h>
52#include <string.h>
53#include <assert.h>
54#include "jlong.h"
55
56#include "sun_security_pkcs11_wrapper_PKCS11.h"
57
58#ifdef P11_ENABLE_C_SIGNINIT
59/*
60 * Class: sun_security_pkcs11_wrapper_PKCS11
61 * Method: C_SignInit
62 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
63 * Parametermapping: *PKCS11*
64 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
65 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism
66 * @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
67 */
68JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignInit
69 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
70{
71 CK_SESSION_HANDLE ckSessionHandle;
72 CK_MECHANISM_PTR ckpMechanism = NULL;
73 CK_OBJECT_HANDLE ckKeyHandle;
74 CK_RV rv;
75
76 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
77 if (ckpFunctions == NULL) { return; }
78
79 TRACE0("DEBUG: C_SignInit\n");
80
81 ckSessionHandle = jLongToCKULong(jSessionHandle);
82
83 ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
84 if ((*env)->ExceptionCheck(env)) { return; }
85
86 ckKeyHandle = jLongToCKULong(jKeyHandle);
87
88 rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, ckpMechanism, ckKeyHandle);
89
90 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK ||
91 (ckpMechanism->pParameter == NULL)) {
92 freeCKMechanismPtr(ckpMechanism);
93 } else {
94 (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism));
95 TRACE1("DEBUG C_SignInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism));
96 }
97 TRACE0("FINISHED\n");
98}
99#endif
100
101#ifdef P11_ENABLE_C_SIGN
102/*
103 * Class: sun_security_pkcs11_wrapper_PKCS11
104 * Method: C_Sign
105 * Signature: (J[BI)[B
106 * Parametermapping: *PKCS11*
107 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
108 * @param jbyteArray jData CK_BYTE_PTR pData
109 * CK_ULONG ulDataLen
110 * @return jbyteArray jSignature CK_BYTE_PTR pSignature
111 * CK_ULONG_PTR pulSignatureLen
112 */
113JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Sign
114 (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
115{
116 CK_SESSION_HANDLE ckSessionHandle;
117 CK_BYTE_PTR ckpData = NULL_PTR;
118 CK_ULONG ckDataLength;
119 CK_BYTE_PTR bufP;
120 CK_ULONG ckSignatureLength;
121 CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
122 jbyteArray jSignature = NULL;
123 CK_RV rv;
124
125 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
126 if (ckpFunctions == NULL) { return NULL; }
127
128 TRACE0("DEBUG: C_Sign\n");
129
130 ckSessionHandle = jLongToCKULong(jSessionHandle);
131 jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
132 if ((*env)->ExceptionCheck(env)) {
133 return NULL;
134 }
135
136 TRACE1("DEBUG C_Sign: data length = %lu\n", ckDataLength);
137
138 // unknown signature length
139 bufP = BUF;
140 ckSignatureLength = MAX_STACK_BUFFER_LEN;
141
142 rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength,
143 bufP, &ckSignatureLength);
144
145 TRACE1("DEBUG C_Sign: ret rv=0x%lX\n", rv);
146
147 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
148 jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength);
149 TRACE1("DEBUG C_Sign: signature length = %lu\n", ckSignatureLength);
150 }
151
152 free(ckpData);
153 if (bufP != BUF) { free(bufP); }
154
155 TRACE0("FINISHED\n");
156 return jSignature;
157}
158#endif
159
160#ifdef P11_ENABLE_C_SIGNUPDATE
161/*
162 * Class: sun_security_pkcs11_wrapper_PKCS11
163 * Method: C_SignUpdate
164 * Signature: (J[BII)V
165 * Parametermapping: *PKCS11*
166 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
167 * @param jbyteArray jPart CK_BYTE_PTR pPart
168 * CK_ULONG ulPartLen
169 */
170JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignUpdate
171 (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
172{
173 CK_SESSION_HANDLE ckSessionHandle;
174 CK_RV rv;
175 CK_BYTE_PTR bufP;
176 CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
177 jsize bufLen;
178
179 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
180 if (ckpFunctions == NULL) { return; }
181
182 ckSessionHandle = jLongToCKULong(jSessionHandle);
183
184 if (directIn != 0) {
185 rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, (CK_BYTE_PTR) jlong_to_ptr(directIn), jInLen);
186 ckAssertReturnValueOK(env, rv);
187 return;
188 }
189
190 if (jInLen <= MAX_STACK_BUFFER_LEN) {
191 bufLen = MAX_STACK_BUFFER_LEN;
192 bufP = BUF;
193 } else {
194 bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
195 bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
196 if (bufP == NULL) {
197 throwOutOfMemoryError(env, 0);
198 return;
199 }
200 }
201
202 while (jInLen > 0) {
203 jsize chunkLen = min(bufLen, jInLen);
204 (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
205 if ((*env)->ExceptionCheck(env)) {
206 goto cleanup;
207 }
208 rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, bufP, chunkLen);
209 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
210 goto cleanup;
211 }
212 jInOfs += chunkLen;
213 jInLen -= chunkLen;
214 }
215
216cleanup:
217 if (bufP != BUF) { free(bufP); }
218
219 return;
220}
221#endif
222
223#ifdef P11_ENABLE_C_SIGNFINAL
224/*
225 * Class: sun_security_pkcs11_wrapper_PKCS11
226 * Method: C_SignFinal
227 * Signature: (J)[B
228 * Parametermapping: *PKCS11*
229 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
230 * @return jbyteArray jSignature CK_BYTE_PTR pSignature
231 * CK_ULONG_PTR pulSignatureLen
232 */
233JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignFinal
234 (JNIEnv *env, jobject obj, jlong jSessionHandle, jint jExpectedLength)
235{
236 CK_SESSION_HANDLE ckSessionHandle;
237 jbyteArray jSignature = NULL;
238 CK_RV rv;
239 CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
240 CK_BYTE_PTR bufP = BUF;
241 CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
242
243 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
244 if (ckpFunctions == NULL) { return NULL; }
245
246 ckSessionHandle = jLongToCKULong(jSessionHandle);
247
248 if ((jExpectedLength > 0) && ((CK_ULONG)jExpectedLength < ckSignatureLength)) {
249 ckSignatureLength = jExpectedLength;
250 }
251
252 rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
253 if (rv == CKR_BUFFER_TOO_SMALL) {
254 bufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
255 if (bufP == NULL) {
256 throwOutOfMemoryError(env, 0);
257 return NULL;
258 }
259 rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
260 }
261 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
262 jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength);
263 }
264
265 if (bufP != BUF) { free(bufP); }
266
267 return jSignature;
268}
269#endif
270
271#ifdef P11_ENABLE_C_SIGNRECOVERINIT
272/*
273 * Class: sun_security_pkcs11_wrapper_PKCS11
274 * Method: C_SignRecoverInit
275 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
276 * Parametermapping: *PKCS11*
277 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
278 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism
279 * @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
280 */
281JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecoverInit
282 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
283{
284 CK_SESSION_HANDLE ckSessionHandle;
285 CK_MECHANISM_PTR ckpMechanism = NULL;
286 CK_OBJECT_HANDLE ckKeyHandle;
287 CK_RV rv;
288
289 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
290 if (ckpFunctions == NULL) { return; }
291
292 TRACE0("DEBUG: C_SignRecoverInit\n");
293
294 ckSessionHandle = jLongToCKULong(jSessionHandle);
295 ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
296 if ((*env)->ExceptionCheck(env)) { return; }
297
298 ckKeyHandle = jLongToCKULong(jKeyHandle);
299
300 rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, ckpMechanism, ckKeyHandle);
301
302 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK ||
303 (ckpMechanism->pParameter == NULL)) {
304 freeCKMechanismPtr(ckpMechanism);
305 } else {
306 (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism));
307 TRACE1("DEBUG C_SignRecoverInit, stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism));
308 }
309 TRACE0("FINISHED\n");
310}
311#endif
312
313#ifdef P11_ENABLE_C_SIGNRECOVER
314/*
315 * Class: sun_security_pkcs11_wrapper_PKCS11
316 * Method: C_SignRecover
317 * Signature: (J[BII[BII)I
318 * Parametermapping: *PKCS11*
319 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
320 * @param jbyteArray jData CK_BYTE_PTR pData
321 * CK_ULONG ulDataLen
322 * @return jbyteArray jSignature CK_BYTE_PTR pSignature
323 * CK_ULONG_PTR pulSignatureLen
324 */
325JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecover
326 (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
327{
328 CK_SESSION_HANDLE ckSessionHandle;
329 CK_RV rv;
330 CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
331 CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
332 CK_BYTE_PTR inBufP;
333 CK_BYTE_PTR outBufP = OUTBUF;
334 CK_ULONG ckSignatureLength = 0;
335
336 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
337 if (ckpFunctions == NULL) { return 0; }
338
339 ckSessionHandle = jLongToCKULong(jSessionHandle);
340
341 if (jInLen <= MAX_STACK_BUFFER_LEN) {
342 inBufP = INBUF;
343 ckSignatureLength = MAX_STACK_BUFFER_LEN;
344 } else {
345 inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
346 if (inBufP == NULL) {
347 throwOutOfMemoryError(env, 0);
348 return 0;
349 }
350 ckSignatureLength = jInLen;
351 }
352
353 (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
354 if ((*env)->ExceptionCheck(env)) {
355 goto cleanup;
356 }
357
358 rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
359 /* re-alloc larger buffer if it fits into our Java buffer */
360 if ((rv == CKR_BUFFER_TOO_SMALL) && (ckSignatureLength <= jIntToCKULong(jOutLen))) {
361 outBufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
362 if (outBufP == NULL) {
363 throwOutOfMemoryError(env, 0);
364 goto cleanup;
365 }
366 rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
367 }
368 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
369 (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckSignatureLength, (jbyte *)outBufP);
370 }
371cleanup:
372 if (inBufP != INBUF) { free(inBufP); }
373 if (outBufP != OUTBUF) { free(outBufP); }
374
375 return ckSignatureLength;
376}
377#endif
378
379#ifdef P11_ENABLE_C_VERIFYINIT
380/*
381 * Class: sun_security_pkcs11_wrapper_PKCS11
382 * Method: C_VerifyInit
383 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
384 * Parametermapping: *PKCS11*
385 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
386 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism
387 * @param jlong jKeyHandle CK_OBJECT_HANDLE hKey
388 */
389JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyInit
390 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
391{
392 CK_SESSION_HANDLE ckSessionHandle;
393 CK_MECHANISM_PTR ckpMechanism = NULL;
394 CK_OBJECT_HANDLE ckKeyHandle;
395 CK_RV rv;
396
397 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
398 if (ckpFunctions == NULL) { return; }
399
400 TRACE0("DEBUG: C_VerifyInit\n");
401
402 ckSessionHandle = jLongToCKULong(jSessionHandle);
403 ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
404 if ((*env)->ExceptionCheck(env)) {
405 return;
406 }
407
408 ckKeyHandle = jLongToCKULong(jKeyHandle);
409
410 rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, ckpMechanism, ckKeyHandle);
411
412 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK ||
413 (ckpMechanism->pParameter == NULL)) {
414 freeCKMechanismPtr(ckpMechanism);
415 } else {
416 (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism));
417 TRACE1("DEBUG C_VerifyInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism));
418 }
419 TRACE0("FINISHED\n");
420}
421#endif
422
423#ifdef P11_ENABLE_C_VERIFY
424/*
425 * Class: sun_security_pkcs11_wrapper_PKCS11
426 * Method: C_Verify
427 * Signature: (J[B[B)V
428 * Parametermapping: *PKCS11*
429 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
430 * @param jbyteArray jData CK_BYTE_PTR pData
431 * CK_ULONG ulDataLen
432 * @param jbyteArray jSignature CK_BYTE_PTR pSignature
433 * CK_ULONG_PTR pulSignatureLen
434 */
435JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Verify
436 (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData, jbyteArray jSignature)
437{
438 CK_SESSION_HANDLE ckSessionHandle;
439 CK_BYTE_PTR ckpData = NULL_PTR;
440 CK_BYTE_PTR ckpSignature = NULL_PTR;
441 CK_ULONG ckDataLength;
442 CK_ULONG ckSignatureLength;
443 CK_RV rv = 0;
444
445 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
446 if (ckpFunctions == NULL) { return; }
447
448 ckSessionHandle = jLongToCKULong(jSessionHandle);
449
450 jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
451 if ((*env)->ExceptionCheck(env)) {
452 return;
453 }
454
455 jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
456 if ((*env)->ExceptionCheck(env)) {
457 goto cleanup;
458 }
459
460 /* verify the signature */
461 rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength);
462
463cleanup:
464 free(ckpData);
465 free(ckpSignature);
466
467 ckAssertReturnValueOK(env, rv);
468}
469#endif
470
471#ifdef P11_ENABLE_C_VERIFYUPDATE
472/*
473 * Class: sun_security_pkcs11_wrapper_PKCS11
474 * Method: C_VerifyUpdate
475 * Signature: (J[BII)V
476 * Parametermapping: *PKCS11*
477 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
478 * @param jbyteArray jPart CK_BYTE_PTR pPart
479 * CK_ULONG ulPartLen
480 */
481JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyUpdate
482 (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
483{
484 CK_SESSION_HANDLE ckSessionHandle;
485 CK_RV rv;
486 CK_BYTE_PTR bufP;
487 CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
488 jsize bufLen;
489
490 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
491 if (ckpFunctions == NULL) { return; }
492
493 ckSessionHandle = jLongToCKULong(jSessionHandle);
494
495 if (directIn != 0) {
496 rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen);
497 ckAssertReturnValueOK(env, rv);
498 return;
499 }
500
501 if (jInLen <= MAX_STACK_BUFFER_LEN) {
502 bufLen = MAX_STACK_BUFFER_LEN;
503 bufP = BUF;
504 } else {
505 bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
506 bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
507 if (bufP == NULL) {
508 throwOutOfMemoryError(env, 0);
509 goto cleanup;
510 }
511 }
512
513 while (jInLen > 0) {
514 jsize chunkLen = min(bufLen, jInLen);
515 (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
516 if ((*env)->ExceptionCheck(env)) {
517 goto cleanup;
518 }
519
520 rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, bufP, chunkLen);
521 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
522 goto cleanup;
523 }
524 jInOfs += chunkLen;
525 jInLen -= chunkLen;
526 }
527
528cleanup:
529 if (bufP != BUF) { free(bufP); }
530}
531#endif
532
533#ifdef P11_ENABLE_C_VERIFYFINAL
534/*
535 * Class: sun_security_pkcs11_wrapper_PKCS11
536 * Method: C_VerifyFinal
537 * Signature: (J[B)V
538 * Parametermapping: *PKCS11*
539 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
540 * @param jbyteArray jSignature CK_BYTE_PTR pSignature
541 * CK_ULONG ulSignatureLen
542 */
543JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyFinal
544 (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature)
545{
546 CK_SESSION_HANDLE ckSessionHandle;
547 CK_BYTE_PTR ckpSignature = NULL_PTR;
548 CK_ULONG ckSignatureLength;
549 CK_RV rv;
550
551 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
552 if (ckpFunctions == NULL) { return; }
553
554 ckSessionHandle = jLongToCKULong(jSessionHandle);
555 jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
556 if ((*env)->ExceptionCheck(env)) {
557 return;
558 }
559
560 /* verify the signature */
561 rv = (*ckpFunctions->C_VerifyFinal)(ckSessionHandle, ckpSignature, ckSignatureLength);
562
563 free(ckpSignature);
564
565 ckAssertReturnValueOK(env, rv);
566}
567#endif
568
569#ifdef P11_ENABLE_C_VERIFYRECOVERINIT
570/*
571 * Class: sun_security_pkcs11_wrapper_PKCS11
572 * Method: C_VerifyRecoverInit
573 * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
574 * Parametermapping: *PKCS11*
575 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
576 * @param jobject jMechanism CK_MECHANISM_PTR pMechanism
577 * @return jlong jKeyHandle CK_OBJECT_HANDLE hKey
578 */
579JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecoverInit
580 (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
581{
582 CK_SESSION_HANDLE ckSessionHandle;
583 CK_MECHANISM_PTR ckpMechanism = NULL;
584 CK_OBJECT_HANDLE ckKeyHandle;
585 CK_RV rv;
586
587 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
588 if (ckpFunctions == NULL) { return; }
589
590 TRACE0("DEBUG: C_VerifyRecoverInit\n");
591
592 ckSessionHandle = jLongToCKULong(jSessionHandle);
593 ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
594 if ((*env)->ExceptionCheck(env)) { return; }
595
596 ckKeyHandle = jLongToCKULong(jKeyHandle);
597
598 rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, ckpMechanism, ckKeyHandle);
599
600 if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK ||
601 (ckpMechanism->pParameter == NULL)) {
602 freeCKMechanismPtr(ckpMechanism);
603 } else {
604 (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism));
605 TRACE1("DEBUG C_VerifyRecoverInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism));
606 }
607 TRACE0("FINISHED\n");
608}
609#endif
610
611#ifdef P11_ENABLE_C_VERIFYRECOVER
612/*
613 * Class: sun_security_pkcs11_wrapper_PKCS11
614 * Method: C_VerifyRecover
615 * Signature: (J[BII[BII)I
616 * Parametermapping: *PKCS11*
617 * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
618 * @param jbyteArray jSignature CK_BYTE_PTR pSignature
619 * CK_ULONG ulSignatureLen
620 * @return jbyteArray jData CK_BYTE_PTR pData
621 * CK_ULONG_PTR pulDataLen
622 */
623JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover
624 (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
625{
626 CK_SESSION_HANDLE ckSessionHandle;
627 CK_RV rv;
628 CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
629 CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
630 CK_BYTE_PTR inBufP;
631 CK_BYTE_PTR outBufP = OUTBUF;
632 CK_ULONG ckDataLength = 0;
633
634 CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
635 if (ckpFunctions == NULL) { return 0; }
636
637 ckSessionHandle = jLongToCKULong(jSessionHandle);
638
639 if (jInLen <= MAX_STACK_BUFFER_LEN) {
640 inBufP = INBUF;
641 ckDataLength = MAX_STACK_BUFFER_LEN;
642 } else {
643 inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
644 if (inBufP == NULL) {
645 throwOutOfMemoryError(env, 0);
646 return 0;
647 }
648 ckDataLength = jInLen;
649 }
650
651 (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
652 if ((*env)->ExceptionCheck(env)) {
653 goto cleanup;
654 }
655
656 rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
657
658 /* re-alloc larger buffer if it fits into our Java buffer */
659 if ((rv == CKR_BUFFER_TOO_SMALL) && (ckDataLength <= jIntToCKULong(jOutLen))) {
660 outBufP = (CK_BYTE_PTR) malloc(ckDataLength);
661 if (outBufP == NULL) {
662 throwOutOfMemoryError(env, 0);
663 goto cleanup;
664 }
665 rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
666 }
667 if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
668 (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDataLength, (jbyte *)outBufP);
669 }
670
671cleanup:
672 if (inBufP != INBUF) { free(inBufP); }
673 if (outBufP != OUTBUF) { free(outBufP); }
674
675 return ckDataLength;
676}
677#endif
678