--- /dev/null 2017-01-18 09:30:05.425422781 -0800 +++ new/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c 2017-01-18 23:07:39.575884699 -0800 @@ -0,0 +1,674 @@ +/* + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + */ + +/* Copyright (c) 2002 Graz University of Technology. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The end-user documentation included with the redistribution, if any, must + * include the following acknowledgment: + * + * "This product includes software developed by IAIK of Graz University of + * Technology." + * + * Alternately, this acknowledgment may appear in the software itself, if + * and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Graz University of Technology" and "IAIK of Graz University of + * Technology" must not be used to endorse or promote products derived from + * this software without prior written permission. + * + * 5. Products derived from this software may not be called + * "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior + * written permission of Graz University of Technology. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pkcs11wrapper.h" + +#include +#include +#include +#include +#include "jlong.h" + +#include "sun_security_pkcs11_wrapper_PKCS11.h" + +#ifdef P11_ENABLE_C_SIGNINIT +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_SignInit + * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jobject jMechanism CK_MECHANISM_PTR pMechanism + * @return jlong jKeyHandle CK_OBJECT_HANDLE hKey + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignInit + (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_MECHANISM ckMechanism; + CK_OBJECT_HANDLE ckKeyHandle; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jMechanismToCKMechanism(env, jMechanism, &ckMechanism); + if ((*env)->ExceptionCheck(env)) { return; } + ckKeyHandle = jLongToCKULong(jKeyHandle); + + rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, &ckMechanism, ckKeyHandle); + + if (ckMechanism.pParameter != NULL_PTR) { + free(ckMechanism.pParameter); + } + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_SIGN +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_Sign + * Signature: (J[B)[B + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jbyteArray jData CK_BYTE_PTR pData + * CK_ULONG ulDataLen + * @return jbyteArray jSignature CK_BYTE_PTR pSignature + * CK_ULONG_PTR pulSignatureLen + */ +JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Sign + (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_BYTE_PTR ckpData = NULL_PTR; + CK_BYTE_PTR ckpSignature; + CK_ULONG ckDataLength; + CK_ULONG ckSignatureLength = 0; + jbyteArray jSignature = NULL; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return NULL; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength); + if ((*env)->ExceptionCheck(env)) { return NULL; } + + /* START standard code */ + + /* first determine the length of the signature */ + rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckSignatureLength); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { + free(ckpData); + return NULL; + } + + ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE)); + if (ckpSignature == NULL) { + free(ckpData); + throwOutOfMemoryError(env, 0); + return NULL; + } + + /* now get the signature */ + rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength); + /* END standard code */ + + + /* START workaround code for operation abort bug in pkcs#11 of Datakey and iButton */ +/* + ckpSignature = (CK_BYTE_PTR) malloc(256 * sizeof(CK_BYTE)); + if (ckpSignature == NULL) { + free(ckpData); + throwOutOfMemoryError(env, 0); + return NULL; + } + rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength); + + if (rv == CKR_BUFFER_TOO_SMALL) { + free(ckpSignature); + ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE)); + if (ckpSignature == NULL) { + free(ckpData); + throwOutOfMemoryError(env, 0); + return NULL; + } + rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength); + } + */ + /* END workaround code */ + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength); + } + free(ckpData); + free(ckpSignature); + + return jSignature ; +} +#endif + +#ifdef P11_ENABLE_C_SIGNUPDATE +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_SignUpdate + * Signature: (J[BII)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jbyteArray jPart CK_BYTE_PTR pPart + * CK_ULONG ulPartLen + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignUpdate + (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_RV rv; + CK_BYTE_PTR bufP; + CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; + jsize bufLen; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + + if (directIn != 0) { + rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, (CK_BYTE_PTR) jlong_to_ptr(directIn), jInLen); + ckAssertReturnValueOK(env, rv); + return; + } + + if (jInLen <= MAX_STACK_BUFFER_LEN) { + bufLen = MAX_STACK_BUFFER_LEN; + bufP = BUF; + } else { + bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen); + bufP = (CK_BYTE_PTR) malloc((size_t)bufLen); + if (bufP == NULL) { + throwOutOfMemoryError(env, 0); + return; + } + } + + while (jInLen > 0) { + jsize chunkLen = min(bufLen, jInLen); + (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP); + if ((*env)->ExceptionCheck(env)) { + if (bufP != BUF) { free(bufP); } + return; + } + rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, bufP, chunkLen); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { + if (bufP != BUF) { + free(bufP); + } + return; + } + jInOfs += chunkLen; + jInLen -= chunkLen; + } + + if (bufP != BUF) { free(bufP); } +} +#endif + +#ifdef P11_ENABLE_C_SIGNFINAL +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_SignFinal + * Signature: (J)[B + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @return jbyteArray jSignature CK_BYTE_PTR pSignature + * CK_ULONG_PTR pulSignatureLen + */ +JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignFinal + (JNIEnv *env, jobject obj, jlong jSessionHandle, jint jExpectedLength) +{ + CK_SESSION_HANDLE ckSessionHandle; + jbyteArray jSignature = NULL; + CK_RV rv; + CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR bufP = BUF; + CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return NULL; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + + if ((jExpectedLength > 0) && ((CK_ULONG)jExpectedLength < ckSignatureLength)) { + ckSignatureLength = jExpectedLength; + } + + rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength); + if (rv == CKR_BUFFER_TOO_SMALL) { + bufP = (CK_BYTE_PTR) malloc(ckSignatureLength); + if (bufP == NULL) { + throwOutOfMemoryError(env, 0); + return NULL; + } + rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength); + } + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength); + } + + if (bufP != BUF) { free(bufP); } + + return jSignature; +} +#endif + +#ifdef P11_ENABLE_C_SIGNRECOVERINIT +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_SignRecoverInit + * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jobject jMechanism CK_MECHANISM_PTR pMechanism + * @return jlong jKeyHandle CK_OBJECT_HANDLE hKey + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecoverInit + (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_MECHANISM ckMechanism; + CK_OBJECT_HANDLE ckKeyHandle; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jMechanismToCKMechanism(env, jMechanism, &ckMechanism); + if ((*env)->ExceptionCheck(env)) { return; } + + ckKeyHandle = jLongToCKULong(jKeyHandle); + + rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle); + + if (ckMechanism.pParameter != NULL_PTR) { + free(ckMechanism.pParameter); + } + + if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_SIGNRECOVER +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_SignRecover + * Signature: (J[BII[BII)I + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jbyteArray jData CK_BYTE_PTR pData + * CK_ULONG ulDataLen + * @return jbyteArray jSignature CK_BYTE_PTR pSignature + * CK_ULONG_PTR pulSignatureLen + */ +JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignRecover + (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_RV rv; + CK_BYTE INBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; + CK_BYTE_PTR outBufP = OUTBUF; + CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return 0; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + + if (jInLen <= MAX_STACK_BUFFER_LEN) { + inBufP = INBUF; + } else { + inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen); + if (inBufP == NULL) { + throwOutOfMemoryError(env, 0); + return 0; + } + } + + (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); + if ((*env)->ExceptionCheck(env)) { + if (inBufP != INBUF) { free(inBufP); } + return 0; + } + rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength); + /* re-alloc larger buffer if it fits into our Java buffer */ + if ((rv == CKR_BUFFER_TOO_SMALL) && (ckSignatureLength <= jIntToCKULong(jOutLen))) { + outBufP = (CK_BYTE_PTR) malloc(ckSignatureLength); + if (outBufP == NULL) { + if (inBufP != INBUF) { + free(inBufP); + } + throwOutOfMemoryError(env, 0); + return 0; + } + rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength); + } + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckSignatureLength, (jbyte *)outBufP); + } + + if (inBufP != INBUF) { free(inBufP); } + if (outBufP != OUTBUF) { free(outBufP); } + + return ckSignatureLength; +} +#endif + +#ifdef P11_ENABLE_C_VERIFYINIT +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_VerifyInit + * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jobject jMechanism CK_MECHANISM_PTR pMechanism + * @return jlong jKeyHandle CK_OBJECT_HANDLE hKey + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyInit + (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_MECHANISM ckMechanism; + CK_OBJECT_HANDLE ckKeyHandle; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jMechanismToCKMechanism(env, jMechanism, &ckMechanism); + if ((*env)->ExceptionCheck(env)) { return; } + + ckKeyHandle = jLongToCKULong(jKeyHandle); + + rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, &ckMechanism, ckKeyHandle); + + if(ckMechanism.pParameter != NULL_PTR) { + free(ckMechanism.pParameter); + } + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_VERIFY +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_Verify + * Signature: (J[B[B)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jbyteArray jData CK_BYTE_PTR pData + * CK_ULONG ulDataLen + * @param jbyteArray jSignature CK_BYTE_PTR pSignature + * CK_ULONG_PTR pulSignatureLen + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Verify + (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData, jbyteArray jSignature) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_BYTE_PTR ckpData = NULL_PTR; + CK_BYTE_PTR ckpSignature = NULL_PTR; + CK_ULONG ckDataLength; + CK_ULONG ckSignatureLength; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength); + if ((*env)->ExceptionCheck(env)) { return; } + + jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength); + if ((*env)->ExceptionCheck(env)) { + free(ckpData); + return; + } + + /* verify the signature */ + rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength); + + free(ckpData); + free(ckpSignature); + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_VERIFYUPDATE +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_VerifyUpdate + * Signature: (J[BII)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jbyteArray jPart CK_BYTE_PTR pPart + * CK_ULONG ulPartLen + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyUpdate + (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_RV rv; + CK_BYTE_PTR bufP; + CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; + jsize bufLen; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + + if (directIn != 0) { + rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, (CK_BYTE_PTR)jlong_to_ptr(directIn), jInLen); + ckAssertReturnValueOK(env, rv); + return; + } + + if (jInLen <= MAX_STACK_BUFFER_LEN) { + bufLen = MAX_STACK_BUFFER_LEN; + bufP = BUF; + } else { + bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen); + bufP = (CK_BYTE_PTR) malloc((size_t)bufLen); + if (bufP == NULL) { + throwOutOfMemoryError(env, 0); + return; + } + } + + while (jInLen > 0) { + jsize chunkLen = min(bufLen, jInLen); + (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP); + if ((*env)->ExceptionCheck(env)) { + if (bufP != BUF) { free(bufP); } + return; + } + + rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, bufP, chunkLen); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { + if (bufP != BUF) { free(bufP); } + return; + } + jInOfs += chunkLen; + jInLen -= chunkLen; + } + + if (bufP != BUF) { free(bufP); } +} +#endif + +#ifdef P11_ENABLE_C_VERIFYFINAL +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_VerifyFinal + * Signature: (J[B)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jbyteArray jSignature CK_BYTE_PTR pSignature + * CK_ULONG ulSignatureLen + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyFinal + (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_BYTE_PTR ckpSignature = NULL_PTR; + CK_ULONG ckSignatureLength; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength); + if ((*env)->ExceptionCheck(env)) { return; } + + /* verify the signature */ + rv = (*ckpFunctions->C_VerifyFinal)(ckSessionHandle, ckpSignature, ckSignatureLength); + + free(ckpSignature); + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_VERIFYRECOVERINIT +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_VerifyRecoverInit + * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jobject jMechanism CK_MECHANISM_PTR pMechanism + * @return jlong jKeyHandle CK_OBJECT_HANDLE hKey + */ +JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecoverInit + (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_MECHANISM ckMechanism; + CK_OBJECT_HANDLE ckKeyHandle; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jMechanismToCKMechanism(env, jMechanism, &ckMechanism); + if ((*env)->ExceptionCheck(env)) { return; } + + ckKeyHandle = jLongToCKULong(jKeyHandle); + + rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle); + + if (ckMechanism.pParameter != NULL_PTR) { + free(ckMechanism.pParameter); + } + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_VERIFYRECOVER +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_VerifyRecover + * Signature: (J[BII[BII)I + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jbyteArray jSignature CK_BYTE_PTR pSignature + * CK_ULONG ulSignatureLen + * @return jbyteArray jData CK_BYTE_PTR pData + * CK_ULONG_PTR pulDataLen + */ +JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover + (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_RV rv; + CK_BYTE INBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN]; + CK_BYTE_PTR inBufP; + CK_BYTE_PTR outBufP = OUTBUF; + CK_ULONG ckDataLength = MAX_STACK_BUFFER_LEN; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return 0; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + + if (jInLen <= MAX_STACK_BUFFER_LEN) { + inBufP = INBUF; + } else { + inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen); + if (inBufP == NULL) { + throwOutOfMemoryError(env, 0); + return 0; + } + } + + (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); + if ((*env)->ExceptionCheck(env)) { + if (inBufP != INBUF) { free(inBufP); } + return 0; + } + + rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength); + + /* re-alloc larger buffer if it fits into our Java buffer */ + if ((rv == CKR_BUFFER_TOO_SMALL) && (ckDataLength <= jIntToCKULong(jOutLen))) { + outBufP = (CK_BYTE_PTR) malloc(ckDataLength); + if (outBufP == NULL) { + if (inBufP != INBUF) { free(inBufP); } + throwOutOfMemoryError(env, 0); + return 0; + } + rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength); + } + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDataLength, (jbyte *)outBufP); + } + + if (inBufP != INBUF) { free(inBufP); } + if (outBufP != OUTBUF) { free(outBufP); } + + return ckDataLength; +} +#endif