]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
GnuTLS: Extend certinfo to callbacks
authorDavid Woodhouse <dwmw2@infradead.org>
Fri, 7 May 2021 15:01:43 +0000 (16:01 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Sat, 8 May 2021 07:33:04 +0000 (08:33 +0100)
Now that the cert_info struct has a back-reference to the vpninfo, we
can use it as the private data for callbacks.

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

index e1eeee8d6ddea30a4f9ca03e8d151e6cfb7ff25b..00860af8d1fdef0a4b0e531015e4cc5ea8f35bdf 100644 (file)
--- a/gnutls.c
+++ b/gnutls.c
@@ -991,6 +991,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct cert_info *
        size_t key_id_size = sizeof(key_id);
        char name[80];
 
+       certinfo->vpninfo = vpninfo;
        fdata.data = NULL;
 
        key_is_p11 = !strncmp(certinfo->key, "pkcs11:", 7);
@@ -1063,7 +1064,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct cert_info *
                        goto out;
                }
 
-               gnutls_x509_crt_set_pin_function(cert, gnutls_pin_callback, vpninfo);
+               gnutls_x509_crt_set_pin_function(cert, gnutls_pin_callback, certinfo);
 
                /* Yes, even for *system* URLs the only API GnuTLS offers us is
                   ...import_pkcs11_url(). */
@@ -1170,7 +1171,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct cert_info *
                        goto out;
                }
 
-               gnutls_privkey_set_pin_function(gci->pkey, gnutls_pin_callback, vpninfo);
+               gnutls_privkey_set_pin_function(gci->pkey, gnutls_pin_callback, certinfo);
 
                err = gnutls_privkey_import_url(gci->pkey, certinfo->key, 0);
                if (err) {
@@ -1197,7 +1198,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct cert_info *
                        goto out;
                }
 
-               gnutls_pkcs11_privkey_set_pin_function(p11key, gnutls_pin_callback, vpninfo);
+               gnutls_pkcs11_privkey_set_pin_function(p11key, gnutls_pin_callback, certinfo);
 
                err = gnutls_pkcs11_privkey_import_url(p11key, key_url, 0);
 
@@ -1369,7 +1370,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct cert_info *
                             _("This version of OpenConnect was built without TPM2 support\n"));
                return -EINVAL;
 #else
-               ret = load_tpm2_key(vpninfo, &fdata, &gci->pkey, &pkey_sig);
+               ret = load_tpm2_key(vpninfo, certinfo, &fdata, &gci->pkey, &pkey_sig);
                if (ret)
                        goto out;
 
@@ -2518,7 +2519,8 @@ static int gnutls_pin_callback(void *priv, int attempt, const char *uri,
                               const char *token_label, unsigned int flags,
                               char *pin, size_t pin_max)
 {
-       struct openconnect_info *vpninfo = priv;
+       struct cert_info *certinfo = priv;
+       struct openconnect_info *vpninfo = certinfo->vpninfo;
        struct pin_cache **cache = &vpninfo->pin_cache;
        struct oc_auth_form f;
        struct oc_form_opt o;
@@ -2551,10 +2553,10 @@ static int gnutls_pin_callback(void *priv, int attempt, const char *uri,
                (*cache)->token = strdup(uri);
        }
 
-       if (!attempt && vpninfo->certinfo[0].password) {
-               snprintf(pin, pin_max, "%s", vpninfo->certinfo[0].password);
-               (*cache)->pin = vpninfo->certinfo[0].password;
-               vpninfo->certinfo[0].password = NULL;
+       if (!attempt && certinfo->password) {
+               snprintf(pin, pin_max, "%s", certinfo->password);
+               (*cache)->pin = certinfo->password;
+               certinfo->password = NULL;
                return 0;
        }
 
index f697668094e45d2cbb461918b91280badc095145..5705bb7b802ba8c1cc321c573570c251e19737cc 100644 (file)
--- a/gnutls.h
+++ b/gnutls.h
@@ -28,18 +28,19 @@ int load_tpm1_key(struct openconnect_info *vpninfo, struct cert_info *certinfo,
                  gnutls_datum_t *fdata, gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig);
 void release_tpm1_ctx(struct openconnect_info *info);
 
-int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
-                gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig);
+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);
-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, struct cert_info *certinfo,
+                    gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
                     unsigned int parent, int emptyauth, int legacy,
                     gnutls_datum_t *privdata, gnutls_datum_t *pubdata);
 
 int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
