summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2002-12-16 17:16:45 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2002-12-16 17:16:45 +0000
commit3bbfedf3d68fd064cfb0e3d567f202a5375f6b5f (patch)
treee5fd7b9200761b081894b3cf0cc32e86a1c06c2c
parentaa23650777efb3dfd84993631f4505af8e4b66f2 (diff)
downloadgnutls-3bbfedf3d68fd064cfb0e3d567f202a5375f6b5f.tar.gz
First part of SRP-6 support. Follows draft-ietf-tls-srp-04 and does not need the second key exchange part. Does not work yet.
-rw-r--r--libextra/auth_srp.c320
-rw-r--r--libextra/auth_srp_rsa.c20
-rw-r--r--libextra/ext_srp.c28
-rw-r--r--libextra/gnutls_srp.c105
-rw-r--r--libextra/gnutls_srp.h2
5 files changed, 237 insertions, 238 deletions
diff --git a/libextra/auth_srp.c b/libextra/auth_srp.c
index e72f460946..cb033b5511 100644
--- a/libextra/auth_srp.c
+++ b/libextra/auth_srp.c
@@ -33,18 +33,18 @@
#include <gnutls_str.h>
#include <gnutls_datum.h>
-int _gnutls_gen_srp_server_kx2(gnutls_session, opaque **);
+int _gnutls_gen_srp_server_kx0(gnutls_session, opaque **);
int _gnutls_gen_srp_client_kx0(gnutls_session, opaque **);
-int _gnutls_proc_srp_server_kx2(gnutls_session, opaque *, size_t);
+int _gnutls_proc_srp_server_kx0(gnutls_session, opaque *, size_t);
int _gnutls_proc_srp_client_kx0(gnutls_session, opaque *, size_t);
const MOD_AUTH_STRUCT srp_auth_struct = {
"SRP",
NULL,
NULL,
+ _gnutls_gen_srp_server_kx0,
NULL,
- _gnutls_gen_srp_server_kx2,
_gnutls_gen_srp_client_kx0,
NULL,
NULL,
@@ -52,8 +52,8 @@ const MOD_AUTH_STRUCT srp_auth_struct = {
NULL,
NULL, /* certificate */
+ _gnutls_proc_srp_server_kx0,
NULL,
- _gnutls_proc_srp_server_kx2,
_gnutls_proc_srp_client_kx0,
NULL,
NULL,
@@ -73,7 +73,7 @@ const MOD_AUTH_STRUCT srp_auth_struct = {
/* 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_hello(gnutls_session state, opaque * data, size_t _data_size)
+int _gnutls_gen_srp_server_kx0(gnutls_session state, opaque ** data)
{
int ret;
uint8 *data_n, *data_s;
@@ -81,7 +81,9 @@ int _gnutls_gen_srp_server_hello(gnutls_session state, opaque * data, size_t _da
SRP_PWD_ENTRY *pwd_entry;
int err;
SRP_SERVER_AUTH_INFO info;
- ssize_t data_size = _data_size;
+ ssize_t data_size;
+ size_t n_b;
+ uint8 *data_b;
if ( (ret=_gnutls_auth_info_set( state, GNUTLS_CRD_SRP, sizeof( SRP_SERVER_AUTH_INFO_INT), 1)) < 0) {
gnutls_assert();
@@ -123,43 +125,8 @@ int _gnutls_gen_srp_server_hello(gnutls_session state, opaque * data, size_t _da
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if ((size_t)data_size < pwd_entry->n.size +
- pwd_entry->g.size + pwd_entry->salt.size + 5) {
- gnutls_assert();
- return GNUTLS_E_INVALID_REQUEST;
- }
-
- /* copy the salt
+ /* Calculate: B = (3v + g^b) % N
*/
- data_s = data;
-
- _gnutls_write_datum8( data_s, pwd_entry->salt);
-
- /* copy N (mod n) */
- data_n = &data_s[1 + pwd_entry->salt.size];
- _gnutls_write_datum16( data_n, pwd_entry->n);
-
-
- data_g = &data_n[2 + pwd_entry->n.size];
- /* copy G (generator) to data */
- _gnutls_write_datum16( data_g, pwd_entry->g);
-
-
- ret = pwd_entry->g.size + pwd_entry->n.size +
- pwd_entry->salt.size + 5;
- _gnutls_srp_entry_free( pwd_entry);
-
- return ret;
-}
-
-/* send the second key exchange message */
-int _gnutls_gen_srp_server_kx2(gnutls_session state, opaque ** data)
-{
- int ret;
- size_t n_b;
- uint8 *data_b;
-
- /* calculate: B = (v + g^b) % N */
B = _gnutls_calc_srp_B( &_b, G, N, V);
if (B==NULL) {
gnutls_assert();
@@ -171,57 +138,55 @@ int _gnutls_gen_srp_server_kx2(gnutls_session state, opaque ** data)
return GNUTLS_E_MPI_PRINT_FAILED;
}
- (*data) = gnutls_malloc(n_b + 2);
+
+ /* Allocate size to hold the N, g, s, B
+ */
+
+ data_size = (pwd_entry->n.size + 2 + pwd_entry->g.size + 2 +
+ pwd_entry->salt.size + 1) + (n_b + 2);
+
+ (*data) = gnutls_malloc( data_size);
if ( (*data) == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
- /* copy B */
- data_b = (*data);
- if (_gnutls_mpi_print( &data_b[2], &n_b, B)!=0)
- return GNUTLS_E_MPI_PRINT_FAILED;
+ /* copy N (mod n)
+ */
+ data_n = *data;
+ _gnutls_write_datum16( data_n, pwd_entry->n);
- _gnutls_write_uint16( n_b, data_b);
- /* calculate u */
- state->key->u = _gnutls_calc_srp_u(B);
- if (state->key->u==NULL) {
- gnutls_assert();
- gnutls_free( *data);
- return GNUTLS_E_MEMORY_ERROR;
- }
+ /* copy G (generator) to data
+ */
+ data_g = &data_n[2 + pwd_entry->n.size];
+ _gnutls_write_datum16( data_g, pwd_entry->g);
- /* S = (A * v^u) ^ b % N */
- S = _gnutls_calc_srp_S1( A, _b, state->key->u, V, N);
- if ( S==NULL) {
- gnutls_assert();
- gnutls_free( *data);
- return GNUTLS_E_MEMORY_ERROR;
- }
- _gnutls_mpi_release(&A);
- _gnutls_mpi_release(&_b);
- _gnutls_mpi_release(&V);
- _gnutls_mpi_release(&state->key->u);
- _gnutls_mpi_release(&B);
+ /* copy the salt
+ */
+ data_s = &data_g[2 + pwd_entry->g.size];
+ _gnutls_write_datum8( data_s, pwd_entry->salt);
- ret = _gnutls_generate_key( state->key);
- _gnutls_mpi_release( &S);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
+ /* Copy the B value
+ */
- return n_b + 2;
-}
+ data_b = &data_s[1+pwd_entry->salt.size];
+ if (_gnutls_mpi_print( &data_b[2], &n_b, B)!=0)
+ return GNUTLS_E_MPI_PRINT_FAILED;
+ _gnutls_write_uint16( n_b, data_b);
+ _gnutls_srp_entry_free( pwd_entry);
+
+ return data_size;
+}
/* return A = g^a % N */
int _gnutls_gen_srp_client_kx0(gnutls_session state, opaque ** data)
{
size_t n_a;
+ int ret;
uint8 *data_a;
char *username;
char *password;
@@ -254,6 +219,34 @@ int _gnutls_gen_srp_client_kx0(gnutls_session state, opaque ** data)
return GNUTLS_E_MEMORY_ERROR;
}
+ /* Rest of SRP calculations
+ */
+
+ /* calculate u */
+ state->key->u = _gnutls_calc_srp_u(A, B);
+ if ( state->key->u == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ /* S = (B - g^x) ^ (a + u * x) % N */
+ S = _gnutls_calc_srp_S2( B, G, state->key->x, _a, state->key->u, N);
+ if (S==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ _gnutls_mpi_release(&_b);
+ _gnutls_mpi_release(&V);
+ _gnutls_mpi_release(&state->key->u);
+ _gnutls_mpi_release(&B);
+
+ ret = _gnutls_generate_key( state->key);
+ _gnutls_mpi_release(&S);
+
+ if (ret < 0)
+ return ret;
+
if (_gnutls_mpi_print( NULL, &n_a, A)!=0) {
gnutls_assert();
return GNUTLS_E_MPI_PRINT_FAILED;
@@ -271,21 +264,75 @@ int _gnutls_gen_srp_client_kx0(gnutls_session state, opaque ** data)
gnutls_free( *data);
return GNUTLS_E_MPI_PRINT_FAILED;
}
-
+ _gnutls_mpi_release(&A);
+
_gnutls_write_uint16( n_a, data_a);
return n_a + 2;
}
-/* receive the first key exchange message ( g, n, s) */
-int _gnutls_proc_srp_server_hello(gnutls_session state, const opaque * data, size_t _data_size)
+
+/* just read A and put it to state */
+int _gnutls_proc_srp_client_kx0(gnutls_session state, opaque * data, size_t _data_size)
+{
+ size_t _n_A;
+ ssize_t data_size = _data_size;
+ int ret;
+
+ DECR_LEN( data_size, 2);
+ _n_A = _gnutls_read_uint16( &data[0]);
+
+ DECR_LEN( data_size, _n_A);
+ if (_gnutls_mpi_scan(&A, &data[2], &_n_A) || A == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+
+ /* Start the SRP calculations.
+ * - Calculate u
+ */
+ state->key->u = _gnutls_calc_srp_u(A, B);
+ if (state->key->u==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ /* S = (A * v^u) ^ b % N
+ */
+ S = _gnutls_calc_srp_S1( A, _b, state->key->u, V, N);
+ if ( S==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ _gnutls_mpi_release(&A);
+ _gnutls_mpi_release(&_b);
+ _gnutls_mpi_release(&V);
+ _gnutls_mpi_release(&state->key->u);
+ _gnutls_mpi_release(&B);
+
+ ret = _gnutls_generate_key( state->key);
+ _gnutls_mpi_release( &S);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ return 0;
+}
+
+/* receive the key exchange message ( n, g, s, B)
+ */
+int _gnutls_proc_srp_server_kx0(gnutls_session state, opaque * data, size_t _data_size)
{
uint8 n_s;
- uint16 n_g, n_n;
- size_t _n_s, _n_g, _n_n;
+ uint16 n_g, n_n, n_b;
+ size_t _n_s, _n_g, _n_n, _n_b;
const uint8 *data_n;
const uint8 *data_g;
const uint8 *data_s;
+ const uint8 *data_b;
int i, ret;
opaque hd[SRP_MAX_HASH_SIZE];
char *username, *password;
@@ -309,14 +356,8 @@ int _gnutls_proc_srp_server_hello(gnutls_session state, const opaque * data, siz
i = 0;
- DECR_LEN( data_size, 1);
- n_s = data[i];
- i += 1;
-
- DECR_LEN( data_size, n_s);
- data_s = &data[i];
- i += n_s;
-
+ /* Read N
+ */
DECR_LEN( data_size, 2);
n_n = _gnutls_read_uint16( &data[i]);
i += 2;
@@ -324,7 +365,9 @@ int _gnutls_proc_srp_server_hello(gnutls_session state, const opaque * data, siz
DECR_LEN( data_size, n_n);
data_n = &data[i];
i += n_n;
-
+
+ /* Read G
+ */
DECR_LEN( data_size, 2);
n_g = _gnutls_read_uint16( &data[i]);
i += 2;
@@ -333,16 +376,42 @@ int _gnutls_proc_srp_server_hello(gnutls_session state, const opaque * data, siz
data_g = &data[i];
i += n_g;
+ /* Read salt
+ */
+ DECR_LEN( data_size, 1);
+ n_s = data[i];
+ i += 1;
+
+ DECR_LEN( data_size, n_s);
+ data_s = &data[i];
+ i += n_s;
+
+ /* Read B
+ */
+ DECR_LEN( data_size, 2);
+ n_b = data[i];
+ i += 2;
+
+ DECR_LEN( data_size, n_b);
+ data_b = &data[i];
+ i += n_b;
+
_n_s = n_s;
_n_g = n_g;
_n_n = n_n;
+ _n_b = n_b;
+
+ if (_gnutls_mpi_scan(&N, data_n, &_n_n) != 0) {
+ gnutls_assert();
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
- if (_gnutls_mpi_scan(&N, data_n, &_n_n) != 0 || N == NULL) {
+ if (_gnutls_mpi_scan(&G, data_g, &_n_g) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
- if (_gnutls_mpi_scan(&G, data_g, &_n_g) != 0 || G == NULL) {
+ if (_gnutls_mpi_scan(&B, data_b, &_n_b) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
@@ -355,78 +424,13 @@ int _gnutls_proc_srp_server_hello(gnutls_session state, const opaque * data, siz
return ret;
}
- if (_gnutls_mpi_scan(&state->key->x, hd, &_n_g) != 0 || state->key->x==NULL) {
+ if (_gnutls_mpi_scan(&state->key->x, hd, &_n_g) != 0) {
gnutls_assert();
return GNUTLS_E_MPI_SCAN_FAILED;
}
-
- return 0;
-}
-
-/* just read A and put it to state */
-int _gnutls_proc_srp_client_kx0(gnutls_session state, opaque * data, size_t _data_size)
-{
- size_t _n_A;
- ssize_t data_size = _data_size;
-
- DECR_LEN( data_size, 2);
- _n_A = _gnutls_read_uint16( &data[0]);
-
- DECR_LEN( data_size, _n_A);
- if (_gnutls_mpi_scan(&A, &data[2], &_n_A) || A == NULL) {
- gnutls_assert();
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
-
- return 0;
-}
-
-
-int _gnutls_proc_srp_server_kx2(gnutls_session state, opaque * data, size_t _data_size)
-{
- size_t _n_B;
- ssize_t data_size = _data_size;
- int ret;
-
- DECR_LEN( data_size, 2);
- _n_B = _gnutls_read_uint16( &data[0]);
-
- DECR_LEN( data_size, _n_B);
- if (_gnutls_mpi_scan(&B, &data[2], &_n_B) || B==NULL) {
- gnutls_assert();
- return GNUTLS_E_MPI_SCAN_FAILED;
- }
-
- /* calculate u */
- state->key->u = _gnutls_calc_srp_u( B);
- if ( state->key->u == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- /* S = (B - g^x) ^ (a + u * x) % N */
- S = _gnutls_calc_srp_S2( B, G, state->key->x, _a, state->key->u, N);
- if (S==NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
- _gnutls_mpi_release(&A);
- _gnutls_mpi_release(&_b);
- _gnutls_mpi_release(&V);
- _gnutls_mpi_release(&state->key->u);
- _gnutls_mpi_release(&B);
-
- ret = _gnutls_generate_key( state->key);
- _gnutls_mpi_release(&S);
-
- if (ret < 0)
- return ret;
-
- return _data_size - data_size; /* return the remaining data
- * needed in auth_srp_rsa.
- */
+ return 0;
}
#endif /* ENABLE_SRP */
diff --git a/libextra/auth_srp_rsa.c b/libextra/auth_srp_rsa.c
index 6476ea4f76..89f3c4c8d9 100644
--- a/libextra/auth_srp_rsa.c
+++ b/libextra/auth_srp_rsa.c
@@ -39,15 +39,15 @@
#include <gnutls_x509.h>
#include <gnutls_extra.h>
-static int gen_srp_cert_server_kx2(gnutls_session, opaque **);
-static int proc_srp_cert_server_kx2(gnutls_session, opaque *, size_t);
+static int gen_srp_cert_server_kx0(gnutls_session, opaque **);
+static int proc_srp_cert_server_kx0(gnutls_session, opaque *, size_t);
const MOD_AUTH_STRUCT srp_rsa_auth_struct = {
"SRP",
_gnutls_gen_cert_server_certificate,
NULL,
+ gen_srp_cert_server_kx0,
NULL,
- gen_srp_cert_server_kx2,
_gnutls_gen_srp_client_kx0,
NULL,
NULL,
@@ -55,8 +55,8 @@ const MOD_AUTH_STRUCT srp_rsa_auth_struct = {
_gnutls_proc_cert_server_certificate,
NULL, /* certificate */
+ proc_srp_cert_server_kx0,
NULL,
- proc_srp_cert_server_kx2,
_gnutls_proc_srp_client_kx0,
NULL,
NULL,
@@ -67,8 +67,8 @@ const MOD_AUTH_STRUCT srp_dss_auth_struct = {
"SRP",
_gnutls_gen_cert_server_certificate,
NULL,
+ gen_srp_cert_server_kx0,
NULL,
- gen_srp_cert_server_kx2,
_gnutls_gen_srp_client_kx0,
NULL,
NULL,
@@ -76,15 +76,15 @@ const MOD_AUTH_STRUCT srp_dss_auth_struct = {
_gnutls_proc_cert_server_certificate,
NULL, /* certificate */
+ proc_srp_cert_server_kx0,
NULL,
- proc_srp_cert_server_kx2,
_gnutls_proc_srp_client_kx0,
NULL,
NULL,
NULL
};
-static int gen_srp_cert_server_kx2(gnutls_session session, opaque ** data)
+static int gen_srp_cert_server_kx0(gnutls_session session, opaque ** data)
{
ssize_t ret, data_size;
gnutls_datum signature, ddata;
@@ -93,7 +93,7 @@ gnutls_cert *apr_cert_list;
gnutls_private_key *apr_pkey;
int apr_cert_list_length;
- ret = _gnutls_gen_srp_server_kx2( session, data);
+ ret = _gnutls_gen_srp_server_kx0( session, data);
if (ret < 0) return ret;
@@ -143,7 +143,7 @@ int apr_cert_list_length;
extern OPENPGP_CERT2GNUTLS_CERT _E_gnutls_openpgp_cert2gnutls_cert;
-static int proc_srp_cert_server_kx2(gnutls_session session, opaque * data, size_t _data_size)
+static int proc_srp_cert_server_kx0(gnutls_session session, opaque * data, size_t _data_size)
{
ssize_t ret;
int sigsize;
@@ -153,7 +153,7 @@ CERTIFICATE_AUTH_INFO info;
gnutls_cert peer_cert;
opaque* p;
- ret = _gnutls_proc_srp_server_kx2( session, data, _data_size);
+ ret = _gnutls_proc_srp_server_kx0( session, data, _data_size);
if (ret < 0) return ret;
data_size = _data_size - ret;
diff --git a/libextra/ext_srp.c b/libextra/ext_srp.c
index 6a16bd4dcd..3624af2a21 100644
--- a/libextra/ext_srp.c
+++ b/libextra/ext_srp.c
@@ -52,13 +52,6 @@ int _gnutls_srp_recv_params( gnutls_session state, const opaque* data, size_t _d
memcpy( state->security_parameters.extensions.srp_username, &data[1], len);
state->security_parameters.extensions.srp_username[len]=0; /* null terminated */
}
- } else { /* client side reading server hello extensions */
- if (state->internals.resumed==RESUME_FALSE)
- return _gnutls_proc_srp_server_hello( state, data, data_size);
- else /* we do not need to process this if
- * we are resuming.
- */
- return 0;
}
return 0;
}
@@ -107,27 +100,6 @@ int _gnutls_srp_send_params( gnutls_session state, opaque* data, size_t data_siz
memcpy( &data[1], cred->username, len);
return len + 1;
}
- } else { /* SERVER SIDE sending (g,n,s) */
- /* We only send the packet if we are NOT
- * resuming AND we are using SRP
- */
-
- /* note that security parameters are not fully established
- */
-
- if ( !is_srp(state->security_parameters.current_cipher_suite))
- return 0; /* no data to send */
-
- /* Even if we are resuming, the username in the parameters
- * should be non null.
- */
- if (state->security_parameters.extensions.srp_username[0]==0)
- return GNUTLS_E_ILLEGAL_SRP_USERNAME;
-
- if (state->internals.resumed==RESUME_FALSE)
- return _gnutls_gen_srp_server_hello( state, data, data_size);
- else
- return 0;
}
return 0;
}
diff --git a/libextra/gnutls_srp.c b/libextra/gnutls_srp.c
index 9c042002c4..5e84bb29db 100644
--- a/libextra/gnutls_srp.c
+++ b/libextra/gnutls_srp.c
@@ -78,17 +78,25 @@ int _gnutls_srp_gx(opaque * text, size_t textsize, opaque ** result, GNUTLS_MPI
*/
GNUTLS_MPI _gnutls_calc_srp_B(GNUTLS_MPI * ret_b, GNUTLS_MPI g, GNUTLS_MPI n, GNUTLS_MPI v)
{
- GNUTLS_MPI tmpB;
+ GNUTLS_MPI tmpB, tmpV;
GNUTLS_MPI b, B;
int bits;
- /* calculate: B = (v + g^b) % N */
+ /* calculate: B = (3v + g^b) % N
+ */
bits = _gnutls_mpi_get_nbits(n);
b = _gnutls_mpi_new(bits); /* FIXME: allocate in secure memory */
if (b==NULL) {
gnutls_assert();
return NULL;
}
+
+ tmpV = _gnutls_mpi_alloc_like(n);
+
+ if (tmpV == NULL) {
+ _gnutls_mpi_release(&b);
+ return NULL;
+ }
_gnutls_mpi_randomize(b, bits, GCRY_STRONG_RANDOM);
@@ -96,6 +104,7 @@ GNUTLS_MPI _gnutls_calc_srp_B(GNUTLS_MPI * ret_b, GNUTLS_MPI g, GNUTLS_MPI n, GN
if (tmpB==NULL) {
gnutls_assert();
_gnutls_mpi_release( &b);
+ _gnutls_mpi_release(&tmpV);
return NULL;
}
@@ -104,13 +113,17 @@ GNUTLS_MPI _gnutls_calc_srp_B(GNUTLS_MPI * ret_b, GNUTLS_MPI g, GNUTLS_MPI n, GN
gnutls_assert();
_gnutls_mpi_release( &b);
_gnutls_mpi_release( &tmpB);
+ _gnutls_mpi_release(&tmpV);
return NULL;
}
+ _gnutls_mpi_mul_ui(tmpV, v, 3);
+
_gnutls_mpi_powm(tmpB, g, b, n);
- _gnutls_mpi_addm(B, v, tmpB, n);
+ _gnutls_mpi_addm(B, tmpV, tmpB, n);
_gnutls_mpi_release(&tmpB);
+ _gnutls_mpi_release(&tmpV);
if (ret_b)
*ret_b = b;
@@ -120,43 +133,47 @@ GNUTLS_MPI _gnutls_calc_srp_B(GNUTLS_MPI * ret_b, GNUTLS_MPI g, GNUTLS_MPI n, GN
return B;
}
-GNUTLS_MPI _gnutls_calc_srp_u(GNUTLS_MPI B)
+GNUTLS_MPI _gnutls_calc_srp_u(GNUTLS_MPI A, GNUTLS_MPI B)
{
- size_t b_size;
- opaque *b_holder, hd[MAX_HASH_SIZE];
+ size_t b_size, a_size;
+ opaque *holder, hd[MAX_HASH_SIZE];
+ size_t holder_size;
GNUTLS_HASH_HANDLE td;
uint32 u;
- GNUTLS_MPI ret;
+ int ret;
+ GNUTLS_MPI res;
+ _gnutls_mpi_print( NULL, &a_size, A);
_gnutls_mpi_print( NULL, &b_size, B);
- b_holder = gnutls_malloc(b_size);
- if (b_holder==NULL) return NULL;
- _gnutls_mpi_print( b_holder, &b_size, B);
+ holder_size = a_size + b_size;
+ holder = gnutls_alloca(holder_size);
+ if (holder==NULL) return NULL;
+
+ _gnutls_mpi_print( holder, &a_size, A);
+ _gnutls_mpi_print( &holder[a_size], &b_size, B);
td = _gnutls_hash_init(GNUTLS_MAC_SHA);
if (td==NULL) {
- gnutls_free(b_holder);
+ gnutls_afree(holder);
gnutls_assert();
return NULL;
}
- _gnutls_hash(td, b_holder, b_size);
+ _gnutls_hash(td, holder, holder_size);
_gnutls_hash_deinit(td, hd);
/* convert the first 4 bytes of hd to uint32
*/
- u = _gnutls_read_uint32( hd);
+ ret = _gnutls_mpi_scan( &res, holder, &holder_size);
+ gnutls_afree(holder);
- gnutls_free(b_holder);
-
- ret = _gnutls_mpi_set_ui(NULL, u);
- if (ret==NULL) {
+ if (ret < 0) {
gnutls_assert();
return NULL;
}
- return ret;
+ return res;
}
/* S = (A * v^u) ^ b % N
@@ -164,8 +181,8 @@ GNUTLS_MPI _gnutls_calc_srp_u(GNUTLS_MPI B)
*/
GNUTLS_MPI _gnutls_calc_srp_S1(GNUTLS_MPI A, GNUTLS_MPI b, GNUTLS_MPI u, GNUTLS_MPI v, GNUTLS_MPI n)
{
- GNUTLS_MPI tmp1, tmp2;
- GNUTLS_MPI S;
+ GNUTLS_MPI tmp1=NULL, tmp2 = NULL;
+ GNUTLS_MPI S = NULL;
S = _gnutls_mpi_alloc_like(n);
if (S==NULL)
@@ -174,20 +191,20 @@ GNUTLS_MPI _gnutls_calc_srp_S1(GNUTLS_MPI A, GNUTLS_MPI b, GNUTLS_MPI u, GNUTLS_
tmp1 = _gnutls_mpi_alloc_like(n);
tmp2 = _gnutls_mpi_alloc_like(n);
- if (tmp1 == NULL || tmp2 == NULL) {
- _gnutls_mpi_release(&tmp1);
- _gnutls_mpi_release(&tmp2);
- return NULL;
- }
+ if (tmp1 == NULL || tmp2 == NULL)
+ goto freeall;
_gnutls_mpi_powm(tmp1, v, u, n);
_gnutls_mpi_mulm(tmp2, A, tmp1, n);
- _gnutls_mpi_release(&tmp1);
-
_gnutls_mpi_powm(S, tmp2, b, n);
- _gnutls_mpi_release(&tmp2);
return S;
+
+ freeall:
+ _gnutls_mpi_release(&tmp1);
+ _gnutls_mpi_release(&tmp2);
+
+ return NULL;
}
/* A = g^a % N
@@ -267,12 +284,13 @@ int _gnutls_calc_srp_x(char *username, char *password, opaque * salt,
}
-/* S = (B - g^x) ^ (a + u * x) % N
+/* S = (B - 3*g^x) ^ (a + u * x) % N
* this is our shared key
*/
GNUTLS_MPI _gnutls_calc_srp_S2(GNUTLS_MPI B, GNUTLS_MPI g, GNUTLS_MPI x, GNUTLS_MPI a, GNUTLS_MPI u, GNUTLS_MPI n)
{
- GNUTLS_MPI S, tmp1, tmp2, tmp4;
+ GNUTLS_MPI S=NULL, tmp1=NULL, tmp2=NULL;
+ GNUTLS_MPI tmp4=NULL, tmp3=NULL;
S = _gnutls_mpi_alloc_like(n);
if (S==NULL)
@@ -280,29 +298,34 @@ GNUTLS_MPI _gnutls_calc_srp_S2(GNUTLS_MPI B, GNUTLS_MPI g, GNUTLS_MPI x, GNUTLS_
tmp1 = _gnutls_mpi_alloc_like(n);
tmp2 = _gnutls_mpi_alloc_like(n);
- if (tmp1 == NULL || tmp2 == NULL) {
- _gnutls_mpi_release(&tmp1);
- _gnutls_mpi_release(&tmp2);
- return NULL;
+ tmp3 = _gnutls_mpi_alloc_like(n);
+ if (tmp1 == NULL || tmp2 == NULL || tmp3 == NULL) {
+ goto freeall;
}
- _gnutls_mpi_powm(tmp1, g, x, n);
-
- _gnutls_mpi_subm(tmp2, B, tmp1, n);
+ _gnutls_mpi_powm(tmp1, g, x, n); /* g^x */
+ _gnutls_mpi_mul_ui(tmp3, tmp1, 3); /* 3*g^x */
+ _gnutls_mpi_subm(tmp2, B, tmp3, n);
tmp4 = _gnutls_mpi_alloc_like(n);
if (tmp4==NULL)
- return NULL;
+ goto freeall;
_gnutls_mpi_mul(tmp1, u, x);
_gnutls_mpi_add(tmp4, a, tmp1);
- _gnutls_mpi_release(&tmp1);
-
_gnutls_mpi_powm(S, tmp2, tmp4, n);
+
+ return S;
+
+ freeall:
+
+ _gnutls_mpi_release(&tmp1);
_gnutls_mpi_release(&tmp2);
+ _gnutls_mpi_release(&tmp3);
_gnutls_mpi_release(&tmp4);
+ _gnutls_mpi_release(&S);
- return S;
+ return NULL;
}
/**
diff --git a/libextra/gnutls_srp.h b/libextra/gnutls_srp.h
index b0918aab07..fa3883606b 100644
--- a/libextra/gnutls_srp.h
+++ b/libextra/gnutls_srp.h
@@ -2,7 +2,7 @@
int _gnutls_srp_gx(opaque *text, size_t textsize, opaque** result, MPI g, MPI prime, gnutls_alloc_function);
MPI _gnutls_calc_srp_B(MPI * ret_b, MPI g, MPI n, MPI v);
-MPI _gnutls_calc_srp_u( MPI B);
+MPI _gnutls_calc_srp_u( MPI A, MPI B);
MPI _gnutls_calc_srp_S1(MPI A, MPI b, MPI u, MPI v, MPI n);
MPI _gnutls_calc_srp_A(MPI *a, MPI g, MPI n);
MPI _gnutls_calc_srp_S2(MPI B, MPI g, MPI x, MPI a, MPI u, MPI n);