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-3-gd1b7996


From: Nikos Mavrogiannopoulos
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_3_0_21-3-gd1b7996
Date: Wed, 04 Jul 2012 21:17:45 +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=d1b7996804f90b0d5efb8a6c468f78fc4b07386f

The branch, master has been updated
       via  d1b7996804f90b0d5efb8a6c468f78fc4b07386f (commit)
      from  8eb212b1e03671b774ed13071eb72b402e1c0882 (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 d1b7996804f90b0d5efb8a6c468f78fc4b07386f
Author: Nikos Mavrogiannopoulos <address@hidden>
Date:   Wed Jul 4 22:53:00 2012 +0200

    Added initial support for TPM keys.

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

Summary of changes:
 NEWS                            |    1 +
 configure.ac                    |   29 +++
 doc/Makefile.am                 |    2 +
 lib/Makefile.am                 |    6 +-
 lib/gnutls_errors.c             |    8 +-
 lib/includes/gnutls/abstract.h  |    7 +-
 lib/includes/gnutls/gnutls.h.in |    3 +
 lib/libgnutls.map               |    1 +
 lib/pkcs11.c                    |   22 ++--
 lib/pkcs11_int.h                |    7 +-
 lib/pkcs11_privkey.c            |    2 +-
 lib/tpm.c                       |  376 +++++++++++++++++++++++++++++++++++++++
 12 files changed, 444 insertions(+), 20 deletions(-)
 create mode 100644 lib/tpm.c

diff --git a/NEWS b/NEWS
index ada7b42..20e8886 100644
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,7 @@ by Alexandre Bique.
 ** API and ABI modifications:
 GNUTLS_CERT_SIGNATURE_FAILURE: Added
 GNUTLS_CAMELLIA_192_CBC: Added
+gnutls_privkey_import_tpm_raw: Added
 gnutls_privkey_import_pkcs11_url: Added
 gnutls_privkey_import_openpgp_raw: Added
 gnutls_privkey_import_x509_raw: Added
diff --git a/configure.ac b/configure.ac
index eba91ad..e774be4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -153,6 +153,33 @@ fi
 
 AM_CONDITIONAL(ENABLE_PKCS11, test "$with_p11_kit" != "no")
 
+AC_ARG_WITH(tpm,
+       AS_HELP_STRING([--without-tpm],
+               [Build without TPM (trousers) support]))
+if test "$with_tpm" != "no"; then
+    LIBS="$oldlibs -ltspi"
+    AC_MSG_CHECKING([for tss library])
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([
+                  #include <trousers/tss.h>
+                  #include <trousers/trousers.h>],[
+                  int err = Tspi_Context_Create((void *)0);
+                  Trspi_Error_String(err);])],
+                 [AC_MSG_RESULT(yes)
+                  AC_SUBST([TSS_LIBS], [-ltspi])
+                  AC_SUBST([TSS_CFLAGS], [])
+                  AC_DEFINE([HAVE_TROUSERS], 1, [Enable TPM])
+                  with_tpm=yes],
+                 [AC_MSG_RESULT(no)
+                  AC_MSG_WARN([[
+*** 
+*** trousers was not found. TPM support will be disabled.
+*** ]])
+                 with_tpm=no])
+    LIBS="$oldlibs"
+fi
+
+AM_CONDITIONAL(ENABLE_TROUSERS, test "$with_tpm" != "no")
+
 enable_local_libopts=yes
 dnl PKG_CHECK_MODULES([autoopts], autoopts >= 36.2.11,, 
[enable_local_libopts=yes])
 
@@ -208,6 +235,7 @@ AC_SUBST(GNUTLS_REQUIRES_PRIVATE)
 AC_SUBST(GNUTLS_ZLIB_LIBS_PRIVATE)
 
 
+
 gl_INIT
 
 dnl GCC warnings to enable
@@ -581,4 +609,5 @@ AC_MSG_NOTICE([Hardware acceleration/support:
   /dev/crypto:      $enable_cryptodev
   Hardware accel:   $hw_accel
   PKCS#11 support:  $with_p11_kit
+  TPM support:      $with_tpm
 ])
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 685d387..ce3e25b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -514,8 +514,10 @@ FUNCS += functions/gnutls_privkey_import_x509
 FUNCS += functions/gnutls_privkey_import_openpgp
 FUNCS += functions/gnutls_privkey_import_openpgp_raw
 FUNCS += functions/gnutls_privkey_import_x509_raw
