]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Shift TSS context out of generic vpninfo
authorDavid Woodhouse <dwmw2@infradead.org>
Mon, 1 Oct 2018 11:51:20 +0000 (12:51 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Wed, 3 Oct 2018 07:38:03 +0000 (08:38 +0100)
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
gnutls.c
gnutls.h
gnutls_tpm.c
openconnect-internal.h

index 49dad28675151a84a54e93f36c393a210f198e05..dc285570be892a96194f749e67128e08d4ba0f3a 100644 (file)
--- a/gnutls.c
+++ b/gnutls.c
 #include <gnutls/pkcs12.h>
 #include <gnutls/abstract.h>
 
-#ifdef HAVE_TROUSERS
-#include <trousers/tss.h>
-#include <trousers/trousers.h>
-#endif
-
 #ifdef HAVE_P11KIT
 #include <p11-kit/p11-kit.h>
 #include <p11-kit/pkcs11.h>
@@ -1316,7 +1311,7 @@ static int load_certificate(struct openconnect_info *vpninfo)
                             _("This version of OpenConnect was built without TPM support\n"));
                return -EINVAL;
 #else
-               ret = load_tpm_key(vpninfo, &fdata, &pkey, &pkey_sig);
+               ret = load_tpm1_key(vpninfo, &fdata, &pkey, &pkey_sig);
                if (ret)
                        goto out;
 
@@ -2319,26 +2314,7 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final)
                gnutls_certificate_free_credentials(vpninfo->https_cred);
                vpninfo->https_cred = NULL;
 #ifdef HAVE_TROUSERS
-               if (vpninfo->tpm_key_policy) {
-                       Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy);
-                       vpninfo->tpm_key = 0;
-               }
-               if (vpninfo->tpm_key) {
-                       Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key);
-                       vpninfo->tpm_key = 0;
-               }
-               if (vpninfo->srk_policy) {
-                       Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy);
-                       vpninfo->srk_policy = 0;
-               }
-               if (vpninfo->srk) {
-                       Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk);
-                       vpninfo->srk = 0;
-               }
-               if (vpninfo->tpm_context) {
-                       Tspi_Context_Close(vpninfo->tpm_context);
-                       vpninfo->tpm_context = 0;
-               }
+               release_tpm1_ctx(vpninfo);
 #endif
        }
 }
index 5eeacb0f3433801fd7ce88930e138b7e8947d5d0..93ad42dca70a90502da28336f1f5c724d1e6d9db 100644 (file)
--- a/gnutls.h
+++ b/gnutls.h
@@ -24,8 +24,9 @@
 
 #include "openconnect-internal.h"
 
-int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
-                gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig);
+int load_tpm1_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
+                 gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig);
+void release_tpm1_ctx(struct openconnect_info *info);
 
 char *get_gnutls_cipher(gnutls_session_t session);
 
index ed417d19741c6bb41d8beeebb0b1630eda06603d..9f55b2b85551d9b541a096112faf79bf61121fb8 100644 (file)
 #include "gnutls.h"
 
 #ifdef HAVE_TROUSERS
+#include <trousers/tss.h>
+#include <trousers/trousers.h>
+
+struct oc_tpm1_ctx {
+       TSS_HCONTEXT tpm_context;
+       TSS_HKEY srk;
+       TSS_HPOLICY srk_policy;
+       TSS_HKEY tpm_key;
+       TSS_HPOLICY tpm_key_policy;
+};
 
 /* Signing function for TPM privkeys, set with gnutls_privkey_import_ext() */
 static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
@@ -44,7 +54,7 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
                     _("TPM sign function called for %d bytes.\n"),
                     data->size);
 
-       err = Tspi_Context_CreateObject(vpninfo->tpm_context, TSS_OBJECT_TYPE_HASH,
+       err = Tspi_Context_CreateObject(vpninfo->tpm1->tpm_context, TSS_OBJECT_TYPE_HASH,
                                        TSS_HASH_OTHER, &hash);
        if (err) {
                vpn_progress(vpninfo, PRG_ERR,
@@ -57,13 +67,13 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to set value in TPM hash object: %s\n"),
                             Trspi_Error_String(err));
-               Tspi_Context_CloseObject(vpninfo->tpm_context, hash);
+               Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, hash);
                return GNUTLS_E_PK_SIGN_FAILED;
        }
