Pass down Q for FFDHE in al pre TLS1.3 as well
authorSimo Sorce <simo@redhat.com>
Wed, 22 May 2019 19:08:45 +0000 (15:08 -0400)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 23 May 2019 09:35:12 +0000 (11:35 +0200)
Signed-off-by: Simo Sorce <simo@redhat.com>
lib/auth/dh_common.c
lib/dh.c

index 2058d81e59dfc719012e19a9c5c8f1817b34dd44..19c205bbe8cfc1de08fc87d3269d49fa02b36f24 100644 (file)
@@ -182,10 +182,11 @@ _gnutls_proc_dh_common_server_kx(gnutls_session_t session,
                                 uint8_t * data, size_t _data_size)
 {
        uint16_t n_Y, n_g, n_p;
-       size_t _n_Y, _n_g, _n_p;
+       size_t _n_Y, _n_g, _n_p, _n_q;
        uint8_t *data_p;
        uint8_t *data_g;
        uint8_t *data_Y;
+       uint8_t *data_q = NULL;
        int i, bits, ret, p_bits;
        unsigned j;
        ssize_t data_size = _data_size;
@@ -245,6 +246,8 @@ _gnutls_proc_dh_common_server_kx(gnutls_session_t session,
                                session->internals.hsk_flags |= HSK_USED_FFDHE;
                                _gnutls_session_group_set(session, session->internals.priorities->groups.entry[j]);
                                session->key.proto.tls12.dh.params.qbits = *session->internals.priorities->groups.entry[j]->q_bits;
+                               data_q = session->internals.priorities->groups.entry[j]->q->data;
+                               _n_q = session->internals.priorities->groups.entry[j]->q->size;
                                break;
                        }
                }
@@ -265,8 +268,19 @@ _gnutls_proc_dh_common_server_kx(gnutls_session_t session,
                _gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_G]);
                return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
        }
+       if (data_q && _gnutls_mpi_init_scan_nz(
+                           &session->key.proto.tls12.dh.params.params[DH_Q],
+                           data_q, _n_q) != 0) {
+               /* we release now because params_nr is not yet set */
+               _gnutls_mpi_release(
+                       &session->key.proto.tls12.dh.params.params[DH_P]);
+               _gnutls_mpi_release(
+                       &session->key.proto.tls12.dh.params.params[DH_G]);
+               return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
+       }
 
-       session->key.proto.tls12.dh.params.params_nr = 3; /* include empty q */
+       /* include, possibly empty, q */
+       session->key.proto.tls12.dh.params.params_nr = 3;
        session->key.proto.tls12.dh.params.algo = GNUTLS_PK_DH;
 
        if (!(session->internals.hsk_flags & HSK_USED_FFDHE)) {
index 06bc2e1be4af35a3c08ef5e20d677f90b7e501c7..ded939d0d43617e7c00cef8d0ff74a9471d414e7 100644 (file)
--- a/lib/dh.c
+++ b/lib/dh.c
@@ -37,7 +37,7 @@
 
 static
 int set_dh_pk_params(gnutls_session_t session, bigint_t g, bigint_t p,
-                       unsigned q_bits)
+                    bigint_t q, unsigned q_bits)
 {
        /* just in case we are resuming a session */
        gnutls_pk_params_release(&session->key.proto.tls12.dh.params);
@@ -54,7 +54,16 @@ int set_dh_pk_params(gnutls_session_t session, bigint_t g, bigint_t p,
                return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
        }
 
-       session->key.proto.tls12.dh.params.params_nr = 3; /* include empty q */
+       if (q) {
+               session->key.proto.tls12.dh.params.params[DH_Q] = _gnutls_mpi_copy(q);
+               if (session->key.proto.tls12.dh.params.params[DH_Q] == NULL) {
+                       _gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_P]);
+                       _gnutls_mpi_release(&session->key.proto.tls12.dh.params.params[DH_G]);
+                       return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+               }
+       }
+       /* include, possibly empty, q */
+       session->key.proto.tls12.dh.params.params_nr = 3;
        session->key.proto.tls12.dh.params.algo = GNUTLS_PK_DH;
        session->key.proto.tls12.dh.params.qbits = q_bits;
 
@@ -70,7 +79,7 @@ _gnutls_figure_dh_params(gnutls_session_t session, gnutls_dh_params_t dh_params,
                      gnutls_params_function * func, gnutls_sec_param_t sec_param)
 {
        gnutls_params_st params;
-       bigint_t p, g;
+       bigint_t p, g, q = NULL;
        unsigned free_pg = 0;
        int ret;
        unsigned q_bits = 0, i;
@@ -100,6 +109,14 @@ _gnutls_figure_dh_params(gnutls_session_t session, gnutls_dh_params_t dh_params,
                                        goto cleanup;
                                }
 
+                               ret = _gnutls_mpi_init_scan_nz(&q,
+                                               session->internals.priorities->groups.entry[i]->q->data,
+                                               session->internals.priorities->groups.entry[i]->q->size);
+                               if (ret < 0) {
+                                       gnutls_assert();
+                                       goto cleanup;
+                               }
+
                                session->internals.hsk_flags |= HSK_USED_FFDHE;
                                q_bits = *session->internals.priorities->groups.entry[i]->q_bits;
                                goto finished;
@@ -158,7 +175,7 @@ _gnutls_figure_dh_params(gnutls_session_t session, gnutls_dh_params_t dh_params,
  finished:
        _gnutls_dh_save_group(session, g, p);
 
-       ret = set_dh_pk_params(session, g, p, q_bits);
+       ret = set_dh_pk_params(session, g, p, q, q_bits);
        if (ret < 0) {
                gnutls_assert();
        }
@@ -166,6 +183,7 @@ _gnutls_figure_dh_params(gnutls_session_t session, gnutls_dh_params_t dh_params,
  cleanup:
        if (free_pg) {
                _gnutls_mpi_release(&p);
+               _gnutls_mpi_release(&q);
                _gnutls_mpi_release(&g);
        }
        if (params.deinit && params.type == GNUTLS_PARAMS_DH)