< 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 >