]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Respect TLS signature algorithm in server KX.
authorDaiki Ueno <ueno@unixuser.org>
Mon, 31 Aug 2009 05:40:38 +0000 (14:40 +0900)
committerSimon Josefsson <simon@josefsson.org>
Mon, 31 Aug 2009 12:59:47 +0000 (14:59 +0200)
Verify signature of DH parameters in Server Key Exchange with the
embedded signature algorithm.

Signed-off-by: Simon Josefsson <simon@josefsson.org>
lib/auth_dhe.c
lib/auth_rsa_export.c
lib/auth_srp_rsa.c
lib/gnutls_sig.c
lib/gnutls_sig.h

index ec595eeb99e39334da64ed7e78401fe0e43d2e31..ea9cf3a57f80cea668993d766860273b742adf17 100644 (file)
@@ -180,11 +180,14 @@ proc_dhe_server_kx (gnutls_session_t session, opaque * data,
                    size_t _data_size)
 {
   int sigsize;
+  opaque *sigdata;
   gnutls_datum_t vparams, signature;
   int ret;
   cert_auth_info_t info = _gnutls_get_auth_info (session);
   ssize_t data_size = _data_size;
   gnutls_cert peer_cert;
+  gnutls_sign_algorithm_t sign_algo = GNUTLS_SIGN_UNKNOWN;
+  gnutls_protocol_t ver = gnutls_protocol_get_version (session);
 
   if (info == NULL || info->ncerts == 0)
     {
@@ -205,11 +208,28 @@ proc_dhe_server_kx (gnutls_session_t session, opaque * data,
   vparams.size = ret;
   vparams.data = data;
 
+  sigdata = &data[vparams.size];
+  if (_gnutls_version_has_selectable_sighash (ver))
+    {
+      sign_algorithm_st aid;
+
+      DECR_LEN(data_size, 1);
+      aid.hash_algorithm = *sigdata++;
+      DECR_LEN(data_size, 1);
+      aid.sign_algorithm = *sigdata++;
+      sign_algo = _gnutls_tls_aid_to_sign (aid);
+      if (sign_algo == GNUTLS_SIGN_UNKNOWN)
+       {
+         gnutls_assert ();
+         return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+       }
+    }
   DECR_LEN (data_size, 2);
-  sigsize = _gnutls_read_uint16 (&data[vparams.size]);
+  sigsize = _gnutls_read_uint16 (sigdata);
+  sigdata += 2;
 
   DECR_LEN (data_size, sigsize);
-  signature.data = &data[vparams.size + 2];
+  signature.data = sigdata;
   signature.size = sigsize;
 
   if ((ret =
@@ -221,7 +241,8 @@ proc_dhe_server_kx (gnutls_session_t session, opaque * data,
       return ret;
     }
 
-  ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature);
+  ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature,
+                                  sign_algo);
 
   _gnutls_gcert_deinit (&peer_cert);
   if (ret < 0)
index 606f85c468f8216d15cf465f5b6424d2be870e93..638395b1285c82c58eadd0964961c2d2fa82ad83 100644 (file)
@@ -308,7 +308,8 @@ proc_rsa_export_server_kx (gnutls_session_t session,
       return ret;
     }
 
-  ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature);
+  ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature,
+                                  GNUTLS_SIGN_UNKNOWN);
 
   _gnutls_gcert_deinit (&peer_cert);
   if (ret < 0)
index 2f2ea96662d8cde4b3af5ce0961159fd10e9942a..1689ce2540ad9c6bbc2b05062b8bf7b1f357b49e 100644 (file)
@@ -191,7 +191,8 @@ proc_srp_cert_server_kx (gnutls_session_t session, opaque * data,
       return ret;
     }
 
-  ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature);
+  ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature,
+                                  GNUTLS_SIGN_UNKNOWN);
 
   _gnutls_gcert_deinit (&peer_cert);
   if (ret < 0)
