From 4f12dc41e9107169871ce719f7354c3df70b7e27 Mon Sep 17 00:00:00 2001 From: Alessio Di Mauro Date: Fri, 23 Oct 2015 19:43:36 +0200 Subject: [PATCH] YKCS11: Added raw certificate extraction. --- ykcs11/objects.c | 55 ++++++++++++++++++++++++------------------ ykcs11/openssl_utils.c | 20 +++++++++++++++ ykcs11/openssl_utils.h | 1 + 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/ykcs11/objects.c b/ykcs11/objects.c index 3767ca9..fa7f09b 100644 --- a/ykcs11/objects.c +++ b/ykcs11/objects.c @@ -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); } +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 */ CK_RV get_doa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { CK_BYTE_PTR data; @@ -319,31 +323,32 @@ CK_RV get_doa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { /* Get certificate object attribute */ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { CK_BYTE_PTR data; - CK_BYTE tmp[64]; + CK_BYTE b_tmp[1024]; + CK_ULONG ul_tmp; CK_ULONG len = 0; 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: DBG(("CLASS")); - len = 1; - tmp[0] = CKO_CERTIFICATE; - data = tmp; + len = sizeof(CK_ULONG); + ul_tmp = CKO_CERTIFICATE; + data = (CK_BYTE_PTR) &ul_tmp; break; case CKA_TOKEN: // Technically all these objects are token objects DBG(("TOKEN")); - len = 1; - tmp[0] = piv_objects[obj].token; - data = tmp; + len = sizeof(CK_BBOOL); + b_tmp[0] = piv_objects[obj].token; + data = b_tmp; break; case CKA_PRIVATE: DBG(("PRIVATE")); - len = 1; - tmp[0] = piv_objects[obj].private; - data = tmp; + len = sizeof(CK_BBOOL); + b_tmp[0] = piv_objects[obj].private; + data = b_tmp; break; case CKA_LABEL: @@ -353,14 +358,18 @@ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { break; case CKA_VALUE: - DBG(("VALUE TODO")); - return CKR_FUNCTION_FAILED; + DBG(("VALUE")); + 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: DBG(("CERTIFICATE TYPE")); - len = 1; - tmp[0] = CKC_X_509; // Support only X.509 certs - data = tmp; + len = sizeof(CK_ULONG); + ul_tmp = CKC_X_509; // Support only X.509 certs + data = (CK_BYTE_PTR) ul_tmp; break; case CKA_ISSUER: @@ -377,9 +386,9 @@ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { case CKA_ID: DBG(("ID")); - len = 1; - tmp[0] = piv_objects[obj].sub_id; - data = tmp; + len = sizeof(CK_BYTE); + b_tmp[0] = piv_objects[obj].sub_id; + data = b_tmp; break; case CKA_START_DATE: @@ -392,9 +401,9 @@ CK_RV get_coa(CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_PTR template) { case CKA_MODIFIABLE: DBG(("MODIFIABLE")); - len = 1; - tmp[0] = piv_objects[obj].modifiable; - data = tmp; + len = sizeof(CK_BBOOL); + b_tmp[0] = piv_objects[obj].modifiable; + data = b_tmp; break; 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_BYTE_PTR data; CK_BYTE b_tmp[1024]; - CK_ULONG ul_tmp; // TODO: fix elsewhere too + CK_ULONG ul_tmp; CK_ULONG len = 0; DBG(("For public key object %lu, get ", obj)); diff --git a/ykcs11/openssl_utils.c b/ykcs11/openssl_utils.c index 5d59599..8b68c2d 100644 --- a/ykcs11/openssl_utils.c +++ b/ykcs11/openssl_utils.c @@ -236,6 +236,26 @@ CK_RV do_check_cert(CK_BYTE_PTR in, CK_ULONG_PTR cert_len) { 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) { X509_free((X509 *) cert); diff --git a/ykcs11/openssl_utils.h b/ykcs11/openssl_utils.h index 8ded6f2..09f6482 100644 --- a/ykcs11/openssl_utils.h +++ b/ykcs11/openssl_utils.h @@ -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_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_get_raw_cert(X509 *cert, CK_BYTE_PTR out, CK_ULONG_PTR out_len); CK_RV free_cert(X509 *cert); CK_RV do_store_pubk(X509 *cert, EVP_PKEY **key);