]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
First part of SRP-6 support. Follows draft-ietf-tls-srp-04 and does not need the...
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 16 Dec 2002 17:16:45 +0000 (17:16 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 16 Dec 2002 17:16:45 +0000 (17:16 +0000)
libextra/auth_srp.c
libextra/auth_srp_rsa.c
libextra/ext_srp.c
libextra/gnutls_srp.c
libextra/gnutls_srp.h

index e72f460946ce84fadf82e95f13223f1b4ec30d7b..cb033b5511ee952da521c07a10bbb54c3f89017b 100644 (file)
 #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 */
index 6476ea4f7611df96bce2bd708788cb1e1081bc77..89f3c4c8d9ee6fb33296d5eb35d920fc68cb948c 100644 (file)
 #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;
index 6a16bd4dcd790ece7a5ea0dbc10d6bf31710d63a..3624af2a2136763080e130791fb72b9602cd8cf7 100644 (file)
@@ -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;
 }
index 9c042002c49a79311f033df8fbe71068a16d9ed9..5e84bb29dbc55333e6938b5f4f7e6143797dc9f1 100644 (file)
@@ -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;
 }
 
 /**
index b0918aab07353004c93e1bbacee27e769a10bed6..fa3883606b368345ffd4b0c2ff04677a69144ce9 100644 (file)
@@ -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);