]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Provide password to load_tpm2_key
authorTom Carroll <incentivedesign@gmail.com>
Sun, 3 May 2020 04:38:11 +0000 (21:38 -0700)
committerTom Carroll <incentivedesign@gmail.com>
Wed, 6 May 2020 08:54:26 +0000 (01:54 -0700)
Permit a single instance of tpm2. Return -EBUSY to inform of caller of
existing instance. Duplicate password when necessary.

Signed-off-by: Tom Carroll <incentivedesign@gmail.com>
gnutls.c
gnutls.h
gnutls_tpm2.c
gnutls_tpm2_esys.c
gnutls_tpm2_ibm.c

index c747962bd42c3a9757d49129c48c0458fef9cd4a..8c408c427dca5184a31336b0b0bcab4892dfa5cb 100644 (file)
--- a/gnutls.c
+++ b/gnutls.c
@@ -1679,7 +1679,7 @@ static int load_keycert(struct openconnect_info *vpninfo,
                             _("This version of OpenConnect was built without TPM2 support\n"));
                return -EINVAL;
 #else
-               ret = load_tpm2_key(vpninfo, &fdata, &pkey, &pkey_sig);
+               ret = load_tpm2_key(vpninfo, &fdata, password, &pkey, &pkey_sig);
                if (ret)
                        goto out;
 
index 6d39f9be94ac94717245549ba6902f46dd854f9a..30c99020a2946d0ef78ff62e73f6eb1c72eb9346 100644 (file)
--- a/gnutls.h
+++ b/gnutls.h
@@ -30,9 +30,12 @@ int load_tpm1_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
 void release_tpm1_ctx(struct openconnect_info *info);
 
 int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
+                const char *password,
                 gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig);
 void release_tpm2_ctx(struct openconnect_info *info);
-int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
+int install_tpm2_key(struct openconnect_info *vpninfo,
+                    const char *password,
+                    gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
                     unsigned int parent, int emptyauth, int legacy,
                     gnutls_datum_t *privdata, gnutls_datum_t *pubdata);
 
index 698a9e2edb497045e7f052fba242bcab15661aec..29b17e8a677e8837e64228a9ea12daa8fc36abcd 100644 (file)
@@ -175,6 +175,7 @@ static int decode_data(ASN1_TYPE n, gnutls_datum_t *r)
 }
 
 int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
+                 const char *password,
                  gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
 {
        gnutls_datum_t asn1, pubdata, privdata;
@@ -187,6 +188,12 @@ int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
        int err, ret = -EINVAL;
        const asn1_static_node *asn1tab;
 
+       if (vpninfo->tpm2) {
+               vpn_progress(vpninfo, PRG_ERR,
+                            _("TPM2 is in use.\n"));
+               return -EBUSY;
+       }
+
        err = gnutls_pem_base64_decode_alloc("TSS2 PRIVATE KEY", fdata, &asn1);
        if (!err) {
                asn1tab = tpmkey_asn1_tab;
@@ -282,7 +289,8 @@ int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
 
        /* Now we've extracted what we need from the ASN.1, invoke the
         * actual TPM2 code (whichever implementation we end up with */
-       ret = install_tpm2_key(vpninfo, pkey, pkey_sig, parent, emptyauth,
+       ret = install_tpm2_key(vpninfo, password,
+                              pkey, pkey_sig, parent, emptyauth,
                               asn1tab == tpmkey_asn1_tab_old, &privdata, &pubdata);
        if (ret < 0)
                goto out_tpmkey;
index c5eabd823a91c4bfb43880c0ea1f69b6016d5d5b..746eea1c7bea5e6ddc1fd66071b9e2ebacec1be6 100644 (file)
@@ -65,6 +65,7 @@ struct oc_tpm2_ctx {
        TPM2B_PRIVATE priv;
        TPM2B_DIGEST userauth;
        TPM2B_DIGEST ownerauth;
+       char *key_pass;
        unsigned int need_userauth:1;
        unsigned int need_ownerauth:1;
        unsigned int did_ownerauth:1;
@@ -356,12 +357,12 @@ static int auth_tpm2_key(struct openconnect_info *vpninfo, ESYS_CONTEXT *ctx, ES
 {
        TSS2_RC r;
 
-       if (vpninfo->tpm2->need_userauth || vpninfo->cert_password) {
+       if (vpninfo->tpm2->need_userauth || vpninfo->tpm2->key_pass) {
                char *pass = NULL;
 
-               if (vpninfo->cert_password) {
-                       pass = vpninfo->cert_password;
-                       vpninfo->cert_password = NULL;
+               if (vpninfo->tpm2->key_pass) {
+                       pass = vpninfo->tpm2->key_pass;
+                       vpninfo->tpm2->key_pass = NULL;
                } else {
                        int err = request_passphrase(vpninfo, "openconnect_tpm2_key",
                                                     &pass, _("Enter TPM2 key password:"));
@@ -524,7 +525,9 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        return ret;
 }
 
-int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
+int install_tpm2_key(struct openconnect_info *vpninfo,
+                    const char *password,
+                    gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
                     unsigned int parent, int emptyauth, int legacy, gnutls_datum_t *privdata, gnutls_datum_t *pubdata)
 {
        TSS2_RC r;
@@ -541,6 +544,11 @@ int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, g
        if (!vpninfo->tpm2)
                return -ENOMEM;
 
+       if (password && (vpninfo->tpm2->key_pass = strdup(password)) == NULL) {
+               free(vpninfo->tpm2);
+               return -ENOMEM;
+       }
+
        vpninfo->tpm2->parent = parent;
 
        r = Tss2_MU_TPM2B_PRIVATE_Unmarshal(privdata->data, privdata->size, NULL,
@@ -583,6 +591,7 @@ void release_tpm2_ctx(struct openconnect_info *vpninfo)
        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_pass(&vpninfo->tpm2->key_pass);
                free(vpninfo->tpm2);
        }
        vpninfo->tpm2 = NULL;
index 3fe33b6c70efe7b81a0e9bd7bafb3d6ad2fdaea6..c86d13a34952fc88cd3c9c15a71ffb7052194382 100644 (file)
@@ -470,7 +470,9 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        return ret;
 }
 
-int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
+int install_tpm2_key(struct openconnect_info *vpninfo,
+                    const char *password,
+                    gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
                     unsigned int parent, int emptyauth, int legacy,
                     gnutls_datum_t *privdata, gnutls_datum_t *pubdata)
 {
@@ -478,6 +480,8 @@ int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, g
        BYTE *der;
        INT32 dersize;
 
+       (void) password;
+
        if (!parent_is_persistent(parent) &&
            parent != TPM_RH_OWNER && parent != TPM_RH_NULL &&
            parent != TPM_RH_ENDORSEMENT && parent != TPM_RH_PLATFORM) {