]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
several cleanups in order to support ssl3
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 15 Nov 2000 18:18:22 +0000 (18:18 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Wed, 15 Nov 2000 18:18:22 +0000 (18:18 +0000)
12 files changed:
configure.in
lib/gnutls.c
lib/gnutls.h
lib/gnutls_algorithms.c
lib/gnutls_algorithms.h
lib/gnutls_cipher.c
lib/gnutls_cipher.h
lib/gnutls_cipher_int.c
lib/gnutls_errors.c
lib/gnutls_errors.h
lib/gnutls_handshake.c
lib/gnutls_int.h

index 9da7f0115f7249bb8abb36a15fab52c538cc4634..9b122f348feff9587e9d067d51860458785a1c05 100644 (file)
@@ -11,7 +11,7 @@ AC_DEFINE_UNQUOTED(T_OS, "$target_os")
 
 GNUTLS_MAJOR_VERSION=0
 GNUTLS_MINOR_VERSION=0
-GNUTLS_MICRO_VERSION=3
+GNUTLS_MICRO_VERSION=4
 GNUTLS_VERSION=$GNUTLS_MAJOR_VERSION.$GNUTLS_MINOR_VERSION.$GNUTLS_MICRO_VERSION
 
 
@@ -27,7 +27,7 @@ AM_PATH_GCRYPT(1.1.1a,,
        AC_MSG_ERROR([[
 ***  
 *** libgcrypt was not found. You may want to get it from
-*** ftp://ftp.gnupg.org/gcrypt/devel/
+*** ftp://ftp.gnupg.org/pub/gcrypt/alpha/gnupg/
 ***
 ]]))
 
index df95fd1a67bd739d9d6d46144a0275794ecd5e12..d370b59df40a9e20448762a33d21cd04278883ec 100644 (file)
 #include "gnutls_hash_int.h"
 #include "gnutls_cipher_int.h"
 
-/* This function should check if we support the version of the peer.
- * However now we only support version 3.1 
- */
-int _gnutls_valid_version(GNUTLS_STATE state, int major, int minor)
-{
-GNUTLS_Version ver = {0, major, minor};
-
-       if (_gnutls_version_is_supported(ver) > 0 ) {
-               return 0; /* supported */
-       }
-       return 1;
-}
-
 GNUTLS_Version gnutls_get_current_version(GNUTLS_STATE state) {
 GNUTLS_Version ver;
        ver.local = state->connection_state.version.local;
@@ -337,15 +324,17 @@ int gnutls_close_nowait(int cd, GNUTLS_STATE state)
  * send (if called by the user the Content is specific)
  * It is intended to transfer data, under the current state.    
  */
-ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char *data, size_t sizeofdata)
+#define MAX_ENC_LEN 16384
+ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, void *_data, size_t sizeofdata)
 {
-       GNUTLSPlaintext *gtxt;
-       GNUTLSCompressed *gcomp;
-       GNUTLSCiphertext *gcipher;
-       int iterations, i, err;
+       uint8 *cipher;
+       int i, err, cipher_size;
+       int ret = 0;
+       int iterations;
        uint16 length;
-       int ret = 0, Size;
-
+       int Size;
+       uint8 headers[5];
+       uint8 *data=_data;
 
        if (sizeofdata == 0)
                return 0;
@@ -353,148 +342,71 @@ ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char *data
                return GNUTLS_E_INVALID_SESSION;
        }
 
