src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 47216 71c04702a3d5
child 58679 9c3209ff7550
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c	Thu Oct 17 20:27:44 2019 +0100
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_sign.c	Thu Oct 17 20:53:35 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
@@ -63,31 +63,38 @@
  * Parametermapping:                    *PKCS11*
  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ * @param   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_MECHANISM_PTR ckpMechanism = NULL;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return; }
 
+    TRACE0("DEBUG: C_SignInit\n");
+
     ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+
+    ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
     if ((*env)->ExceptionCheck(env)) { return; }
+
     ckKeyHandle = jLongToCKULong(jKeyHandle);
 
-    rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
+    rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, ckpMechanism, ckKeyHandle);
 
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK ||
+            (ckpMechanism->pParameter == NULL)) {
+        freeCKMechanismPtr(ckpMechanism);
+    } else {
+        (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism));
+        TRACE1("DEBUG C_SignInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism));
     }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
@@ -95,7 +102,7 @@
 /*
  * Class:     sun_security_pkcs11_wrapper_PKCS11
  * Method:    C_Sign
- * Signature: (J[B)[B
+ * Signature: (J[BI)[B
  * Parametermapping:                    *PKCS11*
  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
  * @param   jbyteArray jData            CK_BYTE_PTR pData
@@ -108,69 +115,45 @@
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_BYTE_PTR ckpData = NULL_PTR;
-    CK_BYTE_PTR ckpSignature;
     CK_ULONG ckDataLength;
-    CK_ULONG ckSignatureLength = 0;
+    CK_BYTE_PTR bufP;
+    CK_ULONG ckSignatureLength;
+    CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
     jbyteArray jSignature = NULL;
     CK_RV rv;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return NULL; }
 
+    TRACE0("DEBUG: C_Sign\n");
+
     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);
+    if ((*env)->ExceptionCheck(env)) {
         return NULL;
     }
 
-    /* now get the signature */
-    rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength);
- /* END standard code */
-
+    TRACE1("DEBUG C_Sign: data length = %lu\n", ckDataLength);
 
-    /* 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);
+    // unknown signature length
+    bufP = BUF;
+    ckSignatureLength = MAX_STACK_BUFFER_LEN;
+
+    rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength,
+        bufP, &ckSignatureLength);
+
+    TRACE1("DEBUG C_Sign: ret rv=0x%lX\n", rv);
 
-    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);
+    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
+        jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength);
+        TRACE1("DEBUG C_Sign: signature length = %lu\n", ckSignatureLength);
     }
- */
-    /* END workaround code */
-    if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
-        jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength);
-    }
+
     free(ckpData);
-    free(ckpSignature);
+    if (bufP != BUF) { free(bufP); }
 
-    return jSignature ;
+    TRACE0("FINISHED\n");
+    return jSignature;
 }
 #endif
 
@@ -220,21 +203,20 @@
         jsize chunkLen = min(bufLen, jInLen);
         (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
         if ((*env)->ExceptionCheck(env)) {
-            if (bufP != BUF) { free(bufP); }
-            return;
+            goto cleanup;
         }
         rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, bufP, chunkLen);
         if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-            if (bufP != BUF) {
-                free(bufP);
-            }
-            return;
+            goto cleanup;
         }
         jInOfs += chunkLen;
         jInLen -= chunkLen;
     }
 
+cleanup:
     if (bufP != BUF) { free(bufP); }
+
+    return;
 }
 #endif
 
@@ -294,32 +276,37 @@
  * Parametermapping:                    *PKCS11*
  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ * @param   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_MECHANISM_PTR ckpMechanism = NULL;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return; }
 
+    TRACE0("DEBUG: C_SignRecoverInit\n");
+
     ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
     if ((*env)->ExceptionCheck(env)) { return; }
 
     ckKeyHandle = jLongToCKULong(jKeyHandle);
 
-    rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
+    rv = (*ckpFunctions->C_SignRecoverInit)(ckSessionHandle, ckpMechanism, ckKeyHandle);
 
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK ||
+            (ckpMechanism->pParameter == NULL)) {
+        freeCKMechanismPtr(ckpMechanism);
+    } else {
+        (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism));
+        TRACE1("DEBUG C_SignRecoverInit, stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism));
     }
-
-    if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
@@ -344,7 +331,7 @@
     CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
     CK_BYTE_PTR inBufP;
     CK_BYTE_PTR outBufP = OUTBUF;
-    CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN;
+    CK_ULONG ckSignatureLength = 0;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return 0; }
@@ -353,36 +340,35 @@
 
     if (jInLen <= MAX_STACK_BUFFER_LEN) {
         inBufP = INBUF;
+        ckSignatureLength = MAX_STACK_BUFFER_LEN;
     } else {
         inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
         if (inBufP == NULL) {
             throwOutOfMemoryError(env, 0);
             return 0;
         }
+        ckSignatureLength = jInLen;
     }
 
     (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
     if ((*env)->ExceptionCheck(env)) {
-        if (inBufP != INBUF) { free(inBufP); }
-        return 0;
+        goto cleanup;
     }
+
     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;
+            goto cleanup;
         }
         rv = (*ckpFunctions->C_SignRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckSignatureLength);
     }
     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
         (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckSignatureLength, (jbyte *)outBufP);
     }
-
+cleanup:
     if (inBufP != INBUF) { free(inBufP); }
     if (outBufP != OUTBUF) { free(outBufP); }
 
