diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-12-16 17:16:45 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2002-12-16 17:16:45 +0000 |
commit | 3bbfedf3d68fd064cfb0e3d567f202a5375f6b5f (patch) | |
tree | e5fd7b9200761b081894b3cf0cc32e86a1c06c2c /libextra | |
parent | aa23650777efb3dfd84993631f4505af8e4b66f2 (diff) | |
download | gnutls-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.
Diffstat (limited to 'libextra')
-rw-r--r-- | libextra/auth_srp.c | 320 | ||||
-rw-r--r-- | libextra/auth_srp_rsa.c | 20 | ||||
-rw-r--r-- | libextra/ext_srp.c | 28 | ||||
-rw-r--r-- | libextra/gnutls_srp.c | 105 | ||||
-rw-r--r-- | libextra/gnutls_srp.h | 2 |
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); |