]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Support TLSv1.3 sign functions on SECP curves with TPMv2
authorDavid Woodhouse <dwmw2@infradead.org>
Tue, 11 May 2021 21:09:24 +0000 (22:09 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Tue, 11 May 2021 22:33:58 +0000 (23:33 +0100)
For these curves at least, it basically already works.

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

index 378937e84640aa5bbef429a04c08bdf5e5487b0e..d6f75dc6ecf3f444a253b851d4bc99d092d6a9fa 100644 (file)
--- a/gnutls.h
+++ b/gnutls.h
@@ -44,6 +44,7 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
                         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);
+uint16_t tpm2_key_curve(struct openconnect_info *vpninfo, struct cert_info *certinfo);
 
 /* GnuTLS 3.6.0+ provides this. We have our own for older GnuTLS. There is
  * also _gnutls_encode_ber_rs_raw() in some older versions, but there were
index a3ba3cdb4a64107191261e5d9071fdf41a968a6c..839e1b833542eaf6d458f351206392961be479ce 100644 (file)
@@ -130,18 +130,34 @@ static int rsa_key_info(gnutls_privkey_t key, unsigned int flags, void *_certinf
 #if GNUTLS_VERSION_NUMBER >= 0x030400
 static int ec_key_info(gnutls_privkey_t key, unsigned int flags, void *_certinfo)
 {
+       struct cert_info *certinfo = _certinfo;
+       struct openconnect_info *vpninfo = certinfo->vpninfo;
+
        if (flags & GNUTLS_PRIVKEY_INFO_PK_ALGO)
                return GNUTLS_PK_EC;
 
 #ifdef GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO
        if (flags & GNUTLS_PRIVKEY_INFO_HAVE_SIGN_ALGO) {
+               uint16_t tpm2_curve = tpm2_key_curve(vpninfo, certinfo);
                gnutls_sign_algorithm_t algo = GNUTLS_FLAGS_TO_SIGN_ALGO(flags);
                switch (algo) {
                case GNUTLS_SIGN_ECDSA_SHA1:
                case GNUTLS_SIGN_ECDSA_SHA256:
                        return 1;
 
+               case GNUTLS_SIGN_ECDSA_SECP256R1_SHA256:
+                       return tpm2_curve == 0x0003; /* TPM2_ECC_NIST_P256 */
+
+               case GNUTLS_SIGN_ECDSA_SECP384R1_SHA384:
+                       return tpm2_curve == 0x0004; /* TPM2_ECC_NIST_P384 */
+
+               case GNUTLS_SIGN_ECDSA_SECP521R1_SHA512:
+                       return tpm2_curve == 0x0005; /* TPM2_ECC_NIST_P521 */
+
                default:
+                       vpn_progress(vpninfo, PRG_DEBUG,
+                                    _("Not supporting EC sign algo %s\n"),
+                                    gnutls_sign_get_name(algo));
                        return 0;
                }
        }
index a57b843f56f7368147ced42ce1ec9c62c542bb1c..26e9b05d9bc08ba7c7e1b5b7fa3877272c575630 100644 (file)
@@ -603,6 +603,10 @@ int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinf
        return -EINVAL;
 }
 
+uint16_t tpm2_key_curve(struct openconnect_info *vpninfo, struct cert_info *certinfo)
+{
+       return certinfo->tpm2->pub.publicArea.parameters.eccDetail.curveID;
+}
 
 void release_tpm2_ctx(struct openconnect_info *vpninfo, struct cert_info *certinfo)
 {
index fdf6fe56b004383512fc1857d6a307d41d94c95a..16365dff734f9b853cbe2c0a34e90bac7798daa6 100644 (file)
@@ -553,6 +553,10 @@ int install_tpm2_key(struct openconnect_info *vpninfo, struct cert_info *certinf
        return -EINVAL;
 }
 
+uint16_t tpm2_key_curve(struct openconnect_info *vpninfo, struct cert_info *certinfo)
+{
+       return certinfo->tpm2->pub.publicArea.parameters.eccDetail.curveID;
+}
 
 void release_tpm2_ctx(struct openconnect_info *vpninfo, struct cert_info *certinfo)
 {