gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_3_0_21-28-g9eac1c5


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_3_0_21-28-g9eac1c5
Date: Fri, 13 Jul 2012 15:22:17 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=9eac1c562bdcf72b1cdc77026553f23aefc00f1b

The branch, master has been updated
       via  9eac1c562bdcf72b1cdc77026553f23aefc00f1b (commit)
       via  809678afeb247656c050b91afbe5f4c742df9514 (commit)
       via  e9dffbbcb345baa3be1a440f60ba6310586822cd (commit)
       via  aafed2cb248bc4c3834de32eee021e4cd3800e14 (commit)
       via  8f0e722ff78ea0c782b7b344ecddc760da7c9498 (commit)
       via  e266e502c2b0098a888f8df1fa3626b13dd54494 (commit)
       via  8e4b0973b07292d6495558132f052324fd238a13 (commit)
       via  121f519d1380a6160888a2a31fe392d1a8acf5a5 (commit)
      from  c57bbd2a6f18147916d3e68a390d9844aaa6c162 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9eac1c562bdcf72b1cdc77026553f23aefc00f1b
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Jul 13 17:22:06 2012 +0200

    Added flag to disable the use of callbacks in TPM keys.

commit 809678afeb247656c050b91afbe5f4c742df9514
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Jul 13 17:09:55 2012 +0200

    Added ability to request PIN from a TPM URL. It uses the PKCS11 PIN 
function.

commit e9dffbbcb345baa3be1a440f60ba6310586822cd
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Jul 13 13:48:34 2012 +0200

    corrected function call

commit aafed2cb248bc4c3834de32eee021e4cd3800e14
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Jul 13 13:47:43 2012 +0200

    Added gnutls_pkcs11_advset_pin_function and 
gnutls_pkcs11_advset_token_function

commit 8f0e722ff78ea0c782b7b344ecddc760da7c9498
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Jul 13 13:36:59 2012 +0200

    doc fix

commit e266e502c2b0098a888f8df1fa3626b13dd54494
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Jul 13 13:34:32 2012 +0200

    do not list parent in URL.

commit 8e4b0973b07292d6495558132f052324fd238a13
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Jul 13 13:33:08 2012 +0200

    Allow tpmkey: urls in set_key_file()

commit 121f519d1380a6160888a2a31fe392d1a8acf5a5
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Fri Jul 13 13:19:27 2012 +0200

    Added support for legacy key

-----------------------------------------------------------------------

Summary of changes:
 .gitignore                     |    2 +
 NEWS                           |    2 +
 doc/cha-cert-auth2.texi        |    4 +
 lib/gnutls_privkey.c           |   23 +---
 lib/gnutls_x509.c              |   51 ++++++++
 lib/includes/gnutls/abstract.h |   19 ++-
 lib/includes/gnutls/pkcs11.h   |    7 +
 lib/includes/gnutls/tpm.h      |    2 +-
 lib/libgnutls.map              |    3 +
 lib/pkcs11.c                   |   54 ++++++++-
 lib/tpm.c                      |  277 +++++++++++++++++++++++++++++++---------
 src/certtool-common.c          |   40 ++++++-
 src/tpmtool.c                  |    9 +-
 13 files changed, 402 insertions(+), 91 deletions(-)

diff --git a/.gitignore b/.gitignore
index 622cd82..4cfbcd0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -585,3 +585,5 @@ tests/mini-x509-2
 tests/pkcs12_simple
 win32
 win64
+src/tpmtool
+src/libcmd-tpmtool.la
diff --git a/NEWS b/NEWS
index b57d5f8..d822a60 100644
--- a/NEWS
+++ b/NEWS
@@ -47,6 +47,8 @@ by Alexandre Bique.
 ** API and ABI modifications:
 GNUTLS_CERT_SIGNATURE_FAILURE: Added
 GNUTLS_CAMELLIA_192_CBC: Added
+gnutls_pkcs11_advset_pin_function: Added
+gnutls_pkcs11_advset_token_function: Added
 gnutls_privkey_import_tpm_raw: Added
 gnutls_privkey_import_pkcs11_url: Added
 gnutls_privkey_import_openpgp_raw: Added
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index 573b68d..1b8cb3b 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -432,6 +432,10 @@ are sharing a module. To avoid this problem GnuTLS uses 
@acronym{p11-kit}
 that provides a middleware to control access to resources over the
 multiple users.
 
+To avoid conflicts with multiple registered callbacks for PIN and token 
functions,
+the following two functions set the callbacks if they have not already been 
set.
address@hidden,gnutls_pkcs11_advset_token_function}
+
 Moreover PKCS #11 modules must be reinitialized on the child processes
 after a @funcintref{fork}. @acronym{GnuTLS} provides 
