From: Nikos Mavrogiannopoulos Date: Tue, 8 May 2001 20:16:18 +0000 (+0000) Subject: several fixes for srp. Seems to work now! X-Git-Tag: gnutls-0-1-0-srp~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=94f79b0b28ddb404e5cf8daeb5a98edef2cac632;p=thirdparty%2Fgnutls.git several fixes for srp. Seems to work now! --- diff --git a/lib/auth_srp.c b/lib/auth_srp.c index 1a4034e01b..ca65f1504c 100644 --- a/lib/auth_srp.c +++ b/lib/auth_srp.c @@ -25,6 +25,7 @@ #include "auth_srp.h" #include "gnutls_auth_int.h" #include "gnutls_srp.h" +#include "debug.h" int gen_srp_server_kx(GNUTLS_KEY, opaque **); int gen_srp_server_kx2(GNUTLS_KEY, opaque **); @@ -84,8 +85,10 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data) pwd_algo = (uint8) pwd_entry->algorithm; - gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_g, pwd_entry->g); - gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_n, pwd_entry->n); + if (gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_g, pwd_entry->g)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; + if (gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_n, pwd_entry->n)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; /* copy from pwd_entry to local variables (actually in state) */ G = gcry_mpi_alloc_like(pwd_entry->g); @@ -105,7 +108,8 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data) memcpy( data_g, &pwd_algo, 1); data_g++; - gcry_mpi_print(GCRYMPI_FMT_USG, &data_g[2], &n_g, G); + if(gcry_mpi_print(GCRYMPI_FMT_USG, &data_g[2], &n_g, G)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; _n_g = n_g; #ifndef WORDS_BIGENDIAN _n_g = byteswap16(_n_g); @@ -116,7 +120,8 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data) /* copy N (mod n) */ data_n = &data_g[2 + n_g]; - gcry_mpi_print(GCRYMPI_FMT_USG, &data_n[2], &n_n, N); + if (gcry_mpi_print(GCRYMPI_FMT_USG, &data_n[2], &n_n, N)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; _n_n = n_n; #ifndef WORDS_BIGENDIAN _n_n = byteswap16(_n_n); @@ -154,13 +159,15 @@ int gen_srp_server_kx2(GNUTLS_KEY key, opaque ** data) /* calculate: B = (v + g^b) % N */ B = _gnutls_calc_srp_B( &_b, G, N, V); - gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_b, B); + if (gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_b, B)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; (*data) = gnutls_malloc(n_b + 2); /* copy B */ data_b = (*data); - gcry_mpi_print(GCRYMPI_FMT_USG, &data_b[2], &n_b, B); + if (gcry_mpi_print(GCRYMPI_FMT_USG, &data_b[2], &n_b, B)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; _n_b = n_b; #ifndef WORDS_BIGENDIAN @@ -209,13 +216,16 @@ int gen_srp_client_kx0(GNUTLS_KEY key, opaque ** data) /* calc A = g^a % N */ A = _gnutls_calc_srp_A( &_a, G, N); - gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_a, A); + if (gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_a, A)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; (*data) = gnutls_malloc(n_a + 2); /* copy A */ data_a = (*data); - gcry_mpi_print(GCRYMPI_FMT_USG, &data_a[2], &n_a, A); + if (gcry_mpi_print(GCRYMPI_FMT_USG, &data_a[2], &n_a, A)!=0) + return GNUTLS_E_MPI_PRINT_FAILED; + _n_a = n_a; #ifndef WORDS_BIGENDIAN _n_a = byteswap16(_n_a); @@ -252,9 +262,10 @@ int proc_srp_server_kx(GNUTLS_KEY key, opaque * data, int data_size) return GNUTLS_E_INSUFICIENT_CRED; /* read the algorithm used to generate V */ + i = 0; memcpy( &pwd_algo, data, 1); - i = 1; + i++; memcpy(&n_g, &data[i], 2); i += 2; #ifndef WORDS_BIGENDIAN @@ -267,6 +278,7 @@ int proc_srp_server_kx(GNUTLS_KEY key, opaque * data, int data_size) gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } + memcpy(&n_n, &data[i], 2); #ifndef WORDS_BIGENDIAN n_n = byteswap16(n_n); diff --git a/lib/auth_srp_passwd.c b/lib/auth_srp_passwd.c index 674b4da98e..06573a9b63 100644 --- a/lib/auth_srp_passwd.c +++ b/lib/auth_srp_passwd.c @@ -29,12 +29,15 @@ #include "gnutls_auth_int.h" #include "gnutls_srp.h" #include "gnutls_random.h" +#include "debug.h" static int pwd_put_values( GNUTLS_SRP_PWD_ENTRY *entry, char *str, int str_size) { char * p; int len; opaque *verifier; int verifier_size; +opaque * tmp; +int tmp_size; p = rindex( str, '$'); /* we have n */ if (p==NULL) return -1; @@ -43,34 +46,53 @@ int verifier_size; p++; len = strlen(p); - if (gcry_mpi_scan(&entry->n, GCRYMPI_FMT_HEX, p, NULL)) { + tmp_size = _gnutls_base64_decode( p, len, &tmp); + if (tmp_size < 0) { + gnutls_free(tmp); + return GNUTLS_E_PARSING_ERROR; + } + if (gcry_mpi_scan(&entry->n, GCRYMPI_FMT_USG, tmp, &tmp_size)) { gnutls_assert(); - return -1; + gnutls_free(tmp); + return GNUTLS_E_MPI_SCAN_FAILED; } + gnutls_free(tmp); /* now go for g */ p = rindex( str, '$'); /* we have g */ if (p==NULL) { mpi_release(entry->n); - return -1; + gnutls_assert(); + return GNUTLS_E_PARSING_ERROR; } *p='\0'; p++; len = strlen(p); - if (gcry_mpi_scan(&entry->g, GCRYMPI_FMT_HEX, p, NULL)) { + tmp_size = _gnutls_base64_decode( p, len, &tmp); + + if (tmp_size < 0) { gnutls_assert(); mpi_release(entry->n); - return -1; + gnutls_free(tmp); + return GNUTLS_E_PARSING_ERROR; + } + if (gcry_mpi_scan(&entry->g, GCRYMPI_FMT_USG, tmp, &tmp_size)) { + gnutls_assert(); + gnutls_free(tmp); + mpi_release(entry->n); + return GNUTLS_E_MPI_SCAN_FAILED; } + gnutls_free(tmp); + /* now go for verifier */ p = rindex( str, '$'); /* we have verifier */ if (p==NULL) { mpi_release(entry->n); mpi_release(entry->g); - return -1; + return GNUTLS_E_PARSING_ERROR; } *p='\0'; @@ -82,14 +104,14 @@ int verifier_size; gnutls_assert(); mpi_release(entry->n); mpi_release(entry->g); - return -1; + return GNUTLS_E_PARSING_ERROR; } if (gcry_mpi_scan(&entry->v, GCRYMPI_FMT_USG, verifier, &verifier_size)) { gnutls_assert(); mpi_release(entry->n); mpi_release(entry->g); - return -1; + return GNUTLS_E_MPI_SCAN_FAILED; } @@ -136,7 +158,7 @@ int verifier_size; mpi_release(entry->g); mpi_release(entry->v); gnutls_free(entry->salt); - return -1; + return GNUTLS_E_PARSING_ERROR; } *p='\0'; diff --git a/lib/cert_b64.c b/lib/cert_b64.c index 339cee9852..d905954a71 100644 --- a/lib/cert_b64.c +++ b/lib/cert_b64.c @@ -120,11 +120,11 @@ inline static int decode(uint8 * result, const uint8 * data) return -1; result[2] = ((a1 << 6) & 0xff) | (a2 & 0xff); - if (data[3] == '=') - ret--; - if (data[4] == '=') + if (data[2] == '=') ret--; + if (data[3] == '=') + ret--; return ret; } @@ -253,7 +253,7 @@ int _gnutls_base64_decode(uint8 * data, int data_size, uint8 ** result) data_size *= 4; ret = data_size / 4 * 3; - (*result) = gnutls_malloc(ret); + (*result) = gnutls_malloc(ret+1); if ((*result) == NULL) return -1; @@ -364,7 +364,7 @@ int _gnutls_fbase64_decode(char *msg, uint8 * data, int data_size, #ifdef B64_TEST int main() { - char x[99024]; + char x[100*1024]; int siz; uint8 *b64; @@ -381,11 +381,11 @@ int main() } return 0;*/ - siz = fread(x, 1, 9004, stdin); + siz = fread(x, 1, sizeof(x), stdin); // siz = _gnutls_fbase64_encode("CERTIFICATE", x, siz, &b64); -// siz = _gnutls_base64_encode(x, siz, &b64); - siz = _gnutls_base64_decode(x, siz, &b64); + siz = _gnutls_base64_encode(x, siz, &b64); +// siz = _gnutls_base64_decode(x, siz, &b64); // siz = _gnutls_fbase64_decode("CERTIFICATE", x, siz, &b64); diff --git a/lib/crypt_bcrypt.c b/lib/crypt_bcrypt.c index bf50bdd0f6..c635c6296f 100644 --- a/lib/crypt_bcrypt.c +++ b/lib/crypt_bcrypt.c @@ -604,7 +604,7 @@ char * int i, salt_size = strlen(salt); unsigned char *local_salt, *v; int passwd_len, vsize; - char *tmp, *g, *n; + opaque *tmp, *g, *n; passwd_len = strlen(passwd) + 1; /* we want the null also */ if (passwd_len > 56) diff --git a/lib/crypt_srpsha1.c b/lib/crypt_srpsha1.c index c5d22c073f..5c1397eab5 100644 --- a/lib/crypt_srpsha1.c +++ b/lib/crypt_srpsha1.c @@ -39,7 +39,7 @@ char * int passwd_len; GNUTLS_MAC_HANDLE h1; int vsize, hash_len = gnutls_hash_get_algo_len(GNUTLS_MAC_SHA); - char *tmp, *g, *n; + opaque *tmp, *g, *n; uint8 *rtext, * csalt; passwd_len = strlen(passwd); /* we do not want the null */ diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 5eaaa41bd2..bbb9b7464b 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -57,6 +57,7 @@ static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_KX_ALGORITHM, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_SCAN_FAILED, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_PRINT_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_DECRYPTION_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_DECOMPRESSION_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_COMPRESSION_FAILED, 1), @@ -66,6 +67,7 @@ static gnutls_error_entry error_algorithms[] = { GNUTLS_ERROR_ENTRY( GNUTLS_E_PWD_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_EXPIRED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_HASH_FAILED, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_PARSING_ERROR, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_AGAIN, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_DB_ERROR, 1), {0} diff --git a/lib/gnutls_errors.h b/lib/gnutls_errors.h index 4d0daf19bf..bc373dfd12 100644 --- a/lib/gnutls_errors.h +++ b/lib/gnutls_errors.h @@ -53,6 +53,8 @@ #define GNUTLS_E_PWD_ERROR -31 #define GNUTLS_E_INSUFICIENT_CRED -32 #define GNUTLS_E_HASH_FAILED -33 +#define GNUTLS_E_PARSING_ERROR -34 +#define GNUTLS_E_MPI_PRINT_FAILED -35 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -50 diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 6661172398..e1cf5bf95d 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -538,7 +538,7 @@ int _gnutls_recv_handshake(int cd, GNUTLS_STATE state, uint8 ** data, uint8 *dataptr=NULL; /* for realloc */ uint24 num; int handshake_headers = HANDSHAKE_HEADERS_SIZE; - int recv_type; + HandshakeType recv_type; if (type == GNUTLS_CERTIFICATE) { /* If the ciphersuite does not support certificate just quit */ @@ -1340,6 +1340,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */ ret = _gnutls_recv_server_kx_message(cd, state); if (ret < 0) { + gnutls_assert(); ERR("recv server kx message", ret); gnutls_clearHashDataBuffer(state); return ret; @@ -1352,6 +1353,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */ ret = _gnutls_send_client_kx_message0(cd, state); if (ret < 0) { + gnutls_assert(); ERR("send client kx0", ret); gnutls_clearHashDataBuffer(state); return ret; @@ -1361,6 +1363,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */ ret = _gnutls_recv_server_kx_message2(cd, state); if (ret < 0) { + gnutls_assert(); ERR("recv server kx message2", ret); gnutls_clearHashDataBuffer(state); return ret; @@ -1375,6 +1378,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) _gnutls_recv_handshake(cd, state, NULL, NULL, GNUTLS_SERVER_HELLO_DONE); if (ret < 0) { + gnutls_assert(); ERR("recv server hello done", ret); gnutls_clearHashDataBuffer(state); return ret; @@ -1384,6 +1388,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */ ret = _gnutls_send_client_certificate(cd, state); if (ret < 0) { + gnutls_assert(); ERR("send client certificate", ret); gnutls_clearHashDataBuffer(state); return ret; @@ -1392,6 +1397,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */ ret = _gnutls_send_client_kx_message(cd, state); if (ret < 0) { + gnutls_assert(); ERR("send client kx", ret); gnutls_clearHashDataBuffer(state); return ret; @@ -1403,6 +1409,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) _gnutls_send_client_certificate_verify(cd, state); if (ret < 0) { + gnutls_assert(); ERR("send client certificate verify", ret); gnutls_clearHashDataBuffer(state); return ret; @@ -1416,6 +1423,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) _gnutls_send_handshake(cd, state, NULL, 0, GNUTLS_SERVER_HELLO_DONE); if (ret < 0) { + gnutls_assert(); ERR("send server hello done", ret); gnutls_clearHashDataBuffer(state); return ret; @@ -1427,6 +1435,7 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) if (state->gnutls_internals.resumed == RESUME_FALSE) /* if we are not resuming */ ret = _gnutls_recv_client_kx_message(cd, state); if (ret < 0) { + gnutls_assert(); ERR("recv client kx", ret); gnutls_clearHashDataBuffer(state); return ret; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 1b79c838e2..52d20fef26 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -26,10 +26,10 @@ #define READ_DEBUG #define WRITE_DEBUG #define BUFFERS_DEBUG -#define HARD_DEBUG #define HANDSHAKE_DEBUG -#define DEBUG +#define HARD_DEBUG */ +#define DEBUG #define MAX32 4294967295 #define MAX24 16777215 diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 362ca423ab..a4f1896647 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -340,7 +340,7 @@ int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state) (state->gnutls_internals.current_cipher_suite); /* Do key exchange only if the algorithm permits it */ - if (_gnutls_kx_server_key_exchange(algorithm) != 0) { + if (_gnutls_kx_client_key_exchange(algorithm) != 0) { ret = _gnutls_recv_handshake(cd, state, &data, diff --git a/lib/gnutls_srp.c b/lib/gnutls_srp.c index c85d6b7fd5..35fbb0f5f5 100644 --- a/lib/gnutls_srp.c +++ b/lib/gnutls_srp.c @@ -23,8 +23,10 @@ #include #include #include +#include +#include "debug.h" -// temp here --- +/* These should be added in gcrypt.h */ #define gcry_mpi_add mpi_add #define gcry_mpi_subm mpi_subm #define gcry_mpi_addm mpi_addm @@ -51,12 +53,13 @@ const uint8 diffie_hellman_group1_prime[130] = { 0x04, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, char** ret_g, char** ret_n) { +int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, opaque** ret_g, opaque** ret_n) { MPI g, prime, x, e; size_t n = sizeof diffie_hellman_group1_prime; int result_size, siz; - + char* tmp; + if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, diffie_hellman_group1_prime, &n)) { gnutls_assert(); @@ -75,7 +78,6 @@ int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, char** ret_g, ch /* e = g^x mod prime (n) */ gcry_mpi_powm(e, g, x, prime); - gcry_mpi_release(x); gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &result_size, e); @@ -85,21 +87,31 @@ int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, char** ret_g, ch } siz = 0; - gcry_mpi_print(GCRYMPI_FMT_HEX, NULL, &siz, g); + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &siz, g); if (ret_g!=NULL) { - *ret_g = gnutls_malloc(siz+1); - gcry_mpi_print(GCRYMPI_FMT_HEX, *ret_g, &siz, g); - (*ret_g)[siz] = 0; + tmp = gnutls_malloc(siz); + gcry_mpi_print(GCRYMPI_FMT_USG, tmp, &siz, g); + + if (_gnutls_base64_encode( tmp, siz, ret_g) < 0) { + gnutls_free(tmp); + return GNUTLS_E_UNKNOWN_ERROR; + } + gnutls_free(tmp); } siz = 0; - gcry_mpi_print(GCRYMPI_FMT_HEX, NULL, &siz, prime); + gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &siz, prime); if (ret_n!=NULL) { - *ret_n = gnutls_malloc(siz+1); - gcry_mpi_print(GCRYMPI_FMT_HEX, *ret_n, &siz, prime); - (*ret_n)[siz] = 0; + tmp = gnutls_malloc(siz); + gcry_mpi_print(GCRYMPI_FMT_USG, tmp, &siz, prime); + if (_gnutls_base64_encode( tmp, siz, ret_n) < 0) { + gnutls_free(tmp); + return GNUTLS_E_UNKNOWN_ERROR; + } + + gnutls_free(tmp); } - + gcry_mpi_release(e); gcry_mpi_release(g); gcry_mpi_release(prime); diff --git a/lib/gnutls_srp.h b/lib/gnutls_srp.h index 5e89797c94..67fffba031 100644 --- a/lib/gnutls_srp.h +++ b/lib/gnutls_srp.h @@ -1,4 +1,4 @@ -int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, char** ret_g, char** ret_n); +int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, opaque** ret_g, opaque** ret_n); 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_S1(MPI A, MPI b, MPI u, MPI v, MPI n); diff --git a/src/cli.c b/src/cli.c index bcfdaa8909..5c66953b3c 100644 --- a/src/cli.c +++ b/src/cli.c @@ -82,8 +82,7 @@ int main() gnutls_set_cipher_priority( state, 3, GNUTLS_3DES, GNUTLS_ARCFOUR, GNUTLS_RIJNDAEL); gnutls_set_compression_priority( state, 2, GNUTLS_ZLIB, GNUTLS_NULL_COMPRESSION); -// gnutls_set_kx_priority( state, 2, GNUTLS_KX_SRP, GNUTLS_KX_ANON_DH); - gnutls_set_kx_priority( state, 1, GNUTLS_KX_ANON_DH); + gnutls_set_kx_priority( state, 2, GNUTLS_KX_SRP, GNUTLS_KX_ANON_DH); gnutls_set_kx_cred( state, GNUTLS_KX_ANON_DH, NULL, 0); gnutls_set_kx_cred( state, GNUTLS_KX_SRP, &cred, sizeof(cred)); diff --git a/src/serv.c b/src/serv.c index dddc6d73c3..6783f19135 100644 --- a/src/serv.c +++ b/src/serv.c @@ -46,6 +46,8 @@ int main() int optval = 1; SRP_SERVER_CREDENTIALS cred; + /* this is a password file (created with the included crypt utility) + */ cred.password_file="/tmp/pwd"; listen_sd = socket(AF_INET, SOCK_STREAM, 0);