-       if (sizeofdata < 16384) {
+       if (sizeofdata < MAX_ENC_LEN) {
                iterations = 1;
                Size = sizeofdata;
        } else {
-               iterations = sizeofdata / 16384;
-               Size = 16384;
+               iterations = sizeofdata / MAX_ENC_LEN;
+               Size = MAX_ENC_LEN;
        }
 
+       headers[0]=type;
+       headers[1]=state->connection_state.version.major;
+       headers[2]=state->connection_state.version.minor;
+       
        for (i = 0; i < iterations; i++) {
-               err = _gnutls_text2TLSPlaintext(state, type, &gtxt, &data[i * Size], Size);
-               if (err < 0) {
-                       /*gnutls_perror(err); */
-                       return err;
-               }
-
-               err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt);
-               if (err < 0) {
-                       /*gnutls_perror(err); */
-                       return err;
-               }
-
-               _gnutls_freeTLSPlaintext(gtxt);
-
-               err = _gnutls_TLSCompressed2TLSCiphertext(state, &gcipher, gcomp);
-               if (err < 0) {
-                       /*gnutls_perror(err); */
-                       return err;
-               }
-
-               _gnutls_freeTLSCompressed(gcomp);
-
-               if (Write(cd, &gcipher->type, 1) != 1) {
-                       state->gnutls_internals.valid_connection = VALID_FALSE;
-                       state->gnutls_internals.resumable = RESUME_FALSE;
-                       gnutls_assert();
-                       return GNUTLS_E_UNABLE_SEND_DATA;
-               }
-
-               if (Write(cd, &gcipher->version.major, 1) != 1) {
-                       state->gnutls_internals.valid_connection = VALID_FALSE;
-                       state->gnutls_internals.resumable = RESUME_FALSE;
-                       gnutls_assert();
-                       return GNUTLS_E_UNABLE_SEND_DATA;
-               }
-
-               if (Write(cd, &gcipher->version.minor, 1) != 1) {
-                       state->gnutls_internals.valid_connection = VALID_FALSE;
-                       state->gnutls_internals.resumable = RESUME_FALSE;
-                       gnutls_assert();
-                       return GNUTLS_E_UNABLE_SEND_DATA;
-               }
-#ifdef HARD_DEBUG
-               fprintf(stderr, "Send Packet[%d] %s(%d) with length: %d\n",
-                       (int) state->connection_state.write_sequence_number, _gnutls_packet2str(gcipher->type), gcipher->type, gcipher->length);
-#endif
+               cipher_size = _gnutls_encrypt( state, &data[i*Size], Size, &cipher, type);
+               if (cipher_size<=0) return cipher_size;
 #ifdef WORDS_BIGENDIAN
-               length = gcipher->length;
+               length = cipher_size;
 #else
-               length = byteswap16(gcipher->length);
+               length = byteswap16(cipher_size);
 #endif
-               if (Write(cd, &length, sizeof(uint16)) != sizeof(uint16)) {
+               memmove( &headers[3], &length, sizeof(uint16));
+               if (Write(cd, headers, sizeof(headers)) != sizeof(headers)) {
                        state->gnutls_internals.valid_connection = VALID_FALSE;
                        state->gnutls_internals.resumable = RESUME_FALSE;
                        gnutls_assert();
                        return GNUTLS_E_UNABLE_SEND_DATA;
                }
-
-               if (Write(cd, gcipher->fragment, gcipher->length) != gcipher->length) {
+               if (Write(cd, cipher, cipher_size) != cipher_size) {
                        state->gnutls_internals.valid_connection = VALID_FALSE;
                        state->gnutls_internals.resumable = RESUME_FALSE;
                        gnutls_assert();
                        return GNUTLS_E_UNABLE_SEND_DATA;
                }
                state->connection_state.write_sequence_number++;
-               ret += Size;
-
-               _gnutls_freeTLSCiphertext(gcipher);
        }
-       /* rest data */
+               /* rest data */
        if (iterations > 1) {
-               Size = sizeofdata % 16384;
-               err = _gnutls_text2TLSPlaintext(state, type, &gtxt, &data[ret], Size);
-               if (err < 0) {
-                       /*gnutls_perror(err); */
-                       return err;
-               }
-
-               err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt);
-               if (err < 0) {
-                       /*gnutls_perror(err); */
-                       return err;
-               }
-
-               _gnutls_freeTLSPlaintext(gtxt);
-
-               err = _gnutls_TLSCompressed2TLSCiphertext(state, &gcipher, gcomp);
-               if (err < 0) {
-                       /*gnutls_perror(err); */
-                       return err;
-               }
-               _gnutls_freeTLSCompressed(gcomp);
+               Size = sizeofdata % MAX_ENC_LEN;
+               cipher_size = _gnutls_encrypt( state, &data[i*Size], Size, &cipher, type);
+               if (cipher_size<=0) return cipher_size;
 #ifdef WORDS_BIGENDIAN
-               length = gcipher->length;
+               length = cipher_size;
 #else
-               length = byteswap16(gcipher->length);
+               length = byteswap16(cipher_size);
 #endif
-               if (Write(cd, &gcipher->type, 1) != 1) {
+               memmove( &headers[3], &length, sizeof(uint16));
+               if (Write(cd, headers, sizeof(headers)) != sizeof(headers)) {
                        state->gnutls_internals.valid_connection = VALID_FALSE;
                        state->gnutls_internals.resumable = RESUME_FALSE;
                        gnutls_assert();
                        return GNUTLS_E_UNABLE_SEND_DATA;
                }
-               if (Write(cd, &gcipher->version.major, 1) != 1) {
-                       state->gnutls_internals.valid_connection = VALID_FALSE;
-                       state->gnutls_internals.resumable = RESUME_FALSE;
-                       gnutls_assert();
-                       return GNUTLS_E_UNABLE_SEND_DATA;
-               }
-               if (Write(cd, &gcipher->version.minor, 1) != 1) {
-                       state->gnutls_internals.valid_connection = VALID_FALSE;
-                       state->gnutls_internals.resumable = RESUME_FALSE;
-                       gnutls_assert();
-                       return GNUTLS_E_UNABLE_SEND_DATA;
-               }
-               if (Write(cd, &length, sizeof(uint16)) != sizeof(uint16)) {
-                       state->gnutls_internals.valid_connection = VALID_FALSE;
-                       state->gnutls_internals.resumable = RESUME_FALSE;
-                       gnutls_assert();
-                       return GNUTLS_E_UNABLE_SEND_DATA;
-               }
-               if (Write(cd, gcipher->fragment, gcipher->length) != gcipher->length) {
+               if (Write(cd, cipher, cipher_size) != cipher_size) {
                        state->gnutls_internals.valid_connection = VALID_FALSE;
                        state->gnutls_internals.resumable = RESUME_FALSE;
                        gnutls_assert();
                        return GNUTLS_E_UNABLE_SEND_DATA;
                }
                state->connection_state.write_sequence_number++;
-               ret += Size;
-
-               _gnutls_freeTLSCiphertext(gcipher);
        }
 
+       ret += sizeofdata;
+
+       gnutls_free(cipher);
+
        return ret;
 }
 
@@ -507,31 +419,16 @@ ssize_t _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state)
        int ret = 0, Size;
        uint8 type=GNUTLS_CHANGE_CIPHER_SPEC;
        char data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
+       uint8 headers[5];
 
        if (state->gnutls_internals.valid_connection == VALID_FALSE) {
                return GNUTLS_E_INVALID_SESSION;
        }
 
-       if (Write(cd, &type, 1) != 1) {
-               state->gnutls_internals.valid_connection = VALID_FALSE;
-               state->gnutls_internals.resumable = RESUME_FALSE;
-               gnutls_assert();
-               return GNUTLS_E_UNABLE_SEND_DATA;
-       }
-
-       if (Write(cd, &state->connection_state.version.major, 1) != 1) {
-               state->gnutls_internals.valid_connection = VALID_FALSE;
-               state->gnutls_internals.resumable = RESUME_FALSE;
-               gnutls_assert();
-               return GNUTLS_E_UNABLE_SEND_DATA;
-       }
+       headers[0] = type;
+       headers[1] = state->connection_state.version.major;
+       headers[2] = state->connection_state.version.minor;
 
-       if (Write(cd, &state->connection_state.version.minor, 1) != 1) {
-               state->gnutls_internals.valid_connection = VALID_FALSE;
-               state->gnutls_internals.resumable = RESUME_FALSE;
-               gnutls_assert();
-               return GNUTLS_E_UNABLE_SEND_DATA;
-       }
 #ifdef HARD_DEBUG
        fprintf(stderr, "Send Change Cipher Spec\n");
 #endif
@@ -541,7 +438,9 @@ ssize_t _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state)
 #else
        length = byteswap16((uint16)1);
 #endif
