diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-05-10 23:35:33 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-05-11 22:21:30 +0200 |
commit | 1cd3cedb84b2babc73e7bd273f03512c81a335af (patch) | |
tree | 4dc30e347640fe4fcba18770beca90e0f5b8dc82 | |
parent | 5a8e0037afc1fa9224f86ddc0ced430e2f17bf03 (diff) | |
download | gnutls-1cd3cedb84b2babc73e7bd273f03512c81a335af.tar.gz |
Added several helper functions, to allow printing of tokens.
-rw-r--r-- | lib/includes/gnutls/pkcs11.h | 28 | ||||
-rw-r--r-- | lib/libgnutls.map | 6 | ||||
-rw-r--r-- | lib/pkcs11.c | 215 | ||||
-rw-r--r-- | src/certtool-common.h | 9 | ||||
-rw-r--r-- | src/certtool-gaa.c | 125 | ||||
-rw-r--r-- | src/certtool-gaa.h | 2 | ||||
-rw-r--r-- | src/certtool.c | 8 | ||||
-rw-r--r-- | src/certtool.gaa | 1 | ||||
-rw-r--r-- | src/pkcs11.c | 144 |
9 files changed, 448 insertions, 90 deletions
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h index 924879f50d..814be1e120 100644 --- a/lib/includes/gnutls/pkcs11.h +++ b/lib/includes/gnutls/pkcs11.h @@ -167,11 +167,32 @@ void gnutls_pkcs11_crt_deinit ( gnutls_pkcs11_crt_t certificate); int gnutls_pkcs11_crt_list_deinit (gnutls_pkcs11_crt_t * certificates, const unsigned int ncertificates); typedef enum { - GNUTLS_PKCS11_CRT_ATTR_ALL, + GNUTLS_PKCS11_CRT_ID_HEX=1, + GNUTLS_PKCS11_CRT_LABEL, + GNUTLS_PKCS11_CRT_TOKEN_LABEL, + GNUTLS_PKCS11_CRT_TOKEN_SERIAL, + GNUTLS_PKCS11_CRT_TOKEN_MANUFACTURER, + GNUTLS_PKCS11_CRT_TOKEN_MODEL, +} gnutls_pkcs11_cert_info_t; + +int gnutls_pkcs11_crt_get_info(gnutls_pkcs11_crt_t crt, gnutls_pkcs11_cert_info_t itype, void* output, size_t* output_size); + +typedef enum { + GNUTLS_PKCS11_CRT_ATTR_ALL=1, GNUTLS_PKCS11_CRT_ATTR_TRUSTED, /* marked as trusted */ GNUTLS_PKCS11_CRT_ATTR_WITH_PK, /* with corresponding private key */ -} pkcs11_crt_attributes; +} gnutls_pkcs11_crt_attr_t; + +/* token info */ +typedef enum { + GNUTLS_PKCS11_TOKEN_LABEL, + GNUTLS_PKCS11_TOKEN_SERIAL, + GNUTLS_PKCS11_TOKEN_MANUFACTURER, + GNUTLS_PKCS11_TOKEN_MODEL, +} gnutls_pkcs11_token_info_t; +int gnutls_pkcs11_token_get_url (unsigned int seq, char** url); +int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t, void* output, size_t *output_size); /** * @brief Enumerate available certificates. * @param p_list Location to store the list. @@ -181,9 +202,10 @@ typedef enum { * @return gnutls status. * @note the p_list is should not be initialized. */ -int gnutls_pkcs11_crt_list_import (gnutls_pkcs11_crt_t * p_list, unsigned int *const n_list, const char* url, pkcs11_crt_attributes flags); +int gnutls_pkcs11_crt_list_import_url (gnutls_pkcs11_crt_t * p_list, unsigned int *const n_list, const char* url, gnutls_pkcs11_crt_attr_t flags); int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_crt_t pkcs11_crt); +int gnutls_x509_crt_import_pkcs11_url( gnutls_x509_crt_t crt, const char* url); /** * @brief Return the type of the certificate diff --git a/lib/libgnutls.map b/lib/libgnutls.map index b2143a4286..314d2ee6f6 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -616,10 +616,14 @@ GNUTLS_2_11 gnutls_pkcs11_crt_export_url; gnutls_pkcs11_crt_deinit; gnutls_pkcs11_crt_list_deinit; - gnutls_pkcs11_crt_list_import; + gnutls_pkcs11_crt_list_import_url; gnutls_x509_crt_import_pkcs11; gnutls_pkcs11_crt_get_type; gnutls_x509_crt_list_import_pkcs11; + gnutls_x509_crt_import_pkcs11_url; + gnutls_pkcs11_crt_get_info; + gnutls_pkcs11_token_get_info; + gnutls_pkcs11_token_get_url; } GNUTLS_2_10; GNUTLS_PRIVATE { diff --git a/lib/pkcs11.c b/lib/pkcs11.c index 459b3d57dc..0f6c1fbfaf 100644 --- a/lib/pkcs11.c +++ b/lib/pkcs11.c @@ -31,6 +31,8 @@ #define ID_SIZE 128 #define LABEL_SIZE 128 +/* XXX: try to eliminate this */ +#define MAX_CERT_SIZE 8*1024 struct gnutls_pkcs11_provider_s { pakchois_module_t *module; @@ -67,7 +69,7 @@ struct crt_find_data_st { gnutls_pkcs11_crt_t *p_list; unsigned int* n_list; unsigned int current; - pkcs11_crt_attributes flags; + gnutls_pkcs11_crt_attr_t flags; struct pkcs11_url_info info; }; @@ -78,6 +80,10 @@ struct token_info { struct gnutls_pkcs11_provider_s* prov; }; +/* thus function is called for every token in the traverse_tokens + * function. Once everything is traversed it is called with NULL tinfo. + * 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); static struct gnutls_pkcs11_provider_s providers[MAX_PROVIDERS]; @@ -131,6 +137,52 @@ fail: } +/* returns strings of the PKCS#11 certificate structure. + * Returns null terminated strings but output_size contains + * the size of the actual data only. + */ +int gnutls_pkcs11_crt_get_info(gnutls_pkcs11_crt_t crt, gnutls_pkcs11_cert_info_t itype, + void* output, size_t* output_size) +{ + const char* str; + size_t len; + + switch(itype) { + case GNUTLS_PKCS11_CRT_ID_HEX: + str = crt->info.id; + break; + case GNUTLS_PKCS11_CRT_LABEL: + str = crt->info.label; + break; + case GNUTLS_PKCS11_CRT_TOKEN_LABEL: + str = crt->info.token; + break; + case GNUTLS_PKCS11_CRT_TOKEN_SERIAL: + str = crt->info.serial; + break; + case GNUTLS_PKCS11_CRT_TOKEN_MANUFACTURER: + str = crt->info.manufacturer; + break; + case GNUTLS_PKCS11_CRT_TOKEN_MODEL: + str = crt->info.model; + break; + } + + len = strlen(str); + + if (len+1>*output_size) { + *output_size = len+1; + return GNUTLS_E_SHORT_MEMORY_BUFFER; + } + + strcpy(output, str); + + *output_size = len; + + return 0; +} + + int gnutls_pkcs11_init(unsigned int flags, const char* configfile) { int ret; @@ -423,12 +475,16 @@ static int pkcs11_info_to_url(const struct pkcs11_url_info* info, char** url) init = 1; } - ret = _gnutls_string_append_printf(&str, ";id=%s", info->id); - if (ret < 0) { - gnutls_assert(); - return ret; + if (info->id[0] != 0) { + ret = _gnutls_string_append_printf(&str, ";id=%s", info->id); + if (ret < 0) { + gnutls_assert(); + return ret; + } } + _gnutls_string_append_data(&str, "", 1); + *url = str.data; return 0; @@ -509,11 +565,12 @@ static int traverse_tokens (find_func_t find_func, void* input) if (ret == 0) { found = 1; - break; + goto finish; } } } +finish: /* final call */ if (found == 0) { @@ -579,7 +636,7 @@ static int find_cert_url(pakchois_session_t *pks, struct token_info *info, void* ck_object_handle_t obj; unsigned long count; int found = 0, ret; - unsigned char value[8192], subject[8192]; + unsigned char value[MAX_CERT_SIZE]; char certid_tmp[ID_SIZE]; char label_tmp[LABEL_SIZE]; @@ -653,13 +710,6 @@ static int find_cert_url(pakchois_session_t *pks, struct token_info *info, void* a[2].value_len = sizeof(label_tmp); if (pakchois_get_attribute_value(pks, obj, a, 3) == CKR_OK) { -char buf[512]; -char buf2[512]; -fprintf(stderr, "val: %d, certid: %d\n", a[1].value_len, find_data->certid_raw_size); -fprintf(stderr, "fcertid: %s, gcertid: %s\n", _gnutls_bin2hex (a[1].value, a[1].value_len, buf, - sizeof (buf), NULL), _gnutls_bin2hex (a[1].value, a[1].value_len, buf2, - sizeof (buf2), NULL)); - if (a[1].value_len == find_data->certid_raw_size && memcmp(certid_tmp, find_data->certid_raw, find_data->certid_raw_size)==0) { gnutls_datum_t id = { a[1].value, a[1].value_len }; @@ -715,7 +765,7 @@ int gnutls_pkcs11_crt_import_url (gnutls_pkcs11_crt_t cert, const char * url) gnutls_assert(); return ret; } -fprintf(stderr, "hex2bin: %d, %d\n", ret, find_data.certid_raw_size); + ret = traverse_tokens(find_cert_url, &find_data); if (ret < 0) { gnutls_assert(); @@ -725,6 +775,104 @@ fprintf(stderr, "hex2bin: %d, %d\n", ret, find_data.certid_raw_size); return 0; } +struct token_num { + struct pkcs11_url_info info; + unsigned int seq; /* which one we are looking for */ + unsigned int current; /* which one are we now */ +}; + +static int find_token_num(pakchois_session_t *pks, struct token_info *tinfo, void* input) +{ + struct token_num* find_data = input; + + if (tinfo == NULL) { /* we don't support multiple calls */ + gnutls_assert(); + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; + } + + if (find_data->current == find_data->seq) { + strcpy(find_data->info.manufacturer, tinfo->tinfo.manufacturer_id); + strcpy(find_data->info.token, tinfo->tinfo.label); + strcpy(find_data->info.model, tinfo->tinfo.model); + strcpy(find_data->info.serial, tinfo->tinfo.serial_number); + + return 0; + } + + find_data->current++; + /* search the token for the id */ + + + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; /* non zero is enough */ +} + +int gnutls_pkcs11_token_get_url (unsigned int seq, char** url) +{ + int ret; + struct token_num tn; + + memset(&tn, 0, sizeof(tn)); + tn.seq = seq; + + ret = traverse_tokens(find_token_num, &tn); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = pkcs11_info_to_url(&tn.info, url); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + return 0; + +} + +int gnutls_pkcs11_token_get_info(const char* url, gnutls_pkcs11_token_info_t ttype, void* output, size_t *output_size) +{ + const char* str; + size_t len; + struct pkcs11_url_info info; + int ret; + + ret = pkcs11_url_to_info(url, &info); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + switch(ttype) { + case GNUTLS_PKCS11_TOKEN_LABEL: + str = info.token; + break; + case GNUTLS_PKCS11_TOKEN_SERIAL: + str = info.serial; + break; + case GNUTLS_PKCS11_TOKEN_MANUFACTURER: + str = info.manufacturer; + break; + case GNUTLS_PKCS11_TOKEN_MODEL: + str = info.model; + break; + } + + len = strlen(str); + + if (len+1>*output_size) { + *output_size = len+1; + return GNUTLS_E_SHORT_MEMORY_BUFFER; + } + + strcpy(output, str); + + *output_size = len; + + return 0; +} + + int gnutls_pkcs11_crt_export_url (gnutls_pkcs11_crt_t cert, char ** url) { int ret; @@ -935,7 +1083,7 @@ static int find_crts(pakchois_session_t *pks, struct token_info *info, void* inp ck_rv_t rv; ck_object_handle_t obj; unsigned long count; - unsigned char value[8192], subject[8192]; + unsigned char value[MAX_CERT_SIZE]; char certid_tmp[ID_SIZE]; char label_tmp[LABEL_SIZE]; int ret, i; @@ -1095,7 +1243,7 @@ fail: return ret; } -int gnutls_pkcs11_crt_list_import (gnutls_pkcs11_crt_t * p_list, unsigned int *n_list, const char* url, pkcs11_crt_attributes flags) +int gnutls_pkcs11_crt_list_import_url (gnutls_pkcs11_crt_t * p_list, unsigned int *n_list, const char* url, gnutls_pkcs11_crt_attr_t flags) { int ret; struct crt_find_data_st find_data; @@ -1125,6 +1273,39 @@ int gnutls_pkcs11_crt_list_import (gnutls_pkcs11_crt_t * p_list, unsigned int *n return 0; } +int gnutls_x509_crt_import_pkcs11_url( gnutls_x509_crt_t crt, const char* url) +{ + gnutls_pkcs11_crt_t pcrt; + int ret; + + ret = gnutls_pkcs11_crt_init ( &pcrt); + if (ret < 0) { + gnutls_assert(); + return ret; + } + + ret = gnutls_pkcs11_crt_import_url (pcrt, url); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = gnutls_x509_crt_import(crt, &pcrt->raw, GNUTLS_X509_FMT_DER); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + ret = 0; +cleanup: + + gnutls_pkcs11_crt_deinit(pcrt); + + return ret; +} + + + int gnutls_x509_crt_import_pkcs11( gnutls_x509_crt_t crt, gnutls_pkcs11_crt_t pkcs11_crt) { return gnutls_x509_crt_import(crt, &pkcs11_crt->raw, GNUTLS_X509_FMT_DER); diff --git a/src/certtool-common.h b/src/certtool-common.h index f0132d402f..ae6891e9ab 100644 --- a/src/certtool-common.h +++ b/src/certtool-common.h @@ -27,6 +27,7 @@ enum ACTION_RING_INFO, ACTION_REQUEST, ACTION_PKCS11_LIST, + ACTION_PKCS11_TOKENS, ACTION_PKCS11_EXPORT_URL, }; @@ -34,11 +35,13 @@ enum #define TYPE_CRQ 2 void certtool_version (void); -void pkcs11_list( const char* url, int type); +void pkcs11_list( FILE*outfile, const char* url, int type); void pkcs11_export(FILE* outfile, const char *pkcs11_url); -void print_certificate_info (gnutls_x509_crt_t crt, FILE * out, - unsigned int); +void pkcs11_token_list(FILE* outfile); #define PKCS11_TYPE_ALL 1 #define PKCS11_TYPE_TRUSTED 2 #define PKCS11_TYPE_PK 3 + +extern unsigned char buffer[]; +extern const int buffer_size; diff --git a/src/certtool-gaa.c b/src/certtool-gaa.c index 056f6bef4b..aae181d175 100644 --- a/src/certtool-gaa.c +++ b/src/certtool-gaa.c @@ -180,6 +180,7 @@ void gaa_help(void) __gaa_helpsingle(0, "pkcs11-list", "", "List objects specified by a PKCS#11 URL"); __gaa_helpsingle(0, "pkcs11-list-trusted", "", "List objects marked as trusted, specified by a PKCS#11 URL"); __gaa_helpsingle(0, "pkcs11-list-all", "", "List all objects specified by a PKCS#11 URL"); + __gaa_helpsingle(0, "pkcs11-list-tokens", "", "List all available tokens"); __gaa_helpsingle('d', "debug", "LEVEL ", "specify the debug level. Default is 1."); __gaa_helpsingle('h', "help", "", "shows this help text"); __gaa_helpsingle('v', "version", "", "shows the program's version"); @@ -197,7 +198,7 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 142 "certtool.gaa" +#line 143 "certtool.gaa" int debug; #line 137 "certtool.gaa" int pkcs11_type; @@ -305,61 +306,62 @@ static int gaa_error = 0; #define GAA_MULTIPLE_OPTION 3 #define GAA_REST 0 -#define GAA_NB_OPTION 54 +#define GAA_NB_OPTION 55 #define GAAOPTID_version 1 #define GAAOPTID_help 2 #define GAAOPTID_debug 3 -#define GAAOPTID_pkcs11_list_all 4 -#define GAAOPTID_pkcs11_list_trusted 5 -#define GAAOPTID_pkcs11_list 6 -#define GAAOPTID_pkcs11_export_url 7 -#define GAAOPTID_pkcs11_provider 8 -#define GAAOPTID_pkcs_cipher 9 -#define GAAOPTID_template 10 -#define GAAOPTID_infile 11 -#define GAAOPTID_outfile 12 -#define GAAOPTID_disable_quick_random 13 -#define GAAOPTID_bits 14 -#define GAAOPTID_outraw 15 -#define GAAOPTID_outder 16 -#define GAAOPTID_inraw 17 -#define GAAOPTID_inder 18 -#define GAAOPTID_export_ciphers 19 -#define GAAOPTID_hash 20 -#define GAAOPTID_dsa 21 -#define GAAOPTID_pkcs8 22 -#define GAAOPTID_to_p8 23 -#define GAAOPTID_to_p12 24 -#define GAAOPTID_v1 25 -#define GAAOPTID_fix_key 26 -#define GAAOPTID_pgp_key_info 27 -#define GAAOPTID_key_info 28 -#define GAAOPTID_smime_to_p7 29 -#define GAAOPTID_p7_info 30 -#define GAAOPTID_p12_info 31 -#define GAAOPTID_no_crq_extensions 32 -#define GAAOPTID_crq_info 33 -#define GAAOPTID_crl_info 34 -#define GAAOPTID_pgp_ring_info 35 -#define GAAOPTID_pgp_certificate_info 36 -#define GAAOPTID_certificate_info 37 -#define GAAOPTID_password 38 -#define GAAOPTID_load_ca_certificate 39 -#define GAAOPTID_load_ca_privkey 40 -#define GAAOPTID_load_certificate 41 -#define GAAOPTID_load_request 42 -#define GAAOPTID_load_privkey 43 -#define GAAOPTID_get_dh_params 44 -#define GAAOPTID_generate_dh_params 45 -#define GAAOPTID_verify_crl 46 -#define GAAOPTID_verify_chain 47 -#define GAAOPTID_generate_request 48 -#define GAAOPTID_generate_privkey 49 -#define GAAOPTID_update_certificate 50 -#define GAAOPTID_generate_crl 51 -#define GAAOPTID_generate_proxy 52 -#define GAAOPTID_generate_certificate 53 -#define GAAOPTID_generate_self_signed 54 +#define GAAOPTID_pkcs11_list_tokens 4 +#define GAAOPTID_pkcs11_list_all 5 +#define GAAOPTID_pkcs11_list_trusted 6 +#define GAAOPTID_pkcs11_list 7 +#define GAAOPTID_pkcs11_export_url 8 +#define GAAOPTID_pkcs11_provider 9 +#define GAAOPTID_pkcs_cipher 10 +#define GAAOPTID_template 11 +#define GAAOPTID_infile 12 +#define GAAOPTID_outfile 13 +#define GAAOPTID_disable_quick_random 14 +#define GAAOPTID_bits 15 +#define GAAOPTID_outraw 16 +#define GAAOPTID_outder 17 +#define GAAOPTID_inraw 18 +#define GAAOPTID_inder 19 +#define GAAOPTID_export_ciphers 20 +#define GAAOPTID_hash 21 +#define GAAOPTID_dsa 22 +#define GAAOPTID_pkcs8 23 +#define GAAOPTID_to_p8 24 +#define GAAOPTID_to_p12 25 +#define GAAOPTID_v1 26 +#define GAAOPTID_fix_key 27 +#define GAAOPTID_pgp_key_info 28 +#define GAAOPTID_key_info 29 +#define GAAOPTID_smime_to_p7 30 +#define GAAOPTID_p7_info 31 +#define GAAOPTID_p12_info 32 +#define GAAOPTID_no_crq_extensions 33 +#define GAAOPTID_crq_info 34 +#define GAAOPTID_crl_info 35 +#define GAAOPTID_pgp_ring_info 36 +#define GAAOPTID_pgp_certificate_info 37 +#define GAAOPTID_certificate_info 38 +#define GAAOPTID_password 39 +#define GAAOPTID_load_ca_certificate 40 +#define GAAOPTID_load_ca_privkey 41 +#define GAAOPTID_load_certificate 42 +#define GAAOPTID_load_request 43 +#define GAAOPTID_load_privkey 44 +#define GAAOPTID_get_dh_params 45 +#define GAAOPTID_generate_dh_params 46 +#define GAAOPTID_verify_crl 47 +#define GAAOPTID_verify_chain 48 +#define GAAOPTID_generate_request 49 +#define GAAOPTID_generate_privkey 50 +#define GAAOPTID_update_certificate 51 +#define GAAOPTID_generate_crl 52 +#define GAAOPTID_generate_proxy 53 +#define GAAOPTID_generate_certificate 54 +#define GAAOPTID_generate_self_signed 55 #line 168 "gaa.skel" @@ -684,6 +686,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_list_tokens); GAA_CHECK1STR("", GAAOPTID_pkcs11_list_all); GAA_CHECK1STR("", GAAOPTID_pkcs11_list_trusted); GAA_CHECK1STR("", GAAOPTID_pkcs11_list); @@ -728,6 +731,7 @@ static int gaa_get_option_num(char *str, int status) GAA_CHECKSTR("version", GAAOPTID_version); GAA_CHECKSTR("help", GAAOPTID_help); GAA_CHECKSTR("debug", GAAOPTID_debug); + GAA_CHECKSTR("pkcs11-list-tokens", GAAOPTID_pkcs11_list_tokens); GAA_CHECKSTR("pkcs11-list-all", GAAOPTID_pkcs11_list_all); GAA_CHECKSTR("pkcs11-list-trusted", GAAOPTID_pkcs11_list_trusted); GAA_CHECKSTR("pkcs11-list", GAAOPTID_pkcs11_list); @@ -828,14 +832,14 @@ static int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list) { case GAAOPTID_version: OK = 0; -#line 147 "certtool.gaa" +#line 148 "certtool.gaa" { certtool_version(); exit(0); ;}; return GAA_OK; break; case GAAOPTID_help: OK = 0; -#line 145 "certtool.gaa" +#line 146 "certtool.gaa" { gaa_help(); exit(0); ;}; return GAA_OK; @@ -845,11 +849,18 @@ 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 143 "certtool.gaa" +#line 144 "certtool.gaa" { gaaval->debug = GAATMP_debug.arg1 ;}; return GAA_OK; break; + case GAAOPTID_pkcs11_list_tokens: + OK = 0; +#line 141 "certtool.gaa" +{ gaaval->action = ACTION_PKCS11_TOKENS; ;}; + + return GAA_OK; + break; case GAAOPTID_pkcs11_list_all: OK = 0; #line 140 "certtool.gaa" @@ -1273,7 +1284,7 @@ int gaa(int argc, char **argv, gaainfo *gaaval) if(inited == 0) { -#line 149 "certtool.gaa" +#line 150 "certtool.gaa" { gaaval->bits = 2048; 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; diff --git a/src/certtool-gaa.h b/src/certtool-gaa.h index 8e00cb9a7d..ded4286568 100644 --- a/src/certtool-gaa.h +++ b/src/certtool-gaa.h @@ -8,7 +8,7 @@ typedef struct _gaainfo gaainfo; struct _gaainfo { -#line 142 "certtool.gaa" +#line 143 "certtool.gaa" int debug; #line 137 "certtool.gaa" int pkcs11_type; diff --git a/src/certtool.c b/src/certtool.c index 5a5165e1b1..2b6a729a01 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -75,6 +75,7 @@ static void gaa_parser (int argc, char **argv); void generate_self_signed (void); void generate_request (void); gnutls_x509_crt_t *load_cert_list (int mand, size_t * size); +static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all); static void print_hex_datum (gnutls_datum_t * dat); @@ -1026,7 +1027,10 @@ gaa_parser (int argc, char **argv) generate_pkcs8 (); break; case ACTION_PKCS11_LIST: - pkcs11_list(info.pkcs11_url, info.pkcs11_type); + pkcs11_list(outfile, info.pkcs11_url, info.pkcs11_type); + break; + case ACTION_PKCS11_TOKENS: + pkcs11_token_list(outfile); break; case ACTION_PKCS11_EXPORT_URL: pkcs11_export(outfile, info.pkcs11_url); @@ -1371,7 +1375,7 @@ print_hex_datum (gnutls_datum_t * dat) } -void +static void print_certificate_info (gnutls_x509_crt_t crt, FILE * out, unsigned int all) { gnutls_datum_t cinfo; diff --git a/src/certtool.gaa b/src/certtool.gaa index fec590e7f1..0e9da9e0c0 100644 --- a/src/certtool.gaa +++ b/src/certtool.gaa @@ -138,6 +138,7 @@ option (pkcs11-export-url) STR "URL" { $action = ACTION_PKCS11_EXPORT_URL; $pkcs option (pkcs11-list) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_PK; } "List objects specified by a PKCS#11 URL" option (pkcs11-list-trusted) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_TRUSTED; } "List objects marked as trusted, specified by a PKCS#11 URL" option (pkcs11-list-all) { $action = ACTION_PKCS11_LIST; $pkcs11_type=PKCS11_TYPE_ALL; } "List all objects specified by a PKCS#11 URL" +option (pkcs11-list-tokens) { $action = ACTION_PKCS11_TOKENS; } "List all available tokens" #int debug; option (d, debug) INT "LEVEL" { $debug = $1 } "specify the debug level. Default is 1." diff --git a/src/pkcs11.c b/src/pkcs11.c index b493649613..bc0f5b16fc 100644 --- a/src/pkcs11.c +++ b/src/pkcs11.c @@ -41,9 +41,10 @@ static void pkcs11_common(void) /* lists certificates from a token */ -void pkcs11_list( const char* url, int type) +void pkcs11_list( FILE* outfile, const char* url, int type) { gnutls_pkcs11_crt_t *crt_list; +gnutls_x509_crt_t xcrt; unsigned int crt_list_size = 0; int ret; char* output; @@ -54,7 +55,7 @@ int i, flags; if (url == NULL) url = "pkcs11:"; - ret = gnutls_pkcs11_crt_list_import( NULL, &crt_list_size, url, GNUTLS_PKCS11_CRT_ATTR_ALL); + ret = gnutls_pkcs11_crt_list_import_url( NULL, &crt_list_size, url, GNUTLS_PKCS11_CRT_ATTR_ALL); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { fprintf(stderr, "Error in crt_list_import (1): %s\n", gnutls_strerror(ret)); exit(1); @@ -79,15 +80,69 @@ int i, flags; flags = GNUTLS_PKCS11_CRT_ATTR_ALL; } - ret = gnutls_pkcs11_crt_list_import( crt_list, &crt_list_size, url, flags); + ret = gnutls_pkcs11_crt_list_import_url( crt_list, &crt_list_size, url, flags); if (ret < 0) { fprintf(stderr, "Error in crt_list_import: %s\n", gnutls_strerror(ret)); exit(1); } for (i=0;i<crt_list_size;i++) { - gnutls_pkcs11_crt_export_url(crt_list[i], &output); - fprintf(stderr, "cert[%d]: %s\n\n", i, output); + char buf[128]; + size_t size; + + + ret = gnutls_pkcs11_crt_export_url(crt_list[i], &output); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "Certificate %d:\n\tURL: %s\n", i, output); + + size = sizeof(buf); + ret = gnutls_pkcs11_crt_get_info( crt_list[i], GNUTLS_PKCS11_CRT_LABEL, buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + fprintf(outfile, "\tLabel: %s\n", buf); + + size = sizeof(buf); + ret = gnutls_pkcs11_crt_get_info( crt_list[i], GNUTLS_PKCS11_CRT_ID_HEX, buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + fprintf(outfile, "\tID: %s\n\n", buf); + + + ret = gnutls_x509_crt_init(&xcrt); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + + ret = gnutls_x509_crt_import_pkcs11(xcrt, crt_list[i]); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + +#if 0 + size = buffer_size; + ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fwrite (buffer, 1, size, outfile); + fputs("\n\n", outfile); +#endif + + gnutls_x509_crt_deinit(xcrt); + + } return; @@ -98,6 +153,7 @@ void pkcs11_export(FILE* outfile, const char* url) gnutls_pkcs11_crt_t crt; gnutls_x509_crt_t xcrt; int ret; +size_t size; pkcs11_common(); @@ -128,7 +184,14 @@ int ret; exit(1); } - print_certificate_info(xcrt, outfile, 1); + size = buffer_size; + ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + fwrite (buffer, 1, size, outfile); + fputs("\n\n", outfile); gnutls_x509_crt_deinit(xcrt); gnutls_pkcs11_crt_deinit(crt); @@ -138,3 +201,72 @@ int ret; } + +void pkcs11_token_list(FILE* outfile) +{ +int ret; +int i; +char *url; +char buf[128]; +size_t size; + + pkcs11_common(); + + for (i=0;;i++) { + ret = gnutls_pkcs11_token_get_url(i, &url); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "Token %d:\n\tURL: %s\n", i, url); + + size = sizeof(buf); + ret = gnutls_pkcs11_token_get_info(url, GNUTLS_PKCS11_TOKEN_LABEL, buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tLabel: %s\n", buf); + + size = sizeof(buf); + ret = gnutls_pkcs11_token_get_info(url, GNUTLS_PKCS11_TOKEN_MANUFACTURER, buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tManufacturer: %s\n", buf); + + size = sizeof(buf); + ret = gnutls_pkcs11_token_get_info(url, GNUTLS_PKCS11_TOKEN_MODEL, buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tModel: %s\n", buf); + + size = sizeof(buf); + ret = gnutls_pkcs11_token_get_info(url, GNUTLS_PKCS11_TOKEN_SERIAL, buf, &size); + if (ret < 0) { + fprintf(stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror(ret)); + exit(1); + } + + fprintf(outfile, "\tSerial: %s\n", buf); + fprintf(outfile, "\n\n"); + + gnutls_free(url); + + } + + return; + + + +} |