-                         void *_vpninfo, unsigned int flags,
+                         void *_certinfo, unsigned int flags,
                          const gnutls_datum_t *data, gnutls_datum_t *sig);
 int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
-                        void *_vpninfo, unsigned int flags,
+                        void *_certinfo, unsigned int flags,
                         const gnutls_datum_t *data, gnutls_datum_t *sig);
 int oc_pkcs1_pad(struct openconnect_info *vpninfo,
                 unsigned char *buf, int size, const gnutls_datum_t *data);
index 698a9e2edb497045e7f052fba242bcab15661aec..467cd1d189ded071175abfedb52066c7938a2ec5 100644 (file)
@@ -69,17 +69,18 @@ static const char OID_legacy_loadableKey[] = "2.23.133.10.2";
 static const char OID_loadableKey[] =        "2.23.133.10.1.3";
 
 #if GNUTLS_VERSION_NUMBER < 0x030600
-static int tpm2_rsa_sign_fn(gnutls_privkey_t key, void *_vpninfo,
+static int tpm2_rsa_sign_fn(gnutls_privkey_t key, void *_certinfo,
                            const gnutls_datum_t *data, gnutls_datum_t *sig)
 {
-       return tpm2_rsa_sign_hash_fn(key, GNUTLS_SIGN_UNKNOWN, _vpninfo, 0, data, sig);
+       return tpm2_rsa_sign_hash_fn(key, GNUTLS_SIGN_UNKNOWN, _certinfo, 0, data, sig);
 }
 
 
-static int tpm2_ec_sign_fn(gnutls_privkey_t key, void *_vpninfo,
+static int tpm2_ec_sign_fn(gnutls_privkey_t key, void *_certinfo,
                           const gnutls_datum_t *data, gnutls_datum_t *sig)
 {
-       struct openconnect_info *vpninfo = _vpninfo;
+       struct cert_info *certinfo = _certinfo;
+       struct openconnect_info *vpninfo = certinfo->vpninfo;
        gnutls_sign_algorithm_t algo;
 
        switch (data->size) {
@@ -94,12 +95,12 @@ static int tpm2_ec_sign_fn(gnutls_privkey_t key, void *_vpninfo,
                return GNUTLS_E_PK_SIGN_FAILED;
        }
 
-       return tpm2_ec_sign_hash_fn(key, algo, vpninfo, 0, data, sig);
+       return tpm2_ec_sign_hash_fn(key, algo, certinfo, 0, data, sig);
 }
 #endif
 
 #if GNUTLS_VERSION_NUMBER >= 0x030600
-static int rsa_key_info(gnutls_privkey_t key, unsigned int flags, void *_vpninfo)
+static int rsa_key_info(gnutls_privkey_t key, unsigned int flags, void *_certinfo)
 {
        if (flags & GNUTLS_PRIVKEY_INFO_PK_ALGO)
                return GNUTLS_PK_RSA;
@@ -127,7 +128,7 @@ static int rsa_key_info(gnutls_privkey_t key, unsigned int flags, void *_vpninfo
 #endif
 
 #if GNUTLS_VERSION_NUMBER >= 0x030400
-static int ec_key_info(gnutls_privkey_t key, unsigned int flags, void *_vpninfo)
+static int ec_key_info(gnutls_privkey_t key, unsigned int flags, void *_certinfo)
 {
        if (flags & GNUTLS_PRIVKEY_INFO_PK_ALGO)
                return GNUTLS_PK_EC;
@@ -174,8 +175,8 @@ static int decode_data(ASN1_TYPE n, gnutls_datum_t *r)
        return 0;
 }
 
-int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
-                 gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
+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)
 {
        gnutls_datum_t asn1, pubdata, privdata;
        ASN1_TYPE tpmkey_def = ASN1_TYPE_EMPTY, tpmkey = ASN1_TYPE_EMPTY;
@@ -282,7 +283,7 @@ 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, certinfo, pkey, pkey_sig, parent, emptyauth,
                               asn1tab == tpmkey_asn1_tab_old, &privdata, &pubdata);
        if (ret < 0)
                goto out_tpmkey;
@@ -292,19 +293,19 @@ int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
        switch(ret) {
        case GNUTLS_PK_RSA:
 #if GNUTLS_VERSION_NUMBER >= 0x030600
-               gnutls_privkey_import_ext4(*pkey, vpninfo, NULL, tpm2_rsa_sign_hash_fn, NULL, NULL, rsa_key_info, 0);
+               gnutls_privkey_import_ext4(*pkey, certinfo, NULL, tpm2_rsa_sign_hash_fn, NULL, NULL, rsa_key_info, 0);
 #else
-               gnutls_privkey_import_ext(*pkey, GNUTLS_PK_RSA, vpninfo, tpm2_rsa_sign_fn, NULL, 0);
+               gnutls_privkey_import_ext(*pkey, GNUTLS_PK_RSA, certinfo, tpm2_rsa_sign_fn, NULL, 0);
 #endif
                break;
 
        case GNUTLS_PK_ECC:
 #if GNUTLS_VERSION_NUMBER >= 0x030600
-               gnutls_privkey_import_ext4(*pkey, vpninfo, NULL, tpm2_ec_sign_hash_fn, NULL, NULL, ec_key_info, 0);
+               gnutls_privkey_import_ext4(*pkey, certinfo, NULL, tpm2_ec_sign_hash_fn, NULL, NULL, ec_key_info, 0);
 #elif GNUTLS_VERSION_NUMBER >= 0x030400
-               gnutls_privkey_import_ext3(*pkey, vpninfo, tpm2_ec_sign_fn, NULL, NULL, ec_key_info, 0);
+               gnutls_privkey_import_ext3(*pkey, certinfo, tpm2_ec_sign_fn, NULL, NULL, ec_key_info, 0);
 #else
-               gnutls_privkey_import_ext(*pkey, GNUTLS_PK_EC, vpninfo, tpm2_ec_sign_fn, NULL, 0);
+               gnutls_privkey_import_ext(*pkey, GNUTLS_PK_EC, certinfo, tpm2_ec_sign_fn, NULL, 0);
 #endif
                break;
        }
index 25819843ab9d10c33968261cc71f81f108f35765..7b8a4417f83c9b70155c7efa9c6a241481e877f1 100644 (file)
@@ -352,16 +352,17 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *keyHandle,
        return -EIO;
 }
 
-static int auth_tpm2_key(struct openconnect_info *vpninfo, ESYS_CONTEXT *ctx, ESYS_TR key_handle)
+static int auth_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinfo,
+                        ESYS_CONTEXT *ctx, ESYS_TR key_handle)
 {
        TSS2_RC r;
 
-       if (vpninfo->tpm2->need_userauth || vpninfo->certinfo[0].password) {
+       if (vpninfo->tpm2->need_userauth || certinfo->password) {
                char *pass = NULL;
 
-               if (vpninfo->certinfo[0].password) {
-                       pass = vpninfo->certinfo[0].password;
-                       vpninfo->certinfo[0].password = NULL;
+               if (certinfo->password) {
+                       pass = certinfo->password;
+                       certinfo->password = NULL;
                } else {
                        int err = request_passphrase(vpninfo, "openconnect_tpm2_key",
                                                     &pass, _("Enter TPM2 key password:"));
@@ -383,10 +384,11 @@ static int auth_tpm2_key(struct openconnect_info *vpninfo, ESYS_CONTEXT *ctx, ES
 }
 
 int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
-                         void *_vpninfo, unsigned int flags,
+                         void *_certinfo, unsigned int flags,
                          const gnutls_datum_t *data, gnutls_datum_t *sig)
 {
-       struct openconnect_info *vpninfo = _vpninfo;
+       struct cert_info *certinfo = _certinfo;
+       struct openconnect_info *vpninfo = certinfo->vpninfo;
        int ret = GNUTLS_E_PK_SIGN_FAILED;
        ESYS_CONTEXT *ectx = NULL;
        TPM2B_PUBLIC_KEY_RSA digest, *tsig = NULL;
@@ -407,7 +409,7 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        if (init_tpm2_key(&ectx, &key_handle, vpninfo))
                goto out;
  reauth:
-       if (auth_tpm2_key(vpninfo, ectx, key_handle))
+       if (auth_tpm2_key(vpninfo, certinfo, ectx, key_handle))
                goto out;
 
        r = Esys_RSA_Decrypt(ectx, key_handle,
@@ -448,10 +450,11 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
 }
 
 int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
-                        void *_vpninfo, unsigned int flags,
+                        void *_certinfo, unsigned int flags,
                         const gnutls_datum_t *data, gnutls_datum_t *sig)
 {
-       struct openconnect_info *vpninfo = _vpninfo;
+       struct cert_info *certinfo = _certinfo;
+       struct openconnect_info *vpninfo = certinfo->vpninfo;
        int ret = GNUTLS_E_PK_SIGN_FAILED;
        ESYS_CONTEXT *ectx = NULL;
        TPM2B_DIGEST digest;
@@ -486,7 +489,7 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
        if (init_tpm2_key(&ectx, &key_handle, vpninfo))
                goto out;
  reauth:
-       if (auth_tpm2_key(vpninfo, ectx, key_handle))
+       if (auth_tpm2_key(vpninfo, certinfo, ectx, key_handle))
                goto out;
 
        r = Esys_Sign(ectx, key_handle,
@@ -524,8 +527,10 @@ 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,
-                    unsigned int parent, int emptyauth, int legacy, gnutls_datum_t *privdata, gnutls_datum_t *pubdata)
+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,
+                    gnutls_datum_t *privdata, gnutls_datum_t *pubdata)
 {
        TSS2_RC r;
 
index 3fe33b6c70efe7b81a0e9bd7bafb3d6ad2fdaea6..2f9a693a34a892c1c78b68d67d4339c724dd63bc 100644 (file)
@@ -318,10 +318,11 @@ static void tpm2_unload_key(TSS_CONTEXT *tssContext, TPM_HANDLE key)
 }
 
 int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
-                         void *_vpninfo, unsigned int flags,
+                         void *_certinfo, unsigned int flags,
                          const gnutls_datum_t *data, gnutls_datum_t *sig)
 {
-       struct openconnect_info *vpninfo = _vpninfo;
+       struct cert_info *certinfo = _certinfo;
+       struct openconnect_info *vpninfo = certinfo->vpninfo;
        TSS_CONTEXT *tssContext = NULL;
        RSA_Decrypt_In in;
        RSA_Decrypt_Out out;
@@ -386,10 +387,11 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
 }
 
 int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
-                        void *_vpninfo, unsigned int flags,
+                        void *_certinfo, unsigned int flags,
                         const gnutls_datum_t *data, gnutls_datum_t *sig)
 {
-       struct openconnect_info *vpninfo = _vpninfo;
+       struct cert_info *certinfo = _certinfo;
+       struct openconnect_info *vpninfo = certinfo->vpninfo;
        TSS_CONTEXT *tssContext = NULL;
        Sign_In in;
        Sign_Out out;
@@ -470,7 +472,8 @@ 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, struct cert_info *certinfo,
+                    gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig,
                     unsigned int parent, int emptyauth, int legacy,
                     gnutls_datum_t *privdata, gnutls_datum_t *pubdata)
 {