index bcc4412ce49dde8f74730b22ad25831b6483bd6c..81e833629c3affa2ac5a5d061e6460f85d028bdc 100644 (file)
@@ -298,7 +298,8 @@ _gnutls_tls_sign (gnutls_session_t session,
 static int
 _gnutls_verify_sig (gnutls_cert * cert,
                    const gnutls_datum_t * hash_concat,
-                   gnutls_datum_t * signature, size_t sha1pos)
+                   gnutls_datum_t * signature, size_t sha1pos,
+                   gnutls_pk_algorithm_t pk_algo)
 {
   int ret;
   gnutls_datum_t vdata;
@@ -321,7 +322,9 @@ _gnutls_verify_sig (gnutls_cert * cert,
          return GNUTLS_E_KEY_USAGE_VIOLATION;
        }
 
-  switch (cert->subject_pk_algorithm)
+  if (pk_algo == GNUTLS_PK_UNKNOWN)
+    pk_algo = cert->subject_pk_algorithm;
+  switch (pk_algo)
     {
     case GNUTLS_PK_RSA:
 
@@ -340,7 +343,7 @@ _gnutls_verify_sig (gnutls_cert * cert,
     case GNUTLS_PK_DSA:
 
       vdata.data = &hash_concat->data[sha1pos];
-      vdata.size = 20;         /* sha1 */
+      vdata.size = hash_concat->size - sha1pos;
 
       /* verify signature */
       if ((ret = _gnutls_dsa_verify (&vdata, signature, cert->params,
@@ -419,7 +422,7 @@ _gnutls_verify_sig_hdata (gnutls_session_t session, gnutls_cert * cert,
   dconcat.data = concat;
   dconcat.size = 20 + 16;      /* md5+ sha */
 
-  ret = _gnutls_verify_sig (cert, &dconcat, signature, 16);
+  ret = _gnutls_verify_sig (cert, &dconcat, signature, 16, GNUTLS_SIGN_UNKNOWN);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -436,7 +439,8 @@ _gnutls_verify_sig_hdata (gnutls_session_t session, gnutls_cert * cert,
 int
 _gnutls_verify_sig_params (gnutls_session_t session, gnutls_cert * cert,
                           const gnutls_datum_t * params,
-                          gnutls_datum_t * signature)
+                          gnutls_datum_t * signature,
+                          gnutls_sign_algorithm_t algo)
 {
   gnutls_datum_t dconcat;
   int ret;
@@ -444,6 +448,7 @@ _gnutls_verify_sig_params (gnutls_session_t session, gnutls_cert * cert,
   digest_hd_st td_sha;
   opaque concat[36];
   gnutls_protocol_t ver = gnutls_protocol_get_version (session);
+  gnutls_mac_algorithm_t mac_algo = GNUTLS_MAC_SHA1;
 
   if (!_gnutls_version_has_selectable_prf (ver))
     {
@@ -461,7 +466,9 @@ _gnutls_verify_sig_params (gnutls_session_t session, gnutls_cert * cert,
       _gnutls_hash (&td_md5, params->data, params->size);
     }
 
-  ret = _gnutls_hash_init (&td_sha, GNUTLS_MAC_SHA1);
+  if (algo != GNUTLS_SIGN_UNKNOWN)
+    mac_algo = _gnutls_sign_get_mac_algorithm (algo);
+  ret = _gnutls_hash_init (&td_sha, mac_algo);
   if (ret < 0)
     {
       gnutls_assert ();
@@ -502,7 +509,9 @@ _gnutls_verify_sig_params (gnutls_session_t session, gnutls_cert * cert,
 
   dconcat.data = concat;
 
-  ret = _gnutls_verify_sig (cert, &dconcat, signature, dconcat.size - 20);
+  ret = _gnutls_verify_sig (cert, &dconcat, signature,
+                           dconcat.size - _gnutls_hash_get_algo_len (mac_algo),
+                           _gnutls_sign_get_pk_algorithm (algo));
   if (ret < 0)
     {
       gnutls_assert ();
index f16114c7f2ede473179b9849a92191b34a448b01..81890c4f397d0423d2ab92c1dd8258fbfbcc3dca 100644 (file)
@@ -42,7 +42,8 @@ int _gnutls_verify_sig_hdata (gnutls_session_t session,
 int _gnutls_verify_sig_params (gnutls_session_t session,
                               gnutls_cert * cert,
                               const gnutls_datum_t * params,
-                              gnutls_datum_t * signature);
+                              gnutls_datum_t * signature,
+                              gnutls_sign_algorithm_t algo);
 
 int _gnutls_sign (gnutls_pk_algorithm_t algo,
                  bigint_t * params, int params_size,