]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
certtool can now load private keys and public keys from PKCS #11 tokens (via URLs).
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 7 May 2011 10:52:41 +0000 (12:52 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 7 May 2011 10:52:41 +0000 (12:52 +0200)
doc/manpages/certtool.1
src/Makefile.am
src/certtool-common.c
src/certtool-common.h
src/certtool.c
src/common.c
src/p11common.c [new file with mode: 0644]
src/p11common.h [new file with mode: 0644]
src/pkcs11.c

index 892ac4b9da4e02e5eb645d706a4bc7ccfd632881..895e309b6e08d618ab804a20cc86688607f97d11 100644 (file)
@@ -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
index 5a48efe38b12ea65cec38069b37adc475d07344b..379d3c8f323cba17d6ad403ad3300849abdb9c25 100644 (file)
@@ -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)
index 7e7083dcadba3588422c199caf700ef6025e00c1..a4cc71c92ba627323d5f9d026476cb52a942ccfe 100644 (file)
@@ -103,11 +103,198 @@ 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;
@@ -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;
+}
+
index bcc79d13fad3714d4f2a059649dc28c94709557a..e8ed9c7bac10fa85e58bc6b848767ae36509ef7a 100644 (file)
@@ -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);
index 1256a317c6c2a71908ffc15670053b17efff3f0c..83b7f53bec18f7da045abf177635bdd344e9d4ad 100644 (file)
 #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 ();
index 3115404051a877699a326d605e753e3a43c31712..ef537c36d3db2c9a8ce758867aa1a9a9da079ade 100644 (file)
 #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 (file)
index 0000000..f9cf723
--- /dev/null
@@ -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 (file)
index 0000000..e135bef
--- /dev/null
@@ -0,0 +1 @@
+void pkcs11_common (void);
index c422ec736b187dfc0e64fce4a263328a818be033..fef2839c90cb75ab7f410490fd1141222e5a18ca 100644 (file)
@@ -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 =