@funcref{gnutls_pkcs11_reinit}
 to be called for this purpose.
diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c
index de8061f..2246cab 100644
--- a/lib/gnutls_privkey.c
+++ b/lib/gnutls_privkey.c
@@ -400,27 +400,8 @@ gnutls_privkey_import_ext (gnutls_privkey_t pkey,
                            gnutls_privkey_decrypt_func decrypt_func,
                            unsigned int flags)
 {
-int ret;
-
-  ret = check_if_clean(pkey);
-  if (ret < 0)
-    {
-      gnutls_assert();
-      return ret;
-    }
-  
-  if (sign_func == NULL && decrypt_func == NULL)
-    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-
-  pkey->key.ext.sign_func = sign_func;
-  pkey->key.ext.decrypt_func = decrypt_func;
-  pkey->key.ext.deinit_func = NULL;
-  pkey->key.ext.userdata = userdata;
-  pkey->type = GNUTLS_PRIVKEY_EXT;
-  pkey->pk_algorithm = pk;
-  pkey->flags = flags;
-
-  return 0;
+  return gnutls_privkey_import_ext2( pkey, pk, userdata, sign_func, 
decrypt_func,
+                                     NULL, flags);
 }
 
 /**
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index a757832..413fc34 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -566,6 +566,50 @@ read_key_mem (gnutls_certificate_credentials_t res,
   return 0;
 }
 
+#ifdef HAVE_TROUSERS
+/* Reads a private key from a token.
+ */
+static int
+read_key_tpmurl (gnutls_certificate_credentials_t res, const char *url)
+{
+  int ret;
+  gnutls_privkey_t pkey = NULL;
+
+  /* allocate space for the pkey list
+   */
+
+  ret = gnutls_privkey_init (&pkey);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret =
+    gnutls_privkey_import_tpm_url (pkey, url, NULL, NULL, 0);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  ret = certificate_credentials_append_pkey (res, pkey);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto cleanup;
+    }
+
+  return 0;
+
+cleanup:
+  if (pkey)
+    gnutls_privkey_deinit (pkey);
+
+  return ret;
+}
+#endif
+
 #ifdef ENABLE_PKCS11
 /* Reads a private key from a token.
  */
@@ -828,6 +872,13 @@ read_key_file (gnutls_certificate_credentials_t res,
     }
 #endif /* ENABLE_PKCS11 */
 
+#ifdef HAVE_TROUSERS
+  if (strncmp (keyfile, "tpmkey:", 7) == 0)
+    {
+      return read_key_tpmurl (res, keyfile);
+    }
+#endif /* HAVE_TROUSERS */
+
   data = read_binary_file (keyfile, &size);
 
   if (data == NULL)
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 4c79e5a..562e30c 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -71,13 +71,15 @@ gnutls_pubkey_import_privkey (gnutls_pubkey_t key, 
gnutls_privkey_t pkey,
 int
 gnutls_pubkey_import_tpm_url (gnutls_pubkey_t pkey,
                               const char* url,
-                              const char *srk_password);
+                              const char *srk_password,
+                              unsigned int flags);
 
 int
 gnutls_pubkey_import_tpm_raw (gnutls_pubkey_t pkey,
                               const gnutls_datum_t * fdata,
                               gnutls_x509_crt_fmt_t format,
-                              const char *srk_password);
+                              const char *srk_password,
+                              unsigned int flags);
 
 int gnutls_pubkey_get_preferred_hash_algorithm (gnutls_pubkey_t key,
                                                 gnutls_digest_algorithm_t *
@@ -148,6 +150,10 @@ int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, 
gnutls_pubkey_t key);
 int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key);
 
 #define GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA 1
+/* The following flag disables call to PIN callbacks etc.
+ * Only works for TPM keys.
+ */
+#define GNUTLS_PUBKEY_DISABLE_CALLBACKS (1<<2)
 int
 gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key, 
                             gnutls_sign_algorithm_t algo,
@@ -178,6 +184,10 @@ gnutls_privkey_type_t gnutls_privkey_get_type 
(gnutls_privkey_t key);
 
 #define GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE (1<<0)
 #define GNUTLS_PRIVKEY_IMPORT_COPY (1<<1)
+/* The following flag disables call to PIN callbacks etc.
+ * Only works for TPM keys.
+ */
+#define GNUTLS_PRIVKEY_DISABLE_CALLBACKS (1<<2)
 int gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey,
                                   gnutls_pkcs11_privkey_t key,
                                   unsigned int flags);
@@ -204,11 +214,12 @@ gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey,
                               const gnutls_datum_t * fdata,
                               gnutls_x509_crt_fmt_t format,
                               const char *srk_password,