@@ -398,32 +384,39 @@
  * Parametermapping:                    *PKCS11*
  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
- * @return  jlong jKeyHandle            CK_OBJECT_HANDLE hKey
+ * @param   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_MECHANISM_PTR ckpMechanism = NULL;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return; }
 
+    TRACE0("DEBUG: C_VerifyInit\n");
+
     ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
-    if ((*env)->ExceptionCheck(env)) { return; }
+    ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+    if ((*env)->ExceptionCheck(env)) {
+        return;
+    }
 
     ckKeyHandle = jLongToCKULong(jKeyHandle);
 
-    rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
+    rv = (*ckpFunctions->C_VerifyInit)(ckSessionHandle, ckpMechanism, ckKeyHandle);
 
-    if(ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK ||
+            (ckpMechanism->pParameter == NULL)) {
+        freeCKMechanismPtr(ckpMechanism);
+    } else {
+        (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism));
+        TRACE1("DEBUG C_VerifyInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism));
     }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
@@ -447,28 +440,31 @@
     CK_BYTE_PTR ckpSignature = NULL_PTR;
     CK_ULONG ckDataLength;
     CK_ULONG ckSignatureLength;
-    CK_RV rv;
+    CK_RV rv = 0;
 
     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; }
+    if ((*env)->ExceptionCheck(env)) {
+        return;
+    }
 
     jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
     if ((*env)->ExceptionCheck(env)) {
-        free(ckpData);
-        return;
+        goto cleanup;
     }
 
     /* verify the signature */
     rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength);
 
+cleanup:
     free(ckpData);
     free(ckpSignature);
 
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    ckAssertReturnValueOK(env, rv);
 }
 #endif
 
@@ -510,7 +506,7 @@
         bufP = (CK_BYTE_PTR) malloc((size_t)bufLen);
         if (bufP == NULL) {
             throwOutOfMemoryError(env, 0);
-            return;
+            goto cleanup;
         }
     }
 
@@ -518,19 +514,18 @@
         jsize chunkLen = min(bufLen, jInLen);
         (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP);
         if ((*env)->ExceptionCheck(env)) {
-            if (bufP != BUF) { free(bufP); }
-            return;
+            goto cleanup;
         }
 
         rv = (*ckpFunctions->C_VerifyUpdate)(ckSessionHandle, bufP, chunkLen);
         if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
-            if (bufP != BUF) { free(bufP); }
-            return;
+            goto cleanup;
         }
         jInOfs += chunkLen;
         jInLen -= chunkLen;
     }
 
+cleanup:
     if (bufP != BUF) { free(bufP); }
 }
 #endif
@@ -558,14 +553,16 @@
 
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength);
-    if ((*env)->ExceptionCheck(env)) { return; }
+    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; }
+    ckAssertReturnValueOK(env, rv);
 }
 #endif
 
@@ -583,26 +580,31 @@
     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle)
 {
     CK_SESSION_HANDLE ckSessionHandle;
-    CK_MECHANISM ckMechanism;
+    CK_MECHANISM_PTR ckpMechanism = NULL;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return; }
 
+    TRACE0("DEBUG: C_VerifyRecoverInit\n");
+
     ckSessionHandle = jLongToCKULong(jSessionHandle);
-    jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
+    ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
     if ((*env)->ExceptionCheck(env)) { return; }
 
     ckKeyHandle = jLongToCKULong(jKeyHandle);
 
-    rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, &ckMechanism, ckKeyHandle);
+    rv = (*ckpFunctions->C_VerifyRecoverInit)(ckSessionHandle, ckpMechanism, ckKeyHandle);
 
-    if (ckMechanism.pParameter != NULL_PTR) {
-        free(ckMechanism.pParameter);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK ||
+            (ckpMechanism->pParameter == NULL)) {
+        freeCKMechanismPtr(ckpMechanism);
+    } else {
+        (*env)->SetLongField(env, jMechanism, mech_pHandleID, ptr_to_jlong(ckpMechanism));
+        TRACE1("DEBUG C_VerifyRecoverInit: stored pMech = 0x%lX\n", ptr_to_jlong(ckpMechanism));
     }
-
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
@@ -627,7 +629,7 @@
     CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN];
     CK_BYTE_PTR inBufP;
     CK_BYTE_PTR outBufP = OUTBUF;
-    CK_ULONG ckDataLength = MAX_STACK_BUFFER_LEN;
+    CK_ULONG ckDataLength = 0;
 
     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
     if (ckpFunctions == NULL) { return 0; }
@@ -636,18 +638,19 @@
 
     if (jInLen <= MAX_STACK_BUFFER_LEN) {
         inBufP = INBUF;
+        ckDataLength = MAX_STACK_BUFFER_LEN;
     } else {
         inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen);
         if (inBufP == NULL) {
             throwOutOfMemoryError(env, 0);
             return 0;
         }
+        ckDataLength = jInLen;
     }
 
     (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP);
     if ((*env)->ExceptionCheck(env)) {
-        if (inBufP != INBUF) { free(inBufP); }
-        return 0;
+        goto cleanup;
     }
 
     rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
@@ -656,9 +659,8 @@
     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;
+            goto cleanup;
         }
         rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength);
     }
@@ -666,6 +668,7 @@
         (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDataLength, (jbyte *)outBufP);
     }
 
+cleanup:
     if (inBufP != INBUF) { free(inBufP); }
     if (outBufP != OUTBUF) { free(outBufP); }