int _gnutls_dh_common_print_server_kx (gnutls_session_t session, bigint_t g, bigint_t p, unsigned int q_bits, gnutls_buffer_st* data) { bigint_t x, Y; int ret; /* Y=g^x mod p */ ret = gnutls_calc_dh_secret (&Y, &x, g, p, q_bits); if (ret < 0) { gnutls_assert (); return ret; } session->key.dh_secret = x; _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x)); ret = _gnutls_buffer_append_mpi(data, 16, p, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_buffer_append_mpi(data, 16, g, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_buffer_append_mpi(data, 16, Y, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = data->length; cleanup: _gnutls_mpi_release (&Y); return ret; }
int _gnutls_dh_common_print_server_kx(gnutls_session_t session, gnutls_buffer_st * data) { int ret; unsigned q_bits = session->key.dh_params.flags; if (q_bits < 192 && q_bits != 0) { gnutls_assert(); _gnutls_debug_log("too small q_bits value for DH: %u\n", q_bits); q_bits = 0; /* auto-detect */ } /* Y=g^x mod p */ ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, q_bits, &session->key.dh_params, 1); if (ret < 0) return gnutls_assert_val(ret); _gnutls_dh_set_secret_bits(session, _gnutls_mpi_get_nbits(session->key.dh_params.params[DH_X])); ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_P], 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_G], 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_Y], 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = data->length; cleanup: return ret; }
int _gnutls_gen_dh_common_client_kx_int(gnutls_session_t session, gnutls_buffer_st * data, gnutls_datum_t * pskkey) { int ret; gnutls_pk_params_st peer_pub; gnutls_datum_t tmp_dh_key = {NULL, 0}; gnutls_pk_params_init(&peer_pub); ret = _gnutls_pk_generate_keys(GNUTLS_PK_DH, 0, &session->key.dh_params, 1); if (ret < 0) return gnutls_assert_val(ret); _gnutls_dh_set_secret_bits(session, _gnutls_mpi_get_nbits(session->key.dh_params.params[DH_X])); ret = _gnutls_buffer_append_mpi(data, 16, session->key.dh_params.params[DH_Y], 0); if (ret < 0) { gnutls_assert(); goto error; } peer_pub.params[DH_Y] = session->key.client_Y; /* calculate the key after calculating the message */ ret = _gnutls_pk_derive(GNUTLS_PK_DH, &tmp_dh_key, &session->key.dh_params, &peer_pub); if (ret < 0) { gnutls_assert(); goto error; } if (_gnutls_cipher_suite_get_kx_algo (session->security_parameters.cipher_suite) != GNUTLS_KX_DHE_PSK) { session->key.key.data = tmp_dh_key.data; session->key.key.size = tmp_dh_key.size; } else { /* In DHE_PSK the key is set differently */ ret = _gnutls_set_psk_session_key(session, pskkey, &tmp_dh_key); _gnutls_free_temp_key_datum(&tmp_dh_key); } if (ret < 0) { gnutls_assert(); goto error; } ret = data->length; error: gnutls_pk_params_clear(&session->key.dh_params); return ret; }
int _gnutls_gen_dh_common_client_kx_int (gnutls_session_t session, gnutls_buffer_st* data, gnutls_datum_t* pskkey) { bigint_t x = NULL, X = NULL; int ret; ret = gnutls_calc_dh_secret (&X, &x, session->key.client_g, session->key.client_p, 0); if (ret < 0) { gnutls_assert (); goto error; } _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x)); ret = _gnutls_buffer_append_mpi( data, 16, X, 0); if (ret < 0) { gnutls_assert(); goto error; } /* calculate the key after calculating the message */ ret = gnutls_calc_dh_key (&session->key.KEY, session->key.client_Y, x, session->key.client_p); if (ret < 0) { gnutls_assert(); goto error; } /* THESE SHOULD BE DISCARDED */ _gnutls_mpi_release (&session->key.client_Y); _gnutls_mpi_release (&session->key.client_p); _gnutls_mpi_release (&session->key.client_g); if (_gnutls_cipher_suite_get_kx_algo (session->security_parameters.cipher_suite) != GNUTLS_KX_DHE_PSK) { ret = _gnutls_mpi_dprint (session->key.KEY, &session->key.key); } else /* In DHE_PSK the key is set differently */ { gnutls_datum_t tmp_dh_key; ret = _gnutls_mpi_dprint (session->key.KEY, &tmp_dh_key); if (ret < 0) { gnutls_assert (); goto error; } ret = _gnutls_set_psk_session_key (session, pskkey, &tmp_dh_key); _gnutls_free_datum (&tmp_dh_key); } _gnutls_mpi_release (&session->key.KEY); if (ret < 0) { gnutls_assert (); goto error; } ret = data->length; error: _gnutls_mpi_release (&x); _gnutls_mpi_release (&X); return ret; }
/* return A = g^a % N */ int _gnutls_gen_srp_client_kx(gnutls_session_t session, gnutls_buffer_st * data) { int ret; char *username, *password; gnutls_srp_client_credentials_t cred; extension_priv_data_t epriv; srp_ext_st *priv; ret = _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SRP, &epriv); if (ret < 0) { /* peer didn't send a username */ gnutls_assert(); return GNUTLS_E_UNKNOWN_SRP_USERNAME; } priv = epriv; cred = (gnutls_srp_client_credentials_t) _gnutls_get_cred(session, GNUTLS_CRD_SRP); if (cred == NULL) { gnutls_assert(); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } if (priv->username == NULL) { username = cred->username; password = cred->password; } else { username = priv->username; password = priv->password; } if (username == NULL || password == NULL) { gnutls_assert(); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } /* calc A = g^a % N */ if (G == NULL || N == NULL) { gnutls_assert(); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } A = _gnutls_calc_srp_A(&_a, G, N); if (A == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } /* Rest of SRP calculations */ /* calculate u */ session->key.u = _gnutls_calc_srp_u(A, B, N); if (session->key.u == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } _gnutls_mpi_log("SRP U: ", session->key.u); /* S = (B - g^x) ^ (a + u * x) % N */ S = _gnutls_calc_srp_S2(B, G, session->key.x, _a, session->key.u, N); if (S == NULL) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } _gnutls_mpi_log("SRP B: ", B); zrelease_temp_mpi_key(&_b); zrelease_temp_mpi_key(&V); zrelease_temp_mpi_key(&session->key.u); zrelease_temp_mpi_key(&B); ret = _gnutls_mpi_dprint(session->key.srp_key, &session->key.key); zrelease_temp_mpi_key(&S); if (ret < 0) { gnutls_assert(); return ret; } ret = _gnutls_buffer_append_mpi(data, 16, A, 0); if (ret < 0) return gnutls_assert_val(ret); _gnutls_mpi_log("SRP A: ", A); _gnutls_mpi_release(&A); return data->length; }
/* Send the first key exchange message ( g, n, s) and append the verifier algorithm number * Data is allocated by the caller, and should have data_size size. */ int _gnutls_gen_srp_server_kx(gnutls_session_t session, gnutls_buffer_st * data) { int ret; char *username; SRP_PWD_ENTRY *pwd_entry; srp_server_auth_info_t info; size_t tmp_size; extension_priv_data_t epriv; srp_ext_st *priv; ret = _gnutls_ext_get_session_data(session, GNUTLS_EXTENSION_SRP, &epriv); if (ret < 0) { /* peer didn't send a username */ gnutls_assert(); return GNUTLS_E_UNKNOWN_SRP_USERNAME; } priv = epriv; if ((ret = _gnutls_auth_info_set(session, GNUTLS_CRD_SRP, sizeof(srp_server_auth_info_st), 1)) < 0) { gnutls_assert(); return ret; } info = _gnutls_get_auth_info(session, GNUTLS_CRD_SRP); if (info == NULL) return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); username = info->username; _gnutls_str_cpy(username, MAX_USERNAME_SIZE, priv->username); ret = _gnutls_srp_pwd_read_entry(session, username, &pwd_entry); if (ret < 0) { gnutls_assert(); return ret; } /* copy from pwd_entry to local variables (actually in session) */ tmp_size = pwd_entry->g.size; if (_gnutls_mpi_init_scan_nz(&G, pwd_entry->g.data, tmp_size) < 0) { gnutls_assert(); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } tmp_size = pwd_entry->n.size; if (_gnutls_mpi_init_scan_nz(&N, pwd_entry->n.data, tmp_size) < 0) { gnutls_assert(); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } tmp_size = pwd_entry->v.size; if (_gnutls_mpi_init_scan_nz(&V, pwd_entry->v.data, tmp_size) < 0) { gnutls_assert(); ret = GNUTLS_E_MPI_SCAN_FAILED; goto cleanup; } /* Calculate: B = (k*v + g^b) % N */ B = _gnutls_calc_srp_B(&_b, G, N, V); if (B == NULL) { gnutls_assert(); ret = GNUTLS_E_MEMORY_ERROR; goto cleanup; } /* copy N (mod n) */ ret = _gnutls_buffer_append_data_prefix(data, 16, pwd_entry->n.data, pwd_entry->n.size); if (ret < 0) { gnutls_assert(); goto cleanup; } /* copy G (generator) to data */ ret = _gnutls_buffer_append_data_prefix(data, 16, pwd_entry->g.data, pwd_entry->g.size); if (ret < 0) { gnutls_assert(); goto cleanup; } /* copy the salt */ ret = _gnutls_buffer_append_data_prefix(data, 8, pwd_entry->salt.data, pwd_entry->salt.size); if (ret < 0) { gnutls_assert(); goto cleanup; } /* Copy the B value */ ret = _gnutls_buffer_append_mpi(data, 16, B, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } _gnutls_mpi_log("SRP B: ", B); ret = data->length; cleanup: _gnutls_srp_entry_free(pwd_entry); return ret; }
static int gen_rsa_export_server_kx (gnutls_session_t session, gnutls_buffer_st* data) { gnutls_rsa_params_t rsa_params; const bigint_t *rsa_mpis; int ret = 0; gnutls_pcert_st *apr_cert_list; gnutls_privkey_t apr_pkey; int apr_cert_list_length; gnutls_datum_t signature, ddata; gnutls_certificate_credentials_t cred; gnutls_sign_algorithm_t sign_algo; unsigned int bits = 0; cred = (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL); if (cred == NULL) { gnutls_assert (); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } /* find the appropriate certificate */ if ((ret = _gnutls_get_selected_cert (session, &apr_cert_list, &apr_cert_list_length, &apr_pkey)) < 0) { gnutls_assert (); return ret; } /* abort sending this message if we have a certificate * of 512 bits or less. */ gnutls_privkey_get_pk_algorithm (apr_pkey, &bits); if (apr_pkey && bits <= 512) { gnutls_assert (); return GNUTLS_E_INT_RET_0; } rsa_params = _gnutls_certificate_get_rsa_params (cred->rsa_params, cred->params_func, session); rsa_mpis = _gnutls_rsa_params_to_mpi (rsa_params); if (rsa_mpis == NULL) { gnutls_assert (); return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS; } if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE, sizeof (cert_auth_info_st), 0)) < 0) { gnutls_assert (); return ret; } _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]); ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[0], 0); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_buffer_append_mpi( data, 16, rsa_mpis[1], 0); if (ret < 0) return gnutls_assert_val(ret); /* Generate the signature. */ ddata.data = data->data; ddata.size = data->length; if (apr_cert_list_length > 0) { if ((ret = _gnutls_handshake_sign_data (session, &apr_cert_list[0], apr_pkey, &ddata, &signature, &sign_algo)) < 0) { gnutls_assert (); return ret; } } else { gnutls_assert (); return data->length; /* do not put a signature - ILLEGAL! */ } ret = _gnutls_buffer_append_data_prefix( data, 16, signature.data, signature.size); _gnutls_free_datum (&signature); if (ret < 0) return gnutls_assert_val(ret); return data->length; }