-                              const char *tpm_password);
+                              const char *tpm_password, unsigned int flags);
 
 int
 gnutls_privkey_import_tpm_url (gnutls_privkey_t pkey,
-          const char* url, const char *srk_password, const char *key_password);
+          const char* url, const char *srk_password, const char *key_password,
+          unsigned int flags);
 
 int gnutls_privkey_import_pkcs11_url (gnutls_privkey_t key, const char *url);
 
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index eb95f4c..e1dd841 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -137,6 +137,13 @@ void gnutls_pkcs11_set_token_function 
(gnutls_pkcs11_token_callback_t fn,
 
 void gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
                                      void *userdata);
+
+void gnutls_pkcs11_advset_token_function (gnutls_pkcs11_token_callback_t fn,
+                                       void *userdata);
+
+void gnutls_pkcs11_advset_pin_function (gnutls_pkcs11_pin_callback_t fn,
+                                     void *userdata);
+
 int gnutls_pkcs11_add_provider (const char *name, const char *params);
 int gnutls_pkcs11_obj_init (gnutls_pkcs11_obj_t * obj);
 
diff --git a/lib/includes/gnutls/tpm.h b/lib/includes/gnutls/tpm.h
index d179c71..4f17a4f 100644
--- a/lib/includes/gnutls/tpm.h
+++ b/lib/includes/gnutls/tpm.h
@@ -47,7 +47,7 @@ gnutls_tpm_privkey_generate (gnutls_pk_algorithm_t pk, 
unsigned int bits,
                              unsigned int flags);
 
 void gnutls_tpm_key_list_deinit (gnutls_tpm_key_list_t list);
