From 2a6acc5259f30cb95bcac21e706b74be47799c09 Mon Sep 17 00:00:00 2001 From: Alessio Di Mauro Date: Tue, 11 Aug 2015 16:28:59 +0200 Subject: [PATCH] Update object in the session after key creation (if object already exists). --- ykcs11/debug.h | 2 +- ykcs11/objects.c | 2 +- ykcs11/openssl_utils.c | 6 ++-- ykcs11/token_vendors.c | 2 -- ykcs11/ykcs11.c | 68 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 72 insertions(+), 8 deletions(-) diff --git a/ykcs11/debug.h b/ykcs11/debug.h index a89f49c..5debc5d 100644 --- a/ykcs11/debug.h +++ b/ykcs11/debug.h @@ -1,7 +1,7 @@ #ifndef DEBUG_H #define DEBUG_H -#define YKCS11_DBG 1 // General debug, must be either 1 or 0 +#define YKCS11_DBG 0 // General debug, must be either 1 or 0 #define YKCS11_DINOUT 0 // Function in/out debug, must be either 1 or 0 #define D(x) do { \ diff --git a/ykcs11/objects.c b/ykcs11/objects.c index a72c2cb..ba02f67 100644 --- a/ykcs11/objects.c +++ b/ykcs11/objects.c @@ -58,7 +58,7 @@ static piv_obj_t piv_objects[] = { {PIV_CERT_OBJ_X509_CARD_AUTH, 1, 0, 0, "X.509 Certificate for Card Authentication", 0, 0, get_coa, 1}, {PIV_CERT_OBJ_X509_DS, 1, 0, 0, "X.509 Certificate for Digital Signature", 0, 0, get_coa, 2}, {PIV_CERT_OBJ_X509_KM, 1, 0, 0, "X.509 Certificate for Key Management", 0, 0, get_coa, 3}, - {PIV_CERT_OBJ_LAST, 1, 0, 0, "", 0, 0, get_coa, 4}, + {PIV_CERT_OBJ_LAST, 1, 0, 0, "", 0, 0, NULL, 4}, {PIV_PVTK_OBJ_PIV_AUTH, 1, 1, 0, "Private key for PIV Authentication", 0, 0, get_proa, 0}, // 9a {PIV_PVTK_OBJ_CARD_AUTH, 1, 0, 0, "Private key for Card Authentication", 0, 0, get_proa, 1}, // 9e diff --git a/ykcs11/openssl_utils.c b/ykcs11/openssl_utils.c index cea47c8..3f2c9cf 100644 --- a/ykcs11/openssl_utils.c +++ b/ykcs11/openssl_utils.c @@ -115,13 +115,13 @@ CK_RV do_create_empty_cert(CK_BYTE_PTR in, CK_ULONG in_len, CK_BBOOL is_rsa, CK_ goto create_empty_cert_cleanup; // The curve point should always be 65 bytes - if(*data_ptr++ != 65) + if (*data_ptr++ != 65) goto create_empty_cert_cleanup; - if(EC_POINT_oct2point(ecg, ecp, data_ptr, 65, NULL) == 0) + if (EC_POINT_oct2point(ecg, ecp, data_ptr, 65, NULL) == 0) goto create_empty_cert_cleanup; - if(EC_KEY_set_public_key(eck, ecp) == 0) + if (EC_KEY_set_public_key(eck, ecp) == 0) goto create_empty_cert_cleanup; if (EVP_PKEY_set1_EC_KEY(key, eck) == 0) diff --git a/ykcs11/token_vendors.c b/ykcs11/token_vendors.c index 1571182..083aea2 100644 --- a/ykcs11/token_vendors.c +++ b/ykcs11/token_vendors.c @@ -78,8 +78,6 @@ static CK_RV COMMON_token_generate_key(ykpiv_state *state, CK_BBOOL rsa, CK_BYTE *certptr++ = 0xfe; /* LRC */ *certptr++ = 0; - dump_hex(data, (size_t)(certptr - data), stderr, CK_TRUE); - // Store the certificate into the token if (ykpiv_save_object(state, key_to_object_id(key), data, (size_t)(certptr - data)) != YKPIV_OK) return CKR_DEVICE_ERROR; diff --git a/ykcs11/ykcs11.c b/ykcs11/ykcs11.c index 1200018..57835d4 100644 --- a/ykcs11/ykcs11.c +++ b/ykcs11/ykcs11.c @@ -502,7 +502,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)( // Get the actual certificate data from the token and store it as an X509 object for (i = 0; i < session.slot->token->n_certs; i++) { - rv = token.get_token_raw_certificate(piv_state, cert_ids[i], cert_data, cert_len); + rv = token.get_token_raw_certificate(piv_state, cert_ids[i], cert_data, cert_len); // TODO: double check len here (check inside, never changed but used below) if (rv != CKR_OK) { DBG(("Unable to get certificate data from token")); goto failure; @@ -1589,6 +1589,18 @@ CK_DEFINE_FUNCTION(CK_RV, C_GenerateKeyPair)( DIN; CK_RV rv; token_vendor_t token; + CK_ULONG n_objs; + CK_ULONG n_certs; + CK_ULONG i; + CK_BBOOL is_new; + CK_ULONG dobj_id; + CK_ULONG cert_id; + CK_ULONG pvtk_id; + CK_ULONG pubk_id; + piv_obj_id_t *obj_ptr; + CK_BYTE cert_data[2100]; + CK_ULONG cert_len; + if (piv_state == NULL) { DBG(("libykpiv is not initialized or already finalized")); @@ -1671,6 +1683,60 @@ CK_DEFINE_FUNCTION(CK_RV, C_GenerateKeyPair)( return rv; } + rv = token.get_token_objects_num(piv_state, &n_objs, &n_certs); + if (rv != CKR_OK) { + DBG(("Unable to retrieve token objects")); + return rv; + } + DBG(("There were %lu objs and %lu certs, there are %lu objs and %lu certs", session.slot->token->n_objects, session.slot->token->n_certs, n_objs, n_certs)); + + is_new = CK_TRUE; + for (i = 0; i < session.slot->token->n_objects; i++) { + if (session.slot->token->objects[i] == op_info.op.gen.key_id) + is_new = CK_FALSE; + } + + dobj_id = op_info.op.gen.key_id - PIV_PVTK_OBJ_PIV_AUTH; // TODO: make function for these + cert_id = PIV_DATA_OBJ_LAST + 1 + dobj_id; + pvtk_id = op_info.op.gen.key_id; + pubk_id = PIV_PVTK_OBJ_LAST + 1 + dobj_id; + + // Check whether we created a new object or updated an existing one + if (is_new == CK_TRUE) { + // New object created + DBG(("OBJECT NOT FOUND!")); + } + else { + // Updated old object + cert_len = sizeof(cert_data); + rv = token.get_token_raw_certificate(piv_state, cert_id, cert_data, cert_len); // TODO: double check len here (check inside, never changed but used below). One more time above + if (rv != CKR_OK) { + DBG(("Unable to get certificate data from token")); + return CKR_FUNCTION_FAILED; // TODO: although key generation succeeded at this point + } + + rv = store_cert(cert_id, cert_data, cert_len); + if (rv != CKR_OK) { + DBG(("Unable to store certificate data")); + return CKR_FUNCTION_FAILED; // TODO: although key generation succeeded at this point + } + + /*session.slot->token->n_objects += 4; + session.slot->token->n_certs++; + + obj_ptr = realloc(session.slot->token->objects, session.slot->token->n_objects * sizeof(piv_obj_id_t)); + if (obj_ptr == NULL) { + DBG(("Unable to store new item in the session")); + return CKR_HOST_MEMORY; + } + + obj_ptr = session.slot->token->objects + session.slot->token->n_objects - 4; + *obj_ptr++ = dobj_id; + *obj_ptr++ = cert_id; + *obj_ptr++ = pvtk_id; + *obj_ptr++ = pubk_id;*/ + } + *phPrivateKey = op_info.op.gen.key_id; *phPublicKey = op_info.op.gen.key_id - PIV_PVTK_OBJ_KM + PIV_PUBK_OBJ_KM; // TODO: make function for these?