Use gnutls_pubkey_verify_data2() where possible
authorDavid Woodhouse <David.Woodhouse@intel.com>
Tue, 12 Feb 2013 23:59:34 +0000 (23:59 +0000)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Tue, 12 Feb 2013 23:59:40 +0000 (23:59 +0000)
Unfortunately, gnutls_pubkey_verify_data() is deprecated. Which is a pain;
the 'threat model' that led to that deprecation doesn't apply here, and it
just means we have to jump through hoops to find the 'intended' algorithm
instead of letting it be inferred from the signature.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
configure.ac
gnutls.c
gnutls.h
gnutls_tpm.c

index bf8f6c55156ac32eaf1512fe60da95e8d85814f9..9db65418be863e97420eaa836fd7a74bba6064e9 100644 (file)
@@ -289,6 +289,8 @@ if test "$with_gnutls" = "yes"; then
                 [AC_DEFINE(HAVE_GNUTLS_PKCS12_SIMPLE_PARSE, 1)], [])
     AC_CHECK_FUNC(gnutls_certificate_set_key,
                 [AC_DEFINE(HAVE_GNUTLS_CERTIFICATE_SET_KEY, 1)], [])
+    AC_CHECK_FUNC(gnutls_pubkey_verify_data2,
+                [AC_DEFINE(HAVE_GNUTLS_PUBKEY_VERIFY_DATA2, 1)], [])
     if test "$with_openssl" = "" || test "$with_openssl" = "no"; then
        AC_CHECK_FUNC(gnutls_session_set_premaster,
                 [have_gnutls_dtls=yes], [have_gnutls_dtls=no])
@@ -299,7 +301,7 @@ if test "$with_gnutls" = "yes"; then
        if test "$with_openssl" = "" || test "$with_openssl" = "no"; then
            # They either said no OpenSSL or didn't specify, and GnuTLS can
            # do DTLS, so just use GnuTLS.
-            AC_DEFINE(HAVE_GNUTLS_SESSION_SET_PREMASTER, 1)    
+            AC_DEFINE(HAVE_GNUTLS_SESSION_SET_PREMASTER, 1)
            ssl_library=gnutls
            with_openssl=no
        else
index dbc6d125fca7c08758924e7b6ef82574482842dd..d787ee23b63d11afb8eab105aa4d60ec74298a9d 100644 (file)
--- a/gnutls.c
+++ b/gnutls.c
@@ -1333,6 +1333,8 @@ static int load_certificate(struct openconnect_info *vpninfo)
           match. So sign some dummy data and then check the signature against each
           of the available certificates until we find the right one. */
        if (pkey) {
+               gnutls_sign_algorithm_t algo = GNUTLS_SIGN_RSA_SHA1; // TPM
+
                /* The TPM code may have already signed it, to test authorisation. We
                   only sign here for PKCS#11 keys, in which case fdata might be
                   empty too so point it at dummy data. */
@@ -1342,7 +1344,7 @@ static int load_certificate(struct openconnect_info *vpninfo)
                                fdata.size = 20;
                        }
 
-                       err = sign_dummy_data(vpninfo, pkey, &fdata, &pkey_sig);
+                       err = sign_dummy_data(vpninfo, pkey, &fdata, &pkey_sig, &algo);
                        if (err) {
                                vpn_progress(vpninfo, PRG_ERR,
                                             _("Error signing test data with private key: %s\n"),
@@ -1366,7 +1368,7 @@ static int load_certificate(struct openconnect_info *vpninfo)
                                gnutls_pubkey_deinit(pubkey);
                                continue;
                        }
-                       err = gnutls_pubkey_verify_data(pubkey, 0, &fdata, &pkey_sig);
+                       err = gnutls_pubkey_verify_data2(pubkey, 0, algo, &fdata, &pkey_sig);
                        gnutls_pubkey_deinit(pubkey);
 
                        if (err >= 0) {
index 68d59d2eafa9da3697858b26985164bb5a7e8594..5b121afff0f47a67528262b745958e83b4e7e9b9 100644 (file)
--- a/gnutls.h
+++ b/gnutls.h
@@ -45,6 +45,16 @@ int gnutls_pkcs12_simple_parse (gnutls_pkcs12_t p12, const char *password,
 
 #endif /* !HAVE_GNUTLS_PKCS12_SIMPLE_PARSE */
 
+#ifndef HAVE_GNUTLS_PUBKEY_VERIFY_DATA2
+static inline int gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey,
+                                             gnutls_sign_algorithm_t algo,
+                                             unsigned int flags,
+                                             const gnutls_datum_t *data,
+                                             const gnutls_datum_t *sig)
+{
+       return gnutls_pubkey_verify_data(pubkey, flags, data, sig);
+}
+#endif /* !HAVE_GNUTLS_PUBKEY_VERIFY_DATA2 */
 
 #ifndef HAVE_GNUTLS_CERTIFICATE_SET_KEY
 int gtls2_tpm_sign_cb(gnutls_session_t sess, void *_vpninfo,
@@ -64,12 +74,18 @@ int gtls2_tpm_sign_dummy_data(struct openconnect_info *vpninfo,
 static inline int sign_dummy_data(struct openconnect_info *vpninfo,
                                  gnutls_privkey_t pkey,
                                  const gnutls_datum_t *data,
-                                 gnutls_datum_t *sig)
+                                 gnutls_datum_t *sig,
+                                 gnutls_sign_algorithm_t *algo)
 {
 #if defined (HAVE_TROUSERS) && !defined(HAVE_GNUTLS_CERTIFICATE_SET_KEY)
-       if (pkey == OPENCONNECT_TPM_PKEY)
+       if (pkey == OPENCONNECT_TPM_PKEY) {
+               if (algo)
+                       *algo = GNUTLS_SIGN_RSA_SHA1;
                return gtls2_tpm_sign_dummy_data(vpninfo, data, sig);
+       }
 #endif
+       if (algo)
+               *algo = gnutls_pk_to_sign(gnutls_privkey_get_pk_algorithm(pkey, NULL), GNUTLS_DIG_SHA1);
        return gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA1, 0, data, sig);
 }
 
index bc62d76913604ba51df908131647703ba5429d26..bf3e7965e3b292ce6b502b3721e83574f6b5384c 100644 (file)
@@ -274,7 +274,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
 #endif
 
  retry_sign:
-       err = sign_dummy_data(vpninfo, *pkey, fdata, pkey_sig);
+       err = sign_dummy_data(vpninfo, *pkey, fdata, pkey_sig, NULL);
        if (err == GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
                if (!vpninfo->tpm_key_policy) {
                        err = Tspi_Context_CreateObject(vpninfo->tpm_context,