summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2000-10-07 15:53:16 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2000-10-07 15:53:16 +0000
commitcc6c053db8fa459a5f183b3090afa544f06aa44e (patch)
tree56bffbe1fb2e1ce47ddb1d0af48ef72f1a679983
parent88fb7db5d745bca0bf6fec04f1915ce568aaacd2 (diff)
downloadgnutls-cc6c053db8fa459a5f183b3090afa544f06aa44e.tar.gz
Added some kind of priorities for algorithms. Still experimental.
-rw-r--r--lib/gnutls.c4
-rw-r--r--lib/gnutls_algorithms.c297
-rw-r--r--lib/gnutls_algorithms.h14
-rw-r--r--lib/gnutls_cipher.c10
-rw-r--r--lib/gnutls_errors.c46
-rw-r--r--lib/gnutls_errors.h44
-rw-r--r--lib/gnutls_handshake.c38
-rw-r--r--lib/gnutls_handshake.h1
-rw-r--r--lib/gnutls_int.h6
-rw-r--r--lib/gnutls_kx.c10
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);