diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2000-03-14 11:25:03 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2000-03-14 11:25:03 +0000 |
commit | f23acdac128477b4dca536985426317ca840d020 (patch) | |
tree | 209f9511607ce8a407e064479753f8dc8959e603 | |
parent | 13d6edeacce11a8db7456ff808e4161ae90f097b (diff) | |
download | gnutls-f23acdac128477b4dca536985426317ca840d020.tar.gz |
In case of failure gnutls_recv, sends an alert message.
but, it still cannot receive any.
-rw-r--r-- | README | 5 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/debug.c | 4 | ||||
-rw-r--r-- | src/gnutls.c | 112 | ||||
-rw-r--r-- | src/gnutls.h | 157 | ||||
-rw-r--r-- | src/gnutls_buffers.c | 41 | ||||
-rw-r--r-- | src/gnutls_buffers.h | 3 | ||||
-rw-r--r-- | src/gnutls_cipher.c | 4 | ||||
-rw-r--r-- | src/gnutls_compress.c | 4 | ||||
-rw-r--r-- | src/gnutls_errors.h | 11 | ||||
-rw-r--r-- | src/gnutls_handshake.h | 24 | ||||
-rw-r--r-- | src/gnutls_int.h | 1 | ||||
-rw-r--r-- | src/gnutls_plaintext.c | 6 | ||||
-rw-r--r-- | src/gnutls_record.h | 147 | ||||
-rw-r--r-- | src/test.c | 11 |
15 files changed, 350 insertions, 182 deletions
@@ -0,0 +1,5 @@ +* Run the buildconf script before doing anything. This will create +the needed configure, makefiles etc. using Automake, Autoconf, and libtool. + +* The library needs libgcrypt and libmhash (until hmac is included in libgcrypt) + diff --git a/src/Makefile.am b/src/Makefile.am index ab81c6b0a9..ccee56d4ef 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ include_HEADERS = gnutls.h -EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h gnutls_cipher.h gnutls_buffers.h +EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h gnutls_cipher.h gnutls_buffers.h gnutls_record.h gnutls_handshake.h gnutls_errors.h gnutls_int.h lib_LTLIBRARIES = libgnutls.la libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c gnutls_cipher.c gnutls_buffers.c libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) diff --git a/src/debug.c b/src/debug.c index e6a01194b5..37ca6beb22 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,7 +1,9 @@ #include <stdio.h> #include <stdlib.h> #include <defines.h> -#include "gnutls.h" +#include "gnutls_record.h" +#include "gnutls_handshake.h" +#include "gnutls_errors.h" static char hexconvtab[] = "0123456789abcdef"; diff --git a/src/gnutls.c b/src/gnutls.c index 39f131eda9..15c819c94a 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -1,5 +1,7 @@ #include <defines.h> -#include "gnutls.h" +#include "gnutls_record.h" +#include "gnutls_handshake.h" +#include "gnutls_errors.h" #include "debug.h" #include "gnutls_compress.h" #include "gnutls_plaintext.h" @@ -188,6 +190,16 @@ int _gnutls_set_keys( GNUTLS_STATE state) { return 0; } +int _gnutls_send_alert( int cd, GNUTLS_STATE state, AlertLevel level, AlertDescription desc) { +Alert alert; + + alert.level=level; + alert.description=desc; + + return gnutls_send_int( cd, state, GNUTLS_ALERT, &alert, sizeof(alert)); + +} + int gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, int sizeofdata) { GNUTLSPlaintext *gtxt; GNUTLSCompressed *gcomp; @@ -197,7 +209,8 @@ int gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, in int ret=0, Size; if (sizeofdata==0) return 0; - + if (state->gnutls_internals.valid_connection==VALID_FALSE) return GNUTLS_E_INVALID_SESSION; + if (sizeofdata<16384) { iterations=1; Size=sizeofdata; @@ -228,17 +241,32 @@ int gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, in _gnutls_freeTLSCompressed(gcomp); - write( cd, &gcipher->type, sizeof(ContentType)); - write( cd, &gcipher->version.major, 1); - write( cd, &gcipher->version.minor, 1); + if (write( cd, &gcipher->type, sizeof(ContentType)) != sizeof(ContentType)) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } + if (write( cd, &gcipher->version.major, 1) != 1) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } + if (write( cd, &gcipher->version.minor, 1) != 1) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } #ifdef WORDS_BIGENDIAN length=gcipher->length; #else length=byteswap16(gcipher->length); #endif - write( cd, &length, sizeof(uint16)); - _print_TLSCiphertext( gcipher); - write( cd, gcipher->fragment, gcipher->length); + if (write( cd, &length, sizeof(uint16)) != sizeof(uint16)) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } +// _print_TLSCiphertext( gcipher); + if (write( cd, gcipher->fragment, gcipher->length) != gcipher->length) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } state->connection_state.write_sequence_number++; ret += Size; @@ -272,11 +300,26 @@ int gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, in #else length=byteswap16(gcipher->length); #endif - write( cd, &gcipher->type, sizeof(ContentType)); - write( cd, &gcipher->version.major, 1); - write( cd, &gcipher->version.minor, 1); - write( cd, &length, sizeof(uint16)); - write( cd, gcipher->fragment, gcipher->length); + if (write( cd, &gcipher->type, sizeof(ContentType)) != sizeof(ContentType)) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } + if (write( cd, &gcipher->version.major, 1) != 1) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } + if (write( cd, &gcipher->version.minor, 1) != 1) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } + if (write( cd, &length, sizeof(uint16)) != sizeof(uint16)) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } + if (write( cd, gcipher->fragment, gcipher->length) != gcipher->length) { + state->gnutls_internals.valid_connection=VALID_FALSE; + return GNUTLS_E_UNABLE_SEND_DATA; + } state->connection_state.write_sequence_number++; ret += Size; @@ -297,37 +340,64 @@ int gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char* data, in if (sizeofdata==0) return 0; - do { - read( cd, &gcipher.type, sizeof(ContentType)); - read( cd, &gcipher.version, sizeof(ProtocolVersion)); + while( gnutls_getDataBufferSize(state, type) < sizeofdata) { + + if (state->gnutls_internals.valid_connection==VALID_FALSE) return GNUTLS_E_INVALID_SESSION; + if (read( cd, &gcipher.type, sizeof(ContentType)) != sizeof(ContentType)) { + state->gnutls_internals.valid_connection=VALID_FALSE; + _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_INTERNAL_ERROR); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } + if (read( cd, &gcipher.version, sizeof(ProtocolVersion)) != sizeof(ProtocolVersion)) { + state->gnutls_internals.valid_connection=VALID_FALSE; + _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_INTERNAL_ERROR); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } if ( gcipher.version.major != GNUTLS_VERSION_MAJOR || gcipher.version.minor != GNUTLS_VERSION_MINOR) { + _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_PROTOCOL_VERSION); return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; - } + } - read( cd, &gcipher.length, sizeof(uint16)); + if (read( cd, &gcipher.length, sizeof(uint16)) != sizeof(uint16)) { + state->gnutls_internals.valid_connection=VALID_FALSE; + _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_INTERNAL_ERROR); + return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; + } #ifndef WORDS_BIGENDIAN gcipher.length = byteswap16(gcipher.length); #endif gcipher.fragment = gnutls_malloc(gcipher.length); /* read ciphertext */ - if (read( cd, gcipher.fragment, gcipher.length)!= gcipher.length) { + if (read( cd, gcipher.fragment, gcipher.length) != gcipher.length) { gnutls_free(gcipher.fragment); + state->gnutls_internals.valid_connection=VALID_FALSE; + _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_INTERNAL_ERROR); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } if (ret = _gnutls_TLSCiphertext2TLSCompressed( state, &gcomp, &gcipher) < 0){ gnutls_free(gcipher.fragment); + state->gnutls_internals.valid_connection=VALID_FALSE; + 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); + } return ret; } gnutls_free(gcipher.fragment); if (ret = _gnutls_TLSCompressed2TLSPlaintext( state, >xt, gcomp) < 0){ + state->gnutls_internals.valid_connection=VALID_FALSE; + _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_DECOMPRESSION_FAILURE); return ret; } _gnutls_freeTLSCompressed(gcomp); - + if (ret = _gnutls_TLSPlaintext2text( &tmpdata, gtxt) < 0){ + state->gnutls_internals.valid_connection=VALID_FALSE; + _gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_INTERNAL_ERROR); return ret; } @@ -338,7 +408,7 @@ int gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char* data, in /* Incread sequence number */ state->connection_state.read_sequence_number++; - } while( gnutls_getDataBufferSize(state, type) < sizeofdata); + } ret = gnutls_getDataFromBuffer(state, type, data, sizeofdata); diff --git a/src/gnutls.h b/src/gnutls.h index 14612edc3b..ac69dd1eab 100644 --- a/src/gnutls.h +++ b/src/gnutls.h @@ -1,156 +1,19 @@ -#define svoid void /* for functions that allocate using secure_free */ -#define secure_free free -#define secure_malloc malloc -#define secure_realloc realloc -#define secure_calloc calloc -#define gnutls_malloc malloc -#define gnutls_realloc realloc -#define gnutls_calloc calloc -#define gnutls_free free - -#define rotl64(x,n) (((x) << ((uint16)(n))) | ((x) >> (64 - (uint16)(n)))) -#define rotr64(x,n) (((x) >> ((uint16)(n))) | ((x) << (64 - (uint16)(n)))) -#define rotl32(x,n) (((x) << ((uint16)(n))) | ((x) >> (32 - (uint16)(n)))) -#define rotr32(x,n) (((x) >> ((uint16)(n))) | ((x) << (32 - (uint16)(n)))) -#define rotl16(x,n) (((x) << ((uint16)(n))) | ((x) >> (16 - (uint16)(n)))) -#define rotr16(x,n) (((x) >> ((uint16)(n))) | ((x) << (16 - (uint16)(n)))) - -#define byteswap16(x) ((rotl16(x, 8) & 0x00ff) | (rotr16(x, 8) & 0xff00)) -#define byteswap32(x) ((rotl32(x, 8) & 0x00ff00ff) | (rotr32(x, 8) & 0xff00ff00)) -#define byteswap64(x) ((rotl64(x, 8) & 0x00ff00ff00ff00ff) | (rotr64(x, 8) & 0xff00ff00ff00ff00)) - -typedef unsigned char opaque; - -/* STATE */ -enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT }; +enum ContentType { GNUTLS_APPLICATION_DATA=23 }; +typedef enum ContentType ContentType; enum BulkCipherAlgorithm { CIPHER_NULL, CIPHER_3DES = 4 }; -enum CipherType { CIPHER_STREAM, CIPHER_BLOCK }; -enum IsExportable { EXPORTABLE_TRUE, EXPORTABLE_FALSE }; -enum MACAlgorithm { MAC_NULL, MAC_MD5, MAC_SHA }; -enum CompressionMethod { COMPRESSION_NULL }; - - -typedef enum ConnectionEnd ConnectionEnd; typedef enum BulkCipherAlgorithm BulkCipherAlgorithm; -typedef enum CipherType CipherType; -typedef enum IsExportable IsExportable; +enum MACAlgorithm { MAC_NULL, MAC_MD5, MAC_SHA }; typedef enum MACAlgorithm MACAlgorithm; +enum CompressionMethod { COMPRESSION_NULL }; typedef enum CompressionMethod CompressionMethod; +enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT }; +typedef enum ConnectionEnd ConnectionEnd; -typedef struct { - ConnectionEnd entity; - BulkCipherAlgorithm bulk_cipher_algorithm; - CipherType cipher_type; - uint8 IV_size; /* not specified in the protocol, but later it - * uses it */ - uint8 key_size; - uint8 key_material_length; - IsExportable is_exportable; - MACAlgorithm mac_algorithm; - uint8 hash_size; - CompressionMethod compression_algorithm; - opaque master_secret[48]; - opaque client_random[32]; - opaque server_random[32]; -} SecurityParameters; - -typedef struct { - opaque* server_write_mac_secret; - opaque* client_write_mac_secret; - opaque* server_write_IV; - opaque* client_write_IV; - opaque* server_write_key; - opaque* client_write_key; -} CipherSpecs; - -typedef struct { - opaque* compression_state; - GCRY_CIPHER_HD cipher_state; - opaque* mac_secret; - uint8 mac_secret_size; - uint64 read_sequence_number; - uint64 write_sequence_number; -} ConnectionState; - -typedef struct { - char* buffer; - uint32 bufferSize; -} GNUTLS_INTERNALS; - -typedef struct { - SecurityParameters security_parameters; - CipherSpecs cipher_specs; - ConnectionState connection_state; - GNUTLS_INTERNALS gnutls_internals; -} GNUTLS_STATE_INT; - -typedef GNUTLS_STATE_INT *GNUTLS_STATE; - - -/* Record Protocol */ -enum ContentType { GNUTLS_CHANGE_CIPHER_SPEC=20, GNUTLS_ALERT, GNUTLS_HANDSHAKE, - GNUTLS_APPLICATION_DATA }; -typedef enum ContentType ContentType; - -#define GNUTLS_VERSION_MAJOR 3 -#define GNUTLS_VERSION_MINOR 1 - -typedef struct { - uint8 major; - uint8 minor; -} ProtocolVersion; - -typedef struct { - ContentType type; - ProtocolVersion version; - uint16 length; - opaque* fragment; -} GNUTLSPlaintext; - -typedef struct { - ContentType type; - ProtocolVersion version; - uint16 length; - opaque* fragment; -} GNUTLSCompressed; - -/* This is used for both block ciphers and stream ciphers. In stream ciphers - * the padding is just ignored. - */ -typedef struct { - opaque* content; - opaque* MAC; - uint8* padding; - uint8 padding_length; -} GNUTLS_GenericBlockCipher; - -typedef struct { - opaque* content; - opaque* MAC; -} GNUTLS_GenericStreamCipher; - -typedef struct { - ContentType type; - ProtocolVersion version; - uint16 length; - void* fragment; /* points GenericStreamCipher - * or GenericBlockCipher - */ -} GNUTLSCiphertext; - +struct GNUTLS_STATE_INT; +typedef struct GNUTLS_STATE_INT* GNUTLS_STATE; int gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, char* data, int sizeofdata); -#define gnutls_send( x, y, z, w) gnutls_send_int( x, y, GNUTLS_APPLICATION_DATA, z, w) int gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char* data, int sizeofdata); -#define gnutls_recv( x, y, z, w) gnutls_recv_int( x, y, GNUTLS_APPLICATION_DATA, z, w) - -#define GNUTLS_E_MAC_FAILED -1 -#define GNUTLS_E_UNKNOWN_CIPHER -2 -#define GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM -3 -#define GNUTLS_E_UNKNOWN_MAC_ALGORITHM -4 -#define GNUTLS_E_UNKNOWN_ERROR -5 -#define GNUTLS_E_UNKNOWN_CIPHER_TYPE -6 -#define GNUTLS_E_LARGE_PACKET -7 -#define GNUTLS_E_UNSUPPORTED_VERSION_PACKET -8 -#define GNUTLS_E_UNEXPECTED_PACKET_LENGTH -9 +#define gnutls_send( x, y, z, w) gnutls_send_int( x, y, GNUTLS_APPLICATION_DATA, z, w) +#define gnutls_recv( x, y, z, w) gnutls_recv_int( x, y, GNUTLS_APPLICATION_DATA, z, w) diff --git a/src/gnutls_buffers.c b/src/gnutls_buffers.c new file mode 100644 index 0000000000..5a088bff7b --- /dev/null +++ b/src/gnutls_buffers.c @@ -0,0 +1,41 @@ +#include <defines.h> +#include "gnutls_record.h" +#include "gnutls_handshake.h" +#include "gnutls_errors.h" + +int gnutls_insertDataBuffer(GNUTLS_STATE state, ContentType type, char *data, int length) +{ + int old_buffer=state->gnutls_internals.bufferSize; + + if (type == GNUTLS_APPLICATION_DATA) { + state->gnutls_internals.bufferSize+=length; + state->gnutls_internals.buffer = gnutls_realloc( state->gnutls_internals.buffer, state->gnutls_internals.bufferSize); + memmove( &state->gnutls_internals.buffer[old_buffer], data, length); + } + return 0; + +} + +int gnutls_getDataBufferSize(GNUTLS_STATE state, ContentType type) { + if (type == GNUTLS_APPLICATION_DATA) { + return state->gnutls_internals.bufferSize; + } + return 0; +} + +int gnutls_getDataFromBuffer(GNUTLS_STATE state, ContentType type, char *data, int length) +{ + if ( state->gnutls_internals.bufferSize < length) { + length = state->gnutls_internals.bufferSize; + } + + if (type == GNUTLS_APPLICATION_DATA) { + state->gnutls_internals.bufferSize-=length; + memmove( data, state->gnutls_internals.buffer, length); + + /* overwrite buffer */ + memmove( state->gnutls_internals.buffer, &state->gnutls_internals.buffer[length], state->gnutls_internals.bufferSize); + state->gnutls_internals.buffer = gnutls_realloc( state->gnutls_internals.buffer, state->gnutls_internals.bufferSize); + } + return length; +} diff --git a/src/gnutls_buffers.h b/src/gnutls_buffers.h new file mode 100644 index 0000000000..d09ef12e15 --- /dev/null +++ b/src/gnutls_buffers.h @@ -0,0 +1,3 @@ +int gnutls_insertDataBuffer(GNUTLS_STATE state, ContentType type, char *data, int length); +int gnutls_getDataBufferSize(GNUTLS_STATE state, ContentType type); +int gnutls_getDataFromBuffer(GNUTLS_STATE state, ContentType type, char *data, int length); diff --git a/src/gnutls_cipher.c b/src/gnutls_cipher.c index 4a63d244cc..f2f5c26604 100644 --- a/src/gnutls_cipher.c +++ b/src/gnutls_cipher.c @@ -1,5 +1,7 @@ #include <defines.h> -#include "gnutls.h" +#include "gnutls_record.h" +#include "gnutls_handshake.h" +#include "gnutls_errors.h" #include "gnutls_compress.h" #include "gnutls_cipher.h" #include <mhash.h> diff --git a/src/gnutls_compress.c b/src/gnutls_compress.c index 253c0d6e16..91b6d59a99 100644 --- a/src/gnutls_compress.c +++ b/src/gnutls_compress.c @@ -1,6 +1,8 @@ #include <defines.h> -#include "gnutls.h" +#include "gnutls_record.h" +#include "gnutls_handshake.h" #include "gnutls_compress.h" +#include "gnutls_errors.h" int _gnutls_TLSPlaintext2TLSCompressed(GNUTLS_STATE state, GNUTLSCompressed ** diff --git a/src/gnutls_errors.h b/src/gnutls_errors.h new file mode 100644 index 0000000000..7781671e11 --- /dev/null +++ b/src/gnutls_errors.h @@ -0,0 +1,11 @@ +#define GNUTLS_E_MAC_FAILED -1 +#define GNUTLS_E_UNKNOWN_CIPHER -2 +#define GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM -3 +#define GNUTLS_E_UNKNOWN_MAC_ALGORITHM -4 +#define GNUTLS_E_UNKNOWN_ERROR -5 +#define GNUTLS_E_UNKNOWN_CIPHER_TYPE -6 +#define GNUTLS_E_LARGE_PACKET -7 +#define GNUTLS_E_UNSUPPORTED_VERSION_PACKET -8 +#define GNUTLS_E_UNEXPECTED_PACKET_LENGTH -9 +#define GNUTLS_E_INVALID_SESSION -10 +#define GNUTLS_E_UNABLE_SEND_DATA -11 diff --git a/src/gnutls_handshake.h b/src/gnutls_handshake.h new file mode 100644 index 0000000000..f56e0a4a7e --- /dev/null +++ b/src/gnutls_handshake.h @@ -0,0 +1,24 @@ +enum ChangeCipherSpecType { GNUTLS_TYPE_CHANGE_CIPHER_SPEC }; +enum AlertLevel { GNUTLS_WARNING, GNUTLS_FATAL }; +enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=10, GNUTLS_BAD_RECORD_MAC=20, + GNUTLS_DECRYPTION_FAILED, GNUTLS_RECORD_OVERFLOW, GNUTLS_DECOMPRESSION_FAILURE=30, + GNUTLS_HANDSHAKE_FAILURE=40, GNUTLS_BAD_CERTIFICATE=42, GNUTLS_UNSUPPORTED_CERTIFICATE, + GNUTLS_CERTIFICATE_REVOKED, GNUTLS_CERTIFICATE_EXPIRED, GNUTLS_CERTIFICATE_UNKNOWN, + GNUTLS_ILLEGAL_PARAMETER, GNUTLS_UNKNOWN_CA, GNUTLS_ACCESS_DENIED, GNUTLS_DECODE_ERROR=50, + GNUTLS_DECRYPT_ERROR, GNUTLS_EXPORT_RESTRICTION=60, GNUTLS_PROTOCOL_VERSION=70, + GNUTLS_INSUFFICIENT_SECURITY, GNUTLS_INTERNAL_ERROR=80, GNUTLS_USER_CANCELED=90, + GNUTLS_NO_RENEGOTIATION=100 + }; + +typedef enum AlertDescription AlertDescription; +typedef enum AlertLevel AlertLevel; +typedef enum ChangeCipherSpecType ChangeCipherSpecType; + +typedef struct { + ChangeCipherSpecType type; +} ChangeCipherSpec; + +typedef struct { + AlertLevel level; + AlertDescription description; +} Alert; diff --git a/src/gnutls_int.h b/src/gnutls_int.h new file mode 100644 index 0000000000..de10ca4ce7 --- /dev/null +++ b/src/gnutls_int.h @@ -0,0 +1 @@ +int _gnutls_send_alert( int cd, GNUTLS_STATE state, AlertLevel level, AlertDescription desc); diff --git a/src/gnutls_plaintext.c b/src/gnutls_plaintext.c index 25c8e0588c..3bb6c0656c 100644 --- a/src/gnutls_plaintext.c +++ b/src/gnutls_plaintext.c @@ -1,7 +1,7 @@ #include <defines.h> -#include "gnutls.h" - - +#include "gnutls_record.h" +#include "gnutls_handshake.h" +#include "gnutls_errors.h" /* Plaintext Handling */ int _gnutls_text2TLSPlaintext(ContentType type, GNUTLSPlaintext** plain, char *text, uint16 length) diff --git a/src/gnutls_record.h b/src/gnutls_record.h new file mode 100644 index 0000000000..9d246d6764 --- /dev/null +++ b/src/gnutls_record.h @@ -0,0 +1,147 @@ +#define svoid void /* for functions that allocate using secure_free */ +#define secure_free free +#define secure_malloc malloc +#define secure_realloc realloc +#define secure_calloc calloc +#define gnutls_malloc malloc +#define gnutls_realloc realloc +#define gnutls_calloc calloc +#define gnutls_free free + +#define rotl64(x,n) (((x) << ((uint16)(n))) | ((x) >> (64 - (uint16)(n)))) +#define rotr64(x,n) (((x) >> ((uint16)(n))) | ((x) << (64 - (uint16)(n)))) +#define rotl32(x,n) (((x) << ((uint16)(n))) | ((x) >> (32 - (uint16)(n)))) +#define rotr32(x,n) (((x) >> ((uint16)(n))) | ((x) << (32 - (uint16)(n)))) +#define rotl16(x,n) (((x) << ((uint16)(n))) | ((x) >> (16 - (uint16)(n)))) +#define rotr16(x,n) (((x) >> ((uint16)(n))) | ((x) << (16 - (uint16)(n)))) + +#define byteswap16(x) ((rotl16(x, 8) & 0x00ff) | (rotr16(x, 8) & 0xff00)) +#define byteswap32(x) ((rotl32(x, 8) & 0x00ff00ff) | (rotr32(x, 8) & 0xff00ff00)) +#define byteswap64(x) ((rotl64(x, 8) & 0x00ff00ff00ff00ff) | (rotr64(x, 8) & 0xff00ff00ff00ff00)) + +typedef unsigned char opaque; + +/* STATE */ +enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT }; +enum BulkCipherAlgorithm { CIPHER_NULL, CIPHER_3DES = 4 }; +enum CipherType { CIPHER_STREAM, CIPHER_BLOCK }; +enum IsExportable { EXPORTABLE_TRUE, EXPORTABLE_FALSE }; +enum MACAlgorithm { MAC_NULL, MAC_MD5, MAC_SHA }; +enum CompressionMethod { COMPRESSION_NULL }; + +enum ValidSession { VALID_TRUE, VALID_FALSE }; + +typedef enum ValidSession ValidSession; +typedef enum ConnectionEnd ConnectionEnd; +typedef enum BulkCipherAlgorithm BulkCipherAlgorithm; +typedef enum CipherType CipherType; +typedef enum IsExportable IsExportable; +typedef enum MACAlgorithm MACAlgorithm; +typedef enum CompressionMethod CompressionMethod; + +typedef struct { + ConnectionEnd entity; + BulkCipherAlgorithm bulk_cipher_algorithm; + CipherType cipher_type; + uint8 IV_size; /* not specified in the protocol, but later it + * uses it */ + uint8 key_size; + uint8 key_material_length; + IsExportable is_exportable; + MACAlgorithm mac_algorithm; + uint8 hash_size; + CompressionMethod compression_algorithm; + opaque master_secret[48]; + opaque client_random[32]; + opaque server_random[32]; +} SecurityParameters; + +typedef struct { + opaque* server_write_mac_secret; + opaque* client_write_mac_secret; + opaque* server_write_IV; + opaque* client_write_IV; + opaque* server_write_key; + opaque* client_write_key; +} CipherSpecs; + +typedef struct { + opaque* compression_state; + GCRY_CIPHER_HD cipher_state; + opaque* mac_secret; + uint8 mac_secret_size; + uint64 read_sequence_number; + uint64 write_sequence_number; +} ConnectionState; + +typedef struct { + char* buffer; + uint32 bufferSize; + ValidSession valid_connection; +} GNUTLS_INTERNALS; + +typedef struct { + SecurityParameters security_parameters; + CipherSpecs cipher_specs; + ConnectionState connection_state; + GNUTLS_INTERNALS gnutls_internals; +} GNUTLS_STATE_INT; + +typedef GNUTLS_STATE_INT *GNUTLS_STATE; + + +/* Record Protocol */ +#ifndef CONTENT_TYPE +#define CONTENT_TYPE +enum ContentType { GNUTLS_CHANGE_CIPHER_SPEC=20, GNUTLS_ALERT, GNUTLS_HANDSHAKE, + GNUTLS_APPLICATION_DATA }; +typedef enum ContentType ContentType; +#endif + +#define GNUTLS_VERSION_MAJOR 3 +#define GNUTLS_VERSION_MINOR 1 + +typedef struct { + uint8 major; + uint8 minor; +} ProtocolVersion; + +typedef struct { + ContentType type; + ProtocolVersion version; + uint16 length; + opaque* fragment; +} GNUTLSPlaintext; + +typedef struct { + ContentType type; + ProtocolVersion version; + uint16 length; + opaque* fragment; +} GNUTLSCompressed; + +/* This is used for both block ciphers and stream ciphers. In stream ciphers + * the padding is just ignored. + */ +typedef struct { + opaque* content; + opaque* MAC; + uint8* padding; + uint8 padding_length; +} GNUTLS_GenericBlockCipher; + +typedef struct { + opaque* content; + opaque* MAC; +} GNUTLS_GenericStreamCipher; + +typedef struct { + ContentType type; + ProtocolVersion version; + uint16 length; + void* fragment; /* points GenericStreamCipher + * or GenericBlockCipher + */ +} GNUTLSCiphertext; + + diff --git a/src/test.c b/src/test.c index 6252285cc0..15065a86a8 100644 --- a/src/test.c +++ b/src/test.c @@ -1,23 +1,20 @@ #include <defines.h> #include <gnutls.h> -#include "gnutls_compress.h" -#include "gnutls_plaintext.h" -#include "gnutls_cipher.h" #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> -//#define ENCRYPT +#define ENCRYPT int main() { GNUTLS_STATE state; char text[] = "A very large english test\n"; - GNUTLSPlaintext *gtxt; - GNUTLSCompressed *gcomp; - GNUTLSCiphertext *gcipher; + void *gtxt; + void *gcomp; + void *gcipher; int cd; int ret; char tmp[11]; |