< prev index next >

src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c

Print this page

        

@@ -52,10 +52,337 @@
 #include <string.h>
 #include <assert.h>
 
 #include "sun_security_pkcs11_wrapper_PKCS11.h"
 
+#ifdef P11_ENABLE_GETNATIVEKEYINFO
+
+#define CK_ATTRIBUTES_TEMPLATE_LENGTH (CK_ULONG)61U
+
+static CK_ATTRIBUTE ckpAttributesTemplate[CK_ATTRIBUTES_TEMPLATE_LENGTH] = {
+        {CKA_CLASS, 0, 0},
+        {CKA_TOKEN, 0, 0},
+        {CKA_PRIVATE, 0, 0},
+        {CKA_LABEL, 0, 0},
+        {CKA_APPLICATION, 0, 0},
+        {CKA_VALUE, 0, 0},
+        {CKA_OBJECT_ID, 0, 0},
+        {CKA_CERTIFICATE_TYPE, 0, 0},
+        {CKA_ISSUER, 0, 0},
+        {CKA_SERIAL_NUMBER, 0, 0},
+        {CKA_AC_ISSUER, 0, 0},
+        {CKA_OWNER, 0, 0},
+        {CKA_ATTR_TYPES, 0, 0},
+        {CKA_TRUSTED, 0, 0},
+        {CKA_KEY_TYPE, 0, 0},
+        {CKA_SUBJECT, 0, 0},
+        {CKA_ID, 0, 0},
+        {CKA_SENSITIVE, 0, 0},
+        {CKA_ENCRYPT, 0, 0},
+        {CKA_DECRYPT, 0, 0},
+        {CKA_WRAP, 0, 0},
+        {CKA_UNWRAP, 0, 0},
+        {CKA_SIGN, 0, 0},
+        {CKA_SIGN_RECOVER, 0, 0},
+        {CKA_VERIFY, 0, 0},
+        {CKA_VERIFY_RECOVER, 0, 0},
+        {CKA_DERIVE, 0, 0},
+        {CKA_START_DATE, 0, 0},
+        {CKA_END_DATE, 0, 0},
+        {CKA_MODULUS, 0, 0},
+        {CKA_MODULUS_BITS, 0, 0},
+        {CKA_PUBLIC_EXPONENT, 0, 0},
+        {CKA_PRIVATE_EXPONENT, 0, 0},
+        {CKA_PRIME_1, 0, 0},
+        {CKA_PRIME_2, 0, 0},
+        {CKA_EXPONENT_1, 0, 0},
+        {CKA_EXPONENT_2, 0, 0},
+        {CKA_COEFFICIENT, 0, 0},
+        {CKA_PRIME, 0, 0},
+        {CKA_SUBPRIME, 0, 0},
+        {CKA_BASE, 0, 0},
+        {CKA_PRIME_BITS, 0, 0},
+        {CKA_SUB_PRIME_BITS, 0, 0},
+        {CKA_VALUE_BITS, 0, 0},
+        {CKA_VALUE_LEN, 0, 0},
+        {CKA_EXTRACTABLE, 0, 0},
+        {CKA_LOCAL, 0, 0},
+        {CKA_NEVER_EXTRACTABLE, 0, 0},
+        {CKA_ALWAYS_SENSITIVE, 0, 0},
+        {CKA_KEY_GEN_MECHANISM, 0, 0},
+        {CKA_MODIFIABLE, 0, 0},
+        {CKA_ECDSA_PARAMS, 0, 0},
+        {CKA_EC_PARAMS, 0, 0},
+        {CKA_EC_POINT, 0, 0},
+        {CKA_SECONDARY_AUTH, 0, 0},
+        {CKA_AUTH_PIN_FLAGS, 0, 0},
+        {CKA_HW_FEATURE_TYPE, 0, 0},
+        {CKA_RESET_ON_INIT, 0, 0},
+        {CKA_HAS_RESET, 0, 0},
+        {CKA_VENDOR_DEFINED, 0, 0},
+        {CKA_NETSCAPE_DB, 0, 0},
+};
+
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    getNativeKeyInfo
+ * Signature: (JJJ)[B
+ * Parametermapping:                         *PKCS11*
+ * @param   jlong         jSessionHandle     CK_SESSION_HANDLE hSession
+ * @param   jlong         jKeyHandle         CK_OBJECT_HANDLE hObject
+ * @param   jlong         jWrappingKeyHandle CK_OBJECT_HANDLE hObject
+ * @return  jbyteArray    jNativeKeyInfo     -
+ */
+JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_getNativeKeyInfo
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jKeyHandle, jlong jWrappingKeyHandle)
+{
+    jbyteArray returnValue = NULL;
+    CK_SESSION_HANDLE ckSessionHandle = jLongToCKULong(jSessionHandle);
+    CK_OBJECT_HANDLE ckObjectHandle = jLongToCKULong(jKeyHandle);
+    CK_ATTRIBUTE_PTR ckpAttributes = NULL;
+    CK_RV rv;
+    jbyteArray nativeKeyInfoArray = NULL;
+    jbyteArray nativeKeyInfoWrappedKeyArray = NULL;
+    jbyte* nativeKeyInfoArrayRaw = NULL;
+    jbyte* nativeKeyInfoWrappedKeyArrayRaw = NULL;
+    unsigned int sensitiveAttributePosition = (unsigned int)-1;
+    unsigned int i = 0U, totalDataSize = 0U, attributesCount = 0U;
+    unsigned int totalCkAttributesSize = 0U, totalNativeKeyInfoArraySize = 0U;
+    unsigned long* wrappedKeySizePtr = NULL;
+    jbyte* nativeKeyInfoArrayRawCkAttributes = NULL;
+    jbyte* nativeKeyInfoArrayRawCkAttributesPtr = NULL;
+    jbyte* nativeKeyInfoArrayRawDataPtr = NULL;
+    CK_MECHANISM ckMechanism = {0x0};
+    char iv[16] = {0x0};
+    CK_ULONG ckWrappedKeyLength = 0U;
+    unsigned long* wrappedKeySizeWrappedKeyArrayPtr = NULL;
+    CK_BYTE_PTR wrappedKeyBufferPtr = NULL;
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+
+    if (ckpFunctions == NULL) { goto cleanup; }
+
+    ckpAttributes = (CK_ATTRIBUTE_PTR) malloc(CK_ATTRIBUTES_TEMPLATE_LENGTH * sizeof(CK_ATTRIBUTE));
+    if (ckpAttributes == NULL) {
+        throwOutOfMemoryError(env, 0);
+        goto cleanup;
+    }
+    memcpy(ckpAttributes, ckpAttributesTemplate, CK_ATTRIBUTES_TEMPLATE_LENGTH * sizeof(CK_ATTRIBUTE));
+
+    // Get sizes for value buffers
+    (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle,
+            ckpAttributes, CK_ATTRIBUTES_TEMPLATE_LENGTH);
+
+    for (i = 0; i < CK_ATTRIBUTES_TEMPLATE_LENGTH; i++) {
+        if ((ckpAttributes+i)->ulValueLen != (unsigned long)-1) {
+            totalDataSize += (ckpAttributes+i)->ulValueLen;
+            if ((ckpAttributes+i)->type == CKA_SENSITIVE) {
+                sensitiveAttributePosition = attributesCount;
+            }
+            attributesCount++;
+        }
+    }
+
+    // Allocate a single buffer to hold valid attributes and attribute's values
+    // Buffer structure: [ attributes-size, [ ... attributes ... ], values-size, [ ... values ... ],
+    //                      wrapped-key-size, [ ... wrapped-key ... ] ]
+    //     * sizes are expressed in bytes and data type is unsigned long
+    totalCkAttributesSize = attributesCount * sizeof(CK_ATTRIBUTE);
+    totalNativeKeyInfoArraySize = totalCkAttributesSize + sizeof(unsigned long) * 3 + totalDataSize;
+
+    nativeKeyInfoArray = (*env)->NewByteArray(env, totalNativeKeyInfoArraySize);
+    if (nativeKeyInfoArray == NULL) {
+        goto cleanup;
+    }
+
+    nativeKeyInfoArrayRaw = (*env)->GetByteArrayElements(env, nativeKeyInfoArray, NULL);
+    if (nativeKeyInfoArrayRaw == NULL) {
+        goto cleanup;
+    }
+
+    wrappedKeySizePtr = (unsigned long*)(nativeKeyInfoArrayRaw + sizeof(unsigned long)*2
+                                                            + totalCkAttributesSize + totalDataSize);
+    (*(unsigned long*)nativeKeyInfoArrayRaw) = totalCkAttributesSize;
+    (*(unsigned long*)(nativeKeyInfoArrayRaw + sizeof(unsigned long) + totalCkAttributesSize)) = totalDataSize;
+    *wrappedKeySizePtr = 0;
+
+    nativeKeyInfoArrayRawCkAttributes = nativeKeyInfoArrayRaw + sizeof(unsigned long);
+    nativeKeyInfoArrayRawCkAttributesPtr = nativeKeyInfoArrayRawCkAttributes;
+    nativeKeyInfoArrayRawDataPtr = nativeKeyInfoArrayRaw + totalCkAttributesSize + sizeof(unsigned long) * 2;
+
+    for (i = 0; i < CK_ATTRIBUTES_TEMPLATE_LENGTH; i++) {
+        if ((ckpAttributes+i)->ulValueLen != (unsigned long)-1) {
+            (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).type = (ckpAttributes+i)->type;
+            if ((ckpAttributes+i)->ulValueLen != 0) {
+                (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).pValue = nativeKeyInfoArrayRawDataPtr;
+            } else {
+                (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).pValue = 0;
+            }
+            (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen = (ckpAttributes+i)->ulValueLen;
+            nativeKeyInfoArrayRawDataPtr += (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen;
+            nativeKeyInfoArrayRawCkAttributesPtr += sizeof(CK_ATTRIBUTE);
+        }
+    }
+
+    // Get attribute's values
+    rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle,
+            (CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes, attributesCount);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+        goto cleanup;
+    }
+
+    if ((sensitiveAttributePosition != (unsigned int)-1) &&
+        *(CK_BBOOL*)(((CK_ATTRIBUTE_PTR)(((CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes)
+                +sensitiveAttributePosition))->pValue) == CK_TRUE) {
+        // Key is sensitive. Need to extract it wrapped.
+        if (jWrappingKeyHandle != -1) {
+            ckMechanism.mechanism = CKM_AES_CBC_PAD;
+            ckMechanism.pParameter = &iv;
+            ckMechanism.ulParameterLen = 16;
+            rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, jLongToCKULong(jWrappingKeyHandle),
+                    ckObjectHandle, NULL_PTR, &ckWrappedKeyLength);
+            if (ckWrappedKeyLength != 0) {
+                // Allocate space for getting the wrapped key
+                nativeKeyInfoWrappedKeyArray = (*env)->NewByteArray(env,
+                        totalNativeKeyInfoArraySize + ckWrappedKeyLength);
+                if (nativeKeyInfoWrappedKeyArray == NULL) {
+                    goto cleanup;
+                }
+                nativeKeyInfoWrappedKeyArrayRaw = (*env)->GetByteArrayElements(env, nativeKeyInfoWrappedKeyArray, NULL);
+                if (nativeKeyInfoWrappedKeyArrayRaw == NULL) {
+                    goto cleanup;
+                }
+                memcpy(nativeKeyInfoWrappedKeyArrayRaw, nativeKeyInfoArrayRaw, totalNativeKeyInfoArraySize);
+                wrappedKeySizeWrappedKeyArrayPtr = (unsigned long*)(nativeKeyInfoWrappedKeyArrayRaw +
+                                                sizeof(unsigned long)*2 + totalCkAttributesSize + totalDataSize);
+                *wrappedKeySizeWrappedKeyArrayPtr = (unsigned long)ckWrappedKeyLength;
+                wrappedKeyBufferPtr = (unsigned char*)wrappedKeySizeWrappedKeyArrayPtr + sizeof(unsigned long);
+                rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, jLongToCKULong(jWrappingKeyHandle),
+                                        ckObjectHandle, wrappedKeyBufferPtr, &ckWrappedKeyLength);
+                if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+                    goto cleanup;
+                }
+                *wrappedKeySizeWrappedKeyArrayPtr = (unsigned long)ckWrappedKeyLength;
+            } else {
+                goto cleanup;
+            }
+        } else {
+            goto cleanup;
+        }
+        returnValue = nativeKeyInfoWrappedKeyArray;
+    } else {
+        returnValue = nativeKeyInfoArray;
+    }
+
+cleanup:
+    if (ckpAttributes != NULL) {
+        free(ckpAttributes);
+    }
+
+    if (nativeKeyInfoArrayRaw != NULL) {
+        (*env)->ReleaseByteArrayElements(env, nativeKeyInfoArray, nativeKeyInfoArrayRaw, 0);
+    }
+
+    if (nativeKeyInfoWrappedKeyArrayRaw != NULL) {
+        (*env)->ReleaseByteArrayElements(env, nativeKeyInfoWrappedKeyArray, nativeKeyInfoWrappedKeyArrayRaw, 0);
+    }
+
+    if (nativeKeyInfoArray != NULL && returnValue != nativeKeyInfoArray) {
+        (*env)->DeleteLocalRef(env, nativeKeyInfoArray);
+    }
+
+    if (nativeKeyInfoWrappedKeyArray != NULL && returnValue != nativeKeyInfoWrappedKeyArray) {
+        (*env)->DeleteLocalRef(env, nativeKeyInfoWrappedKeyArray);
+    }
+
+    return returnValue;
+}
+#endif
+
+#ifdef P11_ENABLE_CREATENATIVEKEY
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    createNativeKey
+ * Signature: (J[BJ)J
+ * Parametermapping:                          *PKCS11*
+ * @param   jlong         jSessionHandle      CK_SESSION_HANDLE hSession
+ * @param   jbyteArray    jNativeKeyInfo      -
+ * @param   jlong         jWrappingKeyHandle  CK_OBJECT_HANDLE hObject
+ * @return  jlong         jKeyHandle          CK_OBJECT_HANDLE hObject
+ */
+JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_createNativeKey
+    (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jNativeKeyInfo, jlong jWrappingKeyHandle)
+{
+    CK_OBJECT_HANDLE ckObjectHandle;
+    CK_RV rv;
+    CK_SESSION_HANDLE ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jbyte* nativeKeyInfoArrayRaw = NULL;
+    jlong jObjectHandle = 0L;
+    unsigned long totalCkAttributesSize = 0UL, nativeKeyInfoCkAttributesCount = 0UL;
+    jbyte* nativeKeyInfoArrayRawCkAttributes = NULL;
+    jbyte* nativeKeyInfoArrayRawCkAttributesPtr = NULL;
+    jbyte* nativeKeyInfoArrayRawDataPtr = NULL;
+    unsigned long totalDataSize = 0UL;
+    unsigned long* wrappedKeySizePtr = NULL;
+    unsigned int i = 0U;
+    CK_MECHANISM ckMechanism = {0x0};
+    char iv[16] = {0x0};
+    CK_ULONG ckWrappedKeyLength = 0UL;
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+
+    if (ckpFunctions == NULL) { goto cleanup; }
+
+    nativeKeyInfoArrayRaw = (*env)->GetByteArrayElements(env, jNativeKeyInfo, NULL);
+    if (nativeKeyInfoArrayRaw == NULL) {
+        goto cleanup;
+    }
+
+    totalCkAttributesSize = *(unsigned long*)nativeKeyInfoArrayRaw;
+    nativeKeyInfoCkAttributesCount = totalCkAttributesSize/sizeof(CK_ATTRIBUTE);
+    nativeKeyInfoArrayRawCkAttributes = nativeKeyInfoArrayRaw + sizeof(unsigned long);
+    nativeKeyInfoArrayRawCkAttributesPtr = nativeKeyInfoArrayRawCkAttributes;
+    nativeKeyInfoArrayRawDataPtr = nativeKeyInfoArrayRaw + totalCkAttributesSize + sizeof(unsigned long) * 2;
+    totalDataSize = *(unsigned long*)(nativeKeyInfoArrayRaw + totalCkAttributesSize + sizeof(unsigned long));
+    wrappedKeySizePtr = (unsigned long*)(nativeKeyInfoArrayRaw + sizeof(unsigned long)*2
+                                                                + totalCkAttributesSize + totalDataSize);
+
+    for (i = 0; i < nativeKeyInfoCkAttributesCount; i++) {
+        if ((*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen > 0) {
+            (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).pValue = nativeKeyInfoArrayRawDataPtr;
+        }
+        nativeKeyInfoArrayRawDataPtr += (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen;
+        nativeKeyInfoArrayRawCkAttributesPtr += sizeof(CK_ATTRIBUTE);
+    }
+
+    if (*wrappedKeySizePtr == 0) {
+        // Not a wrapped key
+        rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle, (CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes,
+            jLongToCKULong(nativeKeyInfoCkAttributesCount), &ckObjectHandle);
+    } else {
+        // Wrapped key
+        ckMechanism.mechanism = CKM_AES_CBC_PAD;
+        ckMechanism.pParameter = &iv;
+        ckMechanism.ulParameterLen = 16;
+        rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism, jLongToCKULong(jWrappingKeyHandle),
+                    (CK_BYTE_PTR)(wrappedKeySizePtr + 1), *wrappedKeySizePtr, (CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes,
+                    jLongToCKULong(nativeKeyInfoCkAttributesCount), &ckObjectHandle);
+    }
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+        goto cleanup;
+    }
+
+    jObjectHandle = ckULongToJLong(ckObjectHandle);
+
+cleanup:
+
+    if (nativeKeyInfoArrayRaw != NULL) {
+        (*env)->ReleaseByteArrayElements(env, jNativeKeyInfo, nativeKeyInfoArrayRaw, JNI_ABORT);
+    }
+
+    return jObjectHandle;
+}
+#endif
+
 #ifdef P11_ENABLE_C_GENERATEKEY
 /*
  * Class:     sun_security_pkcs11_wrapper_PKCS11
  * Method:    C_GenerateKey
  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
< prev index next >