summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2010-05-10 23:35:33 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2010-05-11 22:21:30 +0200
commit1cd3cedb84b2babc73e7bd273f03512c81a335af (patch)
tree4dc30e347640fe4fcba18770beca90e0f5b8dc82
parent5a8e0037afc1fa9224f86ddc0ced430e2f17bf03 (diff)
downloadgnutls-1cd3cedb84b2babc73e7bd273f03512c81a335af.tar.gz
Added several helper functions, to allow printing of tokens.
-rw-r--r--lib/includes/gnutls/pkcs11.h28
-rw-r--r--lib/libgnutls.map6
-rw-r--r--lib/pkcs11.c215
-rw-r--r--src/certtool-common.h9
-rw-r--r--src/certtool-gaa.c125
-rw-r--r--src/certtool-gaa.h2
-rw-r--r--src/certtool.c8
-rw-r--r--src/certtool.gaa1
-rw-r--r--src/pkcs11.c144
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;
+
+
+
+}