]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added some kind of priorities for algorithms. Still experimental.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 7 Oct 2000 15:53:16 +0000 (15:53 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 7 Oct 2000 15:53:16 +0000 (15:53 +0000)
lib/gnutls.c
lib/gnutls_algorithms.c
lib/gnutls_algorithms.h
lib/gnutls_cipher.c
lib/gnutls_errors.c
lib/gnutls_errors.h
lib/gnutls_handshake.c
lib/gnutls_handshake.h
lib/gnutls_int.h
lib/gnutls_kx.c

index 6aec640994c586748081185d273024551be57a5e..add847f1a6a701d7a7c477bd7b9dc0ae9db9071a 100644 (file)
@@ -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;
 }
 
 
index 8fbdbb31255b9ce8b399d8097ddb3d02fdbb2d67..a4d2cffd40c3b8443188706b22870bbd9ad8485e 100644 (file)
@@ -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;
+}
index 49f5f70b5699e43d2e5cea3effaca2f31883e638..1307b35cace4a83516ef84eacf988051b8e0ed86 100644 (file)
@@ -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[] = {
 
 
 
+*/
index c824148d1aefc600561515ed60ee8b3986439722..1c4c012163371cf8df6821a44696e99ef7064e44 100644 (file)
@@ -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;
index 9f154d2f8acd7680848237d4c0ef26b39206dcc5..f75a8bb786c7d1b5a5483d645c6728ce16c6e358 100644 (file)
 
 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;
index 673a199b60ad5443ca211cecc9e5aa362f2db2cd..47ecde51338ce44d1d660c71696034b9833275b5 100644 (file)
 #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);
index 967be1722bc6a9b8174b3065d3d96a06025e49cc..cf35f8d5b5585ac93435d8a99bf5290d4f671b9d 100644 (file)
@@ -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);
index b960cb8d2f724a18b8f0eeefd146a55538eab877..93d88518285f46743573a7e0f47234e2e032efdb 100644 (file)
@@ -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);
index 7592a3d1d3aa734d3104207e5a392c1afdf90112..ff3fa507f4869bd321c87c80ca1a42d07550c47d 100644 (file)
@@ -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 };
index a8802bbbc661debdb82cd24bf4d6a06676f2403d..460ed4b29aa1555153ab58e3d5e358d2db7f9272 100644 (file)
@@ -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);