diff options
-rw-r--r-- | lib/auth_anon.c | 17 | ||||
-rw-r--r-- | lib/auth_srp.c | 52 | ||||
-rw-r--r-- | lib/auth_srp.h | 2 | ||||
-rw-r--r-- | lib/auth_srp_passwd.c | 8 | ||||
-rw-r--r-- | lib/ext_srp.c | 36 | ||||
-rw-r--r-- | lib/gnutls_dh.c | 18 | ||||
-rw-r--r-- | lib/gnutls_extensions.c | 7 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 8 | ||||
-rw-r--r-- | lib/gnutls_int.h | 4 | ||||
-rw-r--r-- | lib/gnutls_privkey.c | 4 | ||||
-rw-r--r-- | src/cli.c | 3 |
11 files changed, 102 insertions, 57 deletions
diff --git a/lib/auth_anon.c b/lib/auth_anon.c index f0977b07f1..d06a1a0090 100644 --- a/lib/auth_anon.c +++ b/lib/auth_anon.c @@ -84,6 +84,10 @@ int gen_anon_server_kx( GNUTLS_STATE state, opaque** data) { } g = gnutls_get_dh_params(&p, bits); + if (g==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } state->gnutls_key->auth_info = gnutls_malloc(sizeof(ANON_SERVER_AUTH_INFO)); if (state->gnutls_key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR; @@ -195,18 +199,18 @@ int proc_anon_server_kx( GNUTLS_STATE state, opaque* data, int data_size) { _n_p = n_p; if (gcry_mpi_scan(&state->gnutls_key->client_Y, - GCRYMPI_FMT_USG, data_Y, &_n_Y) != 0) { + GCRYMPI_FMT_USG, data_Y, &_n_Y) != 0 || state->gnutls_key->client_Y==NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } if (gcry_mpi_scan(&state->gnutls_key->client_g, - GCRYMPI_FMT_USG, data_g, &_n_g) != 0) { + GCRYMPI_FMT_USG, data_g, &_n_g) != 0 || state->gnutls_key->client_g==NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } if (gcry_mpi_scan(&state->gnutls_key->client_p, - GCRYMPI_FMT_USG, data_p, &_n_p) != 0) { + GCRYMPI_FMT_USG, data_p, &_n_p) != 0 || state->gnutls_key->client_p==NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } @@ -251,12 +255,17 @@ int proc_anon_client_kx( GNUTLS_STATE state, opaque* data, int data_size) { _n_Y = n_Y; if (gcry_mpi_scan(&state->gnutls_key->client_Y, - GCRYMPI_FMT_USG, &data[2], &_n_Y)) { + GCRYMPI_FMT_USG, &data[2], &_n_Y) !=0 || state->gnutls_key->client_Y==NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } g = gnutls_get_dh_params(&p, bits); + if (g==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + state->gnutls_key->KEY = gnutls_calc_dh_key( state->gnutls_key->client_Y, state->gnutls_key->dh_secret, p); _gnutls_mpi_release(&state->gnutls_key->client_Y); diff --git a/lib/auth_srp.c b/lib/auth_srp.c index 08fafd9dae..3cb0160a22 100644 --- a/lib/auth_srp.c +++ b/lib/auth_srp.c @@ -71,16 +71,24 @@ int gen_srp_server_hello(GNUTLS_STATE state, opaque ** data) size_t n_g, n_n, n_s; size_t ret; uint8 *data_n, *data_s; - uint8 *data_g; + uint8 *data_g, *username; uint8 pwd_algo; GNUTLS_SRP_PWD_ENTRY *pwd_entry; int err; + if ( state->gnutls_key->auth_info == NULL) + state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(SRP_SERVER_AUTH_INFO_INT)); + if (state->gnutls_key->auth_info == NULL) { - return GNUTLS_E_INSUFICIENT_CRED; + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; } + state->gnutls_key->auth_info_size = sizeof(SRP_SERVER_AUTH_INFO_INT); + + username = ((SRP_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->username; + strcpy( username, state->gnutls_internals.srp_username); - pwd_entry = _gnutls_srp_pwd_read_entry( state->gnutls_key, ((SRP_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->username, &err); + pwd_entry = _gnutls_srp_pwd_read_entry( state->gnutls_key, username, &err); if (pwd_entry == NULL) { if (err==0) @@ -108,11 +116,20 @@ int gen_srp_server_hello(GNUTLS_STATE state, opaque ** data) N = gcry_mpi_alloc_like(pwd_entry->n); V = gcry_mpi_alloc_like(pwd_entry->v); + if (G==NULL || N == NULL || V == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + gcry_mpi_set(G, pwd_entry->g); gcry_mpi_set(N, pwd_entry->n); gcry_mpi_set(V, pwd_entry->v); (*data) = gnutls_malloc(n_n + n_g + pwd_entry->salt_size + 6 + 1); + if ((*data)==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } data_g = (*data); @@ -168,6 +185,10 @@ int gen_srp_server_kx2(GNUTLS_STATE state, opaque ** data) return GNUTLS_E_MPI_PRINT_FAILED; (*data) = gnutls_malloc(n_b + 2); + if ( (*data) == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } /* copy B */ data_b = (*data); @@ -218,18 +239,29 @@ int gen_srp_client_kx0(GNUTLS_STATE state, opaque ** data) return GNUTLS_E_INSUFICIENT_CRED; /* calc A = g^a % N */ + if (G == NULL || N == NULL) { + gnutls_assert(); + return GNUTLS_E_INSUFICIENT_CRED; + } + A = _gnutls_calc_srp_A( &_a, G, N); if (gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &n_a, A)!=0) 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 (gcry_mpi_print(GCRYMPI_FMT_USG, &data_a[2], &n_a, A)!=0) + if (gcry_mpi_print(GCRYMPI_FMT_USG, &data_a[2], &n_a, A)!=0) { + gnutls_free( *data); return GNUTLS_E_MPI_PRINT_FAILED; - + } + WRITEuint16( n_a, data_a); return n_a + 2; @@ -299,12 +331,12 @@ int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size _n_g = n_g; _n_n = n_n; - if (gcry_mpi_scan(&N, GCRYMPI_FMT_USG, data_n, &_n_n) != 0) { + if (gcry_mpi_scan(&N, GCRYMPI_FMT_USG, data_n, &_n_n) != 0 || N == NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } - if (gcry_mpi_scan(&G, GCRYMPI_FMT_USG, data_g, &_n_g) != 0) { + if (gcry_mpi_scan(&G, GCRYMPI_FMT_USG, data_g, &_n_g) != 0 || G == NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } @@ -314,7 +346,7 @@ int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size */ _gnutls_calc_srp_x( username, password, (opaque*)data_s, n_s, pwd_algo, &_n_g, hd); - if (gcry_mpi_scan(&state->gnutls_key->x, GCRYMPI_FMT_USG, hd, &_n_g) != 0) { + if (gcry_mpi_scan(&state->gnutls_key->x, GCRYMPI_FMT_USG, hd, &_n_g) != 0 || state->gnutls_key->x==NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } @@ -329,7 +361,7 @@ int proc_srp_client_kx0(GNUTLS_STATE state, opaque * data, int data_size) _n_A = READuint16( &data[0]); - if (gcry_mpi_scan(&A, GCRYMPI_FMT_USG, &data[2], &_n_A)) { + if (gcry_mpi_scan(&A, GCRYMPI_FMT_USG, &data[2], &_n_A) || A == NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } @@ -345,7 +377,7 @@ int proc_srp_server_kx2(GNUTLS_STATE state, opaque * data, int data_size) _n_B = READuint16( &data[0]); - if (gcry_mpi_scan(&B, GCRYMPI_FMT_USG, &data[2], &_n_B)) { + if (gcry_mpi_scan(&B, GCRYMPI_FMT_USG, &data[2], &_n_B) || B==NULL) { gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } diff --git a/lib/auth_srp.h b/lib/auth_srp.h index 1f7a597734..9b75981c42 100644 --- a/lib/auth_srp.h +++ b/lib/auth_srp.h @@ -16,7 +16,7 @@ typedef struct { /* these structures should not use allocated data */ typedef struct SRP_SERVER_AUTH_INFO_INT { - char username[256]; + char username[MAX_SRP_USERNAME]; } *SRP_SERVER_AUTH_INFO; int proc_srp_server_hello(GNUTLS_STATE state, const opaque * data, int data_size); diff --git a/lib/auth_srp_passwd.c b/lib/auth_srp_passwd.c index 3f4726ce1b..902c70794d 100644 --- a/lib/auth_srp_passwd.c +++ b/lib/auth_srp_passwd.c @@ -107,7 +107,7 @@ int indx; return GNUTLS_E_PARSING_ERROR; } - if (gcry_mpi_scan(&entry->v, GCRYMPI_FMT_USG, verifier, &verifier_size)) { + if (gcry_mpi_scan(&entry->v, GCRYMPI_FMT_USG, verifier, &verifier_size) || entry->v == NULL) { gnutls_assert(); gnutls_free(entry->salt); return GNUTLS_E_MPI_SCAN_FAILED; @@ -150,7 +150,7 @@ int tmp_size; gnutls_assert(); return GNUTLS_E_PARSING_ERROR; } - if (gcry_mpi_scan(&entry->g, GCRYMPI_FMT_USG, tmp, &tmp_size)) { + if (gcry_mpi_scan(&entry->g, GCRYMPI_FMT_USG, tmp, &tmp_size) || entry->g==NULL) { gnutls_assert(); gnutls_free(tmp); return GNUTLS_E_MPI_SCAN_FAILED; @@ -178,7 +178,7 @@ int tmp_size; mpi_release(entry->g); return GNUTLS_E_PARSING_ERROR; } - if (gcry_mpi_scan(&entry->n, GCRYMPI_FMT_USG, tmp, &tmp_size)) { + if (gcry_mpi_scan(&entry->n, GCRYMPI_FMT_USG, tmp, &tmp_size) || entry->n==NULL) { gnutls_assert(); gnutls_free(tmp); mpi_release(entry->g); @@ -291,7 +291,7 @@ GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry() { gcry_mpi_randomize( pwd_entry->v, 160, GCRY_WEAK_RANDOM); if (gcry_mpi_scan(&pwd_entry->n, GCRYMPI_FMT_USG, - diffie_hellman_group1_prime, &n)) { + diffie_hellman_group1_prime, &n) !=0 || pwd_entry->n==NULL) { gnutls_assert(); return NULL; } diff --git a/lib/ext_srp.c b/lib/ext_srp.c index d4476b19d1..b2d716e3ec 100644 --- a/lib/ext_srp.c +++ b/lib/ext_srp.c @@ -35,33 +35,18 @@ int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_si } if (state->security_parameters.entity == GNUTLS_SERVER) { - /* algorithm was not selected - */ - if ( gnutls_get_auth_info_type( state) != GNUTLS_SRP) - return 0; - if (data_size > 0) { - if ( state->gnutls_key->auth_info == NULL) - state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(SRP_SERVER_AUTH_INFO)); - - if (state->gnutls_key->auth_info==NULL) return GNUTLS_E_MEMORY_ERROR; - - if (sizeof( ((SRP_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->username) > data_size) { - len = data[0]; - if (len > data_size) { - gnutls_assert(); - return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; - } - memcpy( ((SRP_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->username, &data[1], len); - ((SRP_SERVER_AUTH_INFO)state->gnutls_key->auth_info)->username[len]=0; /* null terminated */ - state->gnutls_key->auth_info_size = sizeof(SRP_SERVER_AUTH_INFO_INT); - } else { - state->gnutls_key->auth_info_size = 0; - gnutls_free(state->gnutls_key->auth_info); - state->gnutls_key->auth_info = NULL; + len = data[0]; + if (len > data_size) { + gnutls_assert(); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } + if ( sizeof( state->gnutls_internals.srp_username) <= len) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } + memcpy( state->gnutls_internals.srp_username, &data[1], len); + state->gnutls_internals.srp_username[len]=0; /* null terminated */ } } else { /* client side reading server hello extensions */ if (state->gnutls_internals.resumed==RESUME_FALSE) @@ -98,7 +83,10 @@ int _gnutls_srp_send_params( GNUTLS_STATE state, opaque** data) { /* We only send the packet if we are NOT * resuming AND we are using SRP */ - if (state->security_parameters.kx_algorithm!=GNUTLS_KX_SRP) + + /* note that security parameters are not fully established + */ + if ( _gnutls_cipher_suite_get_kx_algo(state->security_parameters.current_cipher_suite) != GNUTLS_KX_SRP) return 0; /* no data to send */ if (state->gnutls_internals.resumed==RESUME_FALSE) diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c index 228b7c932a..8a2297675a 100644 --- a/lib/gnutls_dh.c +++ b/lib/gnutls_dh.c @@ -287,9 +287,9 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits) n = sizeof diffie_hellman_group1_prime; if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, - diffie_hellman_group1_prime, &n)) { + diffie_hellman_group1_prime, &n) || prime==NULL) { gnutls_assert(); - abort(); + return NULL; } g = gcry_mpi_set_ui(NULL, DH_G_1024); @@ -303,9 +303,9 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits) n = sizeof diffie_hellman_prime_2048; if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, - diffie_hellman_prime_2048, &n)) { + diffie_hellman_prime_2048, &n) || prime==NULL) { gnutls_assert(); - abort(); + return NULL; } g = gcry_mpi_set_ui(NULL, DH_G_2048); @@ -319,9 +319,9 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits) n = sizeof diffie_hellman_prime_3072; if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, - diffie_hellman_prime_3072, &n)) { + diffie_hellman_prime_3072, &n) || prime==NULL) { gnutls_assert(); - abort(); + return NULL; } g = gcry_mpi_set_ui(NULL, DH_G_3072); @@ -335,9 +335,9 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits) n = sizeof diffie_hellman_prime_4096; if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG, - diffie_hellman_prime_4096, &n)) { + diffie_hellman_prime_4096, &n) || prime==NULL) { gnutls_assert(); - abort(); + return NULL; } g = gcry_mpi_set_ui(NULL, DH_G_4096); @@ -349,7 +349,7 @@ MPI gnutls_get_dh_params(MPI * ret_p, int bits) return g; default: gnutls_assert(); - abort(); + return NULL; } } diff --git a/lib/gnutls_extensions.c b/lib/gnutls_extensions.c index 28d3f656ed..78f263b5b6 100644 --- a/lib/gnutls_extensions.c +++ b/lib/gnutls_extensions.c @@ -79,7 +79,7 @@ const char *_gnutls_extension_get_name(int type) } int _gnutls_parse_extensions( GNUTLS_STATE state, const opaque* data, int data_size) { -int next; +int next, ret; int pos=0; uint8 type; const opaque* sdata; @@ -109,7 +109,10 @@ uint16 size; ext_func_recv = _gnutls_ext_func_recv(type); if (ext_func_recv == NULL) continue; - ext_func_recv( state, sdata, size); + if ( (ret=ext_func_recv( state, sdata, size)) < 0) { + gnutls_assert(); + return ret; + } } while(next > 2); diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 307c740284..8cafba52b4 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -1105,6 +1105,10 @@ static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state) { datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE; data = gnutls_malloc(datalen); + if (data==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } data[pos++] = _gnutls_version_get_major(state->connection_state.version); @@ -1136,6 +1140,10 @@ static int _gnutls_send_server_hello(SOCKET cd, GNUTLS_STATE state) { datalen += 1; data = gnutls_realloc(data, datalen); + if (data==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } comp = (uint8) _gnutls_compression_get_num(state->gnutls_internals. diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index c3960eb335..4937f8fc45 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -48,6 +48,7 @@ #define MAX_X509_CERT_SIZE 10*1024 #define MAX_LOG_SIZE 1024 /* maximum number of log message */ +#define MAX_SRP_USERNAME 256 #define MAX_DNSNAME_SIZE 256 @@ -349,6 +350,9 @@ typedef struct { */ int send_cert_req; int peer_pk_algorithm; + /* holds the username got in the srp tls extension + */ + opaque srp_username[MAX_SRP_USERNAME]; } GNUTLS_INTERNALS; struct GNUTLS_STATE_INT { diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index b26d9432c0..dd34815937 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -65,7 +65,7 @@ int _gnutls_pkcs1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum cert) { return GNUTLS_E_ASN1_PARSING_ERROR; } if (gcry_mpi_scan( &pkey->params[0], /* u */ - GCRYMPI_FMT_USG, str, &len) != 0) { + GCRYMPI_FMT_USG, str, &len) != 0 || pkey->params[0]==NULL) { gnutls_assert(); asn1_delete_structure(pkcs_asn); return GNUTLS_E_MPI_SCAN_FAILED; @@ -83,7 +83,7 @@ int _gnutls_pkcs1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum cert) { } if (gcry_mpi_scan( &pkey->params[1], /* A */ - GCRYMPI_FMT_USG, str, &len) != 0) { + GCRYMPI_FMT_USG, str, &len) != 0 || pkey->params[1] == NULL) { gnutls_assert(); asn1_delete_structure(pkcs_asn); _gnutls_mpi_release( &pkey->params[0]); @@ -177,7 +177,8 @@ int main(int argc, char** argv) gnutls_set_protocol_priority( state, GNUTLS_TLS1, GNUTLS_SSL3, 0); gnutls_set_cipher_priority( state, GNUTLS_ARCFOUR, GNUTLS_3DES_CBC, GNUTLS_RIJNDAEL_CBC, 0); gnutls_set_compression_priority( state, GNUTLS_ZLIB, GNUTLS_NULL_COMPRESSION, 0); - gnutls_set_kx_priority( state, GNUTLS_KX_RSA, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0); +// gnutls_set_kx_priority( state, GNUTLS_KX_RSA, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0); + gnutls_set_kx_priority( state, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0); gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0); gnutls_set_cred( state, GNUTLS_ANON, NULL); |