+FUNCS += functions/gnutls_privkey_import_tpm_raw
 FUNCS += functions/gnutls_privkey_import_pkcs11_url
 FUNCS += functions/gnutls_privkey_import_ext
+FUNCS += functions/gnutls_privkey_import_ext2
 FUNCS += functions/gnutls_privkey_sign_data
 FUNCS += functions/gnutls_privkey_sign_hash
 FUNCS += functions/gnutls_privkey_decrypt_data
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f3289b9..69d98b1 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -76,6 +76,10 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c 
gnutls_cipher.c \
        gnutls_pubkey.c locks.c hash.c gnutls_dtls.c system_override.c  \
        crypto-backend.c verify-tofu.c
 
+if ENABLE_TROUSERS
+COBJECTS += tpm.c
+endif
+
 if ENABLE_PKCS11
 COBJECTS += pkcs11.c pkcs11_privkey.c pkcs11_write.c pkcs11_secret.c
 endif
@@ -120,7 +124,7 @@ libgnutls_la_LIBADD = ../gl/libgnu.la 
x509/libgnutls_x509.la \
        auth/libgnutls_auth.la algorithms/libgnutls_alg.la \
        extras/libgnutls_extras.la \
        $(LTLIBZ)  $(LTLIBINTL) $(LIBSOCKET) $(LTLIBDL) \