-       err = Tspi_Hash_Sign(hash, vpninfo->tpm_key, &sig->size, &sig->data);
-       Tspi_Context_CloseObject(vpninfo->tpm_context, hash);
+       err = Tspi_Hash_Sign(hash, vpninfo->tpm1->tpm_key, &sig->size, &sig->data);
+       Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, hash);
        if (err) {
-               if (vpninfo->tpm_key_policy || err != TPM_E_AUTHFAIL)
+               if (vpninfo->tpm1->tpm_key_policy || err != TPM_E_AUTHFAIL)
                        vpn_progress(vpninfo, PRG_ERR,
                                     _("TPM hash signature failed: %s\n"),
                                     Trspi_Error_String(err));
@@ -75,8 +85,8 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
        return 0;
 }
 
-int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
-                gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
+int load_tpm1_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
+                 gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
 {
        static const TSS_UUID SRK_UUID = TSS_UUID_SRK;
        gnutls_datum_t asn1;
@@ -91,6 +101,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
                             gnutls_strerror(err));
                return -EINVAL;
        }
+       vpninfo->tpm1 = calloc(1, sizeof(*vpninfo->tpm1));
        /* Ick. We have to parse the ASN1 OCTET_STRING for ourselves. */
        if (asn1.size < 2 || asn1.data[0] != 0x04 /* OCTET_STRING */) {
                vpn_progress(vpninfo, PRG_ERR,
@@ -122,29 +133,29 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
                goto out_blob;
        }
 
-       err = Tspi_Context_Create(&vpninfo->tpm_context);
+       err = Tspi_Context_Create(&vpninfo->tpm1->tpm_context);
        if (err) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to create TPM context: %s\n"),
                             Trspi_Error_String(err));
                goto out_blob;
        }
-       err = Tspi_Context_Connect(vpninfo->tpm_context, NULL);
+       err = Tspi_Context_Connect(vpninfo->tpm1->tpm_context, NULL);
        if (err) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to connect TPM context: %s\n"),
                             Trspi_Error_String(err));
                goto out_context;
        }
-       err = Tspi_Context_LoadKeyByUUID(vpninfo->tpm_context, TSS_PS_TYPE_SYSTEM,
-                                        SRK_UUID, &vpninfo->srk);
+       err = Tspi_Context_LoadKeyByUUID(vpninfo->tpm1->tpm_context, TSS_PS_TYPE_SYSTEM,
+                                        SRK_UUID, &vpninfo->tpm1->srk);
        if (err) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to load TPM SRK key: %s\n"),
                             Trspi_Error_String(err));
                goto out_context;
        }
-       err = Tspi_GetPolicyObject(vpninfo->srk, TSS_POLICY_USAGE, &vpninfo->srk_policy);
+       err = Tspi_GetPolicyObject(vpninfo->tpm1->srk, TSS_POLICY_USAGE, &vpninfo->tpm1->srk_policy);
        if (err) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to load TPM SRK policy object: %s\n"),
@@ -159,11 +170,11 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
 
                /* We don't seem to get the error here... */
                if (pass)