-int gnutls_tpm_key_list_get_url (gnutls_tpm_key_list_t list, unsigned int idx, 
char** url);
+int gnutls_tpm_key_list_get_url (gnutls_tpm_key_list_t list, unsigned int idx, 
char** url, unsigned int flags);
 int gnutls_tpm_get_registered (gnutls_tpm_key_list_t *list);
 int gnutls_tpm_privkey_delete (const char* url, const char* srk_password);
 
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index dd9aa1d..f186b25 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -794,6 +794,8 @@ GNUTLS_3_0_0 {
 
 GNUTLS_3_1_0 {
   global:
+        gnutls_pkcs11_advset_pin_function;
+       gnutls_pkcs11_advset_token_function;
        gnutls_pkcs11_obj_list_import_url2;
        gnutls_x509_trust_list_add_system_trust;
        gnutls_x509_trust_list_add_trust_file;
@@ -814,6 +816,7 @@ GNUTLS_3_1_0 {
        gnutls_tpm_get_registered;
        gnutls_tpm_privkey_delete;
        gnutls_pubkey_import_tpm_url;
+       gnutls_privkey_import_tpm_url;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index ec8a482..907cfbd 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -630,10 +630,13 @@ gnutls_pkcs11_deinit (void)
         p11_kit_finalize_module (providers[i].module);
     }
   active_providers = 0;
-
+  
   if (initialized_registered != 0)
     p11_kit_finalize_registered ();
   initialized_registered = 0;
+  
+  gnutls_pkcs11_set_pin_function (NULL, NULL);
+  gnutls_pkcs11_set_token_function (NULL, NULL);
 }
 
 /**
@@ -656,6 +659,31 @@ gnutls_pkcs11_set_pin_function 
(gnutls_pkcs11_pin_callback_t fn,
 }
 
 /**
+ * gnutls_pkcs11_advset_pin_function:
+ * @fn: The PIN callback, a gnutls_pkcs11_pin_callback_t() function.
+ * @userdata: data to be supplied to callback
+ *
+ * This function will set a callback function to be used when a PIN is
+ * required for PKCS 11 operations.  See
+ * gnutls_pkcs11_pin_callback_t() on how the callback should behave.
+ * 
+ * This function unlike gnutls_pkcs11_set_pin_function() will only
+ * set the provided function if it has not previously been set. 
+ *
+ * Since: 3.1.0
+ **/
+void
+gnutls_pkcs11_advset_pin_function (gnutls_pkcs11_pin_callback_t fn,
+                                void *userdata)
+{
+  if (_gnutls_pin_func == NULL)
+    {
+      _gnutls_pin_func = fn;
+      _gnutls_pin_data = userdata;
+    }
+}
+
+/**
  * gnutls_pkcs11_set_token_function:
  * @fn: The token callback
  * @userdata: data to be supplied to callback
@@ -673,6 +701,30 @@ gnutls_pkcs11_set_token_function 
(gnutls_pkcs11_token_callback_t fn,
   _gnutls_token_data = userdata;
 }
 
+/**
+ * gnutls_pkcs11_advset_token_function:
+ * @fn: The token callback
+ * @userdata: data to be supplied to callback
+ *
+ * This function will set a callback function to be used when a token
+ * needs to be inserted to continue PKCS 11 operations.
+ *
+ * This function unlike gnutls_pkcs11_set_token_function() will only
+ * set the provided function if it has not previously been set. 
+ *
+ * Since: 3.1.0
+ **/
+void
+gnutls_pkcs11_advset_token_function (gnutls_pkcs11_token_callback_t fn,
+                                  void *userdata)
+{
+  if (_gnutls_token_func==NULL)
+    {
+      _gnutls_token_func = fn;
+      _gnutls_token_data = userdata;
+    }
+}
+
 int
 pkcs11_url_to_info (const char *url, struct p11_kit_uri **info)
 {
diff --git a/lib/tpm.c b/lib/tpm.c
index d72b2f3..c9cdbd3 100644
--- a/lib/tpm.c
+++ b/lib/tpm.c
@@ -64,6 +64,7 @@ static int import_tpm_key (gnutls_privkey_t pkey,
                            TSS_UUID *uuid,
                            const char *srk_password,
                            const char *key_password);
+static int encode_tpmkey_url(char** url, const TSS_UUID* uuid, const TSS_UUID* 
parent);
 
 /* TPM URL format:
  *
@@ -161,7 +162,7 @@ tpm_sign_fn (gnutls_privkey_t key, void *_s,
        _gnutls_debug_log ("TPM hash signature failed: %s\n",
                           Trspi_Error_String (err));
       if (err == TPM_E_AUTHFAIL)
-       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+       return GNUTLS_E_TPM_KEY_PASSWORD_ERROR;
       else
        return GNUTLS_E_PK_SIGN_FAILED;
     }
@@ -169,8 +170,69 @@ tpm_sign_fn (gnutls_privkey_t key, void *_s,
 }
 
 static const unsigned char nullpass[20];
+static const gnutls_datum_t nulldata = {(void*)nullpass, 20};
 const TSS_UUID srk_uuid = TSS_UUID_SRK;
 
+static int tpm_pin(const TSS_UUID* uuid, char* pin, unsigned int pin_size, 
+                   unsigned int attempts)
+{
+unsigned int flags = 0;
+const char* label;
+char* url = NULL;
+int ret;
+
+  if (attempts > 0) 
+    flags |= GNUTLS_PKCS11_PIN_WRONG;
+    
+  if (uuid)
+    {
+      if (memcmp(uuid, &srk_uuid, sizeof(TSS_UUID)) == 0)
+        label = "SRK";
+      else
+        {
+          ret = encode_tpmkey_url(&url, uuid, NULL);
+          if (ret < 0)
+            return gnutls_assert_val(ret);
+          
+          label = url;
+        }
+    }
+  else
+    label = "unknown";
+
+  ret = _gnutls_pin_func(_gnutls_pin_data, attempts, "TPM", label, flags, pin, 
pin_size);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto cleanup;
+    }
+  
+  ret = 0;
+cleanup:
+  gnutls_free(url);
+  return ret;
+}
+
+
+static TSS_RESULT myTspi_Policy_SetSecret(TSS_HPOLICY hPolicy, 
+                                          UINT32 ulSecretLength, BYTE* 
rgbSecret)
+{
+  if (rgbSecret == NULL)
+    {
+      /* Well known NULL key */
+      return Tspi_Policy_SetSecret (hPolicy,
+                                  TSS_SECRET_MODE_SHA1,
+                                   sizeof (nullpass), (BYTE *) nullpass);
+    }
+  else /* key is given */
+    {
+      return Tspi_Policy_SetSecret (hPolicy, TSS_SECRET_MODE_PLAIN,
+                                    ulSecretLength, rgbSecret);
+    }
+}
+
+#define SAFE_LEN(x) (x==NULL?0:strlen(x))
+
 static int tpm_open_session(struct tpm_ctx_st *s, const char* srk_password)
 {
 int err, ret;
@@ -208,14 +270,8 @@ int err, ret;
       goto out_srk;
     }
 
-  if (srk_password)
-    err = Tspi_Policy_SetSecret (s->srk_policy,
-                                TSS_SECRET_MODE_PLAIN,
-                                strlen (srk_password), (BYTE *) srk_password);
-  else                         /* Well-known NULL key */
-    err = Tspi_Policy_SetSecret (s->srk_policy,
-                                TSS_SECRET_MODE_SHA1,
-                                sizeof (nullpass), (BYTE *) nullpass);
+  err = myTspi_Policy_SetSecret (s->srk_policy,
+                                SAFE_LEN (srk_password), (BYTE *) 
srk_password);
   if (err)
     {
       gnutls_assert ();
@@ -251,6 +307,56 @@ static void tpm_close_session(struct tpm_ctx_st *s)
 }
 
 static int
