GnuTLS: Move TPMv2 context to certinfo
authorDavid Woodhouse <dwmw2@infradead.org>
Sat, 8 May 2021 07:48:16 +0000 (08:48 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Mon, 10 May 2021 09:27:19 +0000 (10:27 +0100)
Precisely the same as we just did for TPMv1, to make the TPM context
per-cert instead of per-vpninfo.

As with TPMv1, some of this *could* be global state in the future.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
gnutls.c
gnutls.h
gnutls_tpm2_esys.c
gnutls_tpm2_ibm.c
openconnect-internal.h

index 52ef49fff3da37ff77777994bbb3ad5835db3c2a..0694002ac8172cf5f9480b3adc65c6e1e44ed65d 100644 (file)
--- a/gnutls.c
+++ b/gnutls.c
@@ -2450,7 +2450,7 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final)
                release_tpm1_ctx(vpninfo, &vpninfo->certinfo[0]);
 #endif
 #ifdef HAVE_TSS2
-               release_tpm2_ctx(vpninfo);
+               release_tpm2_ctx(vpninfo, &vpninfo->certinfo[0]);
 #endif
        }
 }
index 4aa5c5478927e6e72ba803eb1bc0b1498eea4840..378937e84640aa5bbef429a04c08bdf5e5487b0e 100644 (file)
--- a/gnutls.h
+++ b/gnutls.h
@@ -30,7 +30,7 @@ void release_tpm1_ctx(struct openconnect_info *info, struct cert_info *certinfo)
 
 int load_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinfo,
                  gnutls_datum_t *fdata, gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig);
-void release_tpm2_ctx(struct openconnect_info *info);
+void release_tpm2_ctx(struct openconnect_info *info, struct cert_info *certinfo);
 int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinfo,
                     gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
                     unsigned int parent, int emptyauth, int legacy,
index 7b8a4417f83c9b70155c7efa9c6a241481e877f1..5d847056c07326e3cb4e43a10877cdbeb566ec59 100644 (file)
@@ -182,14 +182,14 @@ static void install_tpm_passphrase(struct openconnect_info *vpninfo, TPM2B_DIGES
        free_pass(&pass);
 }
 
