Switch ykcs11 to use private key import from libykpiv.

This commit is contained in:
Alessio Di Mauro
2015-11-19 18:30:08 +01:00
parent 6269280578
commit 8e3314ab42
6 changed files with 120 additions and 100 deletions
+14 -16
View File
@@ -1161,8 +1161,12 @@ 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_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 *p, CK_ULONG_PTR p_len,
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined) { CK_BYTE_PTR *q, CK_ULONG_PTR q_len,
CK_BYTE_PTR *dp, CK_ULONG_PTR dp_len,
CK_BYTE_PTR *dq, CK_ULONG_PTR dq_len,
CK_BYTE_PTR *qinv, CK_ULONG_PTR qinv_len,
CK_ULONG_PTR vendor_defined) {
CK_ULONG i; CK_ULONG i;
CK_BBOOL has_id = CK_FALSE; CK_BBOOL has_id = CK_FALSE;
@@ -1172,11 +1176,6 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
CK_BBOOL has_dp = CK_FALSE; CK_BBOOL has_dp = CK_FALSE;
CK_BBOOL has_dq = CK_FALSE; CK_BBOOL has_dq = CK_FALSE;
CK_BBOOL has_qinv = CK_FALSE; CK_BBOOL has_qinv = CK_FALSE;
CK_ULONG p_len = 0;
CK_ULONG q_len = 0;
CK_ULONG dp_len = 0;
CK_ULONG dq_len = 0;
CK_ULONG qinv_len = 0;
*vendor_defined = 0; *vendor_defined = 0;
@@ -1211,35 +1210,35 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
case CKA_PRIME_1: case CKA_PRIME_1:
has_p = CK_TRUE; has_p = CK_TRUE;
*p = (CK_BYTE_PTR)templ[i].pValue; *p = (CK_BYTE_PTR)templ[i].pValue;
p_len = templ[i].ulValueLen; *p_len = templ[i].ulValueLen;
break; break;
case CKA_PRIME_2: case CKA_PRIME_2:
has_q = CK_TRUE; has_q = CK_TRUE;
*q = (CK_BYTE_PTR)templ[i].pValue; *q = (CK_BYTE_PTR)templ[i].pValue;
q_len = templ[i].ulValueLen; *q_len = templ[i].ulValueLen;
break; break;
case CKA_EXPONENT_1: case CKA_EXPONENT_1:
has_dp = CK_TRUE; has_dp = CK_TRUE;
*dp = (CK_BYTE_PTR)templ[i].pValue; *dp = (CK_BYTE_PTR)templ[i].pValue;
dp_len = templ[i].ulValueLen; *dp_len = templ[i].ulValueLen;
break; break;
case CKA_EXPONENT_2: case CKA_EXPONENT_2:
has_dq = CK_TRUE; has_dq = CK_TRUE;
*dq = (CK_BYTE_PTR)templ[i].pValue; *dq = (CK_BYTE_PTR)templ[i].pValue;
dq_len = templ[i].ulValueLen; *dq_len = templ[i].ulValueLen;
break; break;
case CKA_COEFFICIENT: case CKA_COEFFICIENT:
has_qinv = CK_TRUE; has_qinv = CK_TRUE;
*qinv = (CK_BYTE_PTR)templ[i].pValue; *qinv = (CK_BYTE_PTR)templ[i].pValue;
qinv_len = templ[i].ulValueLen; *qinv_len = templ[i].ulValueLen;
break; break;
@@ -1270,13 +1269,12 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
has_qinv == CK_FALSE) has_qinv == CK_FALSE)
return CKR_TEMPLATE_INCOMPLETE; return CKR_TEMPLATE_INCOMPLETE;
if (p_len != 64 && p_len != 128) if (*p_len != 64 && *p_len != 128)
return CKR_ATTRIBUTE_VALUE_INVALID; return CKR_ATTRIBUTE_VALUE_INVALID;
*value_len = p_len;
if (q_len != p_len || dp_len != p_len || if (*q_len != *p_len || *dp_len > *p_len ||
dq_len != p_len || qinv_len != p_len) *dq_len > *p_len || *qinv_len > *p_len)
return CKR_ATTRIBUTE_VALUE_INVALID; return CKR_ATTRIBUTE_VALUE_INVALID;
return CKR_OK; return CKR_OK;
+6 -2
View File
@@ -18,8 +18,12 @@ CK_RV check_create_cert(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id, 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_ULONG_PTR vendor_defined); 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_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 *p, CK_ULONG_PTR p_len,
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined); CK_BYTE_PTR *q, CK_ULONG_PTR q_len,
CK_BYTE_PTR *dp, CK_ULONG_PTR dp_len,
CK_BYTE_PTR *dq, CK_ULONG_PTR dq_len,
CK_BYTE_PTR *qinv, CK_ULONG_PTR qinv_len,
CK_ULONG_PTR vendor_defined);
CK_RV check_delete_cert(CK_OBJECT_HANDLE hObject, CK_BYTE_PTR id); CK_RV check_delete_cert(CK_OBJECT_HANDLE hObject, CK_BYTE_PTR id);
#endif #endif
+2 -1
View File
@@ -1190,6 +1190,7 @@ typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
#define CKA_TOUCH_ALWAYS 0x00000001U #define CKA_TOUCH_ALWAYS 0x00000001U
#define CKA_PIN_ONCE 0x00000002U #define CKA_PIN_ONCE 0x00000002U
#define CKA_PIN_ALWAYS 0x00000004U #define CKA_PIN_ALWAYS 0x00000004U
#define CKA_PIN_NEVER 0x00000008U
#define CKA_TOUCH_NEVER 0x00000016U
#endif #endif
+59 -71
View File
@@ -176,85 +176,73 @@ static CK_RV COMMON_token_import_cert(ykpiv_state *state, CK_ULONG cert_id, CK_B
return CKR_OK; return CKR_OK;
} }
CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id, CK_BYTE_PTR p, CK_BYTE_PTR q, CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id,
CK_BYTE_PTR dp, CK_BYTE_PTR dq, CK_BYTE_PTR qinv, CK_BYTE_PTR p, CK_ULONG p_len,
CK_BYTE_PTR ec_data, CK_ULONG elem_len, CK_ULONG vendor_defined) { CK_BYTE_PTR q, CK_ULONG q_len,
CK_BYTE_PTR dp, CK_ULONG dp_len,
CK_BYTE_PTR dq, CK_ULONG dq_len,
CK_BYTE_PTR qinv, CK_ULONG qinv_len,
CK_BYTE_PTR ec_data, CK_ULONG ec_data_len,
CK_ULONG vendor_defined) {
unsigned char key_data[1024]; CK_BYTE pin_policy;
unsigned char *in_ptr = key_data; CK_BYTE touch_policy;
unsigned char templ[] = {0, YKPIV_INS_IMPORT_KEY, 0, key_id}; CK_BYTE algo;
unsigned char data[0xff]; ykpiv_rc rc;
unsigned long recv_len = sizeof(data);
int sw;
if (elem_len == 128) // TODO: add a flag to check algo type ? if (p == NULL) {
templ[2] = YKPIV_ALGO_RSA2048; if (ec_data_len == 32 || ec_data_len == 31)
else if (elem_len == 64) algo = YKPIV_ALGO_ECCP256;
templ[2] = YKPIV_ALGO_RSA1024; else
else if(elem_len == 32) algo = YKPIV_ALGO_ECCP384;
templ[2] = YKPIV_ALGO_ECCP256;
if (templ[2] == YKPIV_ALGO_RSA1024 ||templ[2] == YKPIV_ALGO_RSA2048) {
*in_ptr++ = 0x01;
in_ptr += set_length(in_ptr, elem_len);
memcpy(in_ptr, p, (size_t)(elem_len));
in_ptr += elem_len;
*in_ptr++ = 0x02;
in_ptr += set_length(in_ptr, elem_len);
memcpy(in_ptr, q, (size_t)(elem_len));
in_ptr += elem_len;
*in_ptr++ = 0x03;
in_ptr += set_length(in_ptr, elem_len);
memcpy(in_ptr, dp, (size_t)(elem_len));
in_ptr += elem_len;
*in_ptr++ = 0x04;
in_ptr += set_length(in_ptr, elem_len);
memcpy(in_ptr, dq, (size_t)(elem_len));
in_ptr += elem_len;
*in_ptr++ = 0x05;
in_ptr += set_length(in_ptr, elem_len);
memcpy(in_ptr, qinv, (size_t)(elem_len));
in_ptr += elem_len;
} }
else if (templ[2] == YKPIV_ALGO_ECCP256) { else if (ec_data == NULL) {
*in_ptr++ = 0x06; if (p_len == 64)
in_ptr += set_length(in_ptr, elem_len); algo = YKPIV_ALGO_RSA1024;
memcpy(in_ptr, ec_data, (size_t)(elem_len)); else
in_ptr += elem_len; algo = YKPIV_ALGO_RSA2048;
} }
else
// 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; return CKR_FUNCTION_FAILED;
if (sw != 0x9000) pin_policy = YKPIV_PINPOLICY_DEFAULT;
return CKR_DEVICE_ERROR; touch_policy = YKPIV_TOUCHPOLICY_DEFAULT;
if (vendor_defined != 0) {
if (vendor_defined & CKA_PIN_ONCE) {
pin_policy = YKPIV_PINPOLICY_ONCE;
}
else if (vendor_defined & CKA_PIN_ALWAYS) {
pin_policy = YKPIV_PINPOLICY_ALWAYS;
}
else if (vendor_defined & CKA_PIN_NEVER) {
pin_policy = YKPIV_PINPOLICY_NEVER;
}
else
return CKR_ATTRIBUTE_VALUE_INVALID;
return CKR_OK; if (vendor_defined & CKA_TOUCH_ALWAYS) {
touch_policy = YKPIV_TOUCHPOLICY_ALWAYS;
}
else if (vendor_defined & CKA_TOUCH_NEVER) {
touch_policy = YKPIV_TOUCHPOLICY_NEVER;
}
else
return CKR_ATTRIBUTE_VALUE_INVALID;
}
rc = ykpiv_import_private_key(state, key_id, algo,
p, p_len,
q, q_len,
dp, dp_len,
dq, dq_len,
qinv, qinv_len,
ec_data, ec_data_len,
pin_policy, touch_policy);
if (rc != YKPIV_OK)
return CKR_FUNCTION_FAILED;
return CKR_OK;
} }
CK_RV COMMON_token_delete_cert(ykpiv_state *state, CK_ULONG cert_id) { CK_RV COMMON_token_delete_cert(ykpiv_state *state, CK_ULONG cert_id) {
+8 -2
View File
@@ -23,8 +23,14 @@ typedef CK_RV (*get_t_raw_certificate_f)(ykpiv_state *, piv_obj_id_t, CK_BYTE_PT
typedef CK_RV (*t_login_f)(ykpiv_state *, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG); typedef CK_RV (*t_login_f)(ykpiv_state *, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG);
typedef CK_RV (*t_generate_key_f)(ykpiv_state *, CK_BBOOL, CK_BYTE, CK_ULONG, CK_ULONG); typedef CK_RV (*t_generate_key_f)(ykpiv_state *, CK_BBOOL, CK_BYTE, CK_ULONG, CK_ULONG);
typedef CK_RV (*t_import_cert_f)(ykpiv_state *, CK_ULONG, CK_BYTE_PTR); 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, typedef CK_RV (*t_import_private_key_f)(ykpiv_state *, CK_BYTE,
CK_BYTE_PTR, CK_BYTE_PTR, CK_BYTE_PTR, CK_ULONG, CK_ULONG); CK_BYTE_PTR, CK_ULONG,
CK_BYTE_PTR, CK_ULONG,
CK_BYTE_PTR, CK_ULONG,
CK_BYTE_PTR, CK_ULONG,
CK_BYTE_PTR, CK_ULONG,
CK_BYTE_PTR, CK_ULONG,
CK_ULONG);
typedef CK_RV (*t_delete_cert_f)(ykpiv_state *, CK_ULONG); typedef CK_RV (*t_delete_cert_f)(ykpiv_state *, CK_ULONG);
// TODO: replace all the common calls with functions defined in .c that use libykpiv // TODO: replace all the common calls with functions defined in .c that use libykpiv
+31 -8
View File
@@ -858,6 +858,13 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
CK_BYTE_PTR dp; CK_BYTE_PTR dp;
CK_BYTE_PTR dq; CK_BYTE_PTR dq;
CK_BYTE_PTR qinv; CK_BYTE_PTR qinv;
CK_ULONG p_len;
CK_ULONG q_len;
CK_ULONG dp_len;
CK_ULONG dq_len;
CK_ULONG qinv_len;
CK_BYTE_PTR ec_data;
CK_ULONG ec_data_len;
CK_ULONG vendor_defined; CK_ULONG vendor_defined;
token_vendor_t token; token_vendor_t token;
CK_BBOOL is_new; CK_BBOOL is_new;
@@ -980,11 +987,17 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
// Try to parse the key as EC // Try to parse the key as EC
is_rsa = CK_FALSE; is_rsa = CK_FALSE;
rv = check_create_ec_key(pTemplate, ulCount, &id, &value, &value_len, &vendor_defined); rv = check_create_ec_key(pTemplate, ulCount, &id, &ec_data, &ec_data_len, &vendor_defined);
if (rv != CKR_OK) { if (rv != CKR_OK) {
// Try to parse the key as RSA // Try to parse the key as RSA
is_rsa = CK_TRUE; is_rsa = CK_TRUE;
rv = check_create_rsa_key(pTemplate, ulCount, &id, &p, &q, &dp, &dq, &qinv, &value_len, &vendor_defined); rv = check_create_rsa_key(pTemplate, ulCount, &id,
&p, &p_len,
&q, &q_len,
&dp, &dp_len,
&dq, &dq_len,
&qinv, &qinv_len,
&vendor_defined);
if (rv != CKR_OK) { if (rv != CKR_OK) {
DBG("Private key template not valid"); DBG("Private key template not valid");
return rv; return rv;
@@ -997,9 +1010,14 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
if (is_rsa == CK_TRUE) { if (is_rsa == CK_TRUE) {
DBG("Key is RSA"); DBG("Key is RSA");
rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object), p, q, dp, dq, qinv, rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object),
NULL, p, p_len,
value_len, vendor_defined); q, q_len,
dp, dp_len,
dq, dq_len,
qinv, qinv_len,
NULL, 0,
vendor_defined);
if (rv != CKR_OK) { if (rv != CKR_OK) {
DBG("Unable to import RSA private key"); DBG("Unable to import RSA private key");
return rv; return rv;
@@ -1007,9 +1025,14 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
} }
else { else {
DBG("Key is ECDSA"); DBG("Key is ECDSA");
rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object), NULL, NULL, NULL, NULL, NULL, rv = token.token_import_private_key(piv_state, piv_2_ykpiv(object),
value, NULL, 0,
value_len, vendor_defined); NULL, 0,
NULL, 0,
NULL, 0,
NULL, 0,
ec_data, ec_data_len,
vendor_defined);
if (rv != CKR_OK) { if (rv != CKR_OK) {
DBG("Unable to import ECDSA private key"); DBG("Unable to import ECDSA private key");
return rv; return rv;