diff options
author | Daiki Ueno <ueno@gnu.org> | 2023-03-29 14:39:45 +0900 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2023-03-29 15:39:53 +0900 |
commit | 24fdcb325fc6ae42c517a326e2221b9311d6df40 (patch) | |
tree | e06e394f5b2d65f7b07220cb7ed25eb4802f4101 | |
parent | d8464bfaa8277cd004bc114bb88fd4633e814590 (diff) | |
download | gnutls-24fdcb325fc6ae42c517a326e2221b9311d6df40.tar.gz |
audit: emit TLS 1.3 key exchange events
Signed-off-by: Daiki Ueno <ueno@gnu.org>
-rw-r--r-- | lib/audit_int.h | 8 | ||||
-rw-r--r-- | lib/ext/key_share.c | 205 |
2 files changed, 165 insertions, 48 deletions
diff --git a/lib/audit_int.h b/lib/audit_int.h index 19fde02785..ace2b05314 100644 --- a/lib/audit_int.h +++ b/lib/audit_int.h @@ -28,6 +28,14 @@ # include "audit.h" # include <stdint.h> +typedef enum { + GNUTLS_AUDIT_KX_ECDHE = 0, + GNUTLS_AUDIT_KX_DHE = 1, + GNUTLS_AUDIT_KX_PSK = 2, + GNUTLS_AUDIT_KX_ECDHE_PSK = 3, + GNUTLS_AUDIT_KX_DHE_PSK = 4 +} gnutls_audit_key_exchange_algorithm_t; + typedef uint64_t gnutls_audit_context_t; extern gnutls_audit_context_t _gnutls_audit_lib_context; diff --git a/lib/ext/key_share.c b/lib/ext/key_share.c index 2fc543cc9b..6f9affdfe6 100644 --- a/lib/ext/key_share.c +++ b/lib/ext/key_share.c @@ -315,9 +315,29 @@ server_use_key_share(gnutls_session_t session, const gnutls_ecc_curve_entry_st *curve; int ret; + ret = + _gnutls_audit_push_context(&session->internals.audit_context_stack, + (gnutls_audit_context_t) + server_use_key_share); + if (ret < 0) { + return ret; + } + + CRYPTO_AUDITING_STRING_DATA(session->internals. + audit_context_stack.head->context, "name", + "tls::key_exchange"); + + CRYPTO_AUDITING_WORD_DATA(session->internals.audit_context_stack. + head->context, "tls::group", + group->tls_id); + if (group->pk == GNUTLS_PK_EC) { gnutls_pk_params_st pub; + CRYPTO_AUDITING_WORD_DATA(session->internals.audit_context_stack. + head->context, "tls::key_exchange_algorithm", + GNUTLS_AUDIT_KX_ECDHE); + gnutls_pk_params_release(&session->key.kshare.ecdh_params); gnutls_pk_params_init(&session->key.kshare.ecdh_params); @@ -325,25 +345,31 @@ server_use_key_share(gnutls_session_t session, gnutls_pk_params_init(&pub); - if (curve->size * 2 + 1 != data_size) - return + if (curve->size * 2 + 1 != data_size) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } /* generate our key */ ret = _gnutls_pk_generate_keys(curve->pk, curve->id, &session->key.kshare.ecdh_params, 1); - if (ret < 0) - return gnutls_assert_val(ret); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } /* read the public key */ ret = _gnutls_ecc_ansi_x962_import(data, data_size, &pub.params[ECC_X], &pub.params[ECC_Y]); - if (ret < 0) - return gnutls_assert_val(ret); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } pub.algo = group->pk; pub.curve = curve->id; @@ -356,7 +382,8 @@ server_use_key_share(gnutls_session_t session, &pub); gnutls_pk_params_release(&pub); if (ret < 0) { - return gnutls_assert_val(ret); + gnutls_assert(); + goto cleanup; } ret = 0; @@ -365,23 +392,31 @@ server_use_key_share(gnutls_session_t session, group->pk == GNUTLS_PK_ECDH_X448) { gnutls_pk_params_st pub; + CRYPTO_AUDITING_WORD_DATA(session->internals.audit_context_stack. + head->context, "tls::key_exchange_algorithm", + GNUTLS_AUDIT_KX_ECDHE); + gnutls_pk_params_release(&session->key.kshare.ecdhx_params); gnutls_pk_params_init(&session->key.kshare.ecdhx_params); curve = _gnutls_ecc_curve_get_params(group->curve); - if (curve->size != data_size) - return + if (curve->size != data_size) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } /* generate our key */ ret = _gnutls_pk_generate_keys(curve->pk, curve->id, &session->key.kshare.ecdhx_params, 1); - if (ret < 0) - return gnutls_assert_val(ret); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } /* read the public key and generate shared */ gnutls_pk_params_init(&pub); @@ -400,7 +435,8 @@ server_use_key_share(gnutls_session_t session, &session->key.kshare.ecdhx_params, &pub); if (ret < 0) { - return gnutls_assert_val(ret); + gnutls_assert(); + goto cleanup; } ret = 0; @@ -408,14 +444,20 @@ server_use_key_share(gnutls_session_t session, } else if (group->pk == GNUTLS_PK_DH) { gnutls_pk_params_st pub; + CRYPTO_AUDITING_WORD_DATA(session->internals.audit_context_stack. + head->context, "tls::key_exchange_algorithm", + GNUTLS_AUDIT_KX_DHE); + /* we need to initialize the group parameters first */ gnutls_pk_params_release(&session->key.kshare.dh_params); gnutls_pk_params_init(&session->key.kshare.dh_params); - if (data_size != group->prime->size) - return + if (data_size != group->prime->size) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } /* set group params */ ret = @@ -423,29 +465,35 @@ server_use_key_share(gnutls_session_t session, dh_params.params[DH_G], group->generator->data, group->generator->size); - if (ret < 0) - return + if (ret < 0) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } ret = _gnutls_mpi_init_scan_nz(&session->key.kshare. dh_params.params[DH_P], group->prime->data, group->prime->size); - if (ret < 0) - return + if (ret < 0) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } ret = _gnutls_mpi_init_scan_nz(&session->key.kshare. dh_params.params[DH_Q], group->q->data, group->q->size); - if (ret < 0) - return + if (ret < 0) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } session->key.kshare.dh_params.algo = GNUTLS_PK_DH; session->key.kshare.dh_params.qbits = *group->q_bits; @@ -455,18 +503,22 @@ server_use_key_share(gnutls_session_t session, ret = _gnutls_pk_generate_keys(group->pk, 0, &session->key.kshare.dh_params, 1); - if (ret < 0) - return gnutls_assert_val(ret); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } /* read the public key and generate shared */ gnutls_pk_params_init(&pub); ret = _gnutls_mpi_init_scan_nz(&pub.params[DH_Y], data, data_size); - if (ret < 0) - return + if (ret < 0) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } pub.algo = group->pk; @@ -476,17 +528,23 @@ server_use_key_share(gnutls_session_t session, &session->key.kshare.dh_params, &pub); _gnutls_mpi_release(&pub.params[DH_Y]); - if (ret < 0) - return gnutls_assert_val(ret); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } ret = 0; } else { - return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; } _gnutls_debug_log("EXT[%p]: server generated %s shared key\n", session, group->name); + cleanup: + _gnutls_audit_pop_context(&session->internals.audit_context_stack); + return ret; } @@ -500,30 +558,56 @@ client_use_key_share(gnutls_session_t session, const gnutls_ecc_curve_entry_st *curve; int ret; + ret = + _gnutls_audit_push_context(&session->internals.audit_context_stack, + (gnutls_audit_context_t) + client_use_key_share); + if (ret < 0) { + return ret; + } + + CRYPTO_AUDITING_STRING_DATA(session->internals. + audit_context_stack.head->context, "name", + "tls::key_exchange"); + + CRYPTO_AUDITING_WORD_DATA(session->internals.audit_context_stack. + head->context, "tls::group", + group->tls_id); + if (group->pk == GNUTLS_PK_EC) { gnutls_pk_params_st pub; + CRYPTO_AUDITING_WORD_DATA(session->internals.audit_context_stack. + head->context, "tls::key_exchange_algorithm", + GNUTLS_AUDIT_KX_ECDHE); + curve = _gnutls_ecc_curve_get_params(group->curve); gnutls_pk_params_init(&pub); if (session->key.kshare.ecdh_params.algo != group->pk - || session->key.kshare.ecdh_params.curve != curve->id) - return + || session->key.kshare.ecdh_params.curve != curve->id) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } - if (curve->size * 2 + 1 != data_size) - return + if (curve->size * 2 + 1 != data_size) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } /* read the server's public key */ ret = _gnutls_ecc_ansi_x962_import(data, data_size, &pub.params[ECC_X], &pub.params[ECC_Y]); - if (ret < 0) - return gnutls_assert_val(ret); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } pub.algo = group->pk; pub.curve = curve->id; @@ -536,7 +620,8 @@ client_use_key_share(gnutls_session_t session, &pub); gnutls_pk_params_release(&pub); if (ret < 0) { - return gnutls_assert_val(ret); + gnutls_assert(); + goto cleanup; } ret = 0; @@ -545,18 +630,26 @@ client_use_key_share(gnutls_session_t session, group->pk == GNUTLS_PK_ECDH_X448) { gnutls_pk_params_st pub; + CRYPTO_AUDITING_WORD_DATA(session->internals.audit_context_stack. + head->context, "tls::key_exchange_algorithm", + GNUTLS_AUDIT_KX_ECDHE); + curve = _gnutls_ecc_curve_get_params(group->curve); if (session->key.kshare.ecdhx_params.algo != group->pk - || session->key.kshare.ecdhx_params.curve != curve->id) - return + || session->key.kshare.ecdhx_params.curve != curve->id) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } - if (curve->size != data_size) - return + if (curve->size != data_size) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } /* read the public key and generate shared */ gnutls_pk_params_init(&pub); @@ -575,7 +668,8 @@ client_use_key_share(gnutls_session_t session, &session->key.kshare.ecdhx_params, &pub); if (ret < 0) { - return gnutls_assert_val(ret); + gnutls_assert(); + goto cleanup; } ret = 0; @@ -583,26 +677,36 @@ client_use_key_share(gnutls_session_t session, } else if (group->pk == GNUTLS_PK_DH) { gnutls_pk_params_st pub; + CRYPTO_AUDITING_WORD_DATA(session->internals.audit_context_stack. + head->context, "tls::key_exchange_algorithm", + GNUTLS_AUDIT_KX_DHE); + if (session->key.kshare.dh_params.algo != group->pk - || session->key.kshare.dh_params.dh_group != group->id) - return + || session->key.kshare.dh_params.dh_group != group->id) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } - if (data_size != group->prime->size) - return + if (data_size != group->prime->size) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } /* read the public key and generate shared */ gnutls_pk_params_init(&pub); ret = _gnutls_mpi_init_scan_nz(&pub.params[DH_Y], data, data_size); - if (ret < 0) - return + if (ret < 0) { + ret = gnutls_assert_val (GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; + } pub.algo = group->pk; @@ -612,17 +716,22 @@ client_use_key_share(gnutls_session_t session, &session->key.kshare.dh_params, &pub); _gnutls_mpi_release(&pub.params[DH_Y]); - if (ret < 0) - return gnutls_assert_val(ret); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } ret = 0; } else { - return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + ret = gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER); + goto cleanup; } _gnutls_debug_log("EXT[%p]: client generated %s shared key\n", session, group->name); + cleanup: + _gnutls_audit_pop_context(&session->internals.audit_context_stack); return ret; } |