-       $(LTLIBPTHREAD) $(P11_KIT_LIBS) $(LIB_SELECT)
+       $(LTLIBPTHREAD) $(P11_KIT_LIBS) $(LIB_SELECT) $(TSS_LIBS)
 
 if ENABLE_OPENPGP
 libgnutls_la_LIBADD += openpgp/libgnutls_openpgp.la
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 71b6e6a..83e485d 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -286,16 +286,16 @@ static const gnutls_error_entry error_algorithms[] = {
   ERROR_ENTRY (N_("Channel binding data not available"),
                GNUTLS_E_CHANNEL_BINDING_NOT_AVAILABLE, 1),
 
+  ERROR_ENTRY (N_("TPM error."),
+               GNUTLS_E_TPM_ERROR, 1),
   ERROR_ENTRY (N_("PKCS #11 error."),
                GNUTLS_E_PKCS11_ERROR, 1),
   ERROR_ENTRY (N_("PKCS #11 initialization error."),
                GNUTLS_E_PKCS11_LOAD_ERROR, 1),
   ERROR_ENTRY (N_("Error in parsing."),
                GNUTLS_E_PARSING_ERROR, 1),
-  ERROR_ENTRY (N_("PKCS #11 error in PIN."),
-               GNUTLS_E_PKCS11_PIN_ERROR, 1),
-  ERROR_ENTRY (N_("PKCS #11 PIN should be saved."),
-               GNUTLS_E_PKCS11_ERROR, 1),
+  ERROR_ENTRY (N_("Error in provided PIN."),
+               GNUTLS_E_PIN_ERROR, 1),
   ERROR_ENTRY (N_("PKCS #11 error in slot"),
                GNUTLS_E_PKCS11_SLOT_ERROR, 1),
   ERROR_ENTRY (N_("Thread locking error"),
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index af798f9..bb75864 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -50,7 +50,7 @@ typedef int (*gnutls_privkey_decrypt_func) (gnutls_privkey_t 
key,
                                             const gnutls_datum_t * ciphertext,
                                             gnutls_datum_t * plaintext);
 
-typedef int (*gnutls_privkey_deinit_func) (gnutls_privkey_t key,
+typedef void (*gnutls_privkey_deinit_func) (gnutls_privkey_t key,
                                            void *userdata);
 
 int gnutls_pubkey_init (gnutls_pubkey_t * key);
@@ -189,6 +189,11 @@ int gnutls_privkey_import_x509_raw (gnutls_privkey_t pkey,
                                     gnutls_x509_crt_fmt_t format,
                                     const char* password);
 
+int gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey,
+                                   const gnutls_datum_t * fdata,
+                                   gnutls_x509_crt_fmt_t format,
+                                   const char* password);
+
 int gnutls_privkey_import_pkcs11_url (gnutls_privkey_t key, const char *url);
 
 int
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index d27070f..92bd6d3 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1914,6 +1914,9 @@ int gnutls_load_file(const char* filename, gnutls_datum_t 
* data);
 #define GNUTLS_E_X509_UNSUPPORTED_EXTENSION -327
 #define GNUTLS_E_SESSION_EOF -328
 
+#define GNUTLS_E_TPM_ERROR -329
+#define GNUTLS_E_PIN_ERROR GNUTLS_E_PKCS11_PIN_ERROR
+
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
 
 
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 7462813..cf7a7dc 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -806,6 +806,7 @@ GNUTLS_3_1_0 {
        gnutls_x509_privkey_import_openssl;
        gnutls_x509_privkey_import2;
        gnutls_privkey_import_ext2;
+       gnutls_privkey_import_tpm_raw;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 2a62f99..ec8a482 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -74,11 +74,11 @@ static struct gnutls_pkcs11_provider_s 
providers[MAX_PROVIDERS];
 static unsigned int active_providers = 0;
 static unsigned int initialized_registered = 0;
 
-static gnutls_pkcs11_pin_callback_t pin_func;
-static void *pin_data;
+gnutls_pkcs11_pin_callback_t _gnutls_pin_func;
+void *_gnutls_pin_data;
 
-gnutls_pkcs11_token_callback_t token_func;
-void *token_data;
+gnutls_pkcs11_token_callback_t _gnutls_token_func;
+void *_gnutls_token_data;
 
 int
 pkcs11_rv_to_err (ck_rv_t rv)
@@ -651,8 +651,8 @@ void
 gnutls_pkcs11_set_pin_function (gnutls_pkcs11_pin_callback_t fn,
                                 void *userdata)
 {
-  pin_func = fn;
-  pin_data = userdata;
+  _gnutls_pin_func = fn;
+  _gnutls_pin_data = userdata;
 }
 
 /**
@@ -669,8 +669,8 @@ void
 gnutls_pkcs11_set_token_function (gnutls_pkcs11_token_callback_t fn,
                                   void *userdata)
 {
-  token_func = fn;
-  token_data = userdata;
+  _gnutls_token_func = fn;
+  _gnutls_token_data = userdata;
 }
 
 int
@@ -1953,7 +1953,7 @@ retrieve_pin_for_callback (struct ck_token_info 
*token_info, int attempts,
   if (attempts > 0)
     flags |= GNUTLS_PKCS11_PIN_WRONG;
 
-  ret = pin_func (pin_data, attempts, (char*)token_str, label,
+  ret = _gnutls_pin_func (_gnutls_pin_data, attempts, (char*)token_str, label,
                   flags, pin_value, GNUTLS_PKCS11_MAX_PIN_LEN);
   free (token_str);
   free (label);
@@ -1987,7 +1987,7 @@ retrieve_pin (struct p11_kit_uri *info, struct 
ck_token_info *token_info,
     }
 
   /* The global gnutls pin callback */
-  if (pin_func && ret < 0)
+  if (_gnutls_pin_func && ret < 0)
     ret = retrieve_pin_for_callback (token_info, attempts, user_type, pin);
 
   /* Otherwise, PIN entry is necessary for login, so fail if there's
@@ -2102,7 +2102,7 @@ pkcs11_call_token_func (struct p11_kit_uri *info, const 
unsigned retry)
 
   tinfo = p11_kit_uri_get_token_info (info);
   label = p11_kit_space_strdup (tinfo->label, sizeof (tinfo->label));
-  ret = (token_func) (token_data, label, retry);
+  ret = (_gnutls_token_func) (_gnutls_token_data, label, retry);
   free (label);
 
   return ret;
diff --git a/lib/pkcs11_int.h b/lib/pkcs11_int.h
index 538da55..4da4107 100644
--- a/lib/pkcs11_int.h
+++ b/lib/pkcs11_int.h
@@ -34,6 +34,9 @@
 #include <p11-kit/uri.h>
 typedef unsigned char ck_bool_t;
 
+extern gnutls_pkcs11_pin_callback_t _gnutls_pin_func;
+extern void *_gnutls_pin_data;
+
 struct pkcs11_session_info {
   struct ck_function_list * module;
   struct ck_token_info tinfo;
@@ -83,8 +86,8 @@ int pkcs11_login (struct pkcs11_session_info * sinfo,
 
 int pkcs11_call_token_func (struct p11_kit_uri *info, const unsigned retry);
 
-extern gnutls_pkcs11_token_callback_t token_func;
-extern void *token_data;
+extern gnutls_pkcs11_token_callback_t _gnutls_token_func;
+extern void *_gnutls_token_data;
 
 void pkcs11_rescan_slots (void);
 int pkcs11_info_to_url (struct p11_kit_uri *info,
diff --git a/lib/pkcs11_privkey.c b/lib/pkcs11_privkey.c
index f377a9d..487230c 100644
--- a/lib/pkcs11_privkey.c
+++ b/lib/pkcs11_privkey.c
@@ -135,7 +135,7 @@ gnutls_pkcs11_privkey_get_info (gnutls_pkcs11_privkey_t 
pkey,
                ret = pkcs11_find_object (sinfo, &obj, key->info, \
                                          SESSION_LOGIN); \
                if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { \
-                       if (token_func) \
+                       if (_gnutls_token_func) \
                          { \
                            rret = pkcs11_call_token_func (key->info, 
retries++); \
                            if (rret == 0) continue; \
diff --git a/lib/tpm.c b/lib/tpm.c
new file mode 100644
index 0000000..650a846
--- /dev/null
+++ b/lib/tpm.c
@@ -0,0 +1,376 @@
+/*
+ * OpenConnect (SSL + DTLS) VPN client
+ *
+ * Copyright © 2012 Free Software Foundation.
+ * Copyright © 2008-2012 Intel Corporation.
+ *
+ * Author: David Woodhouse <address@hidden>
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * GnuTLS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+/*
+ * TPM code based on client-tpm.c from
+ * Carolin Latze <address@hidden> and Tobias Soder
+ */
+
+#include <gnutls/gnutls.h>
+#include <gnutls/abstract.h>
+
+#include <gnutls_int.h>
+#include <gnutls_errors.h>
+#include <pkcs11_int.h>
+
+#include <trousers/tss.h>
+#include <trousers/trousers.h>
+
+/* Signing function for TPM privkeys, set with gnutls_privkey_import_ext() */
+
+struct tpm_ctx_st
+{
+  TSS_HCONTEXT tpm_context;
+  TSS_HKEY tpm_key;
+  TSS_HPOLICY tpm_key_policy;
+  TSS_HKEY srk;
+  TSS_HPOLICY srk_policy;
+};
+
+static void
+tpm_deinit_fn (gnutls_privkey_t key, void *_s)
+{
+  struct tpm_ctx_st *s = _s;
+
+  Tspi_Context_CloseObject (s->tpm_context, s->tpm_key_policy);
+  Tspi_Context_CloseObject (s->tpm_context, s->tpm_key);
+  Tspi_Context_CloseObject (s->tpm_context, s->srk_policy);
+  Tspi_Context_CloseObject (s->tpm_context, s->srk);
+  Tspi_Context_Close (s->tpm_context);
+  gnutls_free (s);
+}
+
+static int
+tpm_sign_fn (gnutls_privkey_t key, void *_s,
+            const gnutls_datum_t * data, gnutls_datum_t * sig)
+{
+  struct tpm_ctx_st *s = _s;
+  TSS_HHASH hash;
+  int err;
+
+  _gnutls_debug_log ("TPM sign function called for %u bytes.\n",
+                    data->size);
+
+  err =
+      Tspi_Context_CreateObject (s->tpm_context,
+                                TSS_OBJECT_TYPE_HASH, TSS_HASH_OTHER,
+                                &hash);
+  if (err)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Failed to create TPM hash object: %s\n",
+                        Trspi_Error_String (err));
+      return GNUTLS_E_PK_SIGN_FAILED;
+    }
+  err = Tspi_Hash_SetHashValue (hash, data->size, data->data);
+  if (err)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Failed to set value in TPM hash object: %s\n",
+                        Trspi_Error_String (err));
+      Tspi_Context_CloseObject (s->tpm_context, hash);
+      return GNUTLS_E_PK_SIGN_FAILED;
+    }
+  err = Tspi_Hash_Sign (hash, s->tpm_key, &sig->size, &sig->data);
+  Tspi_Context_CloseObject (s->tpm_context, hash);
+  if (err)
+    {
+      if (s->tpm_key_policy || err != TPM_E_AUTHFAIL)
+       _gnutls_debug_log ("TPM hash signature failed: %s\n",
+                          Trspi_Error_String (err));
+      if (err == TPM_E_AUTHFAIL)
+       return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
+      else
+       return GNUTLS_E_PK_SIGN_FAILED;
+    }
+  return 0;
+}
+
+
+/**
+ * gnutls_privkey_import_tpm_raw:
+ * @pkey: The private key
+ * @fdata: The TPM key to be imported
+ * @format: The format of the private key
+ * @password: A password (optional)
+ *
+ * This function will import the given private key to the abstract
+ * #gnutls_privkey_t structure. 
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ *
+ * Since: 3.1.0
+ *
+ **/
+int
+gnutls_privkey_import_tpm_raw (gnutls_privkey_t pkey,
+                              const gnutls_datum_t * fdata,
+                              gnutls_x509_crt_fmt_t format,
+                              const char *password)
+{
+  static const TSS_UUID SRK_UUID = TSS_UUID_SRK;
+  char pin_value[GNUTLS_PKCS11_MAX_PIN_LEN];
+  gnutls_datum_t asn1;
+  unsigned int tss_len;
+  unsigned int attempts = 0;
+  int ofs, err, ret;
+  struct tpm_ctx_st *s;
+  gnutls_datum_t tmp_sig;
+  static const char nullpass[20];
+
+  err = gnutls_pem_base64_decode_alloc ("TSS KEY BLOB", fdata, &asn1);
+  if (err)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Error decoding TSS key blob: %s\n",
+                        gnutls_strerror (err));
+      return GNUTLS_E_INVALID_REQUEST;
+    }
+
+  /* FIXME: do proper decoding */
+
+  /* Ick. We have to parse the ASN1 OCTET_STRING for ourselves. */
+  if (asn1.size < 2 || asn1.data[0] != 0x04 /* OCTET_STRING */ )
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Error in TSS key blob\n");
+      ret = GNUTLS_E_PARSING_ERROR;
+      goto out_blob;
+    }
+
+  s = gnutls_malloc (sizeof (*s));
+  if (s == NULL)
+    {
+      gnutls_assert ();
+      ret = GNUTLS_E_MEMORY_ERROR;
+      goto out_ctx;
+    }
+
+  tss_len = asn1.data[1];
+  ofs = 2;
+  if (tss_len & 0x80)
+    {
+      unsigned int lenlen = tss_len & 0x7f;
+
+      if (asn1.size < 2 + lenlen || lenlen > 3)
+       {
+         gnutls_assert ();
+         _gnutls_debug_log ("Error in TSS key blob\n");
+         ret = GNUTLS_E_PARSING_ERROR;
+         goto out_blob;
+       }
+
+      tss_len = 0;
+      while (lenlen)
+       {
+         tss_len <<= 8;
+         tss_len |= asn1.data[ofs++];
+         lenlen--;
+       }
+    }
+  if (tss_len + ofs != asn1.size)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Error in TSS key blob\n");
+      ret = GNUTLS_E_PARSING_ERROR;
+      goto out_blob;
+    }
+
+  err = Tspi_Context_Create (&s->tpm_context);
+  if (err)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Failed to create TPM context: %s\n",
+                        Trspi_Error_String (err));
+      ret = GNUTLS_E_TPM_ERROR;
+      goto out_blob;
+    }
+  err = Tspi_Context_Connect (s->tpm_context, NULL);
+  if (err)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Failed to connect TPM context: %s\n",
+                        Trspi_Error_String (err));
+      ret = GNUTLS_E_TPM_ERROR;
+      goto out_context;
+    }
+  err =
+      Tspi_Context_LoadKeyByUUID (s->tpm_context, TSS_PS_TYPE_SYSTEM,
+                                 SRK_UUID, &s->srk);
+  if (err)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log
+         ("Failed to load TPM SRK key: %s\n", Trspi_Error_String (err));
+      ret = GNUTLS_E_TPM_ERROR;
+      goto out_context;
+    }
+  err = Tspi_GetPolicyObject (s->srk, TSS_POLICY_USAGE, &s->srk_policy);
+  if (err)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Failed to load TPM SRK policy object: %s\n",
+                        Trspi_Error_String (err));
+      ret = GNUTLS_E_TPM_ERROR;
+      goto out_srk;
+    }
+
+  /* We don't seem to get the error here... */
+  if (password)
+    err = Tspi_Policy_SetSecret (s->srk_policy,
+                                TSS_SECRET_MODE_PLAIN,
+                                strlen (password), (BYTE *) password);
+  else                         /* Well-known NULL key */
+    err = Tspi_Policy_SetSecret (s->srk_policy,
+                                TSS_SECRET_MODE_SHA1,
+                                sizeof (nullpass), (BYTE *) nullpass);
+  if (err)
+    {
+      gnutls_assert ();
+      _gnutls_debug_log ("Failed to set TPM PIN: %s\n",
+                        Trspi_Error_String (err));
+      ret = GNUTLS_E_TPM_ERROR;
+      goto out_srkpol;
+    }
+
+  /* ... we get it here instead. */
+  err = Tspi_Context_LoadKeyByBlob (s->tpm_context, s->srk,
+                                   tss_len, asn1.data + ofs, &s->tpm_key);
+  if (err != 0)
+    {
+      if (password)
+       {
+         gnutls_assert ();
+         _gnutls_debug_log
+             ("Failed to load TPM key blob: %s\n",
+              Trspi_Error_String (err));
+       }
+
+      if (err != TPM_E_AUTHFAIL)
+       {
+         gnutls_assert ();
+         ret = GNUTLS_E_TPM_ERROR;
+         goto out_srkpol;
+       }
+      else
+       {
+         ret = gnutls_assert_val (GNUTLS_E_PIN_ERROR);
+         goto out_srkpol;
+       }
+    }
+
+  ret =
+      gnutls_privkey_import_ext2 (pkey, GNUTLS_PK_RSA, s,
+                                 tpm_sign_fn, NULL, tpm_deinit_fn, 0);
+  if (ret < 0)
+    {
+      gnutls_assert ();
+      goto out_srkpol;
+    }
+
+retry_sign:
+  ret =
+      gnutls_privkey_sign_data (pkey, GNUTLS_DIG_SHA1, 0, fdata, &tmp_sig);
+  if (ret == GNUTLS_E_INSUFFICIENT_CREDENTIALS)
+    {
+      if (!s->tpm_key_policy)
+       {
+         err = Tspi_Context_CreateObject (s->tpm_context,
+                                          TSS_OBJECT_TYPE_POLICY,
+                                          TSS_POLICY_USAGE,
+                                          &s->tpm_key_policy);
+         if (err)
+           {
+             gnutls_assert ();
+             _gnutls_debug_log
+                 ("Failed to create key policy object: %s\n",
+                  Trspi_Error_String (err));
+             ret = GNUTLS_E_TPM_ERROR;
+             goto out_key;
+           }
+         err = Tspi_Policy_AssignToObject (s->tpm_key_policy, s->tpm_key);
+         if (err)
+           {
+             gnutls_assert ();
+             _gnutls_debug_log ("Failed to assign policy to key: %s\n",
+                                Trspi_Error_String (err));
+             ret = GNUTLS_E_TPM_ERROR;
+             goto out_key_policy;
+           }
+       }
+
+      ret =
+         _gnutls_pin_func (_gnutls_pin_data, attempts++, "tpm:",
+                           "TPM key", 0, pin_value,
+                           GNUTLS_PKCS11_MAX_PIN_LEN);
+      if (ret < 0)
+       {
+         ret = gnutls_assert_val (GNUTLS_E_PIN_ERROR);
+         goto out_key_policy;
+       }
+
+      err = Tspi_Policy_SetSecret (s->tpm_key_policy,
+                                  TSS_SECRET_MODE_PLAIN,
+                                  strlen (pin_value), (void *) pin_value);
+
+      if (err)
+       {
+         gnutls_assert ();
+         _gnutls_debug_log ("Failed to set key PIN: %s\n",
+                            Trspi_Error_String (err));
+         goto out_key_policy;
+       }
+      goto retry_sign;
+    }
+  else if (ret < 0)
+    {
+      gnutls_assert ();
+      goto out_blob;
+    }
+
+  gnutls_free (asn1.data);
+  return 0;
+out_key_policy:
+  Tspi_Context_CloseObject (s->tpm_context, s->tpm_key_policy);
+  s->tpm_key_policy = 0;
+out_key:
+  Tspi_Context_CloseObject (s->tpm_context, s->tpm_key);
+  s->tpm_key = 0;
+out_srkpol:
+  Tspi_Context_CloseObject (s->tpm_context, s->srk_policy);
+  s->srk_policy = 0;
+out_srk:
+  Tspi_Context_CloseObject (s->tpm_context, s->srk);
+  s->srk = 0;
+out_context:
+  Tspi_Context_Close (s->tpm_context);
+  s->tpm_context = 0;
+out_ctx:
+  gnutls_free (s);
+out_blob:
+  gnutls_free (asn1.data);
+  return ret;
+}
+


hooks/post-receive
-- 
GNU gnutls



reply via email to

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