-                       err = Tspi_Policy_SetSecret(vpninfo->srk_policy,
+                       err = Tspi_Policy_SetSecret(vpninfo->tpm1->srk_policy,
                                                    TSS_SECRET_MODE_PLAIN,
                                                    strlen(pass), (BYTE *)pass);
                else /* Well-known NULL key */
-                       err = Tspi_Policy_SetSecret(vpninfo->srk_policy,
+                       err = Tspi_Policy_SetSecret(vpninfo->tpm1->srk_policy,
                                                    TSS_SECRET_MODE_SHA1,
                                                    sizeof(nullpass), (BYTE *)nullpass);
                if (err) {
@@ -176,9 +187,9 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
                free(pass);
 
                /* ... we get it here instead. */
-               err = Tspi_Context_LoadKeyByBlob(vpninfo->tpm_context, vpninfo->srk,
+               err = Tspi_Context_LoadKeyByBlob(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk,
                                                 tss_len, asn1.data + ofs,
-                                                &vpninfo->tpm_key);
+                                                &vpninfo->tpm1->tpm_key);
                if (!err)
                        break;
 
@@ -205,19 +216,19 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
  retry_sign:
        err = gnutls_privkey_sign_data(*pkey, GNUTLS_DIG_SHA1, 0, fdata, pkey_sig);
        if (err == GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
-               if (!vpninfo->tpm_key_policy) {
-                       err = Tspi_Context_CreateObject(vpninfo->tpm_context,
+               if (!vpninfo->tpm1->tpm_key_policy) {
+                       err = Tspi_Context_CreateObject(vpninfo->tpm1->tpm_context,
                                                        TSS_OBJECT_TYPE_POLICY,
                                                        TSS_POLICY_USAGE,
-                                                       &vpninfo->tpm_key_policy);
+                                                       &vpninfo->tpm1->tpm_key_policy);
                        if (err) {
                                vpn_progress(vpninfo, PRG_ERR,
                                             _("Failed to create key policy object: %s\n"),
                                             Trspi_Error_String(err));
                                goto out_key;
                        }
-                       err = Tspi_Policy_AssignToObject(vpninfo->tpm_key_policy,
-                                                        vpninfo->tpm_key);
+                       err = Tspi_Policy_AssignToObject(vpninfo->tpm1->tpm_key_policy,
+                                                        vpninfo->tpm1->tpm_key);
                        if (err) {
                                vpn_progress(vpninfo, PRG_ERR,
                                             _("Failed to assign policy to key: %s\n"),
@@ -230,7 +241,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
                if (err)
                        goto out_key_policy;
 
-               err = Tspi_Policy_SetSecret(vpninfo->tpm_key_policy,
+               err = Tspi_Policy_SetSecret(vpninfo->tpm1->tpm_key_policy,
                                            TSS_SECRET_MODE_PLAIN,
                                            strlen(pass), (void *)pass);
                free(pass);
@@ -247,23 +258,53 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
        free(asn1.data);
        return 0;
  out_key_policy:
-       Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy);
-       vpninfo->tpm_key_policy = 0;
+       Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key_policy);
+       vpninfo->tpm1->tpm_key_policy = 0;
  out_key:
-       Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key);
-       vpninfo->tpm_key = 0;
+       Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key);
+       vpninfo->tpm1->tpm_key = 0;
  out_srkpol:
-       Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy);
-       vpninfo->srk_policy = 0;
+       Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk_policy);
+       vpninfo->tpm1->srk_policy = 0;
  out_srk:
-       Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk);
-       vpninfo->srk = 0;
+       Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk);
+       vpninfo->tpm1->srk = 0;
  out_context:
-       Tspi_Context_Close(vpninfo->tpm_context);
-       vpninfo->tpm_context = 0;
+       Tspi_Context_Close(vpninfo->tpm1->tpm_context);
+       vpninfo->tpm1->tpm_context = 0;
  out_blob:
        free(asn1.data);
+       free(vpninfo->tpm1);
+       vpninfo->tpm1 = NULL;
        return -EIO;
 }
 
+void release_tpm1_ctx(struct openconnect_info *vpninfo)
+{
+       if (!vpninfo->tpm1)
+               return;
+
+       if (vpninfo->tpm1->tpm_key_policy) {
+               Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key_policy);
+               vpninfo->tpm1->tpm_key = 0;
+       }
+       if (vpninfo->tpm1->tpm_key) {
+               Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key);
+               vpninfo->tpm1->tpm_key = 0;
+       }
+       if (vpninfo->tpm1->srk_policy) {
+               Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk_policy);
+               vpninfo->tpm1->srk_policy = 0;
+       }
+       if (vpninfo->tpm1->srk) {
+               Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk);
+               vpninfo->tpm1->srk = 0;
+       }
+       if (vpninfo->tpm1->tpm_context) {
+               Tspi_Context_Close(vpninfo->tpm1->tpm_context);
+               vpninfo->tpm1->tpm_context = 0;
+       }
+       free(vpninfo->tpm1);
+       vpninfo->tpm1 = NULL;
+};
 #endif /* HAVE_TROUSERS */
index 118571deee34d90cc537defa7006456fcdf5d312..63547a4a83506dd568189ec73d3ea47fe60b55e6 100644 (file)
 #include <gnutls/abstract.h>
 #include <gnutls/x509.h>
 #include <gnutls/crypto.h>
-#ifdef HAVE_TROUSERS
-#include <trousers/tss.h>
-#include <trousers/trousers.h>
-#endif
 #endif
 
 #ifdef HAVE_ICONV
@@ -349,6 +345,7 @@ struct esp {
 };
 
 struct oc_pcsc_ctx;
+struct oc_tpm1_ctx;
 
 struct openconnect_info {
        const struct vpn_proto *proto;
@@ -504,11 +501,7 @@ struct openconnect_info {
        char local_cert_md5[MD5_SIZE * 2 + 1]; /* For CSD */
        char gnutls_prio[256];
 #ifdef HAVE_TROUSERS
-       TSS_HCONTEXT tpm_context;
-       TSS_HKEY srk;
-       TSS_HPOLICY srk_policy;
-       TSS_HKEY tpm_key;
-       TSS_HPOLICY tpm_key_policy;
+       struct oc_tpm1_ctx *tpm1;
 #endif
 #endif /* OPENCONNECT_GNUTLS */
        struct pin_cache *pin_cache;