From df9a4d0b2ce50dcdae4214c09e86a2acb03f5826 Mon Sep 17 00:00:00 2001 From: Viktor Tarasov Date: Sun, 30 Sep 2012 22:38:27 +0200 Subject: [PATCH] pkcs15: for 'sc_pkcs15_cer's data use the 'der' object type To hold the raw certificate blob in 'sc_pkcs15_cert' data use the 'sc_pkcs15_der' data type. also: ; in 'pkcs15-cert.c' use short call of the debug messages; ; in 'destroy-object' pkcs15 framework handler take into account the multi-application cards: -- when binding card use the application info; -- when finalizing profile use the application ID. --- src/libopensc/pkcs15-cert.c | 91 +++++++++++++++------------- src/libopensc/pkcs15-esteid.c | 4 +- src/libopensc/pkcs15-itacns.c | 4 +- src/libopensc/pkcs15.h | 5 +- src/minidriver/minidriver.c | 6 +- src/pkcs11/framework-pkcs15.c | 79 ++++++++++++------------ src/pkcs15init/pkcs15-oberthur-awp.c | 2 +- src/tools/pkcs15-init.c | 10 +-- src/tools/pkcs15-tool.c | 2 +- 9 files changed, 107 insertions(+), 96 deletions(-) diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index a10ccf61..1bcd5c79 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -33,7 +33,8 @@ #include "asn1.h" #include "pkcs15.h" -static int parse_x509_cert(sc_context_t *ctx, const u8 *buf, size_t buflen, struct sc_pkcs15_cert *cert) +static int +parse_x509_cert(sc_context_t *ctx, const u8 *buf, size_t buflen, struct sc_pkcs15_cert *cert) { int r; struct sc_algorithm_id sig_alg; @@ -80,29 +81,27 @@ static int parse_x509_cert(sc_context_t *ctx, const u8 *buf, size_t buflen, stru }; const u8 *obj; size_t objlen; - + memset(cert, 0, sizeof(*cert)); - obj = sc_asn1_verify_tag(ctx, buf, buflen, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, - &objlen); - if (obj == NULL) { - sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "X.509 certificate not found"); - return SC_ERROR_INVALID_ASN1_OBJECT; - } - cert->data_len = objlen + (obj - buf); + obj = sc_asn1_verify_tag(ctx, buf, buflen, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, &objlen); + if (obj == NULL) + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "X.509 certificate not found"); + + cert->data.len = objlen + (obj - buf); r = sc_asn1_decode(ctx, asn1_cert, obj, objlen, NULL, NULL); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 parsing of certificate failed"); + LOG_TEST_RET(ctx, r, "ASN.1 parsing of certificate failed"); cert->version++; if (pubkey) { cert->key = pubkey; pubkey = NULL; - } else { - sc_debug(ctx,SC_LOG_DEBUG_VERBOSE, "Unable to decode subjectPublicKeyInfo from cert"); - r = SC_ERROR_INVALID_ASN1_OBJECT; + } + else { + LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "Unable to decode subjectPublicKeyInfo from cert"); } sc_asn1_clear_algorithm_id(&sig_alg); - if (r < 0) + if (r < 0) return r; if (serial && serial_len) { @@ -114,6 +113,7 @@ static int parse_x509_cert(sc_context_t *ctx, const u8 *buf, size_t buflen, stru return r; } + int sc_pkcs15_pubkey_from_cert(struct sc_context *ctx, struct sc_pkcs15_der *cert_blob, struct sc_pkcs15_pubkey **out) @@ -124,33 +124,35 @@ sc_pkcs15_pubkey_from_cert(struct sc_context *ctx, cert = calloc(1, sizeof(struct sc_pkcs15_cert)); if (cert == NULL) return SC_ERROR_OUT_OF_MEMORY; - + rv = parse_x509_cert(ctx, cert_blob->value, cert_blob->len, cert); - + *out = cert->key; cert->key = NULL; sc_pkcs15_free_certificate(cert); - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv); + LOG_FUNC_RETURN(ctx, rv); } -int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card, - const struct sc_pkcs15_cert_info *info, - struct sc_pkcs15_cert **cert_out) + +int +sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_cert_info *info, + struct sc_pkcs15_cert **cert_out) { int r; struct sc_pkcs15_cert *cert; u8 *data = NULL; size_t len; - + assert(p15card != NULL && info != NULL && cert_out != NULL); - SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE); + LOG_FUNC_CALLED(p15card->card->ctx); if (info->path.len) { r = sc_pkcs15_read_file(p15card, &info->path, &data, &len); if (r) return r; - } else { + } + else { sc_pkcs15_der_t copy; sc_der_copy(©, &info->value); @@ -169,7 +171,8 @@ int sc_pkcs15_read_certificate(struct sc_pkcs15_card *p15card, sc_pkcs15_free_certificate(cert); return SC_ERROR_INVALID_ASN1_OBJECT; } - cert->data = data; + + cert->data.value = data; *cert_out = cert; return 0; } @@ -204,9 +207,10 @@ static const struct sc_asn1_entry c_asn1_cert[] = { { NULL, 0, 0, 0, NULL, NULL } }; -int sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, - struct sc_pkcs15_object *obj, - const u8 ** buf, size_t *buflen) + +int +sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, + const u8 ** buf, size_t *buflen) { sc_context_t *ctx = p15card->card->ctx; struct sc_pkcs15_cert_info info; @@ -227,7 +231,7 @@ int sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, sc_copy_asn1_entry(c_asn1_x509_cert_value_choice, asn1_x509_cert_value_choice); sc_copy_asn1_entry(c_asn1_type_cert_attr, asn1_type_cert_attr); sc_copy_asn1_entry(c_asn1_cert, asn1_cert); - + sc_format_asn1_entry(asn1_cred_ident + 0, &id_type, NULL, 0); sc_format_asn1_entry(asn1_cred_ident + 1, &id_value, &id_value_len, 0); sc_format_asn1_entry(asn1_com_cert_attr + 0, &info.id, NULL, 0); @@ -242,36 +246,37 @@ int sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card, /* Fill in defaults */ memset(&info, 0, sizeof(info)); info.authority = 0; - + r = sc_asn1_decode(ctx, asn1_cert, *buf, *buflen, buf, buflen); /* In case of error, trash the cert value (direct coding) */ if (r < 0 && der->value) free(der->value); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed"); + LOG_TEST_RET(ctx, r, "ASN.1 decoding failed"); if (!p15card->app || !p15card->app->ddo.aid.len) { r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); - SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot make absolute path"); + LOG_TEST_RET(ctx, r, "Cannot make absolute path"); } - else { + else { info.path.aid = p15card->app->ddo.aid; } - sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Certificate path '%s'", sc_print_path(&info.path)); + sc_log(ctx, "Certificate path '%s'", sc_print_path(&info.path)); obj->type = SC_PKCS15_TYPE_CERT_X509; obj->data = malloc(sizeof(info)); if (obj->data == NULL) - SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(obj->data, &info, sizeof(info)); return 0; } -int sc_pkcs15_encode_cdf_entry(sc_context_t *ctx, - const struct sc_pkcs15_object *obj, - u8 **buf, size_t *bufsize) + +int +sc_pkcs15_encode_cdf_entry(sc_context_t *ctx, const struct sc_pkcs15_object *obj, + u8 **buf, size_t *bufsize) { struct sc_asn1_entry asn1_cred_ident[3], asn1_com_cert_attr[4], asn1_x509_cert_attr[2], asn1_type_cert_attr[2], @@ -289,7 +294,7 @@ int sc_pkcs15_encode_cdf_entry(sc_context_t *ctx, sc_copy_asn1_entry(c_asn1_x509_cert_value_choice, asn1_x509_cert_value_choice); sc_copy_asn1_entry(c_asn1_type_cert_attr, asn1_type_cert_attr); sc_copy_asn1_entry(c_asn1_cert, asn1_cert); - + sc_format_asn1_entry(asn1_com_cert_attr + 0, (void *) &infop->id, NULL, 1); if (infop->authority) sc_format_asn1_entry(asn1_com_cert_attr + 1, (void *) &infop->authority, NULL, 1); @@ -306,7 +311,9 @@ int sc_pkcs15_encode_cdf_entry(sc_context_t *ctx, return r; } -void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert) + +void +sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert) { assert(cert != NULL); @@ -315,12 +322,14 @@ void sc_pkcs15_free_certificate(struct sc_pkcs15_cert *cert) free(cert->subject); free(cert->issuer); free(cert->serial); - free(cert->data); + free(cert->data.value); free(cert->crl); free(cert); } -void sc_pkcs15_free_cert_info(sc_pkcs15_cert_info_t *cert) + +void +sc_pkcs15_free_cert_info(sc_pkcs15_cert_info_t *cert) { if (!cert) return; diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index d9999ba6..8f481c42 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -100,7 +100,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) memset(&cert_info, 0, sizeof(cert_info)); memset(&cert_obj, 0, sizeof(cert_obj)); - + cert_info.id.value[0] = esteid_cert_ids[i]; cert_info.id.len = 1; sc_format_path(esteid_cert_paths[i], &cert_info.path); @@ -117,7 +117,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) unsigned char *tmp = NULL; r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert); if (r == SC_SUCCESS) { - mem = BIO_new_mem_buf(cert->data, cert->data_len); + mem = BIO_new_mem_buf(cert->data.value, cert->data.len); if (!mem) return SC_ERROR_INTERNAL; x509 = d2i_X509_bio(mem, NULL); diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 29c43311..0977af9d 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -236,8 +236,8 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, "Could not read X.509 certificate"); { - const u8 *throwaway = cert->data; - x509 = d2i_X509(NULL, &throwaway, cert->data_len); + const u8 *throwaway = cert->data.value; + x509 = d2i_X509(NULL, &throwaway, cert->data.len); } sc_pkcs15_free_certificate(cert); if (!x509) return SC_SUCCESS; diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 28522c85..f90fcb17 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -287,8 +287,9 @@ struct sc_pkcs15_cert { size_t crl_len; struct sc_pkcs15_pubkey * key; - u8 *data; /* DER encoded raw cert */ - size_t data_len; + + /* DER encoded raw cert */ + struct sc_pkcs15_der data; }; typedef struct sc_pkcs15_cert sc_pkcs15_cert_t; diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c index 154bea05..97e72523 100644 --- a/src/minidriver/minidriver.c +++ b/src/minidriver/minidriver.c @@ -1141,9 +1141,9 @@ md_fs_read_content(PCARD_DATA pCardData, char *parent, struct md_file *file) return; } - file->size = cert->data_len; - file->blob = pCardData->pfnCspAlloc(cert->data_len); - CopyMemory(file->blob, cert->data, cert->data_len); + file->size = cert->data.len; + file->blob = pCardData->pfnCspAlloc(cert->data.len); + CopyMemory(file->blob, cert->data.value, cert->data.len); sc_pkcs15_free_certificate(cert); } } diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 1cf93c84..b3ef7eb1 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -507,13 +507,13 @@ public_key_created(struct pkcs15_fw_data *fw_data, const unsigned int num_object static int -__pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data, - struct sc_pkcs15_object *cert, struct pkcs15_any_object **cert_object) +__pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data, struct sc_pkcs15_object *cert, + struct pkcs15_any_object **cert_object) { - struct sc_pkcs15_cert_info *p15_info; - struct sc_pkcs15_cert *p15_cert; - struct pkcs15_cert_object *object; - struct pkcs15_pubkey_object *obj2; + struct sc_pkcs15_cert_info *p15_info = NULL; + struct sc_pkcs15_cert *p15_cert = NULL; + struct pkcs15_cert_object *object = NULL; + struct pkcs15_pubkey_object *obj2 = NULL; int rv; p15_info = (struct sc_pkcs15_cert_info *) cert->data; @@ -537,9 +537,8 @@ __pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data, object->cert_data = p15_cert; /* Corresponding public key */ - rv = public_key_created(fw_data, fw_data->num_objects, p15_info->id.value, p15_info->id.len, + rv = public_key_created(fw_data, fw_data->num_objects, p15_info->id.value, p15_info->id.len, (struct pkcs15_any_object **) &obj2); - if (rv != SC_SUCCESS) rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &obj2, NULL, &pkcs15_pubkey_ops, sizeof(struct pkcs15_pubkey_object)); @@ -799,12 +798,10 @@ pkcs15_bind_related_objects(struct pkcs15_fw_data *fw_data) continue; sc_log(context, "Looking for objects related to object %d", i); - - if (is_privkey(obj)) { + if (is_privkey(obj)) __pkcs15_prkey_bind_related(fw_data, (struct pkcs15_prkey_object *) obj); - } else if (is_cert(obj)) { + else if (is_cert(obj)) __pkcs15_cert_bind_related(fw_data, (struct pkcs15_cert_object *) obj); - } } } @@ -2067,10 +2064,8 @@ out: static CK_RV -pkcs15_create_public_key(struct sc_pkcs11_slot *slot, - struct sc_profile *profile, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, - CK_OBJECT_HANDLE_PTR phObject) +pkcs15_create_public_key(struct sc_pkcs11_slot *slot, struct sc_profile *profile, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject) { struct sc_pkcs11_card *p11card = slot->card; struct pkcs15_fw_data *fw_data = NULL; @@ -2740,8 +2735,10 @@ pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object) #else struct pkcs15_data_object *obj = (struct pkcs15_data_object*) object; struct pkcs15_any_object *any_obj = (struct pkcs15_any_object*) object; - struct sc_pkcs11_card *p11card = session->slot->card; - struct pkcs15_fw_data *fw_data = NULL; + struct sc_pkcs11_slot *slot = session->slot; + struct sc_pkcs11_card *p11card = slot->card; + struct pkcs15_fw_data *fw_data = NULL; + struct sc_aid *aid = NULL; struct sc_profile *profile = NULL; int rv; @@ -2754,13 +2751,15 @@ pkcs15_any_destroy(struct sc_pkcs11_session *session, void *object) return sc_to_cryptoki_error(rv, "C_DestroyObject"); /* Bind the profile */ - rv = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, NULL, &profile); + rv = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, slot->app_info, &profile); if (rv < 0) { sc_unlock(p11card->card); return sc_to_cryptoki_error(rv, "C_DestroyObject"); } - rv = sc_pkcs15init_finalize_profile(p11card->card, profile, NULL); + if(slot->app_info) + aid = &slot->app_info->aid; + rv = sc_pkcs15init_finalize_profile(p11card->card, profile, aid); if (rv != CKR_OK) { sc_log(context, "Cannot finalize profile: %i", rv); return sc_to_cryptoki_error(rv, "C_DestroyObject"); @@ -2979,8 +2978,8 @@ pkcs15_cert_get_attribute(struct sc_pkcs11_session *session, void *object, CK_AT attr->ulValueLen = 0; return CKR_OK; } - check_attribute_buffer(attr, cert->cert_data->data_len); - memcpy(attr->pValue, cert->cert_data->data, cert->cert_data->data_len); + check_attribute_buffer(attr, cert->cert_data->data.len); + memcpy(attr->pValue, cert->cert_data->data.value, cert->cert_data->data.len); break; case CKA_SERIAL_NUMBER: if (check_cert_data_read(fw_data, cert) != 0) { @@ -3670,15 +3669,12 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, break; case CKA_PRIVATE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); - if (pubkey->pub_p15obj) { - *(CK_BBOOL*)attr->pValue = - (pubkey->pub_p15obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0; - } else if (cert && cert->cert_p15obj) { - *(CK_BBOOL*)attr->pValue = - (cert->pub_p15obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0; - } else { + if (pubkey->pub_p15obj) + *(CK_BBOOL*)attr->pValue = (pubkey->pub_p15obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0; + else if (cert && cert->cert_p15obj) + *(CK_BBOOL*)attr->pValue = (cert->pub_p15obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0; + else return CKR_ATTRIBUTE_TYPE_INVALID; - } break; case CKA_MODIFIABLE: case CKA_EXTRACTABLE: @@ -3690,11 +3686,13 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, len = strlen(pubkey->pub_p15obj->label); check_attribute_buffer(attr, len); memcpy(attr->pValue, pubkey->pub_p15obj->label, len); - } else if (cert && cert->cert_p15obj) { + } + else if (cert && cert->cert_p15obj) { len = strlen(cert->cert_p15obj->label); check_attribute_buffer(attr, len); memcpy(attr->pValue, cert->cert_p15obj->label, len); - } else { + } + else { return CKR_ATTRIBUTE_TYPE_INVALID; } break; @@ -3713,10 +3711,12 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, if (pubkey->pub_info) { check_attribute_buffer(attr, pubkey->pub_info->id.len); memcpy(attr->pValue, pubkey->pub_info->id.value, pubkey->pub_info->id.len); - } else if (cert && cert->cert_info) { + } + else if (cert && cert->cert_info) { check_attribute_buffer(attr, cert->cert_info->id.len); memcpy(attr->pValue, cert->cert_info->id.value, cert->cert_info->id.len); - } else { + } + else { return CKR_ATTRIBUTE_TYPE_INVALID; } break; @@ -3750,15 +3750,16 @@ pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, case CKA_VALUE: if (pubkey->pub_data) { /* TODO: -DEE Not all pubkeys have CKA_VALUE attribute. RSA and EC - * for example don't. So why is this here? + * for example don't. So why is this here? * Why checking for cert in this pkcs15_pubkey_get_attribute? - */ + */ check_attribute_buffer(attr, pubkey->pub_data->data.len); memcpy(attr->pValue, pubkey->pub_data->data.value, pubkey->pub_data->data.len); - } else if (cert && cert->cert_data) { - check_attribute_buffer(attr, cert->cert_data->data_len); - memcpy(attr->pValue, cert->cert_data->data, cert->cert_data->data_len); + } + else if (cert && cert->cert_data) { + check_attribute_buffer(attr, cert->cert_data->data.len); + memcpy(attr->pValue, cert->cert_data->data.value, cert->cert_data->data.len); } break; case CKA_GOSTR3410_PARAMS: diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index f705d847..39abef05 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -1427,7 +1427,7 @@ awp_update_df_create_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *p rv = sc_pkcs15_read_certificate(p15card, cert_info, &p15cert); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: cannot get certificate"); - rv = sc_pkcs15_allocate_object_content(ctx, cert_obj, p15cert->data, p15cert->data_len); + rv = sc_pkcs15_allocate_object_content(ctx, cert_obj, p15cert->data.value, p15cert->data.len); SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "AWP 'update private key' DF failed: cannot allocate content"); rv = awp_encode_cert_info(p15card, cert_obj, &icert); diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index eb71c5d7..7209b659 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -1005,12 +1005,12 @@ is_cacert_already_present(struct sc_pkcs15init_certargs *args) if (r < 0 || !cert) continue; - if (cert->data_len == args->der_encoded.len - && !memcmp(cert->data, args->der_encoded.value, - cert->data_len)) { + if (cert->data.len == args->der_encoded.len + && !memcmp(cert->data.value, args->der_encoded.value, cert->data.len)) { sc_pkcs15_free_certificate(cert); return 1; } + sc_pkcs15_free_certificate(cert); cert=NULL; } @@ -1087,8 +1087,8 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, int r; /* Get the public key from the old cert */ - ptr = sc_oldcert->data; - oldcert = d2i_X509(NULL, &ptr, sc_oldcert->data_len); + ptr = sc_oldcert->data.value; + oldcert = d2i_X509(NULL, &ptr, sc_oldcert->data.len); if (oldcert == NULL) return SC_ERROR_INTERNAL; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index e95d915f..8a3b8157 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -388,7 +388,7 @@ static int read_certificate(void) fprintf(stderr, "Certificate read failed: %s\n", sc_strerror(r)); return 1; } - r = print_pem_object("CERTIFICATE", cert->data, cert->data_len); + r = print_pem_object("CERTIFICATE", cert->data.value, cert->data.len); sc_pkcs15_free_certificate(cert); return r; }