Added support for touch and change policy during key import.
This commit is contained in:
@@ -163,6 +163,7 @@ CK_RV apply_sign_mechanism_init(op_info_t *op_info) {
|
||||
case CKM_RSA_X_509:
|
||||
case CKM_ECDSA:
|
||||
// No hash required for this mechanism
|
||||
op_info->op.sign.md_ctx = NULL;
|
||||
return CKR_OK;
|
||||
|
||||
case CKM_SHA1_RSA_PKCS:
|
||||
|
||||
+14
-2
@@ -1063,7 +1063,7 @@ CK_RV check_create_cert(CK_ATTRIBUTE_PTR templ, CK_ULONG n,
|
||||
}
|
||||
|
||||
CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
CK_BYTE_PTR *value, CK_ULONG_PTR value_len) {
|
||||
CK_BYTE_PTR *value, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined) {
|
||||
|
||||
CK_ULONG i;
|
||||
CK_BBOOL has_id = CK_FALSE;
|
||||
@@ -1073,6 +1073,8 @@ CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
CK_BYTE_PTR ec_params;
|
||||
CK_ULONG ec_params_len;
|
||||
|
||||
*vendor_defined = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
switch (templ[i].type) {
|
||||
case CKA_CLASS:
|
||||
@@ -1108,6 +1110,10 @@ CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
|
||||
break;
|
||||
|
||||
case CKA_VENDOR_DEFINED:
|
||||
*vendor_defined = *((CK_ULONG_PTR)templ[i].pValue);
|
||||
break;
|
||||
|
||||
case CKA_TOKEN:
|
||||
case CKA_LABEL:
|
||||
case CKA_SUBJECT:
|
||||
@@ -1138,7 +1144,7 @@ CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
|
||||
CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
CK_BYTE_PTR *p, CK_BYTE_PTR *q, CK_BYTE_PTR *dp,
|
||||
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len) {
|
||||
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined) {
|
||||
|
||||
CK_ULONG i;
|
||||
CK_BBOOL has_id = CK_FALSE;
|
||||
@@ -1154,6 +1160,8 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
CK_ULONG dq_len;
|
||||
CK_ULONG qinv_len;
|
||||
|
||||
*vendor_defined = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
switch (templ[i].type) {
|
||||
case CKA_CLASS:
|
||||
@@ -1217,6 +1225,10 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
|
||||
break;
|
||||
|
||||
case CKA_VENDOR_DEFINED:
|
||||
*vendor_defined = *((CK_ULONG_PTR)templ[i].pValue);
|
||||
break;
|
||||
|
||||
case CKA_TOKEN:
|
||||
case CKA_LABEL:
|
||||
case CKA_SUBJECT:
|
||||
|
||||
+2
-2
@@ -15,10 +15,10 @@ CK_RV store_cert(piv_obj_id_t cert_id, CK_BYTE_PTR data, CK_ULONG len);
|
||||
CK_RV check_create_cert(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
CK_BYTE_PTR *value, CK_ULONG_PTR cert_len);
|
||||
CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
CK_BYTE_PTR *value, CK_ULONG_PTR value_len);
|
||||
CK_BYTE_PTR *value, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined);
|
||||
CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
||||
CK_BYTE_PTR *p, CK_BYTE_PTR *q, CK_BYTE_PTR *dp,
|
||||
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len);
|
||||
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1183,4 +1183,11 @@ typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
|
||||
/* undo packing */
|
||||
//#include "pkcs11u.h" // TODO: msc specific?
|
||||
|
||||
// YUBICO specific attributes
|
||||
#define CKA_TOUCH_PIN_DEFAULT 0x00000000U
|
||||
#define CKA_TOUCH_ALWAYS 0x00000001U
|
||||
#define CKA_PIN_ONCE 0x00000002U
|
||||
#define CKA_PIN_ALWAYS 0x00000004U
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+21
-1
@@ -151,7 +151,7 @@ static CK_RV COMMON_token_import_cert(ykpiv_state *state, CK_ULONG cert_id, CK_B
|
||||
|
||||
CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id, CK_BYTE_PTR p, CK_BYTE_PTR q,
|
||||
CK_BYTE_PTR dp, CK_BYTE_PTR dq, CK_BYTE_PTR qinv,
|
||||
CK_BYTE_PTR ec_data, CK_ULONG elem_len) {
|
||||
CK_BYTE_PTR ec_data, CK_ULONG elem_len, CK_ULONG vendor_defined) {
|
||||
|
||||
unsigned char key_data[1024];
|
||||
unsigned char *in_ptr = key_data;
|
||||
@@ -200,6 +200,26 @@ CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id, CK_BYT
|
||||
in_ptr += elem_len;
|
||||
}
|
||||
|
||||
// PIN policy and touch
|
||||
if (vendor_defined != 0) {
|
||||
if (vendor_defined & CKA_PIN_ONCE) {
|
||||
*in_ptr++ = YKPIV_PINPOLICY_TAG;
|
||||
*in_ptr++ = 0x01;
|
||||
*in_ptr++ = YKPIV_PINPOLICY_ONCE;
|
||||
}
|
||||
else if (vendor_defined & CKA_PIN_ALWAYS) {
|
||||
*in_ptr++ = YKPIV_PINPOLICY_TAG;
|
||||
*in_ptr++ = 0x01;
|
||||
*in_ptr++ = YKPIV_PINPOLICY_ALWAYS;
|
||||
}
|
||||
|
||||
if (vendor_defined & CKA_TOUCH_ALWAYS) {
|
||||
*in_ptr++ = YKPIV_TOUCHPOLICY_TAG;
|
||||
*in_ptr++ = 0x01;
|
||||
*in_ptr++ = YKPIV_TOUCHPOLICY_ALWAYS;
|
||||
}
|
||||
}
|
||||
|
||||
if (ykpiv_transfer_data(state, templ, key_data, in_ptr - key_data, data, &recv_len, &sw) != YKPIV_OK)
|
||||
return CKR_FUNCTION_FAILED;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ typedef CK_RV (*t_login_f)(ykpiv_state *, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULON
|
||||
typedef CK_RV (*t_generate_key_f)(ykpiv_state *, CK_BBOOL, CK_BYTE, CK_ULONG);
|
||||
typedef CK_RV (*t_import_cert_f)(ykpiv_state *, CK_ULONG, CK_BYTE_PTR);
|
||||
typedef CK_RV (*t_import_private_key_f)(ykpiv_state *, CK_BYTE, CK_BYTE_PTR, CK_BYTE_PTR, CK_BYTE_PTR,
|
||||
CK_BYTE_PTR, CK_BYTE_PTR, CK_BYTE_PTR, CK_ULONG);
|
||||
CK_BYTE_PTR, CK_BYTE_PTR, CK_BYTE_PTR, CK_ULONG, CK_ULONG);
|
||||
|
||||
// TODO: replace all the common calls with functions defined in .c that use libykpiv
|
||||
|
||||
|
||||
+5
-4
@@ -854,6 +854,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
||||
CK_BYTE_PTR dp;
|
||||
CK_BYTE_PTR dq;
|
||||
CK_BYTE_PTR qinv;
|
||||
CK_ULONG vendor_defined;
|
||||
token_vendor_t token;
|
||||
CK_BBOOL is_new;
|
||||
CK_BBOOL is_rsa;
|
||||
@@ -974,11 +975,11 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
||||
|
||||
// Try to parse the key as EC
|
||||
is_rsa = CK_FALSE;
|
||||
rv = check_create_ec_key(pTemplate, ulCount, &id, &value, &value_len);
|
||||
rv = check_create_ec_key(pTemplate, ulCount, &id, &value, &value_len, &vendor_defined);
|
||||
if (rv != CKR_OK) {
|
||||
// Try to parse the key as RSA
|
||||
is_rsa = CK_TRUE;
|
||||
rv = check_create_rsa_key(pTemplate, ulCount, &id, &p, &q, &dp, &dq, &qinv, &value_len);
|
||||
rv = check_create_rsa_key(pTemplate, ulCount, &id, &p, &q, &dp, &dq, &qinv, &value_len, &vendor_defined);
|
||||
if (rv != CKR_OK) {
|
||||
DBG(("Private key template not valid"));
|
||||
return rv;
|
||||
@@ -993,7 +994,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
||||
DBG(("Key is RSA"));
|
||||
rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object), p, q, dp, dq, qinv,
|
||||
NULL,
|
||||
value_len);
|
||||
value_len, vendor_defined);
|
||||
if (rv != CKR_OK) {
|
||||
DBG(("Unable to import RSA private key"));
|
||||
return rv;
|
||||
@@ -1003,7 +1004,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
|
||||
DBG(("Key is ECDSA"));
|
||||
rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object), NULL, NULL, NULL, NULL, NULL,
|
||||
value,
|
||||
value_len);
|
||||
value_len, vendor_defined);
|
||||
if (rv != CKR_OK) {
|
||||
DBG(("Unable to import ECDSA private key"));
|
||||
return rv;
|
||||
|
||||
Reference in New Issue
Block a user