Merge branch 'development' of gitlab.yubico.com:Yubico/yubico-piv-tool into development

This commit is contained in:
Klas Lindfors
2015-10-28 16:08:12 +01:00
11 changed files with 162 additions and 56 deletions
+7 -2
View File
@@ -163,6 +163,7 @@ CK_RV apply_sign_mechanism_init(op_info_t *op_info) {
case CKM_RSA_X_509: case CKM_RSA_X_509:
case CKM_ECDSA: case CKM_ECDSA:
// No hash required for this mechanism // No hash required for this mechanism
op_info->op.sign.md_ctx = NULL;
return CKR_OK; return CKR_OK;
case CKM_SHA1_RSA_PKCS: case CKM_SHA1_RSA_PKCS:
@@ -419,7 +420,7 @@ CK_RV check_pubkey_template(op_info_t *op_info, CK_ATTRIBUTE_PTR templ, CK_ULONG
default: default:
DBG(("Invalid attribute %lx in public key template", templ[i].type)); DBG(("Invalid attribute %lx in public key template", templ[i].type));
return CKR_ATTRIBUTE_VALUE_INVALID; return CKR_ATTRIBUTE_TYPE_INVALID;
} }
} }
@@ -432,6 +433,7 @@ CK_RV check_pvtkey_template(op_info_t *op_info, CK_ATTRIBUTE_PTR templ, CK_ULONG
CK_ULONG i; CK_ULONG i;
op_info->op.gen.rsa = is_RSA_mechanism(op_info->mechanism.mechanism); op_info->op.gen.rsa = is_RSA_mechanism(op_info->mechanism.mechanism);
op_info->op.gen.vendor_defined = 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
switch (templ[i].type) { switch (templ[i].type) {
@@ -472,6 +474,9 @@ CK_RV check_pvtkey_template(op_info_t *op_info, CK_ATTRIBUTE_PTR templ, CK_ULONG
op_info->op.gen.key_id = PIV_PVTK_OBJ_PIV_AUTH + *((CK_BYTE_PTR)templ[i].pValue); op_info->op.gen.key_id = PIV_PVTK_OBJ_PIV_AUTH + *((CK_BYTE_PTR)templ[i].pValue);
break; break;
case CKA_VENDOR_DEFINED:
op_info->op.gen.vendor_defined = (*((CK_ULONG_PTR)templ[i].pValue));
case CKA_SENSITIVE: case CKA_SENSITIVE:
case CKA_DECRYPT: case CKA_DECRYPT:
case CKA_UNWRAP: case CKA_UNWRAP:
@@ -484,7 +489,7 @@ CK_RV check_pvtkey_template(op_info_t *op_info, CK_ATTRIBUTE_PTR templ, CK_ULONG
default: default:
DBG(("Invalid attribute %lx in private key template", templ[i].type)); DBG(("Invalid attribute %lx in private key template", templ[i].type));
return CKR_ATTRIBUTE_VALUE_INVALID; return CKR_ATTRIBUTE_TYPE_INVALID;
} }
} }
+46 -25
View File
@@ -233,6 +233,10 @@ static CK_RV get_curve_parameters(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR
return do_get_curve_parameters(key, data, len); return do_get_curve_parameters(key, data, len);
} }
static CK_RV get_raw_cert(X509 *cert, CK_BYTE_PTR data, CK_ULONG_PTR len) {
return do_get_raw_cert(cert, data, len);
}
/* Get data object attribute */ /* Get data object attribute */
CK_RV get_doa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { CK_RV get_doa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
CK_BYTE_PTR data; CK_BYTE_PTR data;
@@ -319,31 +323,32 @@ CK_RV get_doa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
/* Get certificate object attribute */ /* Get certificate object attribute */
CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
CK_BYTE_PTR data; CK_BYTE_PTR data;
CK_BYTE tmp[64]; CK_BYTE b_tmp[1024];
CK_ULONG ul_tmp;
CK_ULONG len = 0; CK_ULONG len = 0;
DBG(("For certificate object %lu, get ", obj)); DBG(("For certificate object %lu, get ", obj));
switch (template->type) { // TODO: is this needed here? or is it enough ot have one a "level" above? switch (template->type) {
case CKA_CLASS: case CKA_CLASS:
DBG(("CLASS")); DBG(("CLASS"));
len = 1; len = sizeof(CK_ULONG);
tmp[0] = CKO_CERTIFICATE; ul_tmp = CKO_CERTIFICATE;
data = tmp; data = (CK_BYTE_PTR) &ul_tmp;
break; break;
case CKA_TOKEN: case CKA_TOKEN:
// Technically all these objects are token objects // Technically all these objects are token objects
DBG(("TOKEN")); DBG(("TOKEN"));
len = 1; len = sizeof(CK_BBOOL);
tmp[0] = piv_objects[obj].token; b_tmp[0] = piv_objects[obj].token;
data = tmp; data = b_tmp;
break; break;
case CKA_PRIVATE: case CKA_PRIVATE:
DBG(("PRIVATE")); DBG(("PRIVATE"));
len = 1; len = sizeof(CK_BBOOL);
tmp[0] = piv_objects[obj].private; b_tmp[0] = piv_objects[obj].private;
data = tmp; data = b_tmp;
break; break;
case CKA_LABEL: case CKA_LABEL:
@@ -353,14 +358,18 @@ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
break; break;
case CKA_VALUE: case CKA_VALUE:
DBG(("VALUE TODO")); DBG(("VALUE"));
return CKR_FUNCTION_FAILED; len = sizeof(b_tmp);
if (get_raw_cert(cert_objects[piv_objects[obj].sub_id].data, b_tmp, &len) != CKR_OK)
return CKR_FUNCTION_FAILED;
data = b_tmp;
break;
case CKA_CERTIFICATE_TYPE: case CKA_CERTIFICATE_TYPE:
DBG(("CERTIFICATE TYPE")); DBG(("CERTIFICATE TYPE"));
len = 1; len = sizeof(CK_ULONG);
tmp[0] = CKC_X_509; // Support only X.509 certs ul_tmp = CKC_X_509; // Support only X.509 certs
data = tmp; data = (CK_BYTE_PTR) ul_tmp;
break; break;
case CKA_ISSUER: case CKA_ISSUER:
@@ -377,9 +386,9 @@ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
case CKA_ID: case CKA_ID:
DBG(("ID")); DBG(("ID"));
len = 1; len = sizeof(CK_BYTE);
tmp[0] = piv_objects[obj].sub_id; b_tmp[0] = piv_objects[obj].sub_id;
data = tmp; data = b_tmp;
break; break;
case CKA_START_DATE: case CKA_START_DATE:
@@ -392,9 +401,9 @@ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
case CKA_MODIFIABLE: case CKA_MODIFIABLE:
DBG(("MODIFIABLE")); DBG(("MODIFIABLE"));
len = 1; len = sizeof(CK_BBOOL);
tmp[0] = piv_objects[obj].modifiable; b_tmp[0] = piv_objects[obj].modifiable;
data = tmp; data = b_tmp;
break; break;
default: // TODO: there are other attributes for a (x509) certificate default: // TODO: there are other attributes for a (x509) certificate
@@ -666,7 +675,7 @@ CK_RV get_proa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
CK_RV get_puoa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { CK_RV get_puoa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) {
CK_BYTE_PTR data; CK_BYTE_PTR data;
CK_BYTE b_tmp[1024]; CK_BYTE b_tmp[1024];
CK_ULONG ul_tmp; // TODO: fix elsewhere too CK_ULONG ul_tmp;
CK_ULONG len = 0; CK_ULONG len = 0;
DBG(("For public key object %lu, get ", obj)); DBG(("For public key object %lu, get ", obj));
@@ -1054,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_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_ULONG i;
CK_BBOOL has_id = CK_FALSE; CK_BBOOL has_id = CK_FALSE;
@@ -1064,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_BYTE_PTR ec_params;
CK_ULONG ec_params_len; CK_ULONG ec_params_len;
*vendor_defined = 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
switch (templ[i].type) { switch (templ[i].type) {
case CKA_CLASS: case CKA_CLASS:
@@ -1099,6 +1110,10 @@ CK_RV check_create_ec_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
break; break;
case CKA_VENDOR_DEFINED:
*vendor_defined = *((CK_ULONG_PTR)templ[i].pValue);
break;
case CKA_TOKEN: case CKA_TOKEN:
case CKA_LABEL: case CKA_LABEL:
case CKA_SUBJECT: case CKA_SUBJECT:
@@ -1129,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_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_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_ULONG i;
CK_BBOOL has_id = CK_FALSE; CK_BBOOL has_id = CK_FALSE;
@@ -1145,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 dq_len;
CK_ULONG qinv_len; CK_ULONG qinv_len;
*vendor_defined = 0;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
switch (templ[i].type) { switch (templ[i].type) {
case CKA_CLASS: case CKA_CLASS:
@@ -1208,6 +1225,10 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
break; break;
case CKA_VENDOR_DEFINED:
*vendor_defined = *((CK_ULONG_PTR)templ[i].pValue);
break;
case CKA_TOKEN: case CKA_TOKEN:
case CKA_LABEL: case CKA_LABEL:
case CKA_SUBJECT: case CKA_SUBJECT:
+2 -2
View File
@@ -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_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_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_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_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_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 #endif
+20
View File
@@ -236,6 +236,26 @@ CK_RV do_check_cert(CK_BYTE_PTR in, CK_ULONG_PTR cert_len) {
return CKR_OK; return CKR_OK;
} }
CK_RV do_get_raw_cert(X509 *cert, CK_BYTE_PTR out, CK_ULONG_PTR out_len) {
CK_BYTE_PTR p;
int len;
len = i2d_X509(cert, NULL);
if (len < 0)
return CKR_FUNCTION_FAILED;
if ((CK_ULONG)len > *out_len)
return CKR_BUFFER_TOO_SMALL;
p = out;
if ((*out_len = i2d_X509(cert, &p)) == 0)
return CKR_FUNCTION_FAILED;
return CKR_OK;
}
CK_RV free_cert(X509 *cert) { CK_RV free_cert(X509 *cert) {
X509_free((X509 *) cert); X509_free((X509 *) cert);
+1
View File
@@ -13,6 +13,7 @@ CK_RV do_store_cert(CK_BYTE_PTR data, CK_ULONG len, X509 **cert);
CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa, CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa,
CK_BYTE_PTR out, CK_ULONG_PTR out_len); CK_BYTE_PTR out, CK_ULONG_PTR out_len);
CK_RV do_check_cert(CK_BYTE_PTR in, CK_ULONG_PTR cert_len); CK_RV do_check_cert(CK_BYTE_PTR in, CK_ULONG_PTR cert_len);
CK_RV do_get_raw_cert(X509 *cert, CK_BYTE_PTR out, CK_ULONG_PTR out_len);
CK_RV free_cert(X509 *cert); CK_RV free_cert(X509 *cert);
CK_RV do_store_pubk(X509 *cert, EVP_PKEY **key); CK_RV do_store_pubk(X509 *cert, EVP_PKEY **key);
+7
View File
@@ -1183,4 +1183,11 @@ typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
/* undo packing */ /* undo packing */
//#include "pkcs11u.h" // TODO: msc specific? //#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 #endif
+62 -15
View File
@@ -4,6 +4,9 @@
#include <string.h> #include <string.h>
#include "debug.h" #include "debug.h"
#include <stdbool.h>
#include "../tool/util.h"
static CK_RV COMMON_token_login(ykpiv_state *state, CK_USER_TYPE user, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) { static CK_RV COMMON_token_login(ykpiv_state *state, CK_USER_TYPE user, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) {
int tries = 0; // TODO: this is effectively disregarded, should we add a better value in ykpiv_verify? int tries = 0; // TODO: this is effectively disregarded, should we add a better value in ykpiv_verify?
@@ -31,9 +34,11 @@ static CK_RV COMMON_token_login(ykpiv_state *state, CK_USER_TYPE user, CK_UTF8CH
return CKR_OK; return CKR_OK;
} }
static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE key, CK_ULONG key_len) { static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa,
CK_BYTE key, CK_ULONG key_len, CK_ULONG vendor_defined) {
// TODO: make a function in ykpiv for this // TODO: make a function in ykpiv for this
unsigned char in_data[5]; unsigned char in_data[11];
unsigned char *in_ptr = in_data;
unsigned char data[1024]; unsigned char data[1024];
unsigned char templ[] = {0, YKPIV_INS_GENERATE_ASYMMERTRIC, 0, 0}; unsigned char templ[] = {0, YKPIV_INS_GENERATE_ASYMMERTRIC, 0, 0};
unsigned char *certptr; unsigned char *certptr;
@@ -45,10 +50,10 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE
templ[3] = key; templ[3] = key;
in_data[0] = 0xac; *in_ptr++ = 0xac;
in_data[1] = 3; *in_ptr++ = 3;
in_data[2] = 0x80; *in_ptr++ = 0x80;
in_data[3] = 1; *in_ptr++ = 1;
switch(key_len) { switch(key_len) {
case 2048: case 2048:
@@ -61,7 +66,7 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE
case 1024: case 1024:
if (rsa == CK_TRUE) if (rsa == CK_TRUE)
in_data[4] = YKPIV_ALGO_RSA1024; *in_ptr++ = YKPIV_ALGO_RSA1024;
else else
return CKR_FUNCTION_FAILED; return CKR_FUNCTION_FAILED;
@@ -69,7 +74,7 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE
case 256: case 256:
if (rsa == CK_FALSE) if (rsa == CK_FALSE)
in_data[4] = YKPIV_ALGO_ECCP256; *in_ptr++ = YKPIV_ALGO_ECCP256;
else else
return CKR_FUNCTION_FAILED; return CKR_FUNCTION_FAILED;
@@ -78,8 +83,30 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE
default: default:
return CKR_FUNCTION_FAILED; return CKR_FUNCTION_FAILED;
} }
//DBG(("Generating key %x with algorithm %u and length %lu", templ[3], in_data[4], key_len)); // PIN policy and touch
if(ykpiv_transfer_data(state, templ, in_data, sizeof(in_data), data, &recv_len, &sw) != YKPIV_OK || if (vendor_defined != 0) {
if (vendor_defined & CKA_PIN_ONCE) {
in_data[1] += 3;
*in_ptr++ = YKPIV_PINPOLICY_TAG;
*in_ptr++ = 0x01;
*in_ptr++ = YKPIV_PINPOLICY_ONCE;
}
else if (vendor_defined & CKA_PIN_ALWAYS) {
in_data[1] += 3;
*in_ptr++ = YKPIV_PINPOLICY_TAG;
*in_ptr++ = 0x01;
*in_ptr++ = YKPIV_PINPOLICY_ALWAYS;
}
if (vendor_defined & CKA_TOUCH_ALWAYS) {
in_data[1] += 3;
*in_ptr++ = YKPIV_TOUCHPOLICY_TAG;
*in_ptr++ = 0x01;
*in_ptr++ = YKPIV_TOUCHPOLICY_ALWAYS;
}
}
if(ykpiv_transfer_data(state, templ, in_data, in_ptr - in_data, data, &recv_len, &sw) != YKPIV_OK ||
sw != 0x9000) sw != 0x9000)
return CKR_DEVICE_ERROR; return CKR_DEVICE_ERROR;
@@ -151,7 +178,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_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 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 key_data[1024];
unsigned char *in_ptr = key_data; unsigned char *in_ptr = key_data;
@@ -193,17 +220,37 @@ CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id, CK_BYT
memcpy(in_ptr, qinv, (size_t)(elem_len)); memcpy(in_ptr, qinv, (size_t)(elem_len));
in_ptr += elem_len; in_ptr += elem_len;
} }
else if(templ[2] == YKPIV_ALGO_ECCP256) { else if (templ[2] == YKPIV_ALGO_ECCP256) {
*in_ptr++ = 0x06; *in_ptr++ = 0x06;
in_ptr += set_length(in_ptr, elem_len); in_ptr += set_length(in_ptr, elem_len);
memcpy(in_ptr, ec_data, (size_t)(elem_len)); memcpy(in_ptr, ec_data, (size_t)(elem_len));
in_ptr += elem_len; in_ptr += elem_len;
} }
if(ykpiv_transfer_data(state, templ, key_data, in_ptr - key_data, data, &recv_len, &sw) != YKPIV_OK) // 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) if (sw != 0x9000)
return CKR_DEVICE_ERROR; return CKR_DEVICE_ERROR;
return CKR_OK; return CKR_OK;
@@ -211,7 +258,7 @@ CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id, CK_BYT
} }
token_vendor_t get_token_vendor(vendor_id_t vid) { token_vendor_t get_token_vendor(vendor_id_t vid) {
token_vendor_t v; token_vendor_t v;
switch (vid) { switch (vid) {
case YUBICO: case YUBICO:
+2 -2
View File
@@ -21,10 +21,10 @@ typedef CK_RV (*get_t_raw_certificate_f)(ykpiv_state *, piv_obj_id_t, CK_BYTE_PT
// Common token functions below // Common token functions below
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); 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_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 // TODO: replace all the common calls with functions defined in .c that use libykpiv
+9 -5
View File
@@ -10,6 +10,9 @@
#include "openssl_types.h" #include "openssl_types.h"
#include "debug.h" #include "debug.h"
#include <stdbool.h>
#include "../tool/util.h"
#define YKCS11_MANUFACTURER "Yubico (www.yubico.com)" #define YKCS11_MANUFACTURER "Yubico (www.yubico.com)"
#define YKCS11_LIBDESC "PKCS#11 PIV Library (SP-800-73)" #define YKCS11_LIBDESC "PKCS#11 PIV Library (SP-800-73)"
@@ -854,6 +857,7 @@ 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 vendor_defined;
token_vendor_t token; token_vendor_t token;
CK_BBOOL is_new; CK_BBOOL is_new;
CK_BBOOL is_rsa; CK_BBOOL is_rsa;
@@ -974,11 +978,11 @@ 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); rv = check_create_ec_key(pTemplate, ulCount, &id, &value, &value_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); rv = check_create_rsa_key(pTemplate, ulCount, &id, &p, &q, &dp, &dq, &qinv, &value_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;
@@ -993,7 +997,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
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), p, q, dp, dq, qinv,
NULL, NULL,
value_len); value_len, 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;
@@ -1003,7 +1007,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)(
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), NULL, NULL, NULL, NULL, NULL,
value, value,
value_len); value_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;
@@ -2052,7 +2056,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_GenerateKeyPair)(
token = get_token_vendor(session.slot->token->vid); token = get_token_vendor(session.slot->token->vid);
if ((rv = token.token_generate_key(piv_state, op_info.op.gen.rsa, piv_2_ykpiv(op_info.op.gen.key_id), op_info.op.gen.key_len)) != CKR_OK) { if ((rv = token.token_generate_key(piv_state, op_info.op.gen.rsa, piv_2_ykpiv(op_info.op.gen.key_id), op_info.op.gen.key_len, op_info.op.gen.vendor_defined)) != CKR_OK) {
DBG(("Unable to generate key pair")); DBG(("Unable to generate key pair"));
return rv; return rv;
} }
+5 -5
View File
@@ -6,7 +6,7 @@
#include "openssl_types.h" #include "openssl_types.h"
#include "vendors.h" #include "vendors.h"
#define YKCS11_OP_BUFSIZE 4096 #define YKCS11_OP_BUFSIZE 4096
typedef struct { typedef struct {
vendor_id_t vid; vendor_id_t vid;
@@ -28,7 +28,6 @@ typedef struct {
ykcs11_slot_t *slot; ykcs11_slot_t *slot;
} ykcs11_session_t; } ykcs11_session_t;
typedef enum { typedef enum {
YKCS11_NOOP, YKCS11_NOOP,
YKCS11_GEN, YKCS11_GEN,
@@ -38,9 +37,10 @@ typedef enum {
} ykcs11_op_type_t; } ykcs11_op_type_t;
typedef struct { typedef struct {
CK_BBOOL rsa; // RSA or EC key CK_BBOOL rsa; // RSA or EC key
CK_BYTE key_id; // Key id CK_BYTE key_id; // Key id
CK_ULONG key_len; // Length in bits CK_ULONG key_len; // Length in bits
CK_ULONG vendor_defined; // Additional parameters (touch and PIN policy)
} gen_info_t; } gen_info_t;
typedef struct { typedef struct {
+1
View File
@@ -2,6 +2,7 @@
#include "pkcs11.h" #include "pkcs11.h"
#include <string.h> #include <string.h>
#include "debug.h" #include "debug.h"
#include "objects.h"
#define YUBICO_MECHANISMS_NUM 5 #define YUBICO_MECHANISMS_NUM 5