From: Nikos Mavrogiannopoulos Date: Wed, 8 Sep 2010 12:14:46 +0000 (+0200) Subject: PKCS#11 URL support updated to conform to draft-pechanec-pkcs11uri-02. X-Git-Tag: gnutls_2_11_3~54 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=75607800c30f34731e2de396387e007ae71e8ee5;p=thirdparty%2Fgnutls.git PKCS#11 URL support updated to conform to draft-pechanec-pkcs11uri-02. Now in the URL the pkcs11 provider library (module) can be specified thus restricting objects within a single provider. --- diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h index dd5ae55ad3..dd3eacc418 100644 --- a/lib/includes/gnutls/pkcs11.h +++ b/lib/includes/gnutls/pkcs11.h @@ -54,7 +54,7 @@ int gnutls_pkcs11_obj_init ( gnutls_pkcs11_obj_t *certificate); int gnutls_pkcs11_obj_import_url (gnutls_pkcs11_obj_t, const char * url, unsigned int flags/* GNUTLS_PKCS11_OBJ_FLAG_* */); -int gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t, char** url); +int gnutls_pkcs11_obj_export_url (gnutls_pkcs11_obj_t, int detailed, char** url); void gnutls_pkcs11_obj_deinit ( gnutls_pkcs11_obj_t); int gnutls_pkcs11_obj_export(gnutls_pkcs11_obj_t obj, @@ -77,6 +77,10 @@ typedef enum { GNUTLS_PKCS11_OBJ_TOKEN_MANUFACTURER, GNUTLS_PKCS11_OBJ_TOKEN_MODEL, GNUTLS_PKCS11_OBJ_ID, + /* the pkcs11 provider library info */ + GNUTLS_PKCS11_OBJ_LIBRARY_VERSION, + GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION, + GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER, } gnutls_pkcs11_obj_info_t; int gnutls_pkcs11_obj_get_info(gnutls_pkcs11_obj_t crt, gnutls_pkcs11_obj_info_t itype, void* output, size_t* output_size); @@ -107,7 +111,7 @@ typedef enum { GNUTLS_PKCS11_OBJ_DATA, } gnutls_pkcs11_obj_type_t; -int gnutls_pkcs11_token_get_url (unsigned int seq, char** url); +int gnutls_pkcs11_token_get_url (unsigned int seq, int detailed, char** url); int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t, void* output, size_t *output_size); #define GNUTLS_PKCS11_TOKEN_HW 1 @@ -152,7 +156,7 @@ int gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, unsigned int flags, const gnutls_datum_t * ciphertext, gnutls_datum_t * plaintext); -int gnutls_pkcs11_privkey_export_url (gnutls_pkcs11_privkey_t key, char ** url); +int gnutls_pkcs11_privkey_export_url (gnutls_pkcs11_privkey_t key, int detailed, char ** url); /** @} */ diff --git a/lib/pkcs11.c b/lib/pkcs11.c index 365303c05e..5a4a617f34 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -33,6 +33,8 @@ #define MAX_PROVIDERS 16 +static void terminate_string(unsigned char *str, size_t len); + /* XXX: try to eliminate this */ #define MAX_CERT_SIZE 8*1024 @@ -40,6 +42,7 @@ struct gnutls_pkcs11_provider_s { pakchois_module_t *module; unsigned long nslots; ck_slot_id_t *slots; + struct ck_info info; }; struct flags_find_data_st { @@ -216,6 +219,14 @@ int gnutls_pkcs11_add_provider(const char *name, const char *params) gnutls_free(providers[active_providers - 1].slots); goto fail; } + + memset( &providers[active_providers-1].info, 0, sizeof(providers[active_providers-1].info)); + pakchois_get_info(providers[active_providers - 1].module, &providers[active_providers-1].info); + + terminate_string(providers[active_providers-1].info.manufacturer_id, + sizeof(providers[active_providers-1].info.manufacturer_id)); + terminate_string(providers[active_providers-1].info.library_description, + sizeof(providers[active_providers-1].info.library_description)); _gnutls_debug_log("p11: loaded provider '%s' with %d slots\n", name, @@ -289,6 +300,15 @@ int pkcs11_get_info(struct pkcs11_url_info *info, case GNUTLS_PKCS11_OBJ_TOKEN_MODEL: str = info->model; break; + case GNUTLS_PKCS11_OBJ_LIBRARY_DESCRIPTION: + str = info->lib_desc; + break; + case GNUTLS_PKCS11_OBJ_LIBRARY_VERSION: + str = info->lib_version; + break; + case GNUTLS_PKCS11_OBJ_LIBRARY_MANUFACTURER: + str = info->lib_manufacturer; + break; default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; @@ -517,8 +537,40 @@ int pkcs11_url_to_info(const char *url, struct pkcs11_url_info *info) goto cleanup; } - if ((p1 = strstr(url, "manufacturer=")) != NULL) { - p1 += sizeof("manufacturer=") - 1; + if ((p1 = strstr(url, "library-manufacturer=")) != NULL) { + p1 += sizeof("library-manufacturer=") - 1; + l = sizeof(info->lib_manufacturer); + + ret = unescape_string(info->lib_manufacturer, p1, &l, ';'); + if (ret < 0) { + goto cleanup; + } + } + + if ((p1 = strstr(url, "library-description=")) != NULL) { + p1 += sizeof("library-description=") - 1; + l = sizeof(info->lib_desc); + + ret = unescape_string(info->lib_desc, p1, &l, ';'); + if (ret < 0) { + goto cleanup; + } + } + + if ((p1 = strstr(url, "library-version=")) != NULL) { + p1 += sizeof("library-version=") - 1; + l = sizeof(info->lib_version); + + ret = unescape_string(info->lib_version, p1, &l, ';'); + if (ret < 0) { + goto cleanup; + } + } + + if ((p1 = strstr(url, ";manufacturer=")) != NULL || + (p1 = strstr(url, ":manufacturer=")) != NULL) { + + p1 += sizeof(";manufacturer=") - 1; l = sizeof(info->manufacturer); ret = unescape_string(info->manufacturer, p1, &l, ';'); @@ -658,7 +710,7 @@ static int append(gnutls_buffer_st * dest, const char *tname, } -int pkcs11_info_to_url(const struct pkcs11_url_info *info, char **url) +int pkcs11_info_to_url(const struct pkcs11_url_info *info, int detailed, char **url) { gnutls_buffer_st str; int init = 0; @@ -724,6 +776,35 @@ int pkcs11_info_to_url(const struct pkcs11_url_info *info, char **url) init = 1; } + if (detailed) { + if (info->lib_manufacturer[0]) { + ret = append(&str, info->lib_manufacturer, "library-manufacturer", init); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + init = 1; + } + + if (info->lib_version[0]) { + ret = append(&str, info->lib_version, "library-version", init); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + init = 1; + } + + if (info->lib_desc[0]) { + ret = append(&str, info->lib_desc, "library-description", init); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + init = 1; + } + } + if (info->id[0] != 0) { ret = _gnutls_buffer_append_printf(&str, ";id=%s", info->id); @@ -946,7 +1027,8 @@ int pkcs11_open_session(pakchois_session_t ** _pks, /* XXX make wrapper for token_info? */ fix_strings(&tinfo); - if (pkcs11_token_matches_info(info, &tinfo.tinfo) < + if (pkcs11_token_matches_info(info, &tinfo.tinfo, + &providers[x].info) < 0) { goto next; } @@ -1021,7 +1103,7 @@ int _pkcs11_traverse_tokens(find_func_t find_func, void *input, } } - ret = find_func(pks, &info, input); + ret = find_func(pks, &info, &providers[x].info, input); next: @@ -1039,7 +1121,7 @@ int _pkcs11_traverse_tokens(find_func_t find_func, void *input, /* final call */ if (found == 0) { - ret = find_func(pks, NULL, input); + ret = find_func(pks, NULL, NULL, input); } else { ret = 0; } @@ -1072,40 +1154,41 @@ static const char *pkcs11_obj_type_to_str(gnutls_pkcs11_obj_type_t type) /* imports a raw certificate from a token to a pkcs11_obj_t structure. */ -static int pkcs11_obj_import(unsigned int class, gnutls_pkcs11_obj_t crt, +static int pkcs11_obj_import(unsigned int class, gnutls_pkcs11_obj_t obj, const gnutls_datum_t * data, const gnutls_datum_t * id, const gnutls_datum_t * label, - struct ck_token_info *tinfo) + struct ck_token_info *tinfo, + struct ck_info *lib_info) { char *s; int ret; switch (class) { case CKO_CERTIFICATE: - crt->type = GNUTLS_PKCS11_OBJ_X509_CRT; + obj->type = GNUTLS_PKCS11_OBJ_X509_CRT; break; case CKO_PUBLIC_KEY: - crt->type = GNUTLS_PKCS11_OBJ_PUBKEY; + obj->type = GNUTLS_PKCS11_OBJ_PUBKEY; break; case CKO_PRIVATE_KEY: - crt->type = GNUTLS_PKCS11_OBJ_PRIVKEY; + obj->type = GNUTLS_PKCS11_OBJ_PRIVKEY; break; case CKO_SECRET_KEY: - crt->type = GNUTLS_PKCS11_OBJ_SECRET_KEY; + obj->type = GNUTLS_PKCS11_OBJ_SECRET_KEY; break; case CKO_DATA: - crt->type = GNUTLS_PKCS11_OBJ_DATA; + obj->type = GNUTLS_PKCS11_OBJ_DATA; break; default: - crt->type = GNUTLS_PKCS11_OBJ_UNKNOWN; + obj->type = GNUTLS_PKCS11_OBJ_UNKNOWN; } - if (crt->type != GNUTLS_PKCS11_OBJ_UNKNOWN) - strcpy(crt->info.type, pkcs11_obj_type_to_str(crt->type)); + if (obj->type != GNUTLS_PKCS11_OBJ_UNKNOWN) + strcpy(obj->info.type, pkcs11_obj_type_to_str(obj->type)); if (data && data->data) { - ret = _gnutls_set_datum(&crt->raw, data->data, data->size); + ret = _gnutls_set_datum(&obj->raw, data->data, data->size); if (ret < 0) { gnutls_assert(); return ret; @@ -1120,30 +1203,40 @@ static int pkcs11_obj_import(unsigned int class, gnutls_pkcs11_obj_t crt, sizeof tinfo->serial_number); /* write data */ - snprintf(crt->info.manufacturer, sizeof(crt->info.manufacturer), + snprintf(obj->info.manufacturer, sizeof(obj->info.manufacturer), "%s", tinfo->manufacturer_id); - snprintf(crt->info.token, sizeof(crt->info.token), "%s", + snprintf(obj->info.token, sizeof(obj->info.token), "%s", tinfo->label); - snprintf(crt->info.model, sizeof(crt->info.model), "%s", + snprintf(obj->info.model, sizeof(obj->info.model), "%s", tinfo->model); - snprintf(crt->info.serial, sizeof(crt->info.serial), "%s", + snprintf(obj->info.serial, sizeof(obj->info.serial), "%s", tinfo->serial_number); + snprintf(obj->info.lib_manufacturer, sizeof(obj->info.lib_manufacturer), "%s", + lib_info->manufacturer_id); + snprintf(obj->info.lib_desc, sizeof(obj->info.lib_desc), "%s", + lib_info->library_description); + snprintf(obj->info.lib_version, sizeof(obj->info.lib_version), + "%u.%u", (unsigned int)lib_info->library_version.major, + (unsigned int)lib_info->library_version.minor); + + + if (label && label->data) { - memcpy(crt->info.label, label->data, label->size); - crt->info.label[label->size] = 0; + memcpy(obj->info.label, label->data, label->size); + obj->info.label[label->size] = 0; } if (id && id->data) { - s = _gnutls_bin2hex(id->data, id->size, crt->info.id, - sizeof(crt->info.id), ":"); + s = _gnutls_bin2hex(id->data, id->size, obj->info.id, + sizeof(obj->info.id), ":"); if (s == NULL) { gnutls_assert(); return GNUTLS_E_PKCS11_ERROR; } - memmove(crt->info.certid_raw, id->data, id->size); - crt->info.certid_raw_size = id->size; + memmove(obj->info.certid_raw, id->data, id->size); + obj->info.certid_raw_size = id->size; } return 0; @@ -1154,7 +1247,8 @@ static int pkcs11_obj_import_pubkey(pakchois_session_t * pks, gnutls_pkcs11_obj_t crt, const gnutls_datum_t * id, const gnutls_datum_t * label, - struct ck_token_info *tinfo) + struct ck_token_info *tinfo, + struct ck_info* lib_info) { struct ck_attribute a[4]; @@ -1346,7 +1440,7 @@ static int pkcs11_obj_import_pubkey(pakchois_session_t * pks, } return pkcs11_obj_import(CKO_PUBLIC_KEY, crt, NULL, id, label, - tinfo); + tinfo, lib_info); } ck_object_class_t pkcs11_strtype_to_class(const char *type) @@ -1372,7 +1466,7 @@ ck_object_class_t pkcs11_strtype_to_class(const char *type) static int find_obj_url(pakchois_session_t * pks, struct token_info *info, - void *input) + struct ck_info* lib_info, void *input) { struct url_find_data_st *find_data = input; struct ck_attribute a[4]; @@ -1392,7 +1486,7 @@ static int find_obj_url(pakchois_session_t * pks, struct token_info *info, /* do not bother reading the token if basic fields do not match */ - if (pkcs11_token_matches_info(&find_data->crt->info, &info->tinfo) + if (pkcs11_token_matches_info(&find_data->crt->info, &info->tinfo, lib_info) < 0) { gnutls_assert(); return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; @@ -1472,13 +1566,14 @@ static int find_obj_url(pakchois_session_t * pks, struct token_info *info, pkcs11_obj_import_pubkey(pks, obj, find_data->crt, &id, &label, - &info->tinfo); + &info->tinfo, + lib_info); } else { ret = pkcs11_obj_import(class, find_data->crt, &data, &id, &label, - &info->tinfo); + &info->tinfo, lib_info); } if (ret < 0) { gnutls_assert(); @@ -1565,7 +1660,9 @@ struct token_num { }; static int find_token_num(pakchois_session_t * pks, - struct token_info *tinfo, void *input) + struct token_info *tinfo, + struct ck_info* lib_info, + void *input) { struct token_num *find_data = input; @@ -1581,6 +1678,12 @@ static int find_token_num(pakchois_session_t * pks, strcpy(find_data->info.model, tinfo->tinfo.model); strcpy(find_data->info.serial, tinfo->tinfo.serial_number); + strcpy(find_data->info.lib_manufacturer, lib_info->manufacturer_id); + strcpy(find_data->info.lib_desc, lib_info->library_description); + snprintf(find_data->info.lib_version, sizeof(find_data->info.lib_version), + "%u.%u", (unsigned int)lib_info->library_version.major, + (unsigned int)lib_info->library_version.minor); + return 0; } @@ -1594,6 +1697,7 @@ static int find_token_num(pakchois_session_t * pks, /** * gnutls_pkcs11_token_get_url: * @seq: sequence number starting from 0 + * @detailed: non zero if a detailed URL is required * @url: will contain an allocated url * * This function will return the URL for each token available @@ -1603,7 +1707,7 @@ static int find_token_num(pakchois_session_t * pks, * if the sequence number exceeds the available tokens, otherwise a negative error value. **/ -int gnutls_pkcs11_token_get_url(unsigned int seq, char **url) +int gnutls_pkcs11_token_get_url(unsigned int seq, int detailed, char **url) { int ret; struct token_num tn; @@ -1617,7 +1721,7 @@ int gnutls_pkcs11_token_get_url(unsigned int seq, char **url) return ret; } - ret = pkcs11_info_to_url(&tn.info, url); + ret = pkcs11_info_to_url(&tn.info, detailed, url); if (ret < 0) { gnutls_assert(); return ret; @@ -1689,6 +1793,7 @@ int gnutls_pkcs11_token_get_info(const char *url, /** * gnutls_pkcs11_obj_export_url: * @crt: Holds the PKCS 11 certificate + * @detailed: non zero if a detailed URL is required * @url: will contain an allocated url * * This function will export a URL identifying the given certificate. @@ -1696,11 +1801,11 @@ int gnutls_pkcs11_token_get_info(const char *url, * Returns: On success, %GNUTLS_E_SUCCESS is returned, otherwise a * negative error value. **/ -int gnutls_pkcs11_obj_export_url(gnutls_pkcs11_obj_t cert, char **url) +int gnutls_pkcs11_obj_export_url(gnutls_pkcs11_obj_t cert, int detailed, char **url) { int ret; - ret = pkcs11_info_to_url(&cert->info, url); + ret = pkcs11_info_to_url(&cert->info, detailed, url); if (ret < 0) { gnutls_assert(); return ret; @@ -1749,7 +1854,7 @@ int pkcs11_login(pakchois_session_t * pks, const struct token_info *info) strcpy(uinfo.token, info->tinfo.label); strcpy(uinfo.model, info->tinfo.model); strcpy(uinfo.serial, info->tinfo.serial_number); - ret = pkcs11_info_to_url(&uinfo, &token_url); + ret = pkcs11_info_to_url(&uinfo, 1, &token_url); if (ret < 0) { gnutls_assert(); return ret; @@ -1924,7 +2029,7 @@ static int find_privkeys(pakchois_session_t * pks, struct token_info *info, static int find_objs(pakchois_session_t * pks, struct token_info *info, - void *input) + struct ck_info* lib_info, void *input) { struct crt_find_data_st *find_data = input; struct ck_attribute a[4]; @@ -1954,7 +2059,7 @@ static int find_objs(pakchois_session_t * pks, struct token_info *info, /* do not bother reading the token if basic fields do not match */ - if (pkcs11_token_matches_info(&find_data->info, &info->tinfo) < 0) { + if (pkcs11_token_matches_info(&find_data->info, &info->tinfo, lib_info) < 0) { gnutls_assert(); return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } @@ -2153,14 +2258,15 @@ static int find_objs(pakchois_session_t * pks, struct token_info *info, find_data->p_list [find_data->current], &id, &label, - &info->tinfo); + &info->tinfo, + lib_info); } else { ret = pkcs11_obj_import(class, find_data->p_list [find_data->current], &value, &id, &label, - &info->tinfo); + &info->tinfo, lib_info); } if (ret < 0) { gnutls_assert(); @@ -2354,7 +2460,7 @@ int gnutls_x509_crt_list_import_pkcs11(gnutls_x509_crt_t * certs, } static int find_flags(pakchois_session_t * pks, struct token_info *info, - void *input) + struct ck_info* lib_info, void *input) { struct flags_find_data_st *find_data = input; @@ -2365,7 +2471,7 @@ static int find_flags(pakchois_session_t * pks, struct token_info *info, /* do not bother reading the token if basic fields do not match */ - if (pkcs11_token_matches_info(&find_data->info, &info->tinfo) < 0) { + if (pkcs11_token_matches_info(&find_data->info, &info->tinfo, lib_info) < 0) { gnutls_assert(); return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } @@ -2432,7 +2538,7 @@ const char *gnutls_pkcs11_type_get_name(gnutls_pkcs11_obj_type_t type) } int pkcs11_token_matches_info(struct pkcs11_url_info *info, - struct ck_token_info *tinfo) + struct ck_token_info *tinfo, struct ck_info *lib_info) { if (info->manufacturer[0] != 0) { if (strcmp(info->manufacturer, tinfo->manufacturer_id) != @@ -2455,5 +2561,25 @@ int pkcs11_token_matches_info(struct pkcs11_url_info *info, return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } + if (info->lib_manufacturer[0] != 0) { + if (strcmp(info->lib_manufacturer, lib_info->manufacturer_id) != 0) + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + + if (info->lib_desc[0] != 0) { + if (strcmp(info->lib_desc, lib_info->library_description) != 0) + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + + if (info->lib_version[0] != 0) { + char version[16]; + + snprintf(version, sizeof(version), "%u.%u", + (unsigned int)lib_info->library_version.major, + (unsigned int)lib_info->library_version.minor); + if (strcmp(info->lib_version, version) != 0) + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + return 0; } diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h index e345091fee..a8c84b5143 100644 --- a/lib/pkcs11_int.h +++ b/lib/pkcs11_int.h @@ -18,6 +18,15 @@ struct pkcs11_url_info { /* everything here is null terminated strings */ opaque id[PKCS11_ID_SIZE * 3 + 1]; /* hex with delimiters */ opaque type[16]; /* cert/key etc. */ + + opaque lib_manufacturer[sizeof + (((struct ck_info *) NULL)-> + manufacturer_id) + 1]; + opaque lib_desc[sizeof + (((struct ck_info *) NULL)-> + library_description) + 1]; + opaque lib_version[12]; + opaque manufacturer[sizeof (((struct ck_token_info *) NULL)-> manufacturer_id) + 1]; @@ -47,7 +56,7 @@ struct gnutls_pkcs11_obj_st { * It should return 0 if found what it was looking for. */ typedef int (*find_func_t) (pakchois_session_t * pks, - struct token_info * tinfo, void *input); + struct token_info * tinfo, struct ck_info*, void *input); int pkcs11_rv_to_err(ck_rv_t rv); int pkcs11_url_to_info(const char *url, struct pkcs11_url_info *info); @@ -61,7 +70,7 @@ extern gnutls_pkcs11_token_callback_t token_func; extern void *token_data; void pkcs11_rescan_slots(void); -int pkcs11_info_to_url(const struct pkcs11_url_info *info, char **url); +int pkcs11_info_to_url(const struct pkcs11_url_info *info, int detailed, char **url); #define SESSION_WRITE 1 #define SESSION_LOGIN 2 @@ -73,7 +82,7 @@ int _pkcs11_traverse_tokens(find_func_t find_func, void *input, ck_object_class_t pkcs11_strtype_to_class(const char *type); int pkcs11_token_matches_info(struct pkcs11_url_info *info, - struct ck_token_info *tinfo); + struct ck_token_info *tinfo, struct ck_info *lib_info); /* flags are SESSION_* */ int pkcs11_find_object(pakchois_session_t ** _pks, diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c index 5b31b03cd7..a076c5dec8 100644 --- a/lib/pkcs11_privkey.c +++ b/lib/pkcs11_privkey.c @@ -369,6 +369,7 @@ gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, /** * gnutls_pkcs11_privkey_export_url: * @key: Holds the PKCS 11 key + * @detailed: non zero if a detailed URL is required * @url: will contain an allocated url * * This function will export a URL identifying the given key. @@ -377,11 +378,11 @@ gnutls_pkcs11_privkey_decrypt_data(gnutls_pkcs11_privkey_t key, * negative error value. **/ int gnutls_pkcs11_privkey_export_url(gnutls_pkcs11_privkey_t key, - char **url) + int detailed, char **url) { int ret; - ret = pkcs11_info_to_url(&key->info, url); + ret = pkcs11_info_to_url(&key->info, detailed, url); if (ret < 0) { gnutls_assert(); return ret; diff --git a/lib/pkcs11_write.c b/lib/pkcs11_write.c index b9e4e411a0..fac39de9c2 100644 --- a/lib/pkcs11_write.c +++ b/lib/pkcs11_write.c @@ -392,7 +392,9 @@ struct delete_data_st { }; static int delete_obj_url(pakchois_session_t * pks, - struct token_info *info, void *input) + struct token_info *info, + struct ck_info * lib_info, + void *input) { struct delete_data_st *find_data = input; struct ck_attribute a[4]; @@ -411,7 +413,7 @@ static int delete_obj_url(pakchois_session_t * pks, /* do not bother reading the token if basic fields do not match */ - if (pkcs11_token_matches_info(&find_data->info, &info->tinfo) < 0) { + if (pkcs11_token_matches_info(&find_data->info, &info->tinfo, lib_info) < 0) { gnutls_assert(); return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } diff --git a/src/certtool-common.h b/src/certtool-common.h index 952764317e..bf9da58e17 100644 --- a/src/certtool-common.h +++ b/src/certtool-common.h @@ -39,9 +39,9 @@ enum #define TYPE_CRQ 2 void certtool_version (void); -void pkcs11_list( FILE*outfile, const char* url, int type, unsigned int login); +void pkcs11_list( FILE*outfile, const char* url, int type, unsigned int login, unsigned int detailed); void pkcs11_export(FILE* outfile, const char *pkcs11_url, unsigned int login); -void pkcs11_token_list(FILE* outfile); +void pkcs11_token_list(FILE* outfile, unsigned int detailed); void pkcs11_write(FILE* outfile, const char *pkcs11_url, const char* label, int trusted, unsigned int login); void pkcs11_delete(FILE* outfile, const char *pkcs11_url, int batch, unsigned int login); diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c index 921555d6aa..e3a2c4fd58 100644 --- a/src/certtool-gaa.c +++ b/src/certtool-gaa.c @@ -191,6 +191,7 @@ void gaa_help(void) __gaa_helpsingle(0, "pkcs11-write", "URL ", "Writes loaded certificates or private keys to a PKCS11 token."); __gaa_helpsingle(0, "pkcs11-write-label", "label ", "Sets a label for the write operation."); __gaa_helpsingle(0, "pkcs11-write-trusted", "", "Marks the certificate to be imported as trusted."); + __gaa_helpsingle(0, "pkcs11-detailed-url", "", "Export detailed URLs."); __gaa_helpsingle(0, "pkcs11-delete-url", "URL ", "Deletes objects matching the URL."); __gaa_helpsingle('d', "debug", "LEVEL ", "specify the debug level. Default is 1."); __gaa_helpsingle('h', "help", "", "shows this help text"); @@ -209,8 +210,10 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 165 "certtool.gaa" +#line 168 "certtool.gaa" int debug; +#line 163 "certtool.gaa" + int pkcs11_detailed_url; #line 160 "certtool.gaa" int pkcs11_trusted; #line 157 "certtool.gaa" @@ -327,73 +330,74 @@ static int gaa_error = 0; #define GAA_MULTIPLE_OPTION 3 #define GAA_REST 0 -#define GAA_NB_OPTION 66 +#define GAA_NB_OPTION 67 #define GAAOPTID_version 1 #define GAAOPTID_help 2 #define GAAOPTID_debug 3 #define GAAOPTID_pkcs11_delete_url 4 -#define GAAOPTID_pkcs11_write_trusted 5 -#define GAAOPTID_pkcs11_write_label 6 -#define GAAOPTID_pkcs11_write 7 -#define GAAOPTID_pkcs11_login 8 -#define GAAOPTID_pkcs11_list_tokens 9 -#define GAAOPTID_pkcs11_list_all 10 -#define GAAOPTID_pkcs11_list_all_certs 11 -#define GAAOPTID_pkcs11_list_trusted 12 -#define GAAOPTID_pkcs11_list_privkeys 13 -#define GAAOPTID_pkcs11_list_certs 14 -#define GAAOPTID_pkcs11_export_url 15 -#define GAAOPTID_pkcs11_provider 16 -#define GAAOPTID_pkcs_cipher 17 -#define GAAOPTID_template 18 -#define GAAOPTID_infile 19 -#define GAAOPTID_outfile 20 -#define GAAOPTID_disable_quick_random 21 -#define GAAOPTID_sec_param 22 -#define GAAOPTID_bits 23 -#define GAAOPTID_outraw 24 -#define GAAOPTID_outder 25 -#define GAAOPTID_inraw 26 -#define GAAOPTID_inder 27 -#define GAAOPTID_export_ciphers 28 -#define GAAOPTID_hash 29 -#define GAAOPTID_dsa 30 -#define GAAOPTID_pkcs8 31 -#define GAAOPTID_to_p8 32 -#define GAAOPTID_to_p12 33 -#define GAAOPTID_v1 34 -#define GAAOPTID_fix_key 35 -#define GAAOPTID_pubkey_info 36 -#define GAAOPTID_pgp_key_info 37 -#define GAAOPTID_key_info 38 -#define GAAOPTID_smime_to_p7 39 -#define GAAOPTID_p7_info 40 -#define GAAOPTID_p12_info 41 -#define GAAOPTID_no_crq_extensions 42 -#define GAAOPTID_crq_info 43 -#define GAAOPTID_crl_info 44 -#define GAAOPTID_pgp_ring_info 45 -#define GAAOPTID_pgp_certificate_info 46 -#define GAAOPTID_certificate_pubkey 47 -#define GAAOPTID_certificate_info 48 -#define GAAOPTID_password 49 -#define GAAOPTID_load_ca_certificate 50 -#define GAAOPTID_load_ca_privkey 51 -#define GAAOPTID_load_certificate 52 -#define GAAOPTID_load_request 53 -#define GAAOPTID_load_pubkey 54 -#define GAAOPTID_load_privkey 55 -#define GAAOPTID_get_dh_params 56 -#define GAAOPTID_generate_dh_params 57 -#define GAAOPTID_verify_crl 58 -#define GAAOPTID_verify_chain 59 -#define GAAOPTID_generate_request 60 -#define GAAOPTID_generate_privkey 61 -#define GAAOPTID_update_certificate 62 -#define GAAOPTID_generate_crl 63 -#define GAAOPTID_generate_proxy 64 -#define GAAOPTID_generate_certificate 65 -#define GAAOPTID_generate_self_signed 66 +#define GAAOPTID_pkcs11_detailed_url 5 +#define GAAOPTID_pkcs11_write_trusted 6 +#define GAAOPTID_pkcs11_write_label 7 +#define GAAOPTID_pkcs11_write 8 +#define GAAOPTID_pkcs11_login 9 +#define GAAOPTID_pkcs11_list_tokens 10 +#define GAAOPTID_pkcs11_list_all 11 +#define GAAOPTID_pkcs11_list_all_certs 12 +#define GAAOPTID_pkcs11_list_trusted 13 +#define GAAOPTID_pkcs11_list_privkeys 14 +#define GAAOPTID_pkcs11_list_certs 15 +#define GAAOPTID_pkcs11_export_url 16 +#define GAAOPTID_pkcs11_provider 17 +#define GAAOPTID_pkcs_cipher 18 +#define GAAOPTID_template 19 +#define GAAOPTID_infile 20 +#define GAAOPTID_outfile 21 +#define GAAOPTID_disable_quick_random 22 +#define GAAOPTID_sec_param 23 +#define GAAOPTID_bits 24 +#define GAAOPTID_outraw 25 +#define GAAOPTID_outder 26 +#define GAAOPTID_inraw 27 +#define GAAOPTID_inder 28 +#define GAAOPTID_export_ciphers 29 +#define GAAOPTID_hash 30 +#define GAAOPTID_dsa 31 +#define GAAOPTID_pkcs8 32 +#define GAAOPTID_to_p8 33 +#define GAAOPTID_to_p12 34 +#define GAAOPTID_v1 35 +#define GAAOPTID_fix_key 36 +#define GAAOPTID_pubkey_info 37 +#define GAAOPTID_pgp_key_info 38 +#define GAAOPTID_key_info 39 +#define GAAOPTID_smime_to_p7 40 +#define GAAOPTID_p7_info 41 +#define GAAOPTID_p12_info 42 +#define GAAOPTID_no_crq_extensions 43 +#define GAAOPTID_crq_info 44 +#define GAAOPTID_crl_info 45 +#define GAAOPTID_pgp_ring_info 46 +#define GAAOPTID_pgp_certificate_info 47 +#define GAAOPTID_certificate_pubkey 48 +#define GAAOPTID_certificate_info 49 +#define GAAOPTID_password 50 +#define GAAOPTID_load_ca_certificate 51 +#define GAAOPTID_load_ca_privkey 52 +#define GAAOPTID_load_certificate 53 +#define GAAOPTID_load_request 54 +#define GAAOPTID_load_pubkey 55 +#define GAAOPTID_load_privkey 56 +#define GAAOPTID_get_dh_params 57 +#define GAAOPTID_generate_dh_params 58 +#define GAAOPTID_verify_crl 59 +#define GAAOPTID_verify_chain 60 +#define GAAOPTID_generate_request 61 +#define GAAOPTID_generate_privkey 62 +#define GAAOPTID_update_certificate 63 +#define GAAOPTID_generate_crl 64 +#define GAAOPTID_generate_proxy 65 +#define GAAOPTID_generate_certificate 66 +#define GAAOPTID_generate_self_signed 67 #line 168 "gaa.skel" @@ -753,6 +757,7 @@ static int gaa_get_option_num(char *str, int status) #line 375 "gaa.skel" GAA_CHECK1STR("v", GAAOPTID_version); GAA_CHECK1STR("h", GAAOPTID_help); + GAA_CHECK1STR("", GAAOPTID_pkcs11_detailed_url); GAA_CHECK1STR("", GAAOPTID_pkcs11_write_trusted); GAA_CHECK1STR("", GAAOPTID_pkcs11_login); GAA_CHECK1STR("", GAAOPTID_pkcs11_list_tokens); @@ -805,6 +810,7 @@ static int gaa_get_option_num(char *str, int status) GAA_CHECKSTR("help", GAAOPTID_help); GAA_CHECKSTR("debug", GAAOPTID_debug); GAA_CHECKSTR("pkcs11-delete-url", GAAOPTID_pkcs11_delete_url); + GAA_CHECKSTR("pkcs11-detailed-url", GAAOPTID_pkcs11_detailed_url); GAA_CHECKSTR("pkcs11-write-trusted", GAAOPTID_pkcs11_write_trusted); GAA_CHECKSTR("pkcs11-write-label", GAAOPTID_pkcs11_write_label); GAA_CHECKSTR("pkcs11-write", GAAOPTID_pkcs11_write); @@ -921,14 +927,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) { case GAAOPTID_version: OK = 0; -#line 170 "certtool.gaa" +#line 173 "certtool.gaa" { certtool_version(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_help: OK = 0; -#line 168 "certtool.gaa" +#line 171 "certtool.gaa" { gaa_help(); exit(0); ;}; return GAA_OK; @@ -938,7 +944,7 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_debug.arg1, gaa_getint, GAATMP_debug.size1); gaa_index++; -#line 166 "certtool.gaa" +#line 169 "certtool.gaa" { gaaval->debug = GAATMP_debug.arg1 ;}; return GAA_OK; @@ -948,9 +954,16 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) GAA_TESTMOREARGS; GAA_FILL(GAATMP_pkcs11_delete_url.arg1, gaa_getstr, GAATMP_pkcs11_delete_url.size1); gaa_index++; -#line 163 "certtool.gaa" +#line 166 "certtool.gaa" { gaaval->action = ACTION_PKCS11_DELETE_URL; gaaval->pkcs11_url = GAATMP_pkcs11_delete_url.arg1; ;}; + return GAA_OK; + break; + case GAAOPTID_pkcs11_detailed_url: + OK = 0; +#line 164 "certtool.gaa" +{ gaaval->pkcs11_detailed_url = 1; ;}; + return GAA_OK; break; case GAAOPTID_pkcs11_write_trusted: @@ -1465,14 +1478,14 @@ int gaa(int argc, char **argv, gaainfo *gaaval) if(inited == 0) { -#line 172 "certtool.gaa" +#line 175 "certtool.gaa" { gaaval->bits = 0; gaaval->pkcs8 = 0; gaaval->privkey = NULL; gaaval->ca=NULL; gaaval->ca_privkey = NULL; gaaval->debug=1; gaaval->request = NULL; gaaval->infile = NULL; gaaval->outfile = NULL; gaaval->cert = NULL; gaaval->incert_format = 0; gaaval->outcert_format = 0; gaaval->action=-1; gaaval->pass = NULL; gaaval->v1_cert = 0; gaaval->export = 0; gaaval->template = NULL; gaaval->hash=NULL; gaaval->fix_key = 0; gaaval->quick_random=1; gaaval->privkey_op = 0; gaaval->pkcs_cipher = "aes-128"; gaaval->crq_extensions=1; gaaval->pkcs11_provider= NULL; gaaval->pkcs11_url = NULL; gaaval->pkcs11_type = PKCS11_TYPE_PK; gaaval->pubkey=NULL; gaaval->pkcs11_label = NULL; - gaaval->pkcs11_trusted=0; gaaval->sec_param = NULL; gaaval->pkcs11_login = 0; ;}; + gaaval->pkcs11_trusted=0; gaaval->sec_param = NULL; gaaval->pkcs11_login = 0; gaaval->pkcs11_detailed_url = 0; ;}; } inited = 1; diff --git a/src/certtool-gaa.h b/src/certtool-gaa.h index 3e9a529dd0..43f1c4856a 100644 --- a/src/certtool-gaa.h +++ b/src/certtool-gaa.h @@ -8,8 +8,10 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 165 "certtool.gaa" +#line 168 "certtool.gaa" int debug; +#line 163 "certtool.gaa" + int pkcs11_detailed_url; #line 160 "certtool.gaa" int pkcs11_trusted; #line 157 "certtool.gaa" diff --git a/src/certtool.c b/src/certtool.c index 9e210962f2..5e8c2df99f 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -1138,10 +1138,10 @@ gaa_parser (int argc, char **argv) generate_pkcs8 (); break; case ACTION_PKCS11_LIST: - pkcs11_list(outfile, info.pkcs11_url, info.pkcs11_type, info.pkcs11_login); + pkcs11_list(outfile, info.pkcs11_url, info.pkcs11_type, info.pkcs11_login, info.pkcs11_detailed_url); break; case ACTION_PKCS11_TOKENS: - pkcs11_token_list(outfile); + pkcs11_token_list(outfile, info.pkcs11_detailed_url); break; case ACTION_PKCS11_EXPORT_URL: pkcs11_export(outfile, info.pkcs11_url, info.pkcs11_login); diff --git a/src/certtool.gaa b/src/certtool.gaa index 53955b87ec..61e6675400 100644 --- a/src/certtool.gaa +++ b/src/certtool.gaa @@ -160,6 +160,9 @@ option (pkcs11-write-label) STR "label" { $pkcs11_label = $1; } "Sets a label fo #int pkcs11_trusted; option (pkcs11-write-trusted) { $pkcs11_trusted = 1; } "Marks the certificate to be imported as trusted." +#int pkcs11_detailed_url; +option (pkcs11-detailed-url) { $pkcs11_detailed_url = 1; } "Export detailed URLs." + option (pkcs11-delete-url) STR "URL" { $action = ACTION_PKCS11_DELETE_URL; $pkcs11_url = $1; } "Deletes objects matching the URL." #int debug; @@ -175,4 +178,4 @@ init { $bits = 0; $pkcs8 = 0; $privkey = NULL; $ca=NULL; $ca_privkey = NULL; $export = 0; $template = NULL; $hash=NULL; $fix_key = 0; $quick_random=1; $privkey_op = 0; $pkcs_cipher = "aes-128"; $crq_extensions=1; $pkcs11_provider= NULL; $pkcs11_url = NULL; $pkcs11_type = PKCS11_TYPE_PK; $pubkey=NULL; $pkcs11_label = NULL; - $pkcs11_trusted=0; $sec_param = NULL; $pkcs11_login = 0; } + $pkcs11_trusted=0; $sec_param = NULL; $pkcs11_login = 0; $pkcs11_detailed_url = 0; } diff --git a/src/pkcs11.c b/src/pkcs11.c index 98c4f12218..0781ea5e17 100644 --- a/src/pkcs11.c +++ b/src/pkcs11.c @@ -88,7 +88,7 @@ unsigned int obj_flags = 0; obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; if (!batch) { - pkcs11_list(outfile, url, PKCS11_TYPE_ALL, login); + pkcs11_list(outfile, url, PKCS11_TYPE_ALL, login, 1); ret = read_yesno("Are you sure you want to delete those objects? (y/N): "); if (ret == 0) { exit(1); @@ -108,7 +108,7 @@ unsigned int obj_flags = 0; /* lists certificates from a token */ -void pkcs11_list( FILE* outfile, const char* url, int type, unsigned int login) +void pkcs11_list( FILE* outfile, const char* url, int type, unsigned int login, unsigned int detailed) { gnutls_pkcs11_obj_t *crt_list; gnutls_x509_crt_t xcrt; @@ -177,7 +177,7 @@ unsigned int obj_flags = 0; char buf[128]; size_t size; - ret = gnutls_pkcs11_obj_export_url(crt_list[i], &output); + ret = gnutls_pkcs11_obj_export_url(crt_list[i], detailed, &output); if (ret < 0) { fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); exit(1); @@ -349,7 +349,7 @@ unsigned int obj_flags = 0; } -void pkcs11_token_list(FILE* outfile) +void pkcs11_token_list(FILE* outfile, unsigned int detailed) { int ret; int i; @@ -360,7 +360,7 @@ size_t size; pkcs11_common(); for (i=0;;i++) { - ret = gnutls_pkcs11_token_get_url(i, &url); + ret = gnutls_pkcs11_token_get_url(i, detailed, &url); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) break;