+import_tpm_key_cb (gnutls_privkey_t pkey,
+                const gnutls_datum_t * fdata,
+                gnutls_x509_crt_fmt_t format,
+                TSS_UUID *uuid,
+                const char *srk_password,
+                const char *key_password)
+{
+unsigned int attempts = 0;
+char pin1[GNUTLS_PKCS11_MAX_PIN_LEN];
+char pin2[GNUTLS_PKCS11_MAX_PIN_LEN];
+int ret, ret2;
+
+  do
+    {
+      ret = import_tpm_key(pkey, fdata, format, uuid, srk_password, 
key_password);
+
+      if (attempts > 3 || _gnutls_pin_func == NULL)
+        break;
+
+      if (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR)
+        {
+          ret2 = tpm_pin(&srk_uuid, pin1, sizeof(pin1), attempts++);
+          if (ret2 < 0)
+            {
+              gnutls_assert();
+              return GNUTLS_E_TPM_SRK_PASSWORD_ERROR;
+            }
+          srk_password = pin1;
+        }
+
+      if (ret == GNUTLS_E_TPM_KEY_PASSWORD_ERROR)
+        {
+          ret2 = tpm_pin(uuid, pin2, sizeof(pin2), attempts++);
+          if (ret2 < 0)
+            {
+              gnutls_assert();
+              return GNUTLS_E_TPM_KEY_PASSWORD_ERROR;
+            }
+          key_password = pin2;
+        }
+    }
+  while(ret == GNUTLS_E_TPM_KEY_PASSWORD_ERROR || ret == 
GNUTLS_E_TPM_SRK_PASSWORD_ERROR);
+
+  if (ret < 0)
+    gnutls_assert();
+  return ret;
+}
+
+
+static int
 import_tpm_key (gnutls_privkey_t pkey,
                 const gnutls_datum_t * fdata,
                 gnutls_x509_crt_fmt_t format,
@@ -303,20 +409,9 @@ import_tpm_key (gnutls_privkey_t pkey,
                                         asn1.size, asn1.data, &s->tpm_key);
       if (err != 0)
         {
-          if (srk_password)
-            {
-              gnutls_assert ();
-              _gnutls_debug_log
-                  ("Failed to load TPM key blob: %s\n",
-                   Trspi_Error_String (err));
-            }
-
-          if (err)
-            {
-              gnutls_assert ();
-              ret = tss_err(err);
-              goto out_blob;
-            }
+          gnutls_assert ();
+          ret = tss_err(err);
+          goto out_blob;
         }
     }
   else if (uuid)
@@ -348,8 +443,8 @@ import_tpm_key (gnutls_privkey_t pkey,
     }
 
   ret =
-      gnutls_privkey_sign_data (pkey, GNUTLS_DIG_SHA1, 0, fdata, &tmp_sig);
-  if (ret == GNUTLS_E_INSUFFICIENT_CREDENTIALS)
+      gnutls_privkey_sign_data (pkey, GNUTLS_DIG_SHA1, 0, &nulldata, &tmp_sig);
+  if (ret == GNUTLS_E_TPM_KEY_PASSWORD_ERROR)
     {
       if (!s->tpm_key_policy)
        {
@@ -378,9 +473,8 @@ import_tpm_key (gnutls_privkey_t pkey,
            }
        }
 
-      err = Tspi_Policy_SetSecret (s->tpm_key_policy,
-                                  TSS_SECRET_MODE_PLAIN,
-                                  strlen (key_password), (void *) 
key_password);
+      err = myTspi_Policy_SetSecret (s->tpm_key_policy,
+                                    SAFE_LEN(key_password), (void *) 
key_password);
 
       if (err)
        {
@@ -423,11 +517,9 @@ out_ctx:
  * @key_password: A password for the key (optional)
  *
  * This function will import the given private key to the abstract
- * #gnutls_privkey_t structure. If a password is needed to access
- * TPM then or the provided password is wrong, then 
- * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned. If the key password
- * is wrong or not provided then %GNUTLS_E_TPM_KEY_PASSWORD_ERROR
- * is returned. 
+ * #gnutls_privkey_t structure. 
+ *
+ * With respect to passwords the same as in gnutls_privkey_import_tpm_url() 
apply.
  *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error value.
@@ -440,9 +532,13 @@ gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey,
                               const gnutls_datum_t * fdata,
                               gnutls_x509_crt_fmt_t format,
                               const char *srk_password,
-                              const char *key_password)
+                              const char *key_password,
+                              unsigned int flags)
 {
-  return import_tpm_key(pkey, fdata, format, NULL, srk_password, key_password);
+  if (flags & GNUTLS_PRIVKEY_DISABLE_CALLBACKS)
+    return import_tpm_key(pkey, fdata, format, NULL, srk_password, 
key_password);
+  else
+    return import_tpm_key_cb(pkey, fdata, format, NULL, srk_password, 
key_password);
 }
 
 struct tpmkey_url_st
