diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2000-10-07 15:53:16 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2000-10-07 15:53:16 +0000 |
commit | cc6c053db8fa459a5f183b3090afa544f06aa44e (patch) | |
tree | 56bffbe1fb2e1ce47ddb1d0af48ef72f1a679983 | |
parent | 88fb7db5d745bca0bf6fec04f1915ce568aaacd2 (diff) | |
download | gnutls-cc6c053db8fa459a5f183b3090afa544f06aa44e.tar.gz |
Added some kind of priorities for algorithms. Still experimental.
-rw-r--r-- | lib/gnutls.c | 4 | ||||
-rw-r--r-- | lib/gnutls_algorithms.c | 297 | ||||
-rw-r--r-- | lib/gnutls_algorithms.h | 14 | ||||
-rw-r--r-- | lib/gnutls_cipher.c | 10 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 46 | ||||
-rw-r--r-- | lib/gnutls_errors.h | 44 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 38 | ||||
-rw-r--r-- | lib/gnutls_handshake.h | 1 | ||||
-rw-r--r-- | lib/gnutls_int.h | 6 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 10 |
10 files changed, 352 insertions, 118 deletions
diff --git a/lib/gnutls.c b/lib/gnutls.c index 6aec640994..add847f1a6 100644 --- a/lib/gnutls.c +++ b/lib/gnutls.c @@ -77,7 +77,7 @@ int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end) (*state)->gnutls_internals.client_g = NULL; (*state)->gnutls_internals.dh_secret = NULL; - + return 0; } int gnutls_deinit(GNUTLS_STATE * state) @@ -111,7 +111,7 @@ int gnutls_deinit(GNUTLS_STATE * state) mpi_release((*state)->gnutls_internals.dh_secret); gnutls_free(*state); - + return 0; } diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index 8fbdbb3125..a4d2cffd40 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -22,8 +22,8 @@ #include "gnutls_int.h" #include "gnutls_algorithms.h" -#define GNUTLS_CIPHER_ENTRY(name, blksize, keysize, block, iv) \ - { #name, name, blksize, keysize, block, iv } +#define GNUTLS_CIPHER_ENTRY(name, blksize, keysize, block, iv, priority) \ + { #name, name, blksize, keysize, block, iv, priority } struct gnutls_cipher_entry { char *name; @@ -32,12 +32,14 @@ struct gnutls_cipher_entry { size_t keysize; size_t block; size_t iv; + int priority; }; typedef struct gnutls_cipher_entry gnutls_cipher_entry; static gnutls_cipher_entry algorithms[] = { - GNUTLS_CIPHER_ENTRY(GNUTLS_3DES, 8, 24, 1, 8), - GNUTLS_CIPHER_ENTRY(GNUTLS_NULL, 1, 0, 0, 0), + GNUTLS_CIPHER_ENTRY(GNUTLS_3DES, 8, 24, 1, 8, 10), + GNUTLS_CIPHER_ENTRY(GNUTLS_ARCFOUR, 1, 16, 0, 0, -1), + GNUTLS_CIPHER_ENTRY(GNUTLS_NULL, 1, 0, 0, 0, -1), {0} }; @@ -49,20 +51,21 @@ static gnutls_cipher_entry algorithms[] = { GNUTLS_LOOP( if(p->id == algorithm) { a; break; } ) -#define GNUTLS_HASH_ENTRY(name, hashsize) \ - { #name, name, hashsize } +#define GNUTLS_HASH_ENTRY(name, hashsize, priority) \ + { #name, name, hashsize, priority } struct gnutls_hash_entry { char *name; MACAlgorithm id; size_t digestsize; + int priority; }; typedef struct gnutls_hash_entry gnutls_hash_entry; static gnutls_hash_entry hash_algorithms[] = { - GNUTLS_HASH_ENTRY(GNUTLS_MAC_SHA, 20), - GNUTLS_HASH_ENTRY(GNUTLS_MAC_MD5, 16), - GNUTLS_HASH_ENTRY(GNUTLS_MAC_NULL, 0), + GNUTLS_HASH_ENTRY(GNUTLS_MAC_SHA, 20, 20), + GNUTLS_HASH_ENTRY(GNUTLS_MAC_MD5, 16, 10), + GNUTLS_HASH_ENTRY(GNUTLS_MAC_NULL, 0, -1), {0} }; @@ -76,8 +79,8 @@ static gnutls_hash_entry hash_algorithms[] = { -#define GNUTLS_KX_ALGO_ENTRY(name, server_cert, server_kx, client_cert, RSA_premaster, DH_public_value) \ - { #name, name, server_cert, server_kx, client_cert, RSA_premaster, DH_public_value } +#define GNUTLS_KX_ALGO_ENTRY(name, server_cert, server_kx, client_cert, RSA_premaster, DH_public_value, priority) \ + { #name, name, server_cert, server_kx, client_cert, RSA_premaster, DH_public_value, priority } struct gnutls_kx_algo_entry { char *name; @@ -87,16 +90,17 @@ struct gnutls_kx_algo_entry { int client_cert; int RSA_premaster; int DH_public_value; + int priority; }; typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry; static gnutls_kx_algo_entry kx_algorithms[] = { - GNUTLS_KX_ALGO_ENTRY( KX_ANON_DH, 0, 1, 0, 0, 1), - GNUTLS_KX_ALGO_ENTRY( KX_RSA , 1, 0, 1, 1, 0), - GNUTLS_KX_ALGO_ENTRY( KX_DHE_DSS, 1, 1, 1, 0, 0), - GNUTLS_KX_ALGO_ENTRY( KX_DHE_RSA, 1, 1, 1, 0, 0), - GNUTLS_KX_ALGO_ENTRY( KX_DH_DSS , 1, 0, 1, 0, 0), - GNUTLS_KX_ALGO_ENTRY( KX_DH_RSA , 1, 0, 1, 0, 0), + GNUTLS_KX_ALGO_ENTRY(KX_ANON_DH, 0, 1, 0, 0, 1, 5), + GNUTLS_KX_ALGO_ENTRY(KX_RSA, 1, 0, 1, 1, 0, -1), + GNUTLS_KX_ALGO_ENTRY(KX_DHE_DSS, 1, 1, 1, 0, 0, -1), + GNUTLS_KX_ALGO_ENTRY(KX_DHE_RSA, 1, 1, 1, 0, 0, -1), + GNUTLS_KX_ALGO_ENTRY(KX_DH_DSS, 1, 0, 1, 0, 0, -1), + GNUTLS_KX_ALGO_ENTRY(KX_DH_RSA, 1, 0, 1, 0, 0, -1), {0} }; @@ -109,7 +113,41 @@ static gnutls_kx_algo_entry kx_algorithms[] = { +/* Cipher SUITES */ +#define GNUTLS_CIPHER_SUITE_ENTRY(name, block_algorithm, kx_algorithm, mac_algorithm) \ + { #name, name, block_algorithm, kx_algorithm, mac_algorithm } +typedef struct { + char *name; + GNUTLS_CipherSuite id; + BulkCipherAlgorithm block_algorithm; + KX_Algorithm kx_algorithm; + MACAlgorithm mac_algorithm; +} gnutls_cipher_suite_entry; + +#define GNUTLS_DH_anon_WITH_3DES_EDE_CBC_SHA { 0x00, 0x1B } +#define GNUTLS_DH_anon_WITH_ARCFOUR_MD5 { 0x00, 0x18 } + +static gnutls_cipher_suite_entry cs_algorithms[] = { + GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_DH_anon_WITH_ARCFOUR_MD5, GNUTLS_ARCFOUR, KX_ANON_DH, GNUTLS_MAC_MD5), + GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_DH_anon_WITH_3DES_EDE_CBC_SHA, GNUTLS_3DES, KX_ANON_DH, GNUTLS_MAC_SHA), + {0} +}; + +#define GNUTLS_CIPHER_SUITE_LOOP(b) \ + gnutls_cipher_suite_entry *p; \ + for(p = cs_algorithms; p->name != NULL; p++) { b ; } + +#define GNUTLS_CIPHER_SUITE_ALG_LOOP(a) \ + GNUTLS_CIPHER_SUITE_LOOP( if( memcmp( &p->id, &suite, 2)==0) { a; break; } ) + + + + + +/* Generic Functions */ + +/* this function makes the whole string lowercase */ void tolow(char *str, int size) { int i; @@ -128,13 +166,23 @@ int _gnutls_hash_get_digest_size(MACAlgorithm algorithm) } +int _gnutls_is_hash_selected(MACAlgorithm algorithm) +{ + size_t ret = 0; + GNUTLS_HASH_ALG_LOOP(ret = p->priority); + return ret; + +} + + char *_gnutls_hash_get_name(MACAlgorithm algorithm) { char *ret = NULL; char *pointerTo_; /* avoid prefix */ - GNUTLS_HASH_ALG_LOOP(ret = strdup(p->name + sizeof("GNUTLS_") - 1)); + GNUTLS_HASH_ALG_LOOP(ret = + strdup(p->name + sizeof("GNUTLS_") - 1)); if (ret != NULL) { @@ -149,6 +197,21 @@ char *_gnutls_hash_get_name(MACAlgorithm algorithm) return ret; } +int _gnutls_hash_algo_count() +{ + uint8 i, counter = 0; + char *y; + + for (i = 0; i < 255; i++) { + y = _gnutls_hash_get_name(i); + + if (y != NULL) { + free(y); + counter++; + } + } + return counter; +} int _gnutls_hash_is_ok(MACAlgorithm algorithm) { @@ -165,7 +228,7 @@ int _gnutls_hash_is_ok(MACAlgorithm algorithm) -/* CIPHER */ +/* CIPHER functions */ int _gnutls_cipher_get_block_size(BulkCipherAlgorithm algorithm) { size_t ret = 0; @@ -174,6 +237,15 @@ int _gnutls_cipher_get_block_size(BulkCipherAlgorithm algorithm) } +int _gnutls_is_cipher_selected(BulkCipherAlgorithm algorithm) +{ + size_t ret = 0; + GNUTLS_ALG_LOOP(ret = p->priority); + return ret; + +} + + int _gnutls_cipher_is_block(BulkCipherAlgorithm algorithm) { size_t ret = 0; @@ -220,6 +292,22 @@ char *_gnutls_cipher_get_name(BulkCipherAlgorithm algorithm) return ret; } +int _gnutls_cipher_algo_count() +{ + uint8 i, counter = 0; + char *y; + + for (i = 0; i < 255; i++) { + y = _gnutls_cipher_get_name(i); + + if (y != NULL) { + free(y); + counter++; + } + } + return counter; +} + int _gnutls_cipher_is_ok(BulkCipherAlgorithm algorithm) { @@ -235,7 +323,7 @@ int _gnutls_cipher_is_ok(BulkCipherAlgorithm algorithm) } -/* Key EXCHANGE */ +/* Key EXCHANGE functions */ int _gnutls_kx_algo_server_certificate(KX_Algorithm algorithm) { size_t ret = 0; @@ -244,6 +332,14 @@ int _gnutls_kx_algo_server_certificate(KX_Algorithm algorithm) } +int _gnutls_is_kx_algo_selected(KX_Algorithm algorithm) +{ + size_t ret = 0; + GNUTLS_KX_ALG_LOOP(ret = p->priority); + return ret; + +} + int _gnutls_kx_algo_server_key_exchange(KX_Algorithm algorithm) { size_t ret = 0; @@ -298,6 +394,22 @@ char *_gnutls_kx_algo_get_name(KX_Algorithm algorithm) return ret; } +int _gnutls_kx_algo_count() +{ + uint8 i, counter = 0; + char *y; + + for (i = 0; i < 255; i++) { + y = _gnutls_kx_algo_get_name(i); + + if (y != NULL) { + free(y); + counter++; + } + } + return counter; +} + int _gnutls_kx_algo_is_ok(KX_Algorithm algorithm) { @@ -312,15 +424,16 @@ int _gnutls_kx_algo_is_ok(KX_Algorithm algorithm) } -/* Cipher Suites */ -BulkCipherAlgorithm _gnutls_cipher_suite_get_cipher_algo(GNUTLS_CipherSuite suite) +/* Cipher Suite's functions */ +BulkCipherAlgorithm _gnutls_cipher_suite_get_cipher_algo(const GNUTLS_CipherSuite + suite) { size_t ret = 0; - GNUTLS_CIPHER_SUITE_ALG_LOOP(ret = p->cipher_algorithm); + GNUTLS_CIPHER_SUITE_ALG_LOOP(ret = p->block_algorithm); return ret; } -KX_Algorithm _gnutls_cipher_suite_get_kx_algo(GNUTLS_CipherSuite suite) +KX_Algorithm _gnutls_cipher_suite_get_kx_algo(const GNUTLS_CipherSuite suite) { size_t ret = 0; @@ -329,7 +442,7 @@ KX_Algorithm _gnutls_cipher_suite_get_kx_algo(GNUTLS_CipherSuite suite) } -MACAlgorithm _gnutls_cipher_suite_get_mac_algo(GNUTLS_CipherSuite suite) +MACAlgorithm _gnutls_cipher_suite_get_mac_algo(const GNUTLS_CipherSuite suite) { /* In bytes */ size_t ret = 0; GNUTLS_CIPHER_SUITE_ALG_LOOP(ret = p->mac_algorithm); @@ -343,7 +456,9 @@ char *_gnutls_cipher_suite_get_name(GNUTLS_CipherSuite suite) char *pointerTo_; /* avoid prefix */ - GNUTLS_CIPHER_SUITE_ALG_LOOP(ret = strdup(p->name + sizeof("GNUTLS_") - 1)); + GNUTLS_CIPHER_SUITE_ALG_LOOP(ret = + strdup(p->name + sizeof("GNUTLS_") - + 1)); if (ret != NULL) { @@ -374,12 +489,12 @@ int _gnutls_cipher_suite_is_ok(GNUTLS_CipherSuite suite) int _gnutls_cipher_suite_count() { -GNUTLS_CipherSuite suite; -uint8 i, counter=0; -char* y; - suite.CipherSuite[0] = 0x00; - - for (i=0;i<255;i++) { + GNUTLS_CipherSuite suite; + uint8 i, counter = 0; + char *y; + suite.CipherSuite[0] = 0x00; /* FIXME */ + + for (i = 0; i < 255; i++) { suite.CipherSuite[1] = i; y = _gnutls_cipher_suite_get_name(suite); @@ -392,3 +507,121 @@ char* y; return counter; } +/* a compare function for hash(mac) algorithms (using priorities). For use with qsort */ +int _gnutls_compare_mac_algo(const void* i_A1, const void* i_A2) +{ + MACAlgorithm A1 = _gnutls_cipher_suite_get_mac_algo( *(GNUTLS_CipherSuite*)i_A1); + MACAlgorithm A2 = _gnutls_cipher_suite_get_mac_algo( *(GNUTLS_CipherSuite*)i_A2); + int p1 = _gnutls_is_hash_selected(A1); + int p2 = _gnutls_is_hash_selected(A2); + + if (p1 > p2) { + return -1; + } else { + if (p1 == p2) { + /* compare the addresses */ + /* since it is in a list... if A1 is before A2 then it is greater */ + if ( (int)A1 < (int)A2) return 1; else return -1; + } + return 1; + } +} + + +/* a compare function for block algorithms (using priorities). For use with qsort */ +int _gnutls_compare_cipher_algo(const void* i_A1, const void* i_A2) +{ + BulkCipherAlgorithm A1 = _gnutls_cipher_suite_get_cipher_algo( *(GNUTLS_CipherSuite*)i_A1); + BulkCipherAlgorithm A2 = _gnutls_cipher_suite_get_cipher_algo( *(GNUTLS_CipherSuite*)i_A2); + int p1 = _gnutls_is_cipher_selected(A1); + int p2 = _gnutls_is_cipher_selected(A2); + + if (p1 > p2) { + return -1; /* we actually want descending order */ + } else { + if (p1 == p2) { + /* compare the addresses */ + /* since it is in a list... if A1 is before A2 then it is greater */ + if ( (int)A1 < (int)A2) return 1; else return -1; + } + return 1; + } +} + + +/* a compare function for KX algorithms (using priorities). For use with qsort */ +int _gnutls_compare_kx_algo(const void* i_A1, const void* i_A2) +{ + KX_Algorithm A1 = _gnutls_cipher_suite_get_kx_algo(*(GNUTLS_CipherSuite*)i_A1); + KX_Algorithm A2 = _gnutls_cipher_suite_get_kx_algo(*(GNUTLS_CipherSuite*)i_A2); + int p1 = _gnutls_is_kx_algo_selected(A1); + int p2 = _gnutls_is_kx_algo_selected(A2); + + if (p1 > p2) { + return -1; + } else { + if (p1 == p2) { + /* compare the addresses */ + /* since it is in a list... if A1 is before A2 then it is greater */ + if ( (int)A1 < (int)A2) return 1; else return -1; + } + return 1; + } +} + +int _gnutls_supported_ciphersuites(GNUTLS_CipherSuite ** ciphers) +{ + + int i, ret_count; + int count = _gnutls_cipher_suite_count(); + GNUTLS_CipherSuite *tmp_ciphers; + + if (count == 0) { + *ciphers = NULL; + return 0; + } + + tmp_ciphers = gnutls_malloc(count * sizeof(GNUTLS_CipherSuite)); + *ciphers = gnutls_malloc(count * sizeof(GNUTLS_CipherSuite)); + + + for (i = 0; i < count; i++) { + tmp_ciphers[i].CipherSuite[0] = + cs_algorithms[i].id.CipherSuite[0]; + tmp_ciphers[i].CipherSuite[1] = + cs_algorithms[i].id.CipherSuite[1]; + } + +/* First sort using MAC priority (lowest) */ + qsort(tmp_ciphers, count, sizeof(GNUTLS_CipherSuite), _gnutls_compare_mac_algo); + +/* then sort using block algorithm's priorities */ + qsort(tmp_ciphers, count, sizeof(GNUTLS_CipherSuite), _gnutls_compare_cipher_algo); + +/* Last try KX algorithms priority */ + qsort(tmp_ciphers, count, sizeof(GNUTLS_CipherSuite), _gnutls_compare_kx_algo); + + for (i = 0; i < count; i++) { + fprintf(stderr, "**** %s\n", _gnutls_cipher_get_name(_gnutls_cipher_suite_get_cipher_algo(tmp_ciphers[i]))); + if (_gnutls_is_kx_algo_selected( _gnutls_cipher_suite_get_kx_algo(tmp_ciphers[i])) < 0) break; + if (_gnutls_is_hash_selected( _gnutls_cipher_suite_get_mac_algo(tmp_ciphers[i])) < 0) break; + if (_gnutls_is_cipher_selected( _gnutls_cipher_suite_get_cipher_algo(tmp_ciphers[i])) < 0) break; + + (*ciphers)[i].CipherSuite[0] = tmp_ciphers[i].CipherSuite[0]; + (*ciphers)[i].CipherSuite[1] = tmp_ciphers[i].CipherSuite[1]; + } + ret_count=i; + + if (ret_count > 0 && ret_count != count) { + *ciphers = gnutls_realloc(*ciphers, ret_count * sizeof(GNUTLS_CipherSuite)); + } + else { + if (ret_count!=count) { + gnutls_free(*ciphers); + *ciphers=NULL; + } + } + + gnutls_free(tmp_ciphers); + return ret_count; +} diff --git a/lib/gnutls_algorithms.h b/lib/gnutls_algorithms.h index 49f5f70b56..1307b35cac 100644 --- a/lib/gnutls_algorithms.h +++ b/lib/gnutls_algorithms.h @@ -1,16 +1,18 @@ int _gnutls_hash_get_digest_size(MACAlgorithm algorithm); char *_gnutls_hash_get_name(MACAlgorithm algorithm); int _gnutls_hash_is_ok(MACAlgorithm algorithm); +int _gnutls_is_hash_selected(MACAlgorithm algorithm); int _gnutls_cipher_suite_is_ok(GNUTLS_CipherSuite algorithm); +int _gnutls_supported_ciphersuites(GNUTLS_CipherSuite **ciphers); int _gnutls_cipher_suite_count(); char *_gnutls_cipher_suite_get_name(GNUTLS_CipherSuite algorithm); -BulkCipherAlgorithm _gnutls_cipher_suite_get_cipher_algo(GNUTLS_CipherSuite algorithm); -KX_Algorithm _gnutls_cipher_suite_get_kx_algo(GNUTLS_CipherSuite algorithm); -MACAlgorithm _gnutls_cipher_suite_get_mac_algo(GNUTLS_CipherSuite algorithm); +BulkCipherAlgorithm _gnutls_cipher_suite_get_cipher_algo(const GNUTLS_CipherSuite algorithm); +KX_Algorithm _gnutls_cipher_suite_get_kx_algo(const GNUTLS_CipherSuite algorithm); +MACAlgorithm _gnutls_cipher_suite_get_mac_algo(const GNUTLS_CipherSuite algorithm); GNUTLS_CipherSuite _gnutls_cipher_suite_get_suite_name(GNUTLS_CipherSuite algorithm); - +int _gnutls_is_cipher_selected(BulkCipherAlgorithm algorithm); int _gnutls_cipher_get_block_size(BulkCipherAlgorithm algorithm); int _gnutls_cipher_is_block(BulkCipherAlgorithm algorithm); int _gnutls_cipher_is_ok(BulkCipherAlgorithm algorithm); @@ -18,7 +20,7 @@ int _gnutls_cipher_get_key_size(BulkCipherAlgorithm algorithm); int _gnutls_cipher_get_iv_size(BulkCipherAlgorithm algorithm); char *_gnutls_cipher_get_name(BulkCipherAlgorithm algorithm); - +int _gnutls_is_kx_algo_selected(KX_Algorithm algorithm); int _gnutls_kx_algo_server_certificate(KX_Algorithm algorithm); int _gnutls_kx_algo_server_key_exchange(KX_Algorithm algorithm); int _gnutls_kx_algo_client_certificate(KX_Algorithm algorithm); @@ -28,6 +30,7 @@ char *_gnutls_kx_algo_get_name(KX_Algorithm algorithm); int _gnutls_kx_algo_is_ok(KX_Algorithm algorithm); +/* #define GNUTLS_CIPHER_SUITE_ENTRY(suite, kx_algorithm, cipher_algorithm, mac_algorithm) \ { #suite, suite, kx_algorithm, cipher_algorithm, mac_algorithm } @@ -57,3 +60,4 @@ static gnutls_cipher_suite_entry cipher_suite_algorithms[] = { +*/ diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index c824148d1a..1c4c012163 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000 Nikos Mavroyanopoulos + * Copyright (C) 2000 Nikos Mavroyanopoulos * * This file is part of GNUTLS. * @@ -42,6 +42,8 @@ int _gnutls_set_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo) { if (_gnutls_cipher_is_ok(algo) == 0) { + if (_gnutls_is_cipher_selected(algo) < 0) return GNUTLS_E_UNWANTED_ALGORITHM; + state->security_parameters.bulk_cipher_algorithm = algo; if (_gnutls_cipher_is_block(algo) == 1) { state->security_parameters.cipher_type = @@ -89,7 +91,7 @@ int _gnutls_set_mac(GNUTLS_STATE state, MACAlgorithm algo) } else { return GNUTLS_E_UNKNOWN_MAC_ALGORITHM; } - + if (_gnutls_is_hash_selected(algo) < 0) return GNUTLS_E_UNWANTED_ALGORITHM; state->security_parameters.hash_size = _gnutls_hash_get_digest_size(algo); return 0; @@ -294,7 +296,7 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, GNUTLSCompressed * compressed) { GNUTLSCiphertext *ciphertext; - uint8 *padding, *content, *MAC; + uint8 *padding, *content, *MAC=NULL; uint16 c_length; uint8 *data; uint8 pad; @@ -464,7 +466,7 @@ int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state, GNUTLSCiphertext * ciphertext) { GNUTLSCompressed *compressed; - uint8 *content, *MAC; + uint8 *content, *MAC=NULL; uint16 c_length; uint8 *data; uint8 pad; diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index 9f154d2f8a..f75a8bb786 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -23,6 +23,52 @@ void tolow(char *str, int size); +#define GNUTLS_ERROR_ENTRY(name, fatal) \ + { #name, name, fatal } + +struct gnutls_error_entry { + char *name; + int number; + int fatal; +}; +typedef struct gnutls_error_entry gnutls_error_entry; + +static gnutls_error_entry error_algorithms[] = { + GNUTLS_ERROR_ENTRY( GNUTLS_E_MAC_FAILED, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER_SUITE, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_MAC_ALGORITHM, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_ERROR, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER_TYPE, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNWANTED_ALGORITHM, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_LARGE_PACKET, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNSUPPORTED_VERSION_PACKET, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_PACKET_LENGTH, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_INVALID_SESSION, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNABLE_SEND_DATA, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_FATAL_ALERT_RECEIVED ,1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_RECEIVED_BAD_MESSAGE, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_RECEIVED_MORE_DATA, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_PACKET, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_WARNING_ALERT_RECEIVED, 0), + GNUTLS_ERROR_ENTRY( GNUTLS_E_CLOSURE_ALERT_RECEIVED, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_ERROR_IN_FINISHED_PACKET, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_KX_ALGORITHM, 1), + GNUTLS_ERROR_ENTRY( GNUTLS_E_UNIMPLEMENTED_FEATURE, 1), + {0} +}; + +#define GNUTLS_ERROR_LOOP(b) \ + gnutls_error_entry *p; \ + for(p = error_algorithms; p->name != NULL; p++) { b ; } + +#define GNUTLS_ERROR_ALG_LOOP(a) \ + GNUTLS_ERROR_LOOP( if(p->number == error) { a; break; } ) + + + int gnutls_is_fatal_error(int error) { int ret = 0; diff --git a/lib/gnutls_errors.h b/lib/gnutls_errors.h index 673a199b60..47ecde5133 100644 --- a/lib/gnutls_errors.h +++ b/lib/gnutls_errors.h @@ -19,52 +19,10 @@ #define GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET -19 #define GNUTLS_E_UNKNOWN_KX_ALGORITHM -20 #define GNUTLS_E_UNKNOWN_CIPHER_SUITE -21 +#define GNUTLS_E_UNWANTED_ALGORITHM -22 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -50 -#define GNUTLS_ERROR_ENTRY(name, fatal) \ - { #name, name, fatal } - -struct gnutls_error_entry { - char *name; - int number; - int fatal; -}; -typedef struct gnutls_error_entry gnutls_error_entry; - -static gnutls_error_entry error_algorithms[] = { - GNUTLS_ERROR_ENTRY( GNUTLS_E_MAC_FAILED, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER_SUITE, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_MAC_ALGORITHM, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_ERROR, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER_TYPE, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_LARGE_PACKET, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNSUPPORTED_VERSION_PACKET, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_PACKET_LENGTH, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_INVALID_SESSION, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNABLE_SEND_DATA, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_FATAL_ALERT_RECEIVED ,1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_RECEIVED_BAD_MESSAGE, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_RECEIVED_MORE_DATA, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_PACKET, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_WARNING_ALERT_RECEIVED, 0), - GNUTLS_ERROR_ENTRY( GNUTLS_E_CLOSURE_ALERT_RECEIVED, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_ERROR_IN_FINISHED_PACKET, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_KX_ALGORITHM, 1), - GNUTLS_ERROR_ENTRY( GNUTLS_E_UNIMPLEMENTED_FEATURE, 1), - {0} -}; - -#define GNUTLS_ERROR_LOOP(b) \ - gnutls_error_entry *p; \ - for(p = error_algorithms; p->name != NULL; p++) { b ; } - -#define GNUTLS_ERROR_ALG_LOOP(a) \ - GNUTLS_ERROR_LOOP( if(p->number == error) { a; break; } ) - void gnutls_perror(int error); diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index 967be1722b..cf35f8d5b5 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -52,7 +52,7 @@ int _gnutls_send_finished(int cd, GNUTLS_STATE state) memset(concat, 0, 36); - if (state->security_parameters.entity == GNUTLS_CLIENT) { + if (state->security_parameters.entity == GNUTLS_CLIENT) { /* we are a CLIENT */ memmove(concat, state->gnutls_internals.client_md_md5, 16); memmove(&concat[16], state->gnutls_internals.client_md_sha1, 20); @@ -133,12 +133,21 @@ int SelectSuite(opaque ret[2], char *data, int datalen) GNUTLS_CipherSuite *ciphers; x = _gnutls_supported_ciphersuites(&ciphers); +#ifdef HARD_DEBUG + fprintf(stderr, "Requested cipher suites: \n"); + for (j=0;j<datalen;j+=2) fprintf(stderr, "\t%s\n", _gnutls_cipher_suite_get_name( *((GNUTLS_CipherSuite*)&data[j]) )); + fprintf(stderr, "Supported cipher suites: \n"); + for (j=0;j<x;j++) fprintf(stderr, "\t%s\n", _gnutls_cipher_suite_get_name(ciphers[j])); +#endif memset(ret, '\0', sizeof(GNUTLS_CipherSuite)); for (j = 0; j < datalen; j += 2) { for (i = 0; i < x; i++) { - if (memcmp(&ciphers[i].CipherSuite, &data[j], 2) == - 0) { + if (memcmp(&ciphers[i].CipherSuite, &data[j], 2) == 0) { +#ifdef HARD_DEBUG + fprintf(stderr, "Selected cipher suite: "); + fprintf(stderr, "%s\n", _gnutls_cipher_suite_get_name( *((GNUTLS_CipherSuite*)&data[j]) )); +#endif memmove(ret, &ciphers[i].CipherSuite, 2); gnutls_free(ciphers); @@ -178,25 +187,6 @@ int SelectCompMethod(CompressionMethod * ret, char *data, int datalen) } -int _gnutls_supported_ciphersuites(GNUTLS_CipherSuite ** ciphers) -{ - - int i; - int count = _gnutls_cipher_suite_count(); - *ciphers = gnutls_malloc(count * sizeof(GNUTLS_CipherSuite)); - - - for (i = 0; i < count; i++) { - - (*ciphers)[i].CipherSuite[0] = - cipher_suite_algorithms[i].suite.CipherSuite[0]; - (*ciphers)[i].CipherSuite[1] = - cipher_suite_algorithms[i].suite.CipherSuite[1]; - } - - return count; -} - #define SUPPORTED_COMPRESSION_METHODS 1 int _gnutls_supported_compression_methods(CompressionMethod ** comp) @@ -500,7 +490,6 @@ int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char *data, int datalen, opaque ** SessionID, int SessionIDnum) { uint8 session_id_len = 0, z; - uint32 cur_time; int pos = 0; GNUTLS_CipherSuite cipher_suite, *cipher_suites; CompressionMethod compression_method, *compression_methods; @@ -637,6 +626,9 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) char *session_id; uint8 session_id_size; + /* These are in order to hash the messages transmitted and received. + * (needed by the protocol) + */ state->gnutls_internals.client_td_md5 = mhash_init(MHASH_MD5); state->gnutls_internals.client_td_sha1 = mhash_init(MHASH_SHA1); state->gnutls_internals.server_td_md5 = mhash_init(MHASH_MD5); diff --git a/lib/gnutls_handshake.h b/lib/gnutls_handshake.h index b960cb8d2f..93d8851828 100644 --- a/lib/gnutls_handshake.h +++ b/lib/gnutls_handshake.h @@ -1,4 +1,3 @@ -int _gnutls_supported_ciphersuites(GNUTLS_CipherSuite **ciphers); int _gnutls_supported_compression_methods(CompressionMethod **comp); int _gnutls_send_handshake(int cd, GNUTLS_STATE state, void* i_data, uint32 i_datasize, HandshakeType type); int _gnutls_send_hello_request(int cd, GNUTLS_STATE state); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 7592a3d1d3..ff3fa507f4 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -1,8 +1,8 @@ #include <gcrypt.h> #include <mhash.h> -#undef HARD_DEBUG -#undef DEBUG +#define HARD_DEBUG +#define DEBUG #define svoid void /* for functions that allocate using secure_free */ #define secure_free(x) if (x!=NULL) free(x) @@ -69,7 +69,7 @@ typedef struct { /* STATE */ enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT }; -enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_3DES = 4 }; +enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_3DES = 4 }; enum KX_Algorithm { KX_RSA, KX_DHE_DSS, KX_DHE_RSA, KX_DH_DSS, KX_DH_RSA, KX_ANON_DH }; enum KeyExchangeAlgorithm { GNUTLS_RSA, GNUTLS_DIFFIE_HELLMAN }; enum CipherType { CIPHER_STREAM, CIPHER_BLOCK }; diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index a8802bbbc6..460ed4b29a 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000 Nikos Mavroyanopoulos + * Copyright (C) 2000 Nikos Mavroyanopoulos * * This file is part of GNUTLS. * @@ -126,8 +126,8 @@ int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state) uint16 _n_X; uint8 *data; int ret=0; - uint8 *premaster; - int premaster_size; + uint8 *premaster=NULL; + int premaster_size=0; svoid* master; char* random = gnutls_malloc(64); @@ -288,8 +288,8 @@ int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state) uint8 *data; int datasize; int ret=0; - uint8 *premaster; - int premaster_size; + uint8 *premaster=NULL; + int premaster_size=0; svoid* master; uint8* random = gnutls_malloc(64); |