/* return A = g^a % N */ int _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data) { size_t n_a; int ret; uint8_t *data_a; char *username, *password; char buf[64]; gnutls_srp_client_credentials_t cred; cred = (gnutls_srp_client_credentials_t) _gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL); if (cred == NULL) { gnutls_assert (); return GNUTLS_E_INSUFFICIENT_CREDENTIALS; } if (session->internals.srp_username == NULL) { username = cred->username; password = cred->password; } else { username = session->internals.srp_username; password = session->internals.srp_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_dump_mpi ("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_dump_mpi ("SRP B: ", B); _gnutls_mpi_release (&_b); _gnutls_mpi_release (&V); _gnutls_mpi_release (&session->key->u); _gnutls_mpi_release (&B); ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY); _gnutls_mpi_release (&S); if (ret < 0) { gnutls_assert(); return ret; } if (_gnutls_mpi_print (NULL, &n_a, A) != 0) { gnutls_assert (); return GNUTLS_E_MPI_PRINT_FAILED; } (*data) = gnutls_malloc (n_a + 2); if ((*data) == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } /* copy A */ data_a = (*data); if (_gnutls_mpi_print (&data_a[2], &n_a, A) != 0) { gnutls_free (*data); return GNUTLS_E_MPI_PRINT_FAILED; } _gnutls_hard_log ("INT: SRP A[%d]: %s\n", n_a, _gnutls_bin2hex (&data_a[2], n_a, buf, sizeof (buf))); _gnutls_mpi_release (&A); _gnutls_write_uint16 (n_a, data_a); return n_a + 2; }
/* 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; }