@@ -564,6 +660,7 @@ int ret;
       goto cleanup;
     }
 
+#if 0
   if (parent)
     {
       memcpy(u1, &parent->ulTimeLow, 4);
@@ -591,6 +688,7 @@ int ret;
           goto cleanup;
         }
     }
+#endif
 
   ret = _gnutls_buffer_to_datum(&buf, &dret);
   if (ret < 0)
@@ -687,11 +785,16 @@ cleanup:
  * @url: The URL of the TPM key to be imported
  * @srk_password: The password for the SRK key (optional)
  * @key_password: A password for the key (optional)
+ * @flags: One of the %GNUTLS_PRIVKEY flags
  *
  * This function will import the given private key to the abstract
- * #gnutls_privkey_t structure. If a password is needed to access
- * TPM then or the provided password is wrong, then 
- * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned. If the key password
+ * #gnutls_privkey_t structure. 
+ * 
+ * Note that unless %GNUTLS_PRIVKEY_DISABLE_CALLBACKS
+ * is specified, if incorrect (or NULL) passwords are given
+ * the PKCS11 callback functions will be used to obtain the
+ * correct passwords. Otherwise if the SRK password is wrong
+ * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned and if the key password
  * is wrong or not provided then %GNUTLS_E_TPM_KEY_PASSWORD_ERROR
  * is returned. 
  *