-static int init_tpm2_primary(struct openconnect_info *vpninfo,
+static int init_tpm2_primary(struct openconnect_info *vpninfo, struct cert_info *certinfo,
                             ESYS_CONTEXT *ctx, ESYS_TR *primaryHandle)
 {
        TSS2_RC r;
        const char *hierarchy_name;
        ESYS_TR hierarchy;
 
-       switch(vpninfo->tpm2->parent) {
+       switch(certinfo->tpm2->parent) {
        case TPM2_RH_OWNER:     hierarchy = ESYS_TR_RH_OWNER;   hierarchy_name = _("owner"); break;
        case TPM2_RH_NULL:      hierarchy = ESYS_TR_RH_NULL;    hierarchy_name = _("null"); break;
        case TPM2_RH_ENDORSEMENT:hierarchy = ESYS_TR_RH_ENDORSEMENT; hierarchy_name = _("endorsement"); break;
@@ -199,15 +199,15 @@ static int init_tpm2_primary(struct openconnect_info *vpninfo,
 
        vpn_progress(vpninfo, PRG_DEBUG, _("Creating primary key under %s hierarchy.\n"), hierarchy_name);
  reauth:
-       if (vpninfo->tpm2->need_ownerauth) {
+       if (certinfo->tpm2->need_ownerauth) {
                char *pass = NULL;
                if (request_passphrase(vpninfo, "openconnect_tpm2_hierarchy", &pass,
                                           _("Enter TPM2 %s hierarchy password:"), hierarchy_name))
                        return -EPERM;
-               install_tpm_passphrase(vpninfo, &vpninfo->tpm2->ownerauth, pass);
-               vpninfo->tpm2->need_ownerauth = 0;
+               install_tpm_passphrase(vpninfo, &certinfo->tpm2->ownerauth, pass);
+               certinfo->tpm2->need_ownerauth = 0;
        }
-       r = Esys_TR_SetAuth(ctx, hierarchy, &vpninfo->tpm2->ownerauth);
+       r = Esys_TR_SetAuth(ctx, hierarchy, &certinfo->tpm2->ownerauth);
        if (r) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("TPM2 Esys_TR_SetAuth failed: 0x%x\n"),
@@ -217,13 +217,13 @@ static int init_tpm2_primary(struct openconnect_info *vpninfo,
        r = Esys_CreatePrimary(ctx, hierarchy,
                               ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
                               &primarySensitive,
-                              vpninfo->tpm2->legacy_srk ? &primaryTemplate_legacy : &primaryTemplate,
+                              certinfo->tpm2->legacy_srk ? &primaryTemplate_legacy : &primaryTemplate,
                               &allOutsideInfo, &allCreationPCR,
                               primaryHandle, NULL, NULL, NULL, NULL);
        if (r == KEY_AUTH_FAILED) {
                vpn_progress(vpninfo, PRG_DEBUG,
                             _("TPM2 Esys_CreatePrimary owner auth failed\n"));
-               vpninfo->tpm2->need_ownerauth = 1;
+               certinfo->tpm2->need_ownerauth = 1;
                goto reauth;
        } else if (r) {
                vpn_progress(vpninfo, PRG_ERR,
@@ -238,7 +238,7 @@ static int init_tpm2_primary(struct openconnect_info *vpninfo,
 #define parent_is_persistent(parent) ((parent) >> TPM2_HR_SHIFT == TPM2_HT_PERSISTENT)
 
 static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
-                        struct openconnect_info *vpninfo)
+                        struct openconnect_info *vpninfo, struct cert_info *certinfo)
 {
        ESYS_TR parentHandle = ESYS_TR_NONE;
        TSS2_RC r;
@@ -267,41 +267,41 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
                goto error;
        }
 
-       if (parent_is_generated(vpninfo->tpm2->parent)) {
-               if (init_tpm2_primary(vpninfo, *ctx, &parentHandle))
+       if (parent_is_generated(certinfo->tpm2->parent)) {
+               if (init_tpm2_primary(vpninfo, certinfo, *ctx, &parentHandle))
                        goto error;
        } else {
-               r = Esys_TR_FromTPMPublic(*ctx, vpninfo->tpm2->parent,
+               r = Esys_TR_FromTPMPublic(*ctx, certinfo->tpm2->parent,
                                          ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, &parentHandle);
                if (r) {
                        vpn_progress(vpninfo, PRG_ERR,
                                     _("Esys_TR_FromTPMPublic failed for handle 0x%x: 0x%x\n"),
-                                    vpninfo->tpm2->parent, r);
+                                    certinfo->tpm2->parent, r);
                        goto error;
                }
                /* If we don't already have a password (and haven't already authenticated
                 * successfully), check the NODA flag on the parent and demand one if DA
                 * protection is enabled (since that strongly implies there is a non-empty
                 * password). */
-               if (!vpninfo->tpm2->did_ownerauth && !vpninfo->tpm2->ownerauth.size) {
+               if (!certinfo->tpm2->did_ownerauth && !certinfo->tpm2->ownerauth.size) {
                        TPM2B_PUBLIC *pub = NULL;
 
                        r = Esys_ReadPublic(*ctx, parentHandle, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
                                            &pub, NULL, NULL);
                        if (!r && !(pub->publicArea.objectAttributes & TPMA_OBJECT_NODA))
-                               vpninfo->tpm2->need_ownerauth = 1;
+                               certinfo->tpm2->need_ownerauth = 1;
                        free(pub);
                }
        reauth:
-               if (vpninfo->tpm2->need_ownerauth) {
+               if (certinfo->tpm2->need_ownerauth) {
                        char *pass = NULL;
                        if (request_passphrase(vpninfo, "openconnect_tpm2_parent", &pass,
                                               _("Enter TPM2 parent key password:")))
                                return -EPERM;
-                       install_tpm_passphrase(vpninfo, &vpninfo->tpm2->ownerauth, pass);
-                       vpninfo->tpm2->need_ownerauth = 0;
+                       install_tpm_passphrase(vpninfo, &certinfo->tpm2->ownerauth, pass);
+                       certinfo->tpm2->need_ownerauth = 0;
                }
-               r = Esys_TR_SetAuth(*ctx, parentHandle, &vpninfo->tpm2->ownerauth);
+               r = Esys_TR_SetAuth(*ctx, parentHandle, &certinfo->tpm2->ownerauth);
                if (r) {
                        vpn_progress(vpninfo, PRG_ERR,
                                     _("TPM2 Esys_TR_SetAuth failed: 0x%x\n"),
@@ -314,12 +314,12 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
 
        r = Esys_Load(*ctx, parentHandle,
                      ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
-                     &vpninfo->tpm2->priv, &vpninfo->tpm2->pub,
+                     &certinfo->tpm2->priv, &certinfo->tpm2->pub,
                      keyHandle);
        if (r == PARENT_AUTH_FAILED) {
                vpn_progress(vpninfo, PRG_DEBUG,
                             _("TPM2 Esys_Load auth failed\n"));
-               vpninfo->tpm2->need_ownerauth = 1;
+               certinfo->tpm2->need_ownerauth = 1;
                goto reauth;
        }
        if (r) {
@@ -328,9 +328,9 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
                             r);
                goto error;
        }
-       vpninfo->tpm2->did_ownerauth = 1;
+       certinfo->tpm2->did_ownerauth = 1;
 
-       if (parent_is_generated(vpninfo->tpm2->parent)) {
+       if (parent_is_generated(certinfo->tpm2->parent)) {
                r = Esys_FlushContext(*ctx, parentHandle);
                if (r) {
                        vpn_progress(vpninfo, PRG_ERR,
@@ -342,7 +342,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
 
        return 0;
  error:
-       if (parent_is_generated(vpninfo->tpm2->parent) && parentHandle != ESYS_TR_NONE)
+       if (parent_is_generated(certinfo->tpm2->parent) && parentHandle != ESYS_TR_NONE)
                Esys_FlushContext(*ctx, parentHandle);
        if (*keyHandle != ESYS_TR_NONE)
                Esys_FlushContext(*ctx, *keyHandle);
@@ -357,7 +357,7 @@ static int auth_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *cer
 {
        TSS2_RC r;
 
-       if (vpninfo->tpm2->need_userauth || certinfo->password) {
+       if (certinfo->tpm2->need_userauth || certinfo->password) {
                char *pass = NULL;
 
                if (certinfo->password) {
@@ -369,11 +369,11 @@ static int auth_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *cer
                        if (err)
                                return err;
                }
-               install_tpm_passphrase(vpninfo, &vpninfo->tpm2->userauth, pass);
-               vpninfo->tpm2->need_userauth = 0;
+               install_tpm_passphrase(vpninfo, &certinfo->tpm2->userauth, pass);
+               certinfo->tpm2->need_userauth = 0;
        }
 
-       r = Esys_TR_SetAuth(ctx, key_handle, &vpninfo->tpm2->userauth);
+       r = Esys_TR_SetAuth(ctx, key_handle, &certinfo->tpm2->userauth);
        if (r) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("TPM2 Esys_TR_SetAuth failed: 0x%x\n"),
@@ -401,12 +401,12 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
                     _("TPM2 RSA sign function called for %d bytes.\n"),
                     data->size);
 
-       digest.size = vpninfo->tpm2->pub.publicArea.unique.rsa.size;
+       digest.size = certinfo->tpm2->pub.publicArea.unique.rsa.size;
 
        if (oc_pkcs1_pad(vpninfo, digest.buffer, digest.size, data))
                return GNUTLS_E_PK_SIGN_FAILED;
 
-       if (init_tpm2_key(&ectx, &key_handle, vpninfo))
+       if (init_tpm2_key(&ectx, &key_handle, vpninfo, certinfo))
                goto out;
  reauth:
        if (auth_tpm2_key(vpninfo, certinfo, ectx, key_handle))
@@ -418,7 +418,7 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        if (r == KEY_AUTH_FAILED) {
                vpn_progress(vpninfo, PRG_DEBUG,
                             _("TPM2 Esys_RSA_Decrypt auth failed\n"));
-               vpninfo->tpm2->need_userauth = 1;
+               certinfo->tpm2->need_userauth = 1;
                goto reauth;
        }
        if (r) {
@@ -486,7 +486,7 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        memcpy(digest.buffer, data->data, data->size);
        digest.size = data->size;
 
-       if (init_tpm2_key(&ectx, &key_handle, vpninfo))
+       if (init_tpm2_key(&ectx, &key_handle, vpninfo, certinfo))
                goto out;
  reauth:
        if (auth_tpm2_key(vpninfo, certinfo, ectx, key_handle))
@@ -499,7 +499,7 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        if (r == KEY_AUTH_FAILED) {
                vpn_progress(vpninfo, PRG_DEBUG,
                             _("TPM2 Esys_Sign auth failed\n"));
-               vpninfo->tpm2->need_userauth = 1;
+               certinfo->tpm2->need_userauth = 1;
                goto reauth;
        }
        if (r) {
@@ -542,14 +542,14 @@ int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinf
                return -EINVAL;
        }
 
-       vpninfo->tpm2 = calloc(1, sizeof(*vpninfo->tpm2));
-       if (!vpninfo->tpm2)
+       certinfo->tpm2 = calloc(1, sizeof(*certinfo->tpm2));
+       if (!certinfo->tpm2)
                return -ENOMEM;
 
-       vpninfo->tpm2->parent = parent;
+       certinfo->tpm2->parent = parent;
 
        r = Tss2_MU_TPM2B_PRIVATE_Unmarshal(privdata->data, privdata->size, NULL,
-                                           &vpninfo->tpm2->priv);
+                                           &certinfo->tpm2->priv);
        if (r) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to import TPM2 private key data: 0x%x\n"),
@@ -558,7 +558,7 @@ int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinf
        }
 
        r = Tss2_MU_TPM2B_PUBLIC_Unmarshal(pubdata->data, pubdata->size, NULL,
-                                          &vpninfo->tpm2->pub);
+                                          &certinfo->tpm2->pub);
        if (r) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to import TPM2 public key data: 0x%x\n"),
@@ -566,29 +566,29 @@ int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinf
                goto err_out;
        }
 
-       vpninfo->tpm2->need_userauth = !emptyauth;
-       vpninfo->tpm2->legacy_srk = legacy;
+       certinfo->tpm2->need_userauth = !emptyauth;
+       certinfo->tpm2->legacy_srk = legacy;
 
-       switch(vpninfo->tpm2->pub.publicArea.type) {
+       switch(certinfo->tpm2->pub.publicArea.type) {
        case TPM2_ALG_RSA: return GNUTLS_PK_RSA;
        case TPM2_ALG_ECC: return GNUTLS_PK_ECC;
        }
 
        vpn_progress(vpninfo, PRG_ERR,
                     _("Unsupported TPM2 key type %d\n"),
-                    vpninfo->tpm2->pub.publicArea.type);
+                    certinfo->tpm2->pub.publicArea.type);
  err_out:
-       release_tpm2_ctx(vpninfo);
+       release_tpm2_ctx(vpninfo, certinfo);
        return -EINVAL;
 }
 
 
-void release_tpm2_ctx(struct openconnect_info *vpninfo)
+void release_tpm2_ctx(struct openconnect_info *vpninfo, struct cert_info *certinfo)
 {
-       if (vpninfo->tpm2) {
-               clear_mem(vpninfo->tpm2->ownerauth.buffer, sizeof(vpninfo->tpm2->ownerauth.buffer));
-               clear_mem(vpninfo->tpm2->userauth.buffer, sizeof(vpninfo->tpm2->userauth.buffer));
-               free(vpninfo->tpm2);
+       if (certinfo->tpm2) {
+               clear_mem(certinfo->tpm2->ownerauth.buffer, sizeof(certinfo->tpm2->ownerauth.buffer));
+               clear_mem(certinfo->tpm2->userauth.buffer, sizeof(certinfo->tpm2->userauth.buffer));
+               free(certinfo->tpm2);
        }
-       vpninfo->tpm2 = NULL;
+       certinfo->tpm2 = NULL;
 }
index 2f9a693a34a892c1c78b68d67d4339c724dd63bc..ad57afe29a6598e5be0c48193bb68f268a17f2e6 100644 (file)
@@ -227,10 +227,10 @@ static TPM_HANDLE tpm2_load_key(struct openconnect_info *vpninfo, TSS_CONTEXT **
        TPM_HANDLE key = 0;
        TPM_RC rc;
        TPM_HANDLE session;
-       char *pass = vpninfo->tpm2->parent_pass;
+       char *pass = certinfo->tpm2->parent_pass;
        int need_pw = 0;
 
-       vpninfo->tpm2->parent_pass = NULL;
+       certinfo->tpm2->parent_pass = NULL;
 
        rc = TSS_Create(&tssContext);
        if (rc) {
@@ -241,10 +241,10 @@ static TPM_HANDLE tpm2_load_key(struct openconnect_info *vpninfo, TSS_CONTEXT **
        memset(&in, 0, sizeof(in));
        memset(&out, 0, sizeof(out));
 
-       if (parent_is_persistent(vpninfo->tpm2->parent)) {
+       if (parent_is_persistent(certinfo->tpm2->parent)) {
                if (!pass) {
                        TPMT_PUBLIC pub;
-                       rc = tpm2_readpublic(vpninfo, tssContext, vpninfo->tpm2->parent, &pub);
+                       rc = tpm2_readpublic(vpninfo, tssContext, certinfo->tpm2->parent, &pub);
                        if (rc)
                                goto out;
 
@@ -252,10 +252,10 @@ static TPM_HANDLE tpm2_load_key(struct openconnect_info *vpninfo, TSS_CONTEXT **
                                need_pw = 1;
                }
 
-               in.parentHandle = vpninfo->tpm2->parent;
+               in.parentHandle = certinfo->tpm2->parent;
        } else {
        reauth_srk:
-               rc = tpm2_load_srk(vpninfo, tssContext, &in.parentHandle, pass, vpninfo->tpm2->parent, vpninfo->tpm2->legacy_srk);
+               rc = tpm2_load_srk(vpninfo, tssContext, &in.parentHandle, pass, certinfo->tpm2->parent, certinfo->tpm2->legacy_srk);
                if (rc == KEY_AUTH_FAILED) {
                        free_pass(&pass);
                        if (!request_passphrase(vpninfo, "openconnect_tpm2_hierarchy", &pass,
@@ -270,8 +270,8 @@ static TPM_HANDLE tpm2_load_key(struct openconnect_info *vpninfo, TSS_CONTEXT **
        if (rc)
                goto out_flush_srk;
 
-       memcpy(&in.inPublic, &vpninfo->tpm2->pub, sizeof(in.inPublic));
-       memcpy(&in.inPrivate, &vpninfo->tpm2->priv, sizeof(in.inPrivate));
+       memcpy(&in.inPublic, &certinfo->tpm2->pub, sizeof(in.inPublic));
+       memcpy(&in.inPrivate, &certinfo->tpm2->priv, sizeof(in.inPrivate));
        if (need_pw && !pass) {
        reauth_parent:
                if (request_passphrase(vpninfo, "openconnect_tpm2_parent", &pass,
@@ -299,10 +299,10 @@ static TPM_HANDLE tpm2_load_key(struct openconnect_info *vpninfo, TSS_CONTEXT **
                key = out.objectHandle;
 
  out_flush_srk:
-       if (parent_is_generated(vpninfo->tpm2->parent))
+       if (parent_is_generated(certinfo->tpm2->parent))
                tpm2_flush_handle(tssContext, in.parentHandle);
  out:
-       vpninfo->tpm2->parent_pass = pass;
+       certinfo->tpm2->parent_pass = pass;
        if (!key)
                TSS_Delete(tssContext);
        else
@@ -329,13 +329,13 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        int ret = GNUTLS_E_PK_SIGN_FAILED;
        TPM_HANDLE authHandle;
        TPM_RC rc;
-       char *pass = vpninfo->tpm2->key_pass;
+       char *pass = certinfo->tpm2->key_pass;
 
-       vpninfo->tpm2->key_pass = NULL;
+       certinfo->tpm2->key_pass = NULL;
 
        memset(&in, 0, sizeof(in));
 
-       in.cipherText.t.size = vpninfo->tpm2->pub.publicArea.unique.rsa.t.size;
+       in.cipherText.t.size = certinfo->tpm2->pub.publicArea.unique.rsa.t.size;
 
        if (oc_pkcs1_pad(vpninfo, in.cipherText.t.buffer, in.cipherText.t.size, data))
                return GNUTLS_E_PK_SIGN_FAILED;
@@ -371,7 +371,7 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
                goto out;
        }
 
-       vpninfo->tpm2->key_pass = pass;
+       certinfo->tpm2->key_pass = pass;
 
        sig->data = malloc(out.message.t.size);
        if (!sig->data)
@@ -398,10 +398,10 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        int ret = GNUTLS_E_PK_SIGN_FAILED;
        TPM_HANDLE authHandle;
        TPM_RC rc;
-       char *pass = vpninfo->tpm2->key_pass;
+       char *pass = certinfo->tpm2->key_pass;
        gnutls_datum_t sig_r, sig_s;
 
-       vpninfo->tpm2->key_pass = NULL;
+       certinfo->tpm2->key_pass = NULL;
 
        vpn_progress(vpninfo, PRG_DEBUG,
                     _("TPM2 EC sign function called for %d bytes.\n"),
@@ -458,7 +458,7 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
                goto out;
        }
 
-       vpninfo->tpm2->key_pass = pass;
+       certinfo->tpm2->key_pass = pass;
        sig_r.data = out.signature.signature.ecdsa.signatureR.t.buffer;
        sig_r.size = out.signature.signature.ecdsa.signatureR.t.size;
        sig_s.data = out.signature.signature.ecdsa.signatureS.t.buffer;
@@ -489,17 +489,17 @@ int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinf
                return -EINVAL;
        }
 
-       vpninfo->tpm2 = calloc(1, sizeof(*vpninfo->tpm2));
-       if (!vpninfo->tpm2)
+       certinfo->tpm2 = calloc(1, sizeof(*certinfo->tpm2));
+       if (!certinfo->tpm2)
                return -ENOMEM;
 
-       vpninfo->tpm2->parent = parent;
-       vpninfo->tpm2->need_userauth = !emptyauth;
-       vpninfo->tpm2->legacy_srk = legacy;
+       certinfo->tpm2->parent = parent;
+       certinfo->tpm2->need_userauth = !emptyauth;
+       certinfo->tpm2->legacy_srk = legacy;
 
        der = privdata->data;
        dersize = privdata->size;
-       rc = TPM2B_PRIVATE_Unmarshal(&vpninfo->tpm2->priv, &der, &dersize);
+       rc = TPM2B_PRIVATE_Unmarshal(&certinfo->tpm2->priv, &der, &dersize);
        if (rc) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to import TPM2 private key data: 0x%x\n"),
@@ -509,7 +509,7 @@ int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinf
 
        der = pubdata->data;
        dersize = pubdata->size;
-       rc = TPM2B_PUBLIC_Unmarshal(&vpninfo->tpm2->pub, &der, &dersize, FALSE);
+       rc = TPM2B_PUBLIC_Unmarshal(&certinfo->tpm2->pub, &der, &dersize, FALSE);
        if (rc) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to import TPM2 public key data: 0x%x\n"),
@@ -517,27 +517,27 @@ int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinf
                goto err_out;
        }
 
-       switch(vpninfo->tpm2->pub.publicArea.type) {
+       switch(certinfo->tpm2->pub.publicArea.type) {
        case TPM_ALG_RSA: return GNUTLS_PK_RSA;
        case TPM_ALG_ECC: return GNUTLS_PK_ECC;
        }
 
        vpn_progress(vpninfo, PRG_ERR,
                     _("Unsupported TPM2 key type %d\n"),
-                    vpninfo->tpm2->pub.publicArea.type);
-;
+                    certinfo->tpm2->pub.publicArea.type);
+
  err_out:
-       release_tpm2_ctx(vpninfo);
+       release_tpm2_ctx(vpninfo, certinfo);
        return -EINVAL;
 }
 
 
-void release_tpm2_ctx(struct openconnect_info *vpninfo)
+void release_tpm2_ctx(struct openconnect_info *vpninfo, struct cert_info *certinfo)
 {
-       if (vpninfo->tpm2) {
-               free_pass(&vpninfo->tpm2->parent_pass);
-               free_pass(&vpninfo->tpm2->key_pass);
-               free(vpninfo->tpm2);
-               vpninfo->tpm2 = NULL;
+       if (certinfo->tpm2) {
+               free_pass(&certinfo->tpm2->parent_pass);
+               free_pass(&certinfo->tpm2->key_pass);
+               free(certinfo->tpm2);
+               certinfo->tpm2 = NULL;
        }
 }
index 96990a920e65dad0055dd7b370fa23d87ad3e310..ce01d41be8f82404a13b3bb1dc67a7a00ce96e45 100644 (file)
@@ -419,6 +419,9 @@ struct cert_info {
 #if defined(OPENCONNECT_GNUTLS) && defined(HAVE_TROUSERS)
        struct oc_tpm1_ctx *tpm1;
 #endif
+#if defined(OPENCONNECT_GNUTLS) && defined (HAVE_TSS2)
+       struct oc_tpm2_ctx *tpm2;
+#endif
 };
 
 struct openconnect_info {
@@ -586,9 +589,6 @@ struct openconnect_info {
        gnutls_certificate_credentials_t https_cred;
        gnutls_psk_client_credentials_t psk_cred;
        char local_cert_md5[MD5_SIZE * 2 + 1]; /* For CSD */
-#ifdef HAVE_TSS2
-       struct oc_tpm2_ctx *tpm2;
-#endif
 #endif /* OPENCONNECT_GNUTLS */
        char *ciphersuite_config;
        struct oc_text_buf *ttls_pushbuf;