-       if (Write(cd, &length, sizeof(uint16)) != sizeof(uint16)) {
+       memmove( &headers[3], &length, sizeof(uint16));
+       
+       if (Write(cd, headers, 5) != 5) {
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
@@ -564,13 +463,15 @@ ssize_t _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state)
  * send (if called by the user the Content is specific)
  * It is intended to receive data, under the current state.
  */
+#define MAX_RECV_SIZE 18432    /* 2^14+2048 */
 ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data, size_t sizeofdata)
 {
-       GNUTLSPlaintext *gtxt;
-       GNUTLSCompressed *gcomp;
-       GNUTLSCiphertext gcipher;
        uint8 *tmpdata;
        int tmplen;
+       GNUTLS_Version version;
+       uint8 recv_type;
+       uint16 length;
+       uint8 *ciphertext;
        int ret = 0;
 
        /* If we have enough data in the cache do not bother receiving
@@ -585,62 +486,61 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data
                return GNUTLS_E_INVALID_SESSION;
        }
 
-       if (Read(cd, &gcipher.type, 1) != 1) {
+       if ( Read(cd, &recv_type, 1) != 1) {
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
 
-       /* If we expect a change cipher spec then just return - no decryption */
-
-       if (Read(cd, &gcipher.version.major, 1) != 1) {
+       version.local = 0; /* TLS/SSL 3.0 */
+       
+       if (Read(cd, &version.major, 1) != 1) {
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
 
-       if (Read(cd, &gcipher.version.minor, 1) != 1) {
+       if (Read(cd, &version.minor, 1) != 1) {
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
 
-       if (_gnutls_valid_version(state, gcipher.version.major, gcipher.version.minor) != 0) {
+       if (_gnutls_version_is_supported(state, version) == 0) {
 #ifdef DEBUG
-               fprintf(stderr, "INVALID VERSION PACKET: %d.%d\n", gcipher.version.major, gcipher.version.minor);
+               fprintf(stderr, "INVALID VERSION PACKET: %d.%d\n", version.major, version.minor);
 #endif
                _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_PROTOCOL_VERSION);
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
                return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
        } else {
-               GNUTLS_Version ver = { 0, gcipher.version.major, gcipher.version.minor };
-               gnutls_set_current_version(state, ver);
+               gnutls_set_current_version(state, version);
        }
 
-       if (Read(cd, &gcipher.length, 2) != 2) {
+       if (Read(cd, &length, 2) != 2) {
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
 #ifndef WORDS_BIGENDIAN
-       gcipher.length = byteswap16(gcipher.length);
+       length = byteswap16(length);
 #endif
 
 #ifdef HARD_DEBUG
        fprintf(stderr, "Expected Packet[%d] %s(%d) with length: %d\n",
                (int) state->connection_state.read_sequence_number, _gnutls_packet2str(type), type, sizeofdata);
        fprintf(stderr, "Received Packet[%d] %s(%d) with length: %d\n",
-               (int) state->connection_state.read_sequence_number, _gnutls_packet2str(gcipher.type), gcipher.type, gcipher.length);
+               (int) state->connection_state.read_sequence_number, _gnutls_packet2str(recv_type), recv_type, length);
 #endif
 
-       if (gcipher.length > 18432) {   /* 2^14+2048 */
+       if (length > MAX_RECV_SIZE) {
 #ifdef DEBUG
-               fprintf(stderr, "FATAL ERROR: Received packet with length: %d\n", gcipher.length);
+               fprintf(stderr, "FATAL ERROR: Received packet with length: %d\n", length);
 #endif
                _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_RECORD_OVERFLOW);
                state->gnutls_internals.valid_connection = VALID_FALSE;
@@ -648,72 +548,62 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
-       gcipher.fragment = gnutls_malloc(gcipher.length);
 
-       /* read ciphertext */
+       ciphertext = gnutls_malloc(length);
 
-       ret = Read(cd, gcipher.fragment, gcipher.length);
+       /* read ciphertext */
 
+       ret = Read(cd, ciphertext, length);
 
-       if (ret != gcipher.length) {
+       if (ret != length) {
 #ifdef DEBUG
-               fprintf(stderr, "Received packet with length: %d\nExpected %d\n", ret, gcipher.length);
+               fprintf(stderr, "Received packet with length: %d\nExpected %d\n", ret, length);
 #endif
-               gnutls_free(gcipher.fragment);
+               gnutls_free(ciphertext);
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
                gnutls_assert();
                return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
        }
-
-       if (type == GNUTLS_CHANGE_CIPHER_SPEC && gcipher.type == GNUTLS_CHANGE_CIPHER_SPEC) {
+       
+       if (type == GNUTLS_CHANGE_CIPHER_SPEC && recv_type == GNUTLS_CHANGE_CIPHER_SPEC) {
 #ifdef HARD_DEBUG
                fprintf(stderr, "Received Change Cipher Spec Packet\n");
 #endif
-               if (gcipher.length!=1) return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+               if (length!=1) {
+                       gnutls_assert();
+                       gnutls_free(ciphertext);
+                       return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
+               }
                return 0;
        }
 
-
-       ret = _gnutls_TLSCiphertext2TLSCompressed(state, &gcomp, &gcipher);
-       if (ret < 0) {
-               gnutls_free(gcipher.fragment);
-               if (ret == GNUTLS_E_MAC_FAILED) {
-                       _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_BAD_RECORD_MAC);
-               } else {
-                       _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_DECRYPTION_FAILED);
+       tmplen = _gnutls_decrypt( state, ciphertext, length, &tmpdata, type);
+       if (tmplen < 0) {
+               switch (tmplen) {
+                       case GNUTLS_E_MAC_FAILED:
+                               _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_BAD_RECORD_MAC);
+                               break;
+                       case GNUTLS_E_DECRYPTION_FAILED:
+                               _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_DECRYPTION_FAILED);
+                               break;
+                       case GNUTLS_E_DECOMPRESSION_FAILED:
+                               _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_DECOMPRESSION_FAILURE);
+                               break;
                }
                state->gnutls_internals.valid_connection = VALID_FALSE;
                state->gnutls_internals.resumable = RESUME_FALSE;
-               return ret;
-       }
-       gnutls_free(gcipher.fragment);
-
-       ret = _gnutls_TLSCompressed2TLSPlaintext(state, &gtxt, gcomp);
-       if (ret < 0) {
-               _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_DECOMPRESSION_FAILURE);
-               state->gnutls_internals.valid_connection = VALID_FALSE;
-               state->gnutls_internals.resumable = RESUME_FALSE;
-               return ret;
-       }
-       _gnutls_freeTLSCompressed(gcomp);
-
-       ret = _gnutls_TLSPlaintext2text((void *) &tmpdata, gtxt);
-       if (ret < 0) {
-               _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_INTERNAL_ERROR);
-               state->gnutls_internals.valid_connection = VALID_FALSE;
-               state->gnutls_internals.resumable = RESUME_FALSE;
-               return ret;
+               gnutls_assert();
+               gnutls_free(ciphertext);
+               return tmplen;
        }
-       tmplen = gtxt->length;
-
 
-       _gnutls_freeTLSPlaintext(gtxt);
+       gnutls_free(ciphertext);
 
-       if (gcipher.type == type && (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE)) {
+       if ( (recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE)) {
                gnutls_insertDataBuffer(type, state, (void *) tmpdata, tmplen);
        } else {
-               switch (gcipher.type) {
+               switch (recv_type) {
                case GNUTLS_ALERT:
 #ifdef HARD_DEBUG
                        fprintf(stderr, "Alert[%d|%d] - %s - was received\n", tmpdata[0], tmpdata[1], _gnutls_alert2str((int)tmpdata[1]));
@@ -758,18 +648,16 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data
 
 
 
-       /* Insert Application data to buffer */
-       if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && gcipher.type == type) {
+       /* Get Application data from buffer */
+       if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && (recv_type == type)) {
                ret = gnutls_getDataFromBuffer(type, state, data, sizeofdata);
                gnutls_free(tmpdata);
        } else {
-               if (gcipher.type != type) {
+               if (recv_type != type) {
                        gnutls_assert();
                        return GNUTLS_E_RECEIVED_BAD_MESSAGE;
                }
-               /* this is an error because we have messages of fixed
-                * length */
-
+               gnutls_assert(); /* this shouldn't have happened */
                ret = GNUTLS_E_RECEIVED_BAD_MESSAGE;
        }
 
index fba8ac3c5c55dc2141058052240af7e1facd2903..cf712f88226ff4a3782e19b7531df0fadfb7a714 100644 (file)
@@ -20,7 +20,7 @@
 
 enum ContentType { GNUTLS_APPLICATION_DATA=23 };
 typedef enum ContentType ContentType;
-enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_DES=3, GNUTLS_3DES = 4, GNUTLS_AES };
+enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_DES=3, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL };
 typedef enum BulkCipherAlgorithm BulkCipherAlgorithm;
 enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH };
 typedef enum KXAlgorithm KXAlgorithm;
@@ -45,7 +45,7 @@ typedef struct GNUTLS_STATE_INT* GNUTLS_STATE;
 
 int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end);
 int gnutls_deinit(GNUTLS_STATE * state);
-ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, size_t sizeofdata);
+ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, void* data, size_t sizeofdata);
 ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char* data, size_t sizeofdata);
 int gnutls_close(int cd, GNUTLS_STATE state);
 int gnutls_handshake(int cd, GNUTLS_STATE state);
index 3d797d678fef3b401e33a79c5483b926add60d73..3b676ca625051470417ebf96d936f7f6b449208c 100644 (file)
@@ -63,7 +63,7 @@ typedef struct gnutls_cipher_entry gnutls_cipher_entry;
 
 static gnutls_cipher_entry algorithms[] = {
        GNUTLS_CIPHER_ENTRY(GNUTLS_3DES, 8, 24, 1, 8, -1),
-       GNUTLS_CIPHER_ENTRY(GNUTLS_AES, 16, 16, 1, 16, -1),
+       GNUTLS_CIPHER_ENTRY(GNUTLS_RIJNDAEL, 16, 16, 1, 16, -1),
 #ifdef USE_MCRYPT
        GNUTLS_CIPHER_ENTRY(GNUTLS_DES, 8, 8, 1, 8, -1),
        GNUTLS_CIPHER_ENTRY(GNUTLS_ARCFOUR, 1, 16, 0, 0, -1),
@@ -173,11 +173,11 @@ typedef struct {
 #define GNUTLS_DHE_DSS_WITH_DES_CBC_SHA { 0x00, 0x12 }
 #define GNUTLS_DHE_RSA_WITH_DES_CBC_SHA { 0x00, 0x15 }
 
-#define GNUTLS_RSA_WITH_AES_128_CBC_SHA { 0xFF, 0x2F }
-#define GNUTLS_DH_DSS_WITH_AES_128_CBC_SHA { 0xFF, 0x30 }
-#define GNUTLS_DH_RSA_WITH_AES_128_CBC_SHA { 0xFF, 0x31 }
-#define GNUTLS_DHE_DSS_WITH_AES_128_CBC_SHA { 0xFF, 0x32 }
-#define GNUTLS_DHE_RSA_WITH_AES_128_CBC_SHA { 0xFF, 0x33 }
+#define GNUTLS_RSA_WITH_RIJNDAEL_128_CBC_SHA { 0x00, 0x2F }
+#define GNUTLS_DH_DSS_WITH_RIJNDAEL_128_CBC_SHA { 0x00, 0x30 }
+#define GNUTLS_DH_RSA_WITH_RIJNDAEL_128_CBC_SHA { 0x00, 0x31 }
+#define GNUTLS_DHE_DSS_WITH_RIJNDAEL_128_CBC_SHA { 0x00, 0x32 }
+#define GNUTLS_DHE_RSA_WITH_RIJNDAEL_128_CBC_SHA { 0x00, 0x33 }
                       
                       
 static gnutls_cipher_suite_entry cs_algorithms[] = {
@@ -195,11 +195,11 @@ static gnutls_cipher_suite_entry cs_algorithms[] = {
        GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_ARCFOUR_MD5,         GNUTLS_ARCFOUR, GNUTLS_KX_RSA,  GNUTLS_MAC_MD5),
        GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_3DES_EDE_CBC_SHA,    GNUTLS_3DES, GNUTLS_KX_RSA,     GNUTLS_MAC_SHA),
        GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_DES_CBC_SHA,         GNUTLS_DES,  GNUTLS_KX_RSA,     GNUTLS_MAC_SHA),
-       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_AES_128_CBC_SHA,     GNUTLS_AES,  GNUTLS_KX_RSA,     GNUTLS_MAC_SHA),
-       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_DSS_WITH_AES_128_CBC_SHA,  GNUTLS_AES,  GNUTLS_KX_DH_DSS,  GNUTLS_MAC_SHA),
-       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_RSA_WITH_AES_128_CBC_SHA,  GNUTLS_AES,  GNUTLS_KX_DH_RSA,  GNUTLS_MAC_SHA),
-       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DHE_DSS_WITH_AES_128_CBC_SHA, GNUTLS_AES,  GNUTLS_KX_DHE_DSS, GNUTLS_MAC_SHA),
-       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DHE_RSA_WITH_AES_128_CBC_SHA, GNUTLS_AES,  GNUTLS_KX_DHE_RSA, GNUTLS_MAC_SHA),
+       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_RSA_WITH_RIJNDAEL_128_CBC_SHA,        GNUTLS_RIJNDAEL,  GNUTLS_KX_RSA,        GNUTLS_MAC_SHA),
+       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_DSS_WITH_RIJNDAEL_128_CBC_SHA,     GNUTLS_RIJNDAEL,  GNUTLS_KX_DH_DSS,  GNUTLS_MAC_SHA),
+       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DH_RSA_WITH_RIJNDAEL_128_CBC_SHA,     GNUTLS_RIJNDAEL,  GNUTLS_KX_DH_RSA,     GNUTLS_MAC_SHA),
+       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DHE_DSS_WITH_RIJNDAEL_128_CBC_SHA,    GNUTLS_RIJNDAEL,  GNUTLS_KX_DHE_DSS,    GNUTLS_MAC_SHA),
+       GNUTLS_CIPHER_SUITE_ENTRY( GNUTLS_DHE_RSA_WITH_RIJNDAEL_128_CBC_SHA,    GNUTLS_RIJNDAEL,  GNUTLS_KX_DHE_RSA,    GNUTLS_MAC_SHA),
        {0}
 };
 
