From: Daiki Ueno Date: Mon, 31 Aug 2009 05:40:38 +0000 (+0900) Subject: Respect TLS signature algorithm in server KX. X-Git-Tag: gnutls_2_9_4~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=56d2607e547ac4c4eba24fd8ccbd00ffd494d64d;p=thirdparty%2Fgnutls.git Respect TLS signature algorithm in server KX. Verify signature of DH parameters in Server Key Exchange with the embedded signature algorithm. Signed-off-by: Simon Josefsson --- diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c index ec595eeb99..ea9cf3a57f 100644 --- a/lib/auth_dhe.c +++ b/lib/auth_dhe.c @@ -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) diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c index 606f85c468..638395b128 100644 --- a/lib/auth_rsa_export.c +++ b/lib/auth_rsa_export.c @@ -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) diff --git a/lib/auth_srp_rsa.c b/lib/auth_srp_rsa.c index 2f2ea96662..1689ce2540 100644 --- a/lib/auth_srp_rsa.c +++ b/lib/auth_srp_rsa.c @@ -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) diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c index bcc4412ce4..81e833629c 100644 --- a/lib/gnutls_sig.c +++ b/lib/gnutls_sig.c @@ -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 (); diff --git a/lib/gnutls_sig.h b/lib/gnutls_sig.h index f16114c7f2..81890c4f39 100644 --- a/lib/gnutls_sig.h +++ b/lib/gnutls_sig.h @@ -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,