static int proc_anon_client_kx (gnutls_session_t session, opaque * data, size_t _data_size) { gnutls_anon_server_credentials_t cred; int bits; int ret; mpi_t p, g; gnutls_dh_params_t dh_params; const mpi_t *mpis; bits = _gnutls_dh_get_allowed_prime_bits (session); cred = (gnutls_anon_server_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_ANON, NULL); if (cred == NULL) { gnutls_assert (); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } dh_params = _gnutls_get_dh_params (cred->dh_params, cred->params_func, session); mpis = _gnutls_dh_params_to_mpi (dh_params); if (mpis == NULL) { gnutls_assert (); return GNUTLS_E_NO_TEMPORARY_DH_PARAMS; } p = mpis[0]; g = mpis[1]; ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p); return ret; }
static int proc_psk_client_kx (gnutls_session_t session, opaque * data, size_t _data_size) { int bits; int ret; mpi_t p, g; gnutls_dh_params_t dh_params; const mpi_t *mpis; gnutls_psk_server_credentials_t cred; psk_auth_info_t info; gnutls_datum_t username; ssize_t data_size = _data_size; cred = (gnutls_psk_server_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_PSK, NULL); if (cred == NULL) { gnutls_assert (); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } bits = _gnutls_dh_get_allowed_prime_bits (session); if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_PSK, sizeof (psk_auth_info_st), 1)) < 0) { gnutls_assert (); return ret; } dh_params = _gnutls_get_dh_params (cred->dh_params, cred->params_func, session); mpis = _gnutls_dh_params_to_mpi (dh_params); if (mpis == NULL) { gnutls_assert (); return GNUTLS_E_NO_TEMPORARY_DH_PARAMS; } p = mpis[0]; g = mpis[1]; DECR_LEN (data_size, 2); username.size = _gnutls_read_uint16 (&data[0]); DECR_LEN (data_size, username.size); username.data = &data[2]; /* copy the username to the auth info structures */ info = _gnutls_get_auth_info (session); if (username.size > MAX_SRP_USERNAME) { gnutls_assert (); return GNUTLS_E_ILLEGAL_SRP_USERNAME; } memcpy (info->username, username.data, username.size); info->username[username.size] = 0; /* Adjust the data */ data += username.size + 2; ret = _gnutls_proc_dh_common_client_kx (session, data, data_size, g, p); return ret; }
/* Returns the bytes parsed */ int _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; uint8_t *data_p; uint8_t *data_g; uint8_t *data_Y; int i, bits, ret; ssize_t data_size = _data_size; i = 0; DECR_LEN (data_size, 2); n_p = _gnutls_read_uint16 (&data[i]); i += 2; DECR_LEN (data_size, n_p); data_p = &data[i]; i += n_p; DECR_LEN (data_size, 2); n_g = _gnutls_read_uint16 (&data[i]); i += 2; DECR_LEN (data_size, n_g); data_g = &data[i]; i += n_g; DECR_LEN (data_size, 2); n_Y = _gnutls_read_uint16 (&data[i]); i += 2; DECR_LEN (data_size, n_Y); data_Y = &data[i]; _n_Y = n_Y; _n_g = n_g; _n_p = n_p; if (_gnutls_mpi_scan_nz (&session->key.client_Y, data_Y, _n_Y) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } if (_gnutls_mpi_scan_nz (&session->key.client_g, data_g, _n_g) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } if (_gnutls_mpi_scan_nz (&session->key.client_p, data_p, _n_p) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } bits = _gnutls_dh_get_allowed_prime_bits (session); if (bits < 0) { gnutls_assert (); return bits; } if (_gnutls_mpi_get_nbits (session->key.client_p) < (size_t) bits) { /* the prime used by the peer is not acceptable */ gnutls_assert (); return GNUTLS_E_DH_PRIME_UNACCEPTABLE; } _gnutls_dh_set_group (session, session->key.client_g, session->key.client_p); _gnutls_dh_set_peer_public (session, session->key.client_Y); ret = n_Y + n_p + n_g + 6; return ret; }