@@ -521,9 +521,10 @@ int _gnutls_version_cmp(GNUTLS_Version ver1, GNUTLS_Version ver2) {
        return 0;
 }
 
-int _gnutls_version_is_supported(const GNUTLS_Version version)
+int _gnutls_version_is_supported(GNUTLS_STATE state, const GNUTLS_Version version)
 {
        size_t ret = 0;
+       /* FIXME: make it to read it from the state */
        GNUTLS_VERSION_ALG_LOOP(ret = p->supported);
        return ret;
 }
index 96f80303a325bf9035aa61c213d81c67dd54048f..2b3a19b78db95ed02f4352693d9426a84ff18110 100644 (file)
@@ -1,5 +1,5 @@
 /* functions for version */
-int _gnutls_version_is_supported(const GNUTLS_Version version);
+int _gnutls_version_is_supported(GNUTLS_STATE state, const GNUTLS_Version version);
 
 /* functions for macs */
 int   _gnutls_mac_get_digest_size(MACAlgorithm algorithm);
index e0257a58caae76c9bcf3bb1f472ee5aa1be10470..3c8d8cb41371e7e3de3b5cd025005d099970fb30 100644 (file)
 #include "gnutls_hash_int.h"
 #include "gnutls_cipher_int.h"
 
+int _gnutls_encrypt( GNUTLS_STATE state, char* data, size_t data_size, uint8** ciphertext, ContentType type)
+{
+       GNUTLSPlaintext *gtxt;
+       GNUTLSCompressed *gcomp;
+       GNUTLSCiphertext *gcipher;
+       int total_length=0, err, i;
+       
+       if (data_size == 0)
+               return 0;
+
+       err = _gnutls_text2TLSPlaintext(state, type, &gtxt, data, data_size);
+       if (err < 0) {
+               gnutls_assert();
+               return err;
+       }
+
+       err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt);
+       if (err < 0) {
+               gnutls_assert();
+               return err;
+       }
+
+       _gnutls_freeTLSPlaintext(gtxt);
+
+       err = _gnutls_TLSCompressed2TLSCiphertext(state, &gcipher, gcomp);
+       if (err < 0) {
+               gnutls_assert();
+               return err;
+       }
+
+       _gnutls_freeTLSCompressed(gcomp);
+
+       *ciphertext = gnutls_malloc( gcipher->length);
+       if ( *ciphertext == NULL) {
+               gnutls_assert();
+               return GNUTLS_E_MEMORY_ERROR;
+       }
+       memmove( (*ciphertext), gcipher->fragment, gcipher->length);
+
+       total_length += gcipher->length;
+       _gnutls_freeTLSCiphertext(gcipher);
+
+       return total_length;
+}
+
+int _gnutls_decrypt( GNUTLS_STATE state, char* ciphertext, size_t ciphertext_size, uint8** data, ContentType type)
+{
+       GNUTLSPlaintext *gtxt;
+       GNUTLSCompressed *gcomp;
+       GNUTLSCiphertext gcipher;
+       int iterations, i;
+       int err, ret;
+       int total_length=0;
+       
+       if (ciphertext_size == 0)
+               return 0;
+
+       gcipher.type = type;
+       gcipher.length = ciphertext_size;
+       gcipher.version.major = state->connection_state.version.major;
+       gcipher.version.minor = state->connection_state.version.minor;
+       gcipher.fragment = gnutls_malloc(ciphertext_size);
+       memmove( gcipher.fragment, ciphertext, ciphertext_size);
+       
+       ret = _gnutls_TLSCiphertext2TLSCompressed(state, &gcomp, &gcipher);
+       if (ret < 0) {
+               gnutls_free(gcipher.fragment);
+               return ret;
+       }
+       gnutls_free(gcipher.fragment);  
+
+       ret = _gnutls_TLSCompressed2TLSPlaintext(state, &gtxt, gcomp);
+       if (ret < 0) {
+               return ret;
+       }
+
+       _gnutls_freeTLSCompressed(gcomp);
+
+       ret = _gnutls_TLSPlaintext2text((void *) data, gtxt);
+       if (ret < 0) {
+               return ret;
+       }
+       ret = gtxt->length;
+
+       _gnutls_freeTLSPlaintext(gtxt);
+
+       return ret;
+}
+
+
 /* Sets the specified cipher into the pending state */
 int _gnutls_set_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo)
 {
index 1ba32edab2e26547d503aa25d9f591b89015d739..b078f365ac3aba7fdd00435a9a357ed4cfe1c82c 100644 (file)
@@ -1,3 +1,4 @@
+int _gnutls_encrypt( GNUTLS_STATE state, char* data, size_t data_size, uint8** ciphertext, ContentType type);
 int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state,
                                                      GNUTLSCiphertext**
                                                      cipher,
index 547b9b65ea273db36a44e914bc80610e79ce37c8..38c6be1075e9e1a2ff30e293f9e9e6013d4f71a4 100644 (file)
@@ -38,7 +38,7 @@ GNUTLS_CIPHER_HANDLE ret;
                ret = GNUTLS_CIPHER_FAILED;
 #endif
                break;
-       case GNUTLS_AES:
+       case GNUTLS_RIJNDAEL:
 #ifdef USE_MCRYPT
                ret = mcrypt_module_open( "rijndael-128", NULL, "cbc", NULL);
 #else
index 99ce837d824ff2e41e456d94b571440c44402713..c7299aedcc13a15e5fa84ef839d9d7e6511b855c 100644 (file)
@@ -58,6 +58,8 @@ static gnutls_error_entry error_algorithms[] = {
        GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_KX_ALGORITHM, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_MPI_SCAN_FAILED, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_DECRYPTION_FAILED, 1),
+       GNUTLS_ERROR_ENTRY( GNUTLS_E_DECOMPRESSION_FAILED, 1),
+       GNUTLS_ERROR_ENTRY( GNUTLS_E_MEMORY_ERROR, 1),
        GNUTLS_ERROR_ENTRY( GNUTLS_E_UNIMPLEMENTED_FEATURE, 1),
        {0}
 };