@@ -705,7 +808,8 @@ int
 gnutls_privkey_import_tpm_url (gnutls_privkey_t pkey,
                                const char* url,
                                const char *srk_password,
-                               const char *key_password)
+                               const char *key_password,
+                               unsigned int flags)
 {
 struct tpmkey_url_st durl;
 gnutls_datum_t fdata = { NULL, 0 };
@@ -717,7 +821,6 @@ int ret;
 
   if (durl.filename)
     {
-
       ret = gnutls_load_file(durl.filename, &fdata);
       if (ret < 0)
         {
@@ -726,7 +829,7 @@ int ret;
         }
 
       ret = gnutls_privkey_import_tpm_raw (pkey, &fdata, GNUTLS_X509_FMT_PEM,
-                                                                  
srk_password, key_password);
+                                                  srk_password, key_password, 
flags);
       if (ret < 0)
         {
           gnutls_assert();
@@ -735,7 +838,10 @@ int ret;
     }
   else if (durl.uuid_set)
     {
-      ret = import_tpm_key (pkey, NULL, 0, &durl.uuid, srk_password, 
key_password);
+      if (flags & GNUTLS_PRIVKEY_DISABLE_CALLBACKS)
+        ret = import_tpm_key (pkey, NULL, 0, &durl.uuid, srk_password, 
key_password);
+      else
+        ret = import_tpm_key_cb (pkey, NULL, 0, &durl.uuid, srk_password, 
key_password);
       if (ret < 0)
         {
           gnutls_assert();
@@ -802,6 +908,7 @@ int ret;
 }
 
 
+
 static int
 import_tpm_pubkey (gnutls_pubkey_t pkey,
                    const gnutls_datum_t * fdata,
@@ -892,6 +999,43 @@ out_session:
   return ret;
 }
 
+static int
+import_tpm_pubkey_cb (gnutls_pubkey_t pkey,
+                   const gnutls_datum_t * fdata,
+                   gnutls_x509_crt_fmt_t format,
+                   TSS_UUID *uuid,
+                   const char *srk_password)
+{
+unsigned int attempts = 0;
+char pin1[GNUTLS_PKCS11_MAX_PIN_LEN];
+int ret;
+
+  
+  do
+    {
+      ret = import_tpm_pubkey(pkey, fdata, format, uuid, srk_password);
+      
+      if (attempts > 3 || _gnutls_pin_func == NULL)
+        break;
+
+      if (ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR)
+        {
+          ret = tpm_pin(&srk_uuid, pin1, sizeof(pin1), attempts++);
+          if (ret < 0)
+            {
+              gnutls_assert();
+              return GNUTLS_E_TPM_SRK_PASSWORD_ERROR;
+            }
+          srk_password = pin1;
+        }
+    }
+  while(ret == GNUTLS_E_TPM_SRK_PASSWORD_ERROR);
+
+  if (ret < 0)
+    gnutls_assert();
+  return ret;
+}
+
 
 /**
  * gnutls_pubkey_import_tpm_raw:
@@ -900,11 +1044,12 @@ out_session:
  * @format: The format of the private key
  * @srk_password: The password for the SRK key (optional)
  * @key_password: A password for the key (optional)
+ * @flags: One of the %GNUTLS_PUBKEY flags
  *
  * This function will import the public key from the provided
- * TPM key structure. If a password is needed to decrypt
- * the provided key or the provided password is wrong, then 
- * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned. 
+ * TPM key structure. 
+ *
+ * With respect to passwords the same as in gnutls_pubkey_import_tpm_url() 
apply.
  *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error value.
@@ -916,9 +1061,13 @@ int
 gnutls_pubkey_import_tpm_raw (gnutls_pubkey_t pkey,
                               const gnutls_datum_t * fdata,
                               gnutls_x509_crt_fmt_t format,
-                              const char *srk_password)
+                              const char *srk_password,
+                              unsigned int flags)
 {
-  return import_tpm_pubkey(pkey, fdata, format, NULL, srk_password);
+  if (flags & GNUTLS_PUBKEY_DISABLE_CALLBACKS)
+    return import_tpm_pubkey_cb(pkey, fdata, format, NULL, srk_password);
+  else
+    return import_tpm_pubkey(pkey, fdata, format, NULL, srk_password);
 }
 
 /**
@@ -926,11 +1075,16 @@ gnutls_pubkey_import_tpm_raw (gnutls_pubkey_t pkey,
  * @pkey: The public key
  * @url: The URL of the TPM key to be imported
  * @srk_password: The password for the SRK key (optional)
+ * @flags: should be zero
  *
  * This function will import the given private key to the abstract
- * #gnutls_privkey_t structure. If a password is needed to access
- * TPM then or the provided password is wrong, then 
- * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned. 
+ * #gnutls_privkey_t structure. 
+ *
+ * Note that unless %GNUTLS_PUBKEY_DISABLE_CALLBACKS
+ * is specified, if incorrect (or NULL) passwords are given
+ * the PKCS11 callback functions will be used to obtain the
+ * correct passwords. Otherwise if the SRK password is wrong
+ * %GNUTLS_E_TPM_SRK_PASSWORD_ERROR is returned.
  *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error value.
@@ -941,7 +1095,8 @@ gnutls_pubkey_import_tpm_raw (gnutls_pubkey_t pkey,
 int
 gnutls_pubkey_import_tpm_url (gnutls_pubkey_t pkey,
                               const char* url,
-                              const char *srk_password)
+                              const char *srk_password,
+                              unsigned int flags)
 {
 struct tpmkey_url_st durl;
 gnutls_datum_t fdata = { NULL, 0 };
@@ -962,7 +1117,7 @@ int ret;
         }
 
       ret = gnutls_pubkey_import_tpm_raw (pkey, &fdata, GNUTLS_X509_FMT_PEM,
-                                                                 srk_password);
+                                                 srk_password, flags);
       if (ret < 0)
         {
           gnutls_assert();
@@ -971,7 +1126,10 @@ int ret;
     }
   else if (durl.uuid_set)
     {
-      ret = import_tpm_pubkey (pkey, NULL, 0, &durl.uuid, srk_password);
+      if (flags & GNUTLS_PUBKEY_DISABLE_CALLBACKS)
+        ret = import_tpm_pubkey (pkey, NULL, 0, &durl.uuid, srk_password);
+      else
+        ret = import_tpm_pubkey_cb (pkey, NULL, 0, &durl.uuid, srk_password);
       if (ret < 0)
         {
           gnutls_assert();
@@ -1089,8 +1247,8 @@ struct tpm_ctx_st s;
           goto err_sa;
         }
 
-      tssret = Tspi_Policy_SetSecret(key_policy, TSS_SECRET_MODE_PLAIN, 
-                                     strlen(key_password), 
(void*)key_password);
+      tssret = myTspi_Policy_SetSecret(key_policy, 
+                                       SAFE_LEN(key_password), 
(void*)key_password);
       if (tssret != 0)
         {
           gnutls_assert();
@@ -1253,9 +1411,12 @@ gnutls_tpm_key_list_deinit (gnutls_tpm_key_list_t list)
 /**
  * gnutls_tpm_key_list_get_url:
  * @list: a list of the keys
+ * @idx: The index of the key (starting from zero)
+ * @url: The URL to be returned
+ * @flags: should be zero
  *
- * This function will deinitialize the list of stored keys in the TPM.
- *
+ * This function will return for each given index a URL of
+ * the corresponding key.
  * If the provided index is out of bounds then 
%GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
  * is returned.
  *
@@ -1265,7 +1426,7 @@ gnutls_tpm_key_list_deinit (gnutls_tpm_key_list_t list)
  * Since: 3.1.0
  **/
 int
-gnutls_tpm_key_list_get_url (gnutls_tpm_key_list_t list, unsigned int idx, 
char** url)
+gnutls_tpm_key_list_get_url (gnutls_tpm_key_list_t list, unsigned int idx, 
char** url, unsigned int flags)
 {
   if (idx >= list->size)
     return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
diff --git a/src/certtool-common.c b/src/certtool-common.c
index e8e2f1c..f8c05bc 100644
--- a/src/certtool-common.c
+++ b/src/certtool-common.c
@@ -144,6 +144,27 @@ gnutls_x509_privkey_t xkey;
   return key;
 }
 
+#ifdef HAVE_TROUSERS
+
+static gnutls_privkey_t _load_tpm_privkey(const char* url)
+{
+int ret;
+gnutls_privkey_t key;
+
+  ret = gnutls_privkey_init (&key);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));
+
+  ret = gnutls_privkey_import_tpm_url(key, url, NULL, NULL, 0);
+  if (ret < 0)
+    error (EXIT_FAILURE, 0, "importing TPM key: %s: %s",
+           url, gnutls_strerror (ret));
+
+  return key;
+}
+
+#endif
+
 #ifdef ENABLE_PKCS11
 
 static gnutls_privkey_t _load_pkcs11_privkey(const char* url)
