diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-05-07 12:52:41 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2011-05-07 12:52:41 +0200 |
commit | 50c4bb2247957f852dfc52de2e9ca39e09bd3de0 (patch) | |
tree | 3430c308cc3b137f0e21f2d9808fd9b312137bbd | |
parent | b705430a0ad51fcbc48252f439b346de85636e9c (diff) | |
download | gnutls-50c4bb2247957f852dfc52de2e9ca39e09bd3de0.tar.gz |
certtool can now load private keys and public keys from PKCS #11 tokens (via URLs).
-rw-r--r-- | doc/manpages/certtool.1 | 16 | ||||
-rw-r--r-- | src/Makefile.am | 10 | ||||
-rw-r--r-- | src/certtool-common.c | 237 | ||||
-rw-r--r-- | src/certtool-common.h | 6 | ||||
-rw-r--r-- | src/certtool.c | 86 | ||||
-rw-r--r-- | src/common.c | 80 | ||||
-rw-r--r-- | src/p11common.c | 109 | ||||
-rw-r--r-- | src/p11common.h | 1 | ||||
-rw-r--r-- | src/pkcs11.c | 2 |
9 files changed, 397 insertions, 150 deletions
diff --git a/doc/manpages/certtool.1 b/doc/manpages/certtool.1 index 892ac4b9da..895e309b6e 100644 --- a/doc/manpages/certtool.1 +++ b/doc/manpages/certtool.1 @@ -42,11 +42,13 @@ Generate PKCS #3 encoded Diffie-Hellman parameters. .IP "\-\-load\-ca\-certificate FILE" Certificate authority's certificate file to use. .IP "\-\-load\-ca\-privkey FILE" -Certificate authority's private key file to use. +Certificate authority's private key file or PKCS #11 URL to use. .IP "\-\-load\-certificate FILE" Certificate file to use. .IP "\-\-load\-privkey FILE" -Private key file to use. +Private key file or PKCS #11 URL to use. +.IP "\-\-load\-pubkey FILE" +Public key file or PKCS #11 URL to use. .IP "\-\-load\-request FILE" Certificate request file to use. .IP "\-p, \-\-generate\-privkey" @@ -114,6 +116,16 @@ $ certtool \-\-generate\-request \-\-load\-privkey key.pem \\ .fi .RE +To create a certificate request using a key stored in a PKCS #11 +token, run: + +.RS +.nf +$ ./certtool \-\-generate-request \-\-load-privkey "pkcs11:..." \\ + \-\-load-pubkey "pkcs11:..." \-\-outfile request.pem +.fi +.RE + To generate a certificate using the previous request, use the command: .RS diff --git a/src/Makefile.am b/src/Makefile.am index 5a48efe38b..379d3c8f32 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,8 +42,8 @@ noinst_LTLIBRARIES = gnutls_serv_SOURCES = \ list.h serv.c \ udp-serv.c udp-serv.h \ - common.h common.c \ - certtool-common.h + common.h common.c p11common.c \ + certtool-common.h p11common.h gnutls_serv_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la gnutls_serv_LDADD += libcmd-serv.la ../gl/libgnu.la gnutls_serv_LDADD += $(LTLIBGCRYPT) $(LIBSOCKET) $(GETADDRINFO_LIB) @@ -68,7 +68,7 @@ libcmd_psk_la_SOURCES = psk.gaa psk-gaa.h psk-gaa.c benchmark_SOURCES = benchmark.c benchmark_LDADD = ../lib/libgnutls.la ../gl/libgnu.la $(LIB_CLOCK_GETTIME) -gnutls_cli_SOURCES = cli.c common.h common.c +gnutls_cli_SOURCES = cli.c common.h common.c p11common.c p11common.h gnutls_cli_LDADD = ../lib/libgnutls.la ../libextra/libgnutls-extra.la gnutls_cli_LDADD += libcmd-cli.la ../gl/libgnu.la gnutls_cli_LDADD += $(LTLIBGCRYPT) $(LIBSOCKET) $(GETADDRINFO_LIB) @@ -76,7 +76,7 @@ noinst_LTLIBRARIES += libcmd-cli.la libcmd_cli_la_CFLAGS = libcmd_cli_la_SOURCES = cli.gaa cli-gaa.h cli-gaa.c -gnutls_cli_debug_SOURCES = tls_test.c tests.h tests.c common.h common.c +gnutls_cli_debug_SOURCES = tls_test.c tests.h tests.c common.h common.c p11common.c p11common.h gnutls_cli_debug_LDADD = ../lib/libgnutls.la libcmd-cli-debug.la gnutls_cli_debug_LDADD += ../gl/libgnu.la $(LIBSOCKET) $(GETADDRINFO_LIB) noinst_LTLIBRARIES += libcmd-cli-debug.la @@ -85,7 +85,7 @@ libcmd_cli_debug_la_SOURCES = tls_test.gaa tls_test-gaa.h tls_test-gaa.c #certtool -certtool_SOURCES = certtool.c prime.c certtool-common.c +certtool_SOURCES = certtool.c prime.c certtool-common.c p11common.c p11common.h certtool_LDADD = ../lib/libgnutls.la certtool_LDADD += libcmd-certtool.la ../gl/libgnu.la certtool_LDADD += $(LTLIBGCRYPT) diff --git a/src/certtool-common.c b/src/certtool-common.c index 7e7083dcad..a4cc71c92b 100644 --- a/src/certtool-common.c +++ b/src/certtool-common.c @@ -103,12 +103,199 @@ load_secret_key (int mand, common_info_st * info) return &key; } +static gnutls_privkey_t _load_privkey(gnutls_datum_t *dat, common_info_st * info) +{ +int ret; +gnutls_privkey_t key; +gnutls_x509_privkey_t xkey; + + ret = gnutls_x509_privkey_init (&xkey); + if (ret < 0) + error (EXIT_FAILURE, 0, "x509_privkey_init: %s", gnutls_strerror (ret)); + + ret = gnutls_privkey_init (&key); + if (ret < 0) + error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret)); + + if (info->pkcs8) + { + const char *pass = get_pass (); + ret = + gnutls_x509_privkey_import_pkcs8 (xkey, dat, info->incert_format, + pass, 0); + } + else + ret = gnutls_x509_privkey_import (xkey, dat, info->incert_format); + + if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR) + { + error (EXIT_FAILURE, 0, + "import error: could not find a valid PEM header; " + "check if your key is PKCS #8 or PKCS #12 encoded"); + } + + if (ret < 0) + error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s", + info->privkey, gnutls_strerror (ret)); + + ret = gnutls_privkey_import_x509(key, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); + if (ret < 0) + error (EXIT_FAILURE, 0, "gnutls_privkey_import_x509: %s", + gnutls_strerror (ret)); + + return key; +} + +static gnutls_privkey_t _load_pkcs11_privkey(const char* url) +{ +int ret; +gnutls_pkcs11_privkey_t p11key; +gnutls_privkey_t key; + + ret = gnutls_privkey_init (&key); + if (ret < 0) + error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret)); + + ret = gnutls_pkcs11_privkey_init (&p11key); + if (ret < 0) + error (EXIT_FAILURE, 0, "pkcs11_privkey_init: %s", gnutls_strerror (ret)); + + ret = gnutls_pkcs11_privkey_import_url(p11key, url, 0); + if (ret < 0) + error (EXIT_FAILURE, 0, "importing PKCS #11 key: %s: %s", + url, gnutls_strerror (ret)); + + ret = gnutls_privkey_import_pkcs11(key, p11key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); + if (ret < 0) + error (EXIT_FAILURE, 0, "gnutls_privkey_import_pkcs11: %s", + gnutls_strerror (ret)); + + return key; +} + +static gnutls_pubkey_t _load_pkcs11_pubkey(const char* url) +{ +int ret; +gnutls_pkcs11_obj_t obj; +gnutls_x509_crt_t xcrt; +gnutls_pubkey_t pubkey; +unsigned int obj_flags = 0; + + ret = gnutls_pubkey_init (&pubkey); + if (ret < 0) + { + fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror (ret)); + exit (1); + } + + ret = gnutls_pkcs11_obj_init (&obj); + if (ret < 0) + { + fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror (ret)); + exit (1); + } + + ret = gnutls_pkcs11_obj_import_url (obj, url, obj_flags); + if (ret < 0) + { + fprintf (stderr, "Error in %s:%d: %s: %s\n", __func__, __LINE__, + gnutls_strerror (ret), url); + exit (1); + } + + switch (gnutls_pkcs11_obj_get_type (obj)) + { + case GNUTLS_PKCS11_OBJ_X509_CRT: + 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, obj); + if (ret < 0) + { + fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror (ret)); + exit (1); + } + + ret = gnutls_pubkey_import_x509 (pubkey, xcrt, 0); + if (ret < 0) + { + fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror (ret)); + exit (1); + } + + gnutls_x509_crt_deinit (xcrt); + break; + case GNUTLS_PKCS11_OBJ_PUBKEY: + + ret = gnutls_pubkey_import_pkcs11 (pubkey, obj, 0); + if (ret < 0) + { + fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, + gnutls_strerror (ret)); + exit (1); + } + + break; + default: + { + fprintf(stderr, "Unsupported PKCS #11 object\n"); + exit (1); + break; + } + } + + gnutls_pkcs11_obj_deinit (obj); + return pubkey; +} + + /* Load the private key. * @mand should be non zero if it is required to read a private key. */ -gnutls_x509_privkey_t +gnutls_privkey_t load_private_key (int mand, common_info_st * info) { + gnutls_privkey_t key; + gnutls_datum_t dat; + size_t size; + + if (!info->privkey && !mand) + return NULL; + + if (info->privkey == NULL) + error (EXIT_FAILURE, 0, "missing --load-privkey"); + + if (strncmp(info->privkey, "pkcs11:", 7) == 0) + return _load_pkcs11_privkey(info->privkey); + + dat.data = read_binary_file (info->privkey, &size); + dat.size = size; + + if (!dat.data) + error (EXIT_FAILURE, errno, "reading --load-privkey: %s", info->privkey); + + key = _load_privkey(&dat, info); + + free (dat.data); + + return key; +} + +/* Load the private key. + * @mand should be non zero if it is required to read a private key. + */ +gnutls_x509_privkey_t +load_x509_private_key (int mand, common_info_st * info) +{ gnutls_x509_privkey_t key; int ret; gnutls_datum_t dat; @@ -283,20 +470,18 @@ load_request (common_info_st * info) /* Load the CA's private key. */ -gnutls_x509_privkey_t +gnutls_privkey_t load_ca_private_key (common_info_st * info) { - gnutls_x509_privkey_t key; - int ret; + gnutls_privkey_t key; gnutls_datum_t dat; size_t size; if (info->ca_privkey == NULL) error (EXIT_FAILURE, 0, "missing --load-ca-privkey"); - ret = gnutls_x509_privkey_init (&key); - if (ret < 0) - error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret)); + if (strncmp(info->ca_privkey, "pkcs11:", 7) == 0) + return _load_pkcs11_privkey(info->ca_privkey); dat.data = read_binary_file (info->ca_privkey, &size); dat.size = size; @@ -305,19 +490,9 @@ load_ca_private_key (common_info_st * info) error (EXIT_FAILURE, errno, "reading --load-ca-privkey: %s", info->ca_privkey); - if (info->pkcs8) - { - const char *pass = get_pass (); - ret = - gnutls_x509_privkey_import_pkcs8 (key, &dat, info->incert_format, - pass, 0); - } - else - ret = gnutls_x509_privkey_import (key, &dat, info->incert_format); + key = _load_privkey(&dat, info); + free (dat.data); - if (ret < 0) - error (EXIT_FAILURE, 0, "importing --load-ca-privkey: %s: %s", - info->ca_privkey, gnutls_strerror (ret)); return key; } @@ -372,6 +547,9 @@ load_pubkey (int mand, common_info_st * info) if (info->pubkey == NULL) error (EXIT_FAILURE, 0, "missing --load-pubkey"); + if (strncmp(info->privkey, "pkcs11:", 7) == 0) + return _load_pkcs11_pubkey(info->pubkey); + ret = gnutls_pubkey_init (&key); if (ret < 0) error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret)); @@ -399,3 +577,24 @@ load_pubkey (int mand, common_info_st * info) return key; } + +gnutls_pubkey_t load_public_key_or_import(int mand, gnutls_privkey_t privkey, common_info_st * info) +{ +gnutls_pubkey_t pubkey; +int ret; + + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) + error (EXIT_FAILURE, 0, "gnutls_pubkey_init: %s", + gnutls_strerror (ret)); + + ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0); + if (ret < 0) /* could not get (e.g. on PKCS #11 */ + { + gnutls_pubkey_deinit(pubkey); + return load_pubkey(mand, info); + } + + return pubkey; +} + diff --git a/src/certtool-common.h b/src/certtool-common.h index bcc79d13fa..e8ed9c7bac 100644 --- a/src/certtool-common.h +++ b/src/certtool-common.h @@ -56,9 +56,11 @@ typedef struct common_info const char *ca_privkey; } common_info_st; -gnutls_x509_privkey_t load_private_key (int mand, common_info_st * info); +gnutls_pubkey_t load_public_key_or_import(int mand, gnutls_privkey_t privkey, common_info_st * info); +gnutls_privkey_t load_private_key (int mand, common_info_st * info); +gnutls_x509_privkey_t load_x509_private_key (int mand, common_info_st * info); gnutls_x509_crq_t load_request (common_info_st * info); -gnutls_x509_privkey_t load_ca_private_key (common_info_st * info); +gnutls_privkey_t load_ca_private_key (common_info_st * info); gnutls_x509_crt_t load_ca_cert (common_info_st * info); gnutls_x509_crt_t load_cert (int mand, common_info_st * info); gnutls_datum_t *load_secret_key (int mand, common_info_st * info); diff --git a/src/certtool.c b/src/certtool.c index 1256a317c6..83b7f53bec 100644 --- a/src/certtool.c +++ b/src/certtool.c @@ -46,9 +46,12 @@ #include <version-etc.h> #include <certtool-cfg.h> +#include <p11common.h> #include "certtool-gaa.h" #include "certtool-common.h" +#define SIGN_HASH GNUTLS_DIG_SHA1 + static void print_crl_info (gnutls_x509_crl_t crl, FILE * out); void pkcs7_info (void); void crq_info (void); @@ -361,12 +364,13 @@ generate_private_key (void) static gnutls_x509_crt_t -generate_certificate (gnutls_x509_privkey_t * ret_key, +generate_certificate (gnutls_privkey_t * ret_key, gnutls_x509_crt_t ca_crt, int proxy, common_info_st * cinfo) { gnutls_x509_crt_t crt; - gnutls_x509_privkey_t key = NULL; + gnutls_privkey_t key = NULL; + gnutls_pubkey_t pubkey; size_t size; int ret; int client; @@ -385,6 +389,8 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, { key = load_private_key (1, cinfo); + + pubkey = load_public_key_or_import (1, key, cinfo); if (!batch) fprintf (stderr, @@ -421,7 +427,7 @@ generate_certificate (gnutls_x509_privkey_t * ret_key, get_pkcs9_email_crt_set (crt); } - result = gnutls_x509_crt_set_key (crt, key); + result = gnutls_x509_crt_set_pubkey (crt, pubkey); if (result < 0) error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (result)); } @@ -802,7 +808,7 @@ void generate_self_signed (common_info_st * cinfo) { gnutls_x509_crt_t crt; - gnutls_x509_privkey_t key; + gnutls_privkey_t key; size_t size; int result; const char *uri; @@ -829,7 +835,7 @@ generate_self_signed (common_info_st * cinfo) fprintf (stderr, "\n\nSigning certificate...\n"); - result = gnutls_x509_crt_sign2 (crt, crt, key, get_dig (crt), 0); + result = gnutls_x509_crt_privkey_sign (crt, crt, key, get_dig (crt), 0); if (result < 0) error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result)); @@ -841,17 +847,17 @@ generate_self_signed (common_info_st * cinfo) fwrite (buffer, 1, size, outfile); gnutls_x509_crt_deinit (crt); - gnutls_x509_privkey_deinit (key); + gnutls_privkey_deinit (key); } static void generate_signed_certificate (common_info_st * cinfo) { gnutls_x509_crt_t crt; - gnutls_x509_privkey_t key; + gnutls_privkey_t key; size_t size; int result; - gnutls_x509_privkey_t ca_key; + gnutls_privkey_t ca_key; gnutls_x509_crt_t ca_crt; fprintf (stderr, "Generating a signed certificate...\n"); @@ -871,7 +877,7 @@ generate_signed_certificate (common_info_st * cinfo) fprintf (stderr, "\n\nSigning certificate...\n"); - result = gnutls_x509_crt_sign2 (crt, ca_crt, ca_key, get_dig (ca_crt), 0); + result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0); if (result < 0) error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result)); @@ -883,14 +889,15 @@ generate_signed_certificate (common_info_st * cinfo) fwrite (buffer, 1, size, outfile); gnutls_x509_crt_deinit (crt); - gnutls_x509_privkey_deinit (key); + gnutls_privkey_deinit (key); + gnutls_privkey_deinit(ca_key); } static void generate_proxy_certificate (common_info_st * cinfo) { gnutls_x509_crt_t crt, eecrt; - gnutls_x509_privkey_t key, eekey; + gnutls_privkey_t key, eekey; size_t size; int result; @@ -905,7 +912,7 @@ generate_proxy_certificate (common_info_st * cinfo) fprintf (stderr, "\n\nSigning certificate...\n"); - result = gnutls_x509_crt_sign2 (crt, eecrt, eekey, get_dig (eecrt), 0); + result = gnutls_x509_crt_privkey_sign (crt, eecrt, eekey, get_dig (eecrt), 0); if (result < 0) error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result)); @@ -916,8 +923,10 @@ generate_proxy_certificate (common_info_st * cinfo) fwrite (buffer, 1, size, outfile); + gnutls_x509_crt_deinit (eecrt); gnutls_x509_crt_deinit (crt); - gnutls_x509_privkey_deinit (key); + gnutls_privkey_deinit (key); + gnutls_privkey_deinit (eekey); } static void @@ -925,8 +934,7 @@ generate_signed_crl (common_info_st * cinfo) { gnutls_x509_crl_t crl; int result; - gnutls_x509_privkey_t ca_key; - gnutls_privkey_t ca_pkey; + gnutls_privkey_t ca_key; gnutls_x509_crt_t ca_crt; fprintf (stderr, "Generating a signed CRL...\n"); @@ -935,23 +943,14 @@ generate_signed_crl (common_info_st * cinfo) ca_crt = load_ca_cert (cinfo); crl = generate_crl (ca_crt, cinfo); - result = gnutls_privkey_init(&ca_pkey); - if (result < 0) - error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (result)); - - result = gnutls_privkey_import_x509(ca_pkey, ca_key, 0); - if (result < 0) - error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (result)); - fprintf (stderr, "\n"); - - result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_pkey, GNUTLS_DIG_SHA1, 0); + result = gnutls_x509_crl_privkey_sign(crl, ca_crt, ca_key, SIGN_HASH, 0); if (result < 0) error (EXIT_FAILURE, 0, "crl_privkey_sign: %s", gnutls_strerror (result)); print_crl_info (crl, stderr); - gnutls_privkey_deinit( ca_pkey); + gnutls_privkey_deinit( ca_key); gnutls_x509_crl_deinit (crl); } @@ -961,7 +960,7 @@ update_signed_certificate (common_info_st * cinfo) gnutls_x509_crt_t crt; size_t size; int result; - gnutls_x509_privkey_t ca_key; + gnutls_privkey_t ca_key; gnutls_x509_crt_t ca_crt; int days; time_t tim = time (NULL); @@ -984,7 +983,7 @@ update_signed_certificate (common_info_st * cinfo) fprintf (stderr, "\n\nSigning certificate...\n"); - result = gnutls_x509_crt_sign2 (crt, ca_crt, ca_key, get_dig (ca_crt), 0); + result = gnutls_x509_crt_privkey_sign (crt, ca_crt, ca_key, get_dig (ca_crt), 0); if (result < 0) error (EXIT_FAILURE, 0, "crt_sign: %s", gnutls_strerror (result)); @@ -1078,6 +1077,8 @@ gaa_parser (int argc, char **argv) if ((ret = gnutls_global_init ()) < 0) error (EXIT_FAILURE, 0, "global_init: %s", gnutls_strerror (ret)); + + pkcs11_common(); memset (&cinfo, 0, sizeof (cinfo)); cinfo.privkey = info.privkey; @@ -1763,7 +1764,8 @@ void generate_request (common_info_st * cinfo) { gnutls_x509_crq_t crq; - gnutls_x509_privkey_t key; + gnutls_x509_privkey_t xkey; + gnutls_pubkey_t pubkey; gnutls_privkey_t pkey; int ret, ca_status, path_len; const char *pass; @@ -1781,17 +1783,19 @@ generate_request (common_info_st * cinfo) /* Load the private key. */ - key = load_private_key (0, cinfo); - if (!key) + pkey = load_private_key (0, cinfo); + if (!pkey) { - key = generate_private_key_int (); + xkey = generate_private_key_int (); + + print_private_key (xkey); - print_private_key (key); + ret = gnutls_privkey_import_x509(pkey, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); + if (ret < 0) + error (EXIT_FAILURE, 0, "privkey_import_x509: %s", gnutls_strerror (ret)); } - ret = gnutls_privkey_import_x509(pkey, key, 0); - if (ret < 0) - error (EXIT_FAILURE, 0, "privkey_import_x509: %s", gnutls_strerror (ret)); + pubkey = load_public_key_or_import (1, pkey, cinfo); /* Set the DN. */ @@ -1910,11 +1914,11 @@ generate_request (common_info_st * cinfo) } } - ret = gnutls_x509_crq_set_key (crq, key); + ret = gnutls_x509_crq_set_pubkey (crq, pubkey); if (ret < 0) error (EXIT_FAILURE, 0, "set_key: %s", gnutls_strerror (ret)); - ret = gnutls_x509_crq_privkey_sign (crq, pkey, GNUTLS_DIG_SHA1, 0); + ret = gnutls_x509_crq_privkey_sign (crq, pkey, SIGN_HASH, 0); if (ret < 0) error (EXIT_FAILURE, 0, "sign: %s", gnutls_strerror (ret)); @@ -1922,7 +1926,7 @@ generate_request (common_info_st * cinfo) gnutls_x509_crq_deinit (crq); gnutls_privkey_deinit( pkey); - gnutls_x509_privkey_deinit (key); + gnutls_pubkey_deinit( pubkey); } @@ -2306,7 +2310,7 @@ generate_pkcs8 (common_info_st * cinfo) fprintf (stderr, "Generating a PKCS #8 key structure...\n"); - key = load_private_key (1, cinfo); + key = load_x509_private_key (1, cinfo); if (info.pass) password = info.pass; @@ -2358,7 +2362,7 @@ generate_pkcs12 (common_info_st * cinfo) fprintf (stderr, "Generating a PKCS #12 structure...\n"); - key = load_private_key (0, cinfo); + key = load_x509_private_key (0, cinfo); crts = load_cert_list (0, &ncrts, cinfo); name = get_pkcs12_key_name (); diff --git a/src/common.c b/src/common.c index 3115404051..ef537c36d3 100644 --- a/src/common.c +++ b/src/common.c @@ -33,15 +33,12 @@ #include <stdlib.h> #include <string.h> #include <gnutls/gnutls.h> -#include <gnutls/extra.h> #include <gnutls/x509.h> #include <gnutls/openpgp.h> #include <time.h> #include <common.h> -#include <gnutls/pkcs11.h> #define SU(x) (x!=NULL?x:"Unknown") -#define MIN(x,y) ((x)<(y))?(x):(y) int print_cert; extern int verbose; @@ -728,80 +725,3 @@ service_to_port (const char *service) return ntohs (server_port->s_port); } -static int -pin_callback (void *user, int attempt, const char *token_url, - const char *token_label, unsigned int flags, char *pin, - size_t pin_max) -{ - const char *password; - int len; -/* allow caching of PIN */ - static char *cached_url = NULL; - static char cached_pin[32] = ""; - - printf ("PIN required for token '%s' with URL '%s'\n", token_label, - token_url); - if (flags & GNUTLS_PKCS11_PIN_FINAL_TRY) - printf ("*** This is the final try before locking!\n"); - if (flags & GNUTLS_PKCS11_PIN_COUNT_LOW) - printf ("*** Only few tries left before locking!\n"); - - if (flags == 0 && cached_url != NULL) - { - if (strcmp (cached_url, token_url) == 0) - { - if (strlen(pin) >= sizeof(cached_pin)) - { - fprintf (stderr, "Too long PIN given\n"); - exit (1); - } - - strcpy (pin, cached_pin); - return 0; - } - } - - password = getpass ("Enter pin: "); - if (password == NULL || password[0] == 0) - { - fprintf (stderr, "No password given\n"); - exit (1); - } - - len = MIN (pin_max, strlen (password)); - memcpy (pin, password, len); - pin[len] = 0; - - /* cache */ - strcpy (cached_pin, pin); - free (cached_url); - cached_url = strdup (token_url); - - return 0; -} - -static int -token_callback (void *user, const char *label, const unsigned retry) -{ - char buf[32]; - char *p; - - if (retry > 0) - { - fprintf (stderr, "Could not find token %s\n", label); - return -1; - } - printf ("Please insert token '%s' in slot and press enter\n", label); - p = fgets (buf, sizeof (buf), stdin); - - return 0; -} - -void -pkcs11_common (void) -{ - - gnutls_pkcs11_set_pin_function (pin_callback, NULL); - gnutls_pkcs11_set_token_function (token_callback, NULL); - -} diff --git a/src/p11common.c b/src/p11common.c new file mode 100644 index 0000000000..f9cf72358b --- /dev/null +++ b/src/p11common.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2011 Free Software Foundation, Inc. + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GnuTLS. + * + * GnuTLS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GnuTLS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <getpass.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <gnutls/pkcs11.h> +#include <p11common.h> + +#define MIN(x,y) ((x)<(y))?(x):(y) + +static int +pin_callback (void *user, int attempt, const char *token_url, + const char *token_label, unsigned int flags, char *pin, + size_t pin_max) +{ + const char *password; + int len; +/* allow caching of PIN */ + static char *cached_url = NULL; + static char cached_pin[32] = ""; + + printf ("PIN required for token '%s' with URL '%s'\n", token_label, + token_url); + if (flags & GNUTLS_PKCS11_PIN_FINAL_TRY) + printf ("*** This is the final try before locking!\n"); + if (flags & GNUTLS_PKCS11_PIN_COUNT_LOW) + printf ("*** Only few tries left before locking!\n"); + + if (flags == 0 && cached_url != NULL) + { + if (strcmp (cached_url, token_url) == 0) + { + if (strlen(pin) >= sizeof(cached_pin)) + { + fprintf (stderr, "Too long PIN given\n"); + exit (1); + } + + strcpy (pin, cached_pin); + return 0; + } + } + + password = getpass ("Enter pin: "); + if (password == NULL || password[0] == 0) + { + fprintf (stderr, "No password given\n"); + exit (1); + } + + len = MIN (pin_max, strlen (password)); + memcpy (pin, password, len); + pin[len] = 0; + + /* cache */ + strcpy (cached_pin, pin); + free (cached_url); + cached_url = strdup (token_url); + + return 0; +} + +static int +token_callback (void *user, const char *label, const unsigned retry) +{ + char buf[32]; + char *p; + + if (retry > 0) + { + fprintf (stderr, "Could not find token %s\n", label); + return -1; + } + printf ("Please insert token '%s' in slot and press enter\n", label); + p = fgets (buf, sizeof (buf), stdin); + + return 0; +} + +void +pkcs11_common (void) +{ + + gnutls_pkcs11_set_pin_function (pin_callback, NULL); + gnutls_pkcs11_set_token_function (token_callback, NULL); + +} diff --git a/src/p11common.h b/src/p11common.h new file mode 100644 index 0000000000..e135bef9a3 --- /dev/null +++ b/src/p11common.h @@ -0,0 +1 @@ +void pkcs11_common (void); diff --git a/src/pkcs11.c b/src/pkcs11.c index c422ec736b..fef2839c90 100644 --- a/src/pkcs11.c +++ b/src/pkcs11.c @@ -574,7 +574,7 @@ pkcs11_write (FILE * outfile, const char *url, const char *label, int trusted, gnutls_x509_crt_get_key_usage (xcrt, &key_usage, NULL); } - xkey = load_private_key (0, info); + xkey = load_x509_private_key (0, info); if (xkey != NULL) { ret = |