index 808da9a72de35b2b51ab47de1796035a41739679..c3909ca1be611116824e23dbccc1402a3c69e6cf 100644 (file)
@@ -24,6 +24,8 @@
 #define        GNUTLS_E_UNWANTED_ALGORITHM -22
 #define        GNUTLS_E_MPI_SCAN_FAILED -23
 #define GNUTLS_E_DECRYPTION_FAILED -24
+#define GNUTLS_E_MEMORY_ERROR -25
+#define GNUTLS_E_DECOMPRESSION_FAILED -26
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -50
 
 
index c12f6d440a04c728b0f717b4107c8aaec48d63f3..1ec032fa42ef12b8eaac0432474481261ceb91f6 100644 (file)
@@ -593,6 +593,7 @@ int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char *data, int datalen,
        CompressionMethod compression_method, *compression_methods;
        int i, ret=0;
        uint16 x, sizeOfSuites;
+       GNUTLS_Version version;
 
        if (state->security_parameters.entity == GNUTLS_CLIENT) {
                if (datalen < 38) {
@@ -603,8 +604,14 @@ int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char *data, int datalen,
 #ifdef DEBUG
                fprintf(stderr, "Server's version: %d.%d\n", data[pos], data[pos+1]);
 #endif
-               if ( _gnutls_valid_version( state, data[pos], data[pos+1]) != 0) {
+               version.local = 0; /* TLS 1.0 / SSL 3.0 */
+               version.major = data[pos];
+               version.minor = data[pos+1];
+               if ( _gnutls_version_is_supported( state, version) == 0) {
+                       gnutls_assert();
                        return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
+               } else {
+                       gnutls_set_current_version(state, version);
                }
                pos+=2;
                
@@ -679,9 +686,14 @@ int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char *data, int datalen,
 #ifdef DEBUG
                fprintf(stderr, "Client's version: %d.%d\n", data[pos], data[pos+1]);
 #endif
-               if ( _gnutls_valid_version( state, data[pos], data[pos+1]) != 0) {
+               version.local = 0; /* TLS 1.0 / SSL 3.0 */
+               version.major = data[pos];
+               version.minor = data[pos+1];
+               if ( _gnutls_version_is_supported( state, version) == 0) {
                        gnutls_assert();
                        return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
+               } else {
+                       gnutls_set_current_version(state, version);
                }
                pos+=2;
                
index 2b151ff41f723ff07710e60d7631af1c5989072d..f8166e19eedd35e6574864b8cabba537b14fdd2b 100644 (file)
@@ -2,7 +2,7 @@
 
 #define GNUTLS_INT_H
 
-//#define HARD_DEBUG
+#define HARD_DEBUG
 //#define READ_DEBUG
 //#define WRITE_DEBUG
 #define DEBUG
@@ -82,7 +82,7 @@ typedef struct {
 
 /* STATE */
 enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT };
-enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_DES=3, GNUTLS_3DES = 4, GNUTLS_AES };
+enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_DES=3, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL };
 enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH };
 enum KeyExchangeAlgorithm { GNUTLS_RSA, GNUTLS_DIFFIE_HELLMAN };
 enum CipherType { CIPHER_STREAM, CIPHER_BLOCK };
@@ -291,11 +291,10 @@ int gnutls_close(int cd, GNUTLS_STATE state);
 svoid *gnutls_PRF( opaque * secret, int secret_size, uint8 * label,
                  int label_size, opaque * seed, int seed_size,
                  int total_bytes);
-int _gnutls_valid_version( GNUTLS_STATE state, int major, int minor);
 void gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version);
 GNUTLS_Version gnutls_get_current_version(GNUTLS_STATE state);
 int _gnutls_set_keys(GNUTLS_STATE state);
-ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, size_t sizeofdata);
+ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, void* data, size_t sizeofdata);
 ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char* data, size_t sizeofdata);
 int _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state);
 int _gnutls_version_cmp(GNUTLS_Version ver1, GNUTLS_Version ver2);