@@ -280,6 +301,11 @@ load_private_key (int mand, common_info_st * info)
     return _load_pkcs11_privkey(info->privkey);
 #endif
 
+#ifdef HAVE_TROUSERS
+  if (strncmp(info->privkey, "tpmkey:", 7) == 0)
+    return _load_tpm_privkey(info->privkey);
+#endif
+
   dat.data = (void*)read_binary_file (info->privkey, &size);
   dat.size = size;
 
@@ -489,6 +515,11 @@ load_ca_private_key (common_info_st * info)
     return _load_pkcs11_privkey(info->ca_privkey);
 #endif
 
+#ifdef HAVE_TROUSERS
+  if (strncmp(info->privkey, "tpmkey:", 7) == 0)
+    return _load_tpm_privkey(info->privkey);
+#endif
+
   dat.data = (void*)read_binary_file (info->ca_privkey, &size);
   dat.size = size;
 
@@ -596,9 +627,8 @@ int ret;
     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 */
-    {
+  if (!privkey || (ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0)) 
< 0)
+    { /* could not get (e.g. on PKCS #11 */
       gnutls_pubkey_deinit(pubkey);
       return load_pubkey(mand, info);
     }
@@ -645,6 +675,10 @@ gnutls_sec_param_t str_to_sec_param (const char *str)
     {
       return GNUTLS_SEC_PARAM_LOW;
     }
+  else if (strcasecmp (str, "legacy") == 0)
+    {
+      return GNUTLS_SEC_PARAM_LEGACY;
+    }
   else if (strcasecmp (str, "normal") == 0)
     {
       return GNUTLS_SEC_PARAM_NORMAL;
diff --git a/src/tpmtool.c b/src/tpmtool.c
index c4e2866..7f689b5 100644
--- a/src/tpmtool.c
+++ b/src/tpmtool.c
@@ -82,7 +82,10 @@ cmd_parser (int argc, char **argv)
   unsigned int optct;
   unsigned int key_type = GNUTLS_PK_UNKNOWN;
   unsigned int bits = 0, reg = 0;
-  const char* sec_param = NULL;
+  /* Note that the default sec-param is legacy because several TPMs
+   * cannot handle larger keys.
+   */
+  const char* sec_param = "legacy";
   
   optct = optionProcess( &tpmtoolOptions, argc, argv);
   argc += optct;
@@ -219,7 +222,7 @@ static void tpm_list(FILE* outfile)
   fprintf(outfile, "Available keys:\n");
   for (i=0;;i++)
     {
-      ret = gnutls_tpm_key_list_get_url(list, i, &url);
+      ret = gnutls_tpm_key_list_get_url(list, i, &url, 0);
       if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
         break;
       else if (ret < 0)
@@ -244,7 +247,7 @@ static void tpm_pubkey(const char* url, FILE* outfile)
 
   gnutls_pubkey_init(&pubkey);
 
-  ret = gnutls_pubkey_import_tpm_url(pubkey, url, srk_pass);
+  ret = gnutls_pubkey_import_tpm_url(pubkey, url, srk_pass, 0);
 
   free(srk_pass);
 


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]