1 /*
   2  * Copyright (c) 2003, 2012, 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  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
  67  */
  68 JNIEXPORT 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 ckMechanism;
  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     ckSessionHandle = jLongToCKULong(jSessionHandle);
  80     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
  81     if ((*env)->ExceptionCheck(env)) { return; }
  82     ckKeyHandle = jLongToCKULong(jKeyHandle);
  83 
  84     rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
  85 
  86     if (ckMechanism.pParameter != NULL_PTR) {
  87         free(ckMechanism.pParameter);
  88     }
  89 
  90     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
  91 }
  92 #endif
  93 
  94 #ifdef P11_ENABLE_C_SIGN
  95 /*
  96  * Class:     sun_security_pkcs11_wrapper_PKCS11
  97  * Method:    C_Sign
  98  * Signature: (J[B)[B
  99  * Parametermapping:                    *PKCS11*
 100  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 101  * @param   jbyteArray jData            CK_BYTE_PTR pData
 102  *                                      CK_ULONG ulDataLen
 103  * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
 104  *                                      CK_ULONG_PTR pulSignatureLen
 105  */
 106 JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Sign
 107     (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData)
 108 {
 109     CK_SESSION_HANDLE ckSessionHandle;
 110     CK_BYTE_PTR ckpData = NULL_PTR;
 111     CK_BYTE_PTR ckpSignature;
 112     CK_ULONG ckDataLength;
 113     CK_ULONG ckSignatureLength = 0;
 114     jbyteArray jSignature = NULL;
 115     CK_RV rv;
 116 
 117     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 118     if (ckpFunctions == NULL) { return NULL; }
 119 
 120     ckSessionHandle = jLongToCKULong(jSessionHandle);
 121     jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
 122     if ((*env)->ExceptionCheck(env)) { return NULL; }
 123 
 124     /* START standard code */
 125 
 126     /* first determine the length of the signature */
 127     rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckSignatureLength);
 128     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
 129         free(ckpData);
 130         return NULL;
 131     }
 132 
 133     ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
 134     if (ckpSignature == NULL) {
 135         free(ckpData);
 136         throwOutOfMemoryError(env, 0);
 137         return NULL;
 138     }
 139 
 140     /* now get the signature */
 141     rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
 142  /* END standard code */
 143 
 144 
 145     /* START workaround code for operation abort bug in pkcs#11 of Datakey and iButton */
 146 /*
 147     ckpSignature = (CK_BYTE_PTR) malloc(256 * sizeof(CK_BYTE));
 148     if (ckpSignature == NULL) {
 149         free(ckpData);
 150         throwOutOfMemoryError(env, 0);
 151         return NULL;
 152     }
 153     rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
 154 
 155     if (rv == CKR_BUFFER_TOO_SMALL) {
 156         free(ckpSignature);
 157         ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE));
 158         if (ckpSignature == NULL) {
 159             free(ckpData);
 160             throwOutOfMemoryError(env, 0);
 161             return NULL;
 162         }
 163         rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
 164     }
 165  */
 166     /* END workaround code */
 167     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 168         jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength);
 169     }
 170     free(ckpData);
 171     free(ckpSignature);
 172 
 173     return jSignature ;
 174 }
 175 #endif
 176 
 177 #ifdef P11_ENABLE_C_SIGNUPDATE
 178 /*
 179  * Class:     sun_security_pkcs11_wrapper_PKCS11
 180  * Method:    C_SignUpdate
 181  * Signature: (J[BII)V
 182  * Parametermapping:                    *PKCS11*
 183  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 184  * @param   jbyteArray jPart            CK_BYTE_PTR pPart
 185  *                                      CK_ULONG ulPartLen
 186  */
 187 JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignUpdate
 188   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
 189 {
 190     CK_SESSION_HANDLE ckSessionHandle;
 191     CK_RV rv;
 192     CK_BYTE_PTR bufP;
 193     CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
 194     jsize bufLen;
 195 
 196     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 197     if (ckpFunctions == NULL) { return; }
 198 
 199     ckSessionHandle = jLongToCKULong(jSessionHandle);
 200 
 201     if (directIn != 0) {
 202         rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, (CK_BYTE_PTR) jlong_to_ptr(directIn), jInLen);
 203         ckAssertReturnValueOK(env, rv);
 204         return;
 205     }
 206 
 207     if (jInLen <= MAX_STACK_BUFFER_LEN) {
 208         bufLen = MAX_STACK_BUFFER_LEN;
 209         bufP = BUF;
 210     } else {
 211         bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
 212         bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
 213         if (bufP == NULL) {
 214             throwOutOfMemoryError(env, 0);
 215             return;
 216         }
 217     }
 218 
 219     while (jInLen > 0) {
 220         jsize chunkLen = min(bufLen, jInLen);
 221         (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
 222         if ((*env)->ExceptionCheck(env)) {
 223             if (bufP != BUF) { free(bufP); }
 224             return;
 225         }
 226         rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, bufP, chunkLen);
 227         if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
 228             if (bufP != BUF) {
 229                 free(bufP);
 230             }
 231             return;
 232         }
 233         jInOfs += chunkLen;
 234         jInLen -= chunkLen;
 235     }
 236 
 237     if (bufP != BUF) { free(bufP); }
 238 }
 239 #endif
 240 
 241 #ifdef P11_ENABLE_C_SIGNFINAL
 242 /*
 243  * Class:     sun_security_pkcs11_wrapper_PKCS11
 244  * Method:    C_SignFinal
 245  * Signature: (J)[B
 246  * Parametermapping:                    *PKCS11*
 247  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 248  * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
 249  *                                      CK_ULONG_PTR pulSignatureLen
 250  */
 251 JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignFinal
 252     (JNIEnv *env, jobject obj, jlong jSessionHandle, jint jExpectedLength)
 253 {
 254     CK_SESSION_HANDLE ckSessionHandle;
 255     jbyteArray jSignature = NULL;
 256     CK_RV rv;
 257     CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
 258     CK_BYTE_PTR bufP = BUF;
 259     CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
 260 
 261     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 262     if (ckpFunctions == NULL) { return NULL; }
 263 
 264     ckSessionHandle = jLongToCKULong(jSessionHandle);
 265 
 266     if ((jExpectedLength > 0) && ((CK_ULONG)jExpectedLength < ckSignatureLength)) {
 267         ckSignatureLength = jExpectedLength;
 268     }
 269 
 270     rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
 271     if (rv == CKR_BUFFER_TOO_SMALL) {
 272         bufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
 273         if (bufP == NULL) {
 274             throwOutOfMemoryError(env, 0);
 275             return NULL;
 276         }
 277         rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength);
 278     }
 279     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 280         jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength);
 281     }
 282 
 283     if (bufP != BUF) { free(bufP); }
 284 
 285     return jSignature;
 286 }
 287 #endif
 288 
 289 #ifdef P11_ENABLE_C_SIGNRECOVERINIT
 290 /*
 291  * Class:     sun_security_pkcs11_wrapper_PKCS11
 292  * Method:    C_SignRecoverInit
 293  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
 294  * Parametermapping:                    *PKCS11*
 295  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 296  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
 297  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
 298  */
 299 JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecoverInit
 300     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
 301 {
 302     CK_SESSION_HANDLE ckSessionHandle;
 303     CK_MECHANISM ckMechanism;
 304     CK_OBJECT_HANDLE ckKeyHandle;
 305     CK_RV rv;
 306 
 307     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 308     if (ckpFunctions == NULL) { return; }
 309 
 310     ckSessionHandle = jLongToCKULong(jSessionHandle);
 311     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
 312     if ((*env)->ExceptionCheck(env)) { return; }
 313 
 314     ckKeyHandle = jLongToCKULong(jKeyHandle);
 315 
 316     rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
 317 
 318     if (ckMechanism.pParameter != NULL_PTR) {
 319         free(ckMechanism.pParameter);
 320     }
 321 
 322     if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 323 }
 324 #endif
 325 
 326 #ifdef P11_ENABLE_C_SIGNRECOVER
 327 /*
 328  * Class:     sun_security_pkcs11_wrapper_PKCS11
 329  * Method:    C_SignRecover
 330  * Signature: (J[BII[BII)I
 331  * Parametermapping:                    *PKCS11*
 332  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 333  * @param   jbyteArray jData            CK_BYTE_PTR pData
 334  *                                      CK_ULONG ulDataLen
 335  * @return  jbyteArray jSignature       CK_BYTE_PTR pSignature
 336  *                                      CK_ULONG_PTR pulSignatureLen
 337  */
 338 JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecover
 339   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
 340 {
 341     CK_SESSION_HANDLE ckSessionHandle;
 342     CK_RV rv;
 343     CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
 344     CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
 345     CK_BYTE_PTR inBufP;
 346     CK_BYTE_PTR outBufP = OUTBUF;
 347     CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
 348 
 349     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 350     if (ckpFunctions == NULL) { return 0; }
 351 
 352     ckSessionHandle = jLongToCKULong(jSessionHandle);
 353 
 354     if (jInLen <= MAX_STACK_BUFFER_LEN) {
 355         inBufP = INBUF;
 356     } else {
 357         inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
 358         if (inBufP == NULL) {
 359             throwOutOfMemoryError(env, 0);
 360             return 0;
 361         }
 362     }
 363 
 364     (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
 365     if ((*env)->ExceptionCheck(env)) {
 366         if (inBufP != INBUF) { free(inBufP); }
 367         return 0;
 368     }
 369     rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
 370     /* re-alloc larger buffer if it fits into our Java buffer */
 371     if ((rv == CKR_BUFFER_TOO_SMALL) && (ckSignatureLength <= jIntToCKULong(jOutLen))) {
 372         outBufP = (CK_BYTE_PTR) malloc(ckSignatureLength);
 373         if (outBufP == NULL) {
 374             if (inBufP != INBUF) {
 375                 free(inBufP);
 376             }
 377             throwOutOfMemoryError(env, 0);
 378             return 0;
 379         }
 380         rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
 381     }
 382     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 383         (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckSignatureLength, (jbyte *)outBufP);
 384     }
 385 
 386     if (inBufP != INBUF) { free(inBufP); }
 387     if (outBufP != OUTBUF) { free(outBufP); }
 388 
 389     return ckSignatureLength;
 390 }
 391 #endif
 392 
 393 #ifdef P11_ENABLE_C_VERIFYINIT
 394 /*
 395  * Class:     sun_security_pkcs11_wrapper_PKCS11
 396  * Method:    C_VerifyInit
 397  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
 398  * Parametermapping:                    *PKCS11*
 399  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 400  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
 401  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
 402  */
 403 JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyInit
 404     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
 405 {
 406     CK_SESSION_HANDLE ckSessionHandle;
 407     CK_MECHANISM ckMechanism;
 408     CK_OBJECT_HANDLE ckKeyHandle;
 409     CK_RV rv;
 410 
 411     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 412     if (ckpFunctions == NULL) { return; }
 413 
 414     ckSessionHandle = jLongToCKULong(jSessionHandle);
 415     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
 416     if ((*env)->ExceptionCheck(env)) { return; }
 417 
 418     ckKeyHandle = jLongToCKULong(jKeyHandle);
 419 
 420     rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
 421 
 422     if(ckMechanism.pParameter != NULL_PTR) {
 423         free(ckMechanism.pParameter);
 424     }
 425 
 426     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 427 }
 428 #endif
 429 
 430 #ifdef P11_ENABLE_C_VERIFY
 431 /*
 432  * Class:     sun_security_pkcs11_wrapper_PKCS11
 433  * Method:    C_Verify
 434  * Signature: (J[B[B)V
 435  * Parametermapping:                    *PKCS11*
 436  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 437  * @param   jbyteArray jData            CK_BYTE_PTR pData
 438  *                                      CK_ULONG ulDataLen
 439  * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
 440  *                                      CK_ULONG_PTR pulSignatureLen
 441  */
 442 JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Verify
 443     (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData, jbyteArray jSignature)
 444 {
 445     CK_SESSION_HANDLE ckSessionHandle;
 446     CK_BYTE_PTR ckpData = NULL_PTR;
 447     CK_BYTE_PTR ckpSignature = NULL_PTR;
 448     CK_ULONG ckDataLength;
 449     CK_ULONG ckSignatureLength;
 450     CK_RV rv;
 451 
 452     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 453     if (ckpFunctions == NULL) { return; }
 454 
 455     ckSessionHandle = jLongToCKULong(jSessionHandle);
 456     jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength);
 457     if ((*env)->ExceptionCheck(env)) { return; }
 458 
 459     jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
 460     if ((*env)->ExceptionCheck(env)) {
 461         free(ckpData);
 462         return;
 463     }
 464 
 465     /* verify the signature */
 466     rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength);
 467 
 468     free(ckpData);
 469     free(ckpSignature);
 470 
 471     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 472 }
 473 #endif
 474 
 475 #ifdef P11_ENABLE_C_VERIFYUPDATE
 476 /*
 477  * Class:     sun_security_pkcs11_wrapper_PKCS11
 478  * Method:    C_VerifyUpdate
 479  * Signature: (J[BII)V
 480  * Parametermapping:                    *PKCS11*
 481  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 482  * @param   jbyteArray jPart            CK_BYTE_PTR pPart
 483  *                                      CK_ULONG ulPartLen
 484  */
 485 JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyUpdate
 486   (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen)
 487 {
 488     CK_SESSION_HANDLE ckSessionHandle;
 489     CK_RV rv;
 490     CK_BYTE_PTR bufP;
 491     CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
 492     jsize bufLen;
 493 
 494     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 495     if (ckpFunctions == NULL) { return; }
 496 
 497     ckSessionHandle = jLongToCKULong(jSessionHandle);
 498 
 499     if (directIn != 0) {
 500         rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen);
 501         ckAssertReturnValueOK(env, rv);
 502         return;
 503     }
 504 
 505     if (jInLen <= MAX_STACK_BUFFER_LEN) {
 506         bufLen = MAX_STACK_BUFFER_LEN;
 507         bufP = BUF;
 508     } else {
 509         bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen);
 510         bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
 511         if (bufP == NULL) {
 512             throwOutOfMemoryError(env, 0);
 513             return;
 514         }
 515     }
 516 
 517     while (jInLen > 0) {
 518         jsize chunkLen = min(bufLen, jInLen);
 519         (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
 520         if ((*env)->ExceptionCheck(env)) {
 521             if (bufP != BUF) { free(bufP); }
 522             return;
 523         }
 524 
 525         rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, bufP, chunkLen);
 526         if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
 527             if (bufP != BUF) { free(bufP); }
 528             return;
 529         }
 530         jInOfs += chunkLen;
 531         jInLen -= chunkLen;
 532     }
 533 
 534     if (bufP != BUF) { free(bufP); }
 535 }
 536 #endif
 537 
 538 #ifdef P11_ENABLE_C_VERIFYFINAL
 539 /*
 540  * Class:     sun_security_pkcs11_wrapper_PKCS11
 541  * Method:    C_VerifyFinal
 542  * Signature: (J[B)V
 543  * Parametermapping:                    *PKCS11*
 544  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 545  * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
 546  *                                      CK_ULONG ulSignatureLen
 547  */
 548 JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyFinal
 549     (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature)
 550 {
 551     CK_SESSION_HANDLE ckSessionHandle;
 552     CK_BYTE_PTR ckpSignature = NULL_PTR;
 553     CK_ULONG ckSignatureLength;
 554     CK_RV rv;
 555 
 556     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 557     if (ckpFunctions == NULL) { return; }
 558 
 559     ckSessionHandle = jLongToCKULong(jSessionHandle);
 560     jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
 561     if ((*env)->ExceptionCheck(env)) { return; }
 562 
 563     /* verify the signature */
 564     rv = (*ckpFunctions->C_VerifyFinal)(ckSessionHandle, ckpSignature, ckSignatureLength);
 565 
 566     free(ckpSignature);
 567 
 568     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 569 }
 570 #endif
 571 
 572 #ifdef P11_ENABLE_C_VERIFYRECOVERINIT
 573 /*
 574  * Class:     sun_security_pkcs11_wrapper_PKCS11
 575  * Method:    C_VerifyRecoverInit
 576  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V
 577  * Parametermapping:                    *PKCS11*
 578  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 579  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
 580  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
 581  */
 582 JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecoverInit
 583     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
 584 {
 585     CK_SESSION_HANDLE ckSessionHandle;
 586     CK_MECHANISM ckMechanism;
 587     CK_OBJECT_HANDLE ckKeyHandle;
 588     CK_RV rv;
 589 
 590     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 591     if (ckpFunctions == NULL) { return; }
 592 
 593     ckSessionHandle = jLongToCKULong(jSessionHandle);
 594     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
 595     if ((*env)->ExceptionCheck(env)) { return; }
 596 
 597     ckKeyHandle = jLongToCKULong(jKeyHandle);
 598 
 599     rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
 600 
 601     if (ckMechanism.pParameter != NULL_PTR) {
 602         free(ckMechanism.pParameter);
 603     }
 604 
 605     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 606 }
 607 #endif
 608 
 609 #ifdef P11_ENABLE_C_VERIFYRECOVER
 610 /*
 611  * Class:     sun_security_pkcs11_wrapper_PKCS11
 612  * Method:    C_VerifyRecover
 613  * Signature: (J[BII[BII)I
 614  * Parametermapping:                    *PKCS11*
 615  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
 616  * @param   jbyteArray jSignature       CK_BYTE_PTR pSignature
 617  *                                      CK_ULONG ulSignatureLen
 618  * @return  jbyteArray jData            CK_BYTE_PTR pData
 619  *                                      CK_ULONG_PTR pulDataLen
 620  */
 621 JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover
 622   (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen)
 623 {
 624     CK_SESSION_HANDLE ckSessionHandle;
 625     CK_RV rv;
 626     CK_BYTE INBUF[MAX_STACK_BUFFER_LEN];
 627     CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
 628     CK_BYTE_PTR inBufP;
 629     CK_BYTE_PTR outBufP = OUTBUF;
 630     CK_ULONG ckDataLength = MAX_STACK_BUFFER_LEN;
 631 
 632     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
 633     if (ckpFunctions == NULL) { return 0; }
 634 
 635     ckSessionHandle = jLongToCKULong(jSessionHandle);
 636 
 637     if (jInLen <= MAX_STACK_BUFFER_LEN) {
 638         inBufP = INBUF;
 639     } else {
 640         inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
 641         if (inBufP == NULL) {
 642             throwOutOfMemoryError(env, 0);
 643             return 0;
 644         }
 645     }
 646 
 647     (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
 648     if ((*env)->ExceptionCheck(env)) {
 649         if (inBufP != INBUF) { free(inBufP); }
 650         return 0;
 651     }
 652 
 653     rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
 654 
 655     /* re-alloc larger buffer if it fits into our Java buffer */
 656     if ((rv == CKR_BUFFER_TOO_SMALL) && (ckDataLength <= jIntToCKULong(jOutLen))) {
 657         outBufP = (CK_BYTE_PTR) malloc(ckDataLength);
 658         if (outBufP == NULL) {
 659             if (inBufP != INBUF) { free(inBufP); }
 660             throwOutOfMemoryError(env, 0);
 661             return 0;
 662         }
 663         rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
 664     }
 665     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
 666         (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDataLength, (jbyte *)outBufP);
 667     }
 668 
 669     if (inBufP != INBUF) { free(inBufP); }
 670     if (outBufP != OUTBUF) { free(outBufP); }
 671 
 672     return ckDataLength;
 673 }
 674 #endif