YKCS11: added certificate deletion.
This commit is contained in:
@@ -1012,6 +1012,22 @@ CK_RV store_cert(piv_obj_id_t cert_id, CK_BYTE_PTR data, CK_ULONG len) {
|
|||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CK_RV delete_cert(piv_obj_id_t cert_id) {
|
||||||
|
CK_RV rv;
|
||||||
|
|
||||||
|
// Clear the object containing the certificate
|
||||||
|
rv = do_delete_cert(&cert_objects[piv_objects[cert_id].sub_id].data);
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
// Clear the object containing the public key
|
||||||
|
rv = do_delete_pubk(&pubkey_objects[piv_objects[cert_id].sub_id].data);
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
CK_RV check_create_cert(CK_ATTRIBUTE_PTR templ, CK_ULONG n,
|
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 id, CK_BYTE_PTR *value, CK_ULONG_PTR cert_len) {
|
||||||
|
|
||||||
@@ -1263,3 +1279,13 @@ CK_RV check_create_rsa_key(CK_ATTRIBUTE_PTR templ, CK_ULONG n, CK_BYTE_PTR id,
|
|||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CK_RV check_delete_cert(CK_OBJECT_HANDLE hObject, CK_BYTE_PTR id) {
|
||||||
|
|
||||||
|
if (hObject < PIV_CERT_OBJ_X509_PIV_AUTH || hObject >= PIV_CERT_OBJ_LAST)
|
||||||
|
return CKR_ACTION_PROHIBITED;
|
||||||
|
|
||||||
|
*id = hObject - PIV_CERT_OBJ_X509_PIV_AUTH;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
}
|
||||||
|
|||||||
+2
-1
@@ -11,6 +11,7 @@ CK_BBOOL is_private_object(ykcs11_session_t *s, CK_OBJECT_HANDLE obj);
|
|||||||
|
|
||||||
CK_RV get_available_certificate_ids(ykcs11_session_t *s, piv_obj_id_t *cert_ids, CK_ULONG n_certs);
|
CK_RV get_available_certificate_ids(ykcs11_session_t *s, piv_obj_id_t *cert_ids, CK_ULONG n_certs);
|
||||||
CK_RV store_cert(piv_obj_id_t cert_id, CK_BYTE_PTR data, CK_ULONG len);
|
CK_RV store_cert(piv_obj_id_t cert_id, CK_BYTE_PTR data, CK_ULONG len);
|
||||||
|
CK_RV delete_cert(piv_obj_id_t cert_id);
|
||||||
|
|
||||||
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);
|
||||||
@@ -19,6 +20,6 @@ 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_ULONG_PTR vendor_defined);
|
CK_BYTE_PTR *dq, CK_BYTE_PTR *qinv, CK_ULONG_PTR value_len, CK_ULONG_PTR vendor_defined);
|
||||||
|
CK_RV check_delete_cert(CK_OBJECT_HANDLE hObject, CK_BYTE_PTR id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+22
-4
@@ -256,12 +256,21 @@ CK_RV do_get_raw_cert(X509 *cert, CK_BYTE_PTR out, CK_ULONG_PTR out_len) {
|
|||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV free_cert(X509 *cert) {
|
CK_RV do_delete_cert(X509 **cert) {
|
||||||
|
|
||||||
|
X509_free(*cert);
|
||||||
|
cert = NULL;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*CK_RV free_cert(X509 *cert) {
|
||||||
|
|
||||||
X509_free((X509 *) cert);
|
X509_free((X509 *) cert);
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
CK_RV do_store_pubk(X509 *cert, EVP_PKEY **key) {
|
CK_RV do_store_pubk(X509 *cert, EVP_PKEY **key) {
|
||||||
@@ -438,13 +447,22 @@ CK_RV do_get_curve_parameters(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len)
|
|||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV free_key(EVP_PKEY *key) {
|
CK_RV do_delete_pubk(EVP_PKEY **key) {
|
||||||
|
|
||||||
|
EVP_PKEY_free(*key);
|
||||||
|
key = NULL;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*CK_RV free_key(EVP_PKEY *key) {
|
||||||
|
|
||||||
EVP_PKEY_free(key);
|
EVP_PKEY_free(key);
|
||||||
|
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
||||||
CK_RV do_pkcs_1_t1(CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len, CK_ULONG key_len) {
|
CK_RV do_pkcs_1_t1(CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len, CK_ULONG key_len) {
|
||||||
unsigned char buffer[512];
|
unsigned char buffer[512];
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ 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 do_get_raw_cert(X509 *cert, CK_BYTE_PTR out, CK_ULONG_PTR out_len);
|
||||||
CK_RV free_cert(X509 *cert);
|
CK_RV do_delete_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);
|
||||||
CK_KEY_TYPE do_get_key_type(EVP_PKEY *key);
|
CK_KEY_TYPE do_get_key_type(EVP_PKEY *key);
|
||||||
@@ -23,7 +24,8 @@ CK_ULONG do_get_public_exponent(EVP_PKEY *key);
|
|||||||
CK_RV do_get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
CK_RV do_get_public_key(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
||||||
CK_RV do_encode_rsa_public_key(CK_BYTE_PTR data, CK_ULONG len, RSA **key);
|
CK_RV do_encode_rsa_public_key(CK_BYTE_PTR data, CK_ULONG len, RSA **key);
|
||||||
CK_RV do_get_curve_parameters(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
CK_RV do_get_curve_parameters(EVP_PKEY *key, CK_BYTE_PTR data, CK_ULONG_PTR len);
|
||||||
CK_RV free_key(EVP_PKEY *key);
|
CK_RV do_delete_pubk(EVP_PKEY **key);
|
||||||
|
//CK_RV free_key(EVP_PKEY *key);
|
||||||
|
|
||||||
CK_RV do_pkcs_1_t1(CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len, CK_ULONG key_len);
|
CK_RV do_pkcs_1_t1(CK_BYTE_PTR in, CK_ULONG in_len, CK_BYTE_PTR out, CK_ULONG_PTR out_len, CK_ULONG key_len);
|
||||||
CK_RV do_pkcs_1_digest_info(CK_BYTE_PTR in, CK_ULONG in_len, int nid, CK_BYTE_PTR out, CK_ULONG_PTR out_len);
|
CK_RV do_pkcs_1_digest_info(CK_BYTE_PTR in, CK_ULONG in_len, int nid, CK_BYTE_PTR out, CK_ULONG_PTR out_len);
|
||||||
|
|||||||
@@ -755,6 +755,8 @@ typedef CK_ULONG CK_RV;
|
|||||||
#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL
|
#define CKR_ATTRIBUTE_SENSITIVE 0x00000011UL
|
||||||
#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL
|
#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012UL
|
||||||
#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL
|
#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013UL
|
||||||
|
#define CKR_COPY_PROHIBITED 0x0000001AUL
|
||||||
|
#define CKR_ACTION_PROHIBITED 0x0000001BUL
|
||||||
#define CKR_DATA_INVALID 0x00000020UL
|
#define CKR_DATA_INVALID 0x00000020UL
|
||||||
#define CKR_DATA_LEN_RANGE 0x00000021UL
|
#define CKR_DATA_LEN_RANGE 0x00000021UL
|
||||||
#define CKR_DEVICE_ERROR 0x00000030UL
|
#define CKR_DEVICE_ERROR 0x00000030UL
|
||||||
|
|||||||
@@ -257,6 +257,14 @@ CK_RV COMMON_token_import_private_key(ykpiv_state *state, CK_BYTE key_id, CK_BYT
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CK_RV COMMON_token_delete_cert(ykpiv_state *state, CK_ULONG cert_id) {
|
||||||
|
|
||||||
|
if (ykpiv_save_object(state, cert_id, NULL, 0) != YKPIV_OK)
|
||||||
|
return CKR_DEVICE_ERROR;
|
||||||
|
|
||||||
|
return CKR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@@ -278,6 +286,7 @@ token_vendor_t get_token_vendor(vendor_id_t vid) {
|
|||||||
v.token_generate_key = COMMON_token_generate_key;
|
v.token_generate_key = COMMON_token_generate_key;
|
||||||
v.token_import_cert = COMMON_token_import_cert;
|
v.token_import_cert = COMMON_token_import_cert;
|
||||||
v.token_import_private_key = COMMON_token_import_private_key;
|
v.token_import_private_key = COMMON_token_import_private_key;
|
||||||
|
v.token_delete_cert = COMMON_token_delete_cert;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
@@ -298,6 +307,7 @@ token_vendor_t get_token_vendor(vendor_id_t vid) {
|
|||||||
v.token_generate_key = NULL;
|
v.token_generate_key = NULL;
|
||||||
v.token_import_cert = NULL;
|
v.token_import_cert = NULL;
|
||||||
v.token_import_private_key = NULL;
|
v.token_import_private_key = NULL;
|
||||||
|
v.token_delete_cert = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ typedef CK_RV (*t_generate_key_f)(ykpiv_state *, CK_BBOOL, CK_BYTE, CK_ULONG, CK
|
|||||||
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_ULONG);
|
CK_BYTE_PTR, CK_BYTE_PTR, CK_BYTE_PTR, CK_ULONG, 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
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ typedef struct {
|
|||||||
t_generate_key_f token_generate_key;
|
t_generate_key_f token_generate_key;
|
||||||
t_import_cert_f token_import_cert;
|
t_import_cert_f token_import_cert;
|
||||||
t_import_private_key_f token_import_private_key;
|
t_import_private_key_f token_import_private_key;
|
||||||
|
t_delete_cert_f token_delete_cert;
|
||||||
} token_vendor_t;
|
} token_vendor_t;
|
||||||
|
|
||||||
token_vendor_t get_token_vendor(vendor_id_t vid);
|
token_vendor_t get_token_vendor(vendor_id_t vid);
|
||||||
|
|||||||
+87
-1
@@ -1044,7 +1044,93 @@ CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject)(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
DIN;
|
DIN;
|
||||||
DBG(("TODO!!!"));
|
|
||||||
|
CK_RV rv;
|
||||||
|
token_vendor_t token;
|
||||||
|
CK_ULONG i;
|
||||||
|
CK_ULONG j;
|
||||||
|
CK_BYTE id;
|
||||||
|
CK_ULONG cert_id;
|
||||||
|
CK_ULONG pvtk_id;
|
||||||
|
CK_ULONG pubk_id;
|
||||||
|
piv_obj_id_t *obj_ptr;
|
||||||
|
|
||||||
|
DBG(("Deleting object %lu", hObject));
|
||||||
|
|
||||||
|
if (piv_state == NULL) {
|
||||||
|
DBG(("libykpiv is not initialized or already finalized"));
|
||||||
|
return CKR_CRYPTOKI_NOT_INITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session.handle != YKCS11_SESSION_ID) {
|
||||||
|
DBG(("Session is not open"));
|
||||||
|
return CKR_SESSION_CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hSession != session.handle) {
|
||||||
|
DBG(("Unknown session %lu", hSession));
|
||||||
|
return CKR_SESSION_HANDLE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only certificates can be deleted
|
||||||
|
// SO must be logged in
|
||||||
|
if (session.info.state != CKS_RW_SO_FUNCTIONS) {
|
||||||
|
DBG(("Unable to delete objects, SO must be logged in"));
|
||||||
|
return CKR_ACTION_PROHIBITED;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = check_delete_cert(hObject, &id);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
DBG(("Object %lu can not be deleted", hObject));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
token = get_token_vendor(session.slot->token->vid);
|
||||||
|
|
||||||
|
rv = token.token_delete_cert(piv_state, piv_2_ykpiv(hObject));
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
DBG(("Unable to delete object %lu", hObject));
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the object from the session
|
||||||
|
// Do it in a slightly inefficient way but preserve ordering
|
||||||
|
|
||||||
|
cert_id = PIV_CERT_OBJ_X509_PIV_AUTH + id; // TODO: make function for these
|
||||||
|
pvtk_id = PIV_PVTK_OBJ_PIV_AUTH + id;
|
||||||
|
pubk_id = PIV_PUBK_OBJ_PIV_AUTH + id;
|
||||||
|
|
||||||
|
obj_ptr = malloc((session.slot->token->n_objects - 3) * sizeof(piv_obj_id_t));
|
||||||
|
if (obj_ptr == NULL) {
|
||||||
|
DBG(("Unable to allocate memory"));
|
||||||
|
return CKR_HOST_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
j = 0;
|
||||||
|
while (i < session.slot->token->n_objects) {
|
||||||
|
if (session.slot->token->objects[i] == cert_id ||
|
||||||
|
session.slot->token->objects[i] == pvtk_id ||
|
||||||
|
session.slot->token->objects[i] == pubk_id) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj_ptr[j++] = session.slot->token->objects[i++];
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = delete_cert(cert_id);
|
||||||
|
if (rv != CKR_OK) {
|
||||||
|
DBG(("Unable to delete certificate data"));
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(session.slot->token->objects);
|
||||||
|
|
||||||
|
session.slot->token->n_objects -= 3;
|
||||||
|
session.slot->token->n_certs--;
|
||||||
|
session.slot->token->objects = obj_ptr;
|
||||||
|
|
||||||
DOUT;
|
DOUT;
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user