--- old/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c 2018-06-04 19:27:29.798745600 -0300 +++ new/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_keymgmt.c 2018-06-04 19:27:29.608744250 -0300 @@ -54,6 +54,333 @@ #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