aboutsummaryrefslogtreecommitdiff
path: root/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c')
-rw-r--r--src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c442
1 files changed, 441 insertions, 1 deletions
diff --git a/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c b/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c
index 9824da2dfd..fa725ae176 100644
--- a/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c
+++ b/src/share/native/sun/security/pkcs11/wrapper/p11_keymgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, 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.
@@ -54,6 +54,446 @@
#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: (JJJLsun/security/pkcs11/wrapper/CK_MECHANISM;)[B
+ * Parametermapping: *PKCS11*
+ * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
+ * @param jlong jKeyHandle CK_OBJECT_HANDLE hObject
+ * @param jlong jWrappingKeyHandle CK_OBJECT_HANDLE hObject
+ * @param jobject jWrappingMech CK_MECHANISM_PTR pMechanism
+ * @return jbyteArray jNativeKeyInfo -
+ */
+JNIEXPORT jbyteArray JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_getNativeKeyInfo
+ (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jKeyHandle,
+ jlong jWrappingKeyHandle, jobject jWrappingMech)
+{
+ 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;
+ unsigned long totalDataSize = 0UL, attributesCount = 0UL;
+ unsigned long totalCkAttributesSize = 0UL, totalNativeKeyInfoArraySize = 0UL;
+ jbyte* wrappedKeySizePtr = NULL;
+ jbyte* nativeKeyInfoArrayRawCkAttributes = NULL;
+ jbyte* nativeKeyInfoArrayRawCkAttributesPtr = NULL;
+ jbyte* nativeKeyInfoArrayRawDataPtr = NULL;
+ CK_MECHANISM ckMechanism;
+ char iv[16] = {0x0};
+ CK_ULONG ckWrappedKeyLength = 0U;
+ jbyte* wrappedKeySizeWrappedKeyArrayPtr = NULL;
+ CK_BYTE_PTR wrappedKeyBufferPtr = NULL;
+ CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+ CK_OBJECT_CLASS class;
+ CK_KEY_TYPE keyType;
+ CK_BBOOL sensitive;
+ CK_BBOOL netscapeAttributeValueNeeded = CK_FALSE;
+ CK_ATTRIBUTE ckNetscapeAttributesTemplate[4];
+ ckNetscapeAttributesTemplate[0].type = CKA_CLASS;
+ ckNetscapeAttributesTemplate[1].type = CKA_KEY_TYPE;
+ ckNetscapeAttributesTemplate[2].type = CKA_SENSITIVE;
+ ckNetscapeAttributesTemplate[3].type = CKA_NETSCAPE_DB;
+ ckNetscapeAttributesTemplate[0].pValue = &class;
+ ckNetscapeAttributesTemplate[1].pValue = &keyType;
+ ckNetscapeAttributesTemplate[2].pValue = &sensitive;
+ ckNetscapeAttributesTemplate[3].pValue = 0;
+ ckNetscapeAttributesTemplate[0].ulValueLen = sizeof(class);
+ ckNetscapeAttributesTemplate[1].ulValueLen = sizeof(keyType);
+ ckNetscapeAttributesTemplate[2].ulValueLen = sizeof(sensitive);
+ ckNetscapeAttributesTemplate[3].ulValueLen = 0;
+
+ if (ckpFunctions == NULL) { goto cleanup; }
+
+ // If key is private and of DSA or EC type, NSS may require CKA_NETSCAPE_DB
+ // attribute to unwrap it.
+ rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle,
+ ckNetscapeAttributesTemplate,
+ sizeof(ckNetscapeAttributesTemplate)/sizeof(CK_ATTRIBUTE));
+
+ if (rv == CKR_OK && class == CKO_PRIVATE_KEY &&
+ (keyType == CKK_EC || keyType == CKK_DSA) &&
+ sensitive == CK_TRUE &&
+ ckNetscapeAttributesTemplate[3].ulValueLen == CK_UNAVAILABLE_INFORMATION) {
+ // We cannot set the attribute through C_SetAttributeValue here
+ // because it might be read-only. However, we can add it to
+ // the extracted buffer.
+ netscapeAttributeValueNeeded = CK_TRUE;
+ TRACE0("DEBUG: override CKA_NETSCAPE_DB attr value to TRUE\n");
+ }
+
+ 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
+ // NOTE: may return an error code but length values are filled anyways
+ (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle,
+ ckpAttributes, CK_ATTRIBUTES_TEMPLATE_LENGTH);
+
+ for (i = 0; i < CK_ATTRIBUTES_TEMPLATE_LENGTH; i++) {
+ if ((ckpAttributes+i)->ulValueLen != CK_UNAVAILABLE_INFORMATION) {
+ totalDataSize += (ckpAttributes+i)->ulValueLen;
+ if ((ckpAttributes+i)->type == CKA_SENSITIVE) {
+ sensitiveAttributePosition = attributesCount;
+ TRACE0("DEBUG: GetNativeKeyInfo key is sensitive");
+ }
+ attributesCount++;
+ }
+ }
+
+ if (netscapeAttributeValueNeeded) {
+ 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);
+ TRACE1("DEBUG: GetNativeKeyInfo attributesCount = %lu\n", attributesCount);
+ TRACE1("DEBUG: GetNativeKeyInfo sizeof CK_ATTRIBUTE = %zu\n", sizeof(CK_ATTRIBUTE));
+ TRACE1("DEBUG: GetNativeKeyInfo totalCkAttributesSize = %lu\n", totalCkAttributesSize);
+ TRACE1("DEBUG: GetNativeKeyInfo totalDataSize = %lu\n", totalDataSize);
+
+ totalNativeKeyInfoArraySize =
+ totalCkAttributesSize + sizeof(unsigned long) * 3 + totalDataSize;
+
+ TRACE1("DEBUG: GetNativeKeyInfo totalNativeKeyInfoArraySize = %lu\n", totalNativeKeyInfoArraySize);
+
+ nativeKeyInfoArray = (*env)->NewByteArray(env, totalNativeKeyInfoArraySize);
+ if (nativeKeyInfoArray == NULL) {
+ goto cleanup;
+ }
+
+ nativeKeyInfoArrayRaw = (*env)->GetByteArrayElements(env, nativeKeyInfoArray,
+ NULL);
+ if (nativeKeyInfoArrayRaw == NULL) {
+ goto cleanup;
+ }
+
+ wrappedKeySizePtr = nativeKeyInfoArrayRaw +
+ sizeof(unsigned long)*2 + totalCkAttributesSize + totalDataSize;
+ memcpy(nativeKeyInfoArrayRaw, &totalCkAttributesSize, sizeof(unsigned long));
+
+ memcpy(nativeKeyInfoArrayRaw + sizeof(unsigned long) + totalCkAttributesSize,
+ &totalDataSize, sizeof(unsigned long));
+
+ memset(wrappedKeySizePtr, 0, sizeof(unsigned long));
+
+ 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 != CK_UNAVAILABLE_INFORMATION) {
+ (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).type =
+ (ckpAttributes+i)->type;
+ (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen =
+ (ckpAttributes+i)->ulValueLen;
+ if ((ckpAttributes+i)->ulValueLen != 0) {
+ (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).pValue =
+ nativeKeyInfoArrayRawDataPtr;
+ } else {
+ (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).pValue = 0;
+ }
+ nativeKeyInfoArrayRawDataPtr +=
+ (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).ulValueLen;
+ nativeKeyInfoArrayRawCkAttributesPtr += sizeof(CK_ATTRIBUTE);
+ }
+ }
+
+ TRACE0("DEBUG: GetNativeKeyInfo finished prepping nativeKeyInfoArray\n");
+
+ // Get attribute's values
+ rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle,
+ (CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes,
+ attributesCount);
+ if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+ goto cleanup;
+ }
+
+ TRACE0("DEBUG: GetNativeKeyInfo 1st C_GetAttributeValue call passed\n");
+
+ if (netscapeAttributeValueNeeded) {
+ (*(CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributesPtr).type = CKA_NETSCAPE_DB;
+ // Value is not needed, public key is not used
+ }
+
+ 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 != 0) {
+
+ jMechanismToCKMechanism(env, jWrappingMech, &ckMechanism);
+ 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 =
+ nativeKeyInfoWrappedKeyArrayRaw +
+ sizeof(unsigned long)*2 + totalCkAttributesSize +
+ totalDataSize;
+ memcpy(wrappedKeySizeWrappedKeyArrayPtr, &ckWrappedKeyLength, sizeof(unsigned long));
+ TRACE1("DEBUG: GetNativeKeyInfo 1st C_WrapKey wrappedKeyLength = %lu\n", ckWrappedKeyLength);
+
+ wrappedKeyBufferPtr =
+ (CK_BYTE_PTR) (wrappedKeySizeWrappedKeyArrayPtr +
+ sizeof(unsigned long));
+ rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism,
+ jLongToCKULong(jWrappingKeyHandle),ckObjectHandle,
+ wrappedKeyBufferPtr, &ckWrappedKeyLength);
+ if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
+ goto cleanup;
+ }
+ memcpy(wrappedKeySizeWrappedKeyArrayPtr, &ckWrappedKeyLength, sizeof(unsigned long));
+ TRACE1("DEBUG: GetNativeKeyInfo 2nd C_WrapKey wrappedKeyLength = %lu\n", ckWrappedKeyLength);
+ } else {
+ goto cleanup;
+ }
+ } else {
+ ckAssertReturnValueOK(env, CKR_KEY_HANDLE_INVALID);
+ 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[BJLsun/security/pkcs11/wrapper/CK_MECHANISM;)J
+ * Parametermapping: *PKCS11*
+ * @param jlong jSessionHandle CK_SESSION_HANDLE hSession
+ * @param jbyteArray jNativeKeyInfo -
+ * @param jlong jWrappingKeyHandle CK_OBJECT_HANDLE hObject
+ * @param jobject jWrappingMech CK_MECHANISM_PTR pMechanism
+ * @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, jobject jWrappingMech)
+{
+ CK_OBJECT_HANDLE ckObjectHandle;
+ CK_RV rv;
+ CK_SESSION_HANDLE ckSessionHandle = jLongToCKULong(jSessionHandle);
+ jbyte* nativeKeyInfoArrayRaw = NULL;
+ jlong jObjectHandle = 0L;
+ unsigned long totalCkAttributesSize = 0UL;
+ unsigned long nativeKeyInfoCkAttributesCount = 0UL;
+ jbyte* nativeKeyInfoArrayRawCkAttributes = NULL;
+ jbyte* nativeKeyInfoArrayRawCkAttributesPtr = NULL;
+ jbyte* nativeKeyInfoArrayRawDataPtr = NULL;
+ unsigned long totalDataSize = 0UL;
+ jbyte* wrappedKeySizePtr = NULL;
+ unsigned int i = 0U;
+ CK_MECHANISM ckMechanism;
+ 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;
+ }
+
+ memcpy(&totalCkAttributesSize, nativeKeyInfoArrayRaw, sizeof(unsigned long));
+ TRACE1("DEBUG: createNativeKey totalCkAttributesSize = %lu\n", totalCkAttributesSize);
+ nativeKeyInfoCkAttributesCount = totalCkAttributesSize/sizeof(CK_ATTRIBUTE);
+ TRACE1("DEBUG: createNativeKey nativeKeyInfoCkAttributesCount = %lu\n", nativeKeyInfoCkAttributesCount);
+
+ nativeKeyInfoArrayRawCkAttributes = nativeKeyInfoArrayRaw +
+ sizeof(unsigned long);
+ nativeKeyInfoArrayRawCkAttributesPtr = nativeKeyInfoArrayRawCkAttributes;
+ nativeKeyInfoArrayRawDataPtr = nativeKeyInfoArrayRaw +
+ totalCkAttributesSize + sizeof(unsigned long) * 2;
+ memcpy(&totalDataSize, (nativeKeyInfoArrayRaw + totalCkAttributesSize + sizeof(unsigned long)),
+ sizeof(unsigned long));
+ TRACE1("DEBUG: createNativeKey totalDataSize = %lu\n", totalDataSize);
+
+ wrappedKeySizePtr = nativeKeyInfoArrayRaw +
+ sizeof(unsigned long)*2 + totalCkAttributesSize + totalDataSize;
+
+ memcpy(&ckWrappedKeyLength, wrappedKeySizePtr, sizeof(unsigned long));
+ TRACE1("DEBUG: createNativeKey wrappedKeyLength = %lu\n", ckWrappedKeyLength);
+
+ 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 (ckWrappedKeyLength == 0) {
+ // Not a wrapped key
+ rv = (*ckpFunctions->C_CreateObject)(ckSessionHandle,
+ (CK_ATTRIBUTE_PTR)nativeKeyInfoArrayRawCkAttributes,
+ jLongToCKULong(nativeKeyInfoCkAttributesCount), &ckObjectHandle);
+ } else {
+ // Wrapped key
+ jMechanismToCKMechanism(env, jWrappingMech, &ckMechanism);
+ rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism,
+ jLongToCKULong(jWrappingKeyHandle),
+ (CK_BYTE_PTR)(wrappedKeySizePtr + sizeof(unsigned long)),
+ ckWrappedKeyLength,
+ (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