diff options
-rw-r--r-- | lib/Makefile.am | 4 | ||||
-rw-r--r-- | lib/debug.c | 2 | ||||
-rw-r--r-- | lib/gnutls.h.in | 25 | ||||
-rw-r--r-- | lib/gnutls_algorithms.c | 22 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 24 | ||||
-rw-r--r-- | lib/gnutls_cipher.c | 250 | ||||
-rw-r--r-- | lib/gnutls_cipher.h | 13 | ||||
-rw-r--r-- | lib/gnutls_cipher_int.c | 6 | ||||
-rw-r--r-- | lib/gnutls_compress.c | 52 | ||||
-rw-r--r-- | lib/gnutls_compress.h | 13 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 104 | ||||
-rw-r--r-- | lib/gnutls_int.h | 55 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 20 | ||||
-rw-r--r-- | lib/gnutls_plaintext.c | 71 | ||||
-rw-r--r-- | lib/gnutls_plaintext.h | 23 | ||||
-rw-r--r-- | lib/gnutls_record.c | 105 | ||||
-rw-r--r-- | lib/gnutls_v2_compat.c | 35 | ||||
-rw-r--r-- | src/serv.c | 10 |
18 files changed, 332 insertions, 502 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index 7b6116d110..ffdcb960a0 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -4,7 +4,7 @@ bin_SCRIPTS = libgnutls-config m4datadir = $(datadir)/aclocal m4data_DATA = libgnutls.m4 -EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h \ +EXTRA_DIST = debug.h gnutls_compress.h defines.h \ gnutls_cipher.h gnutls_buffers.h gnutls_errors.h gnutls_int.h \ gnutls_handshake.h gnutls_num.h gnutls_algorithms.h gnutls_dh.h \ gnutls_kx.h gnutls_hash_int.h gnutls_cipher_int.h gnutls_db.h \ @@ -16,7 +16,7 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h \ cert_asn1.h cert_der.h gnutls_datum.h auth_x509.h gnutls_gcry.h \ ext_dnsname.h gnutls_pk.h gnutls_record.h lib_LTLIBRARIES = libgnutls.la -libgnutls_la_SOURCES = gnutls_record.c gnutls_compress.c debug.c gnutls_plaintext.c \ +libgnutls_la_SOURCES = gnutls_record.c gnutls_compress.c debug.c \ gnutls_cipher.c gnutls_buffers.c gnutls_handshake.c gnutls_num.c \ gnutls_errors.c gnutls_algorithms.c gnutls_dh.c gnutls_kx.c \ gnutls_priority.c gnutls_hash_int.c gnutls_cipher_int.c \ diff --git a/lib/debug.c b/lib/debug.c index ffc1eb6756..2c61d408bd 100644 --- a/lib/debug.c +++ b/lib/debug.c @@ -63,8 +63,6 @@ void _gnutls_print_state(GNUTLS_STATE state) state->security_parameters.entity); fprintf(stderr, "Cipher Algorithm: %d\n", state->security_parameters.bulk_cipher_algorithm); - fprintf(stderr, "Cipher Type: %d\n", - state->security_parameters.cipher_type); fprintf(stderr, "Key Size: %d\n", state->security_parameters.key_size); fprintf(stderr, "Key Material: %d\n", diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in index 5b50b57b5f..80a5e61748 100644 --- a/lib/gnutls.h.in +++ b/lib/gnutls.h.in @@ -40,6 +40,7 @@ typedef enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=1 typedef enum GNUTLS_Version { GNUTLS_TLS1, GNUTLS_SSL3 } GNUTLS_Version; +#define SOCKET int #define LIST ... struct GNUTLS_STATE_INT; @@ -54,10 +55,10 @@ typedef struct { int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end); int gnutls_deinit(GNUTLS_STATE state); -int gnutls_bye(int cd, GNUTLS_STATE state); -int gnutls_handshake(int cd, GNUTLS_STATE state); +int gnutls_bye(SOCKET cd, GNUTLS_STATE state); +int gnutls_handshake(SOCKET cd, GNUTLS_STATE state); int gnutls_check_pending(GNUTLS_STATE state); -int gnutls_rehandshake(int cd, GNUTLS_STATE state); +int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state); AlertDescription gnutls_get_last_alert( GNUTLS_STATE state); @@ -68,21 +69,21 @@ MACAlgorithm gnutls_get_current_mac_algorithm( GNUTLS_STATE state); CompressionMethod gnutls_get_current_compression_method( GNUTLS_STATE state); /* the name of the specified algorithms */ -char *gnutls_cipher_get_name(BulkCipherAlgorithm); -char *gnutls_mac_get_name(MACAlgorithm); -char *gnutls_compression_get_name(CompressionMethod); -char *gnutls_kx_get_name(KXAlgorithm algorithm); +char *gnutls_cipher_get_name( BulkCipherAlgorithm); +char *gnutls_mac_get_name( MACAlgorithm); +char *gnutls_compression_get_name( CompressionMethod); +char *gnutls_kx_get_name( KXAlgorithm algorithm); /* error functions */ int gnutls_is_fatal_error( int error); void gnutls_perror( int error); -char* gnutls_strerror(int error); +char* gnutls_strerror( int error); -ssize_t gnutls_send(int cd, GNUTLS_STATE state, void *data, size_t sizeofdata, int flags); -ssize_t gnutls_recv(int cd, GNUTLS_STATE state, void *data, size_t sizeofdata, int flags); -ssize_t gnutls_write(int cd, GNUTLS_STATE state, void *data, size_t sizeofdata); -ssize_t gnutls_read(int cd, GNUTLS_STATE state, void *data, size_t sizeofdata); +ssize_t gnutls_send(SOCKET cd, GNUTLS_STATE state, void *data, size_t sizeofdata, int flags); +ssize_t gnutls_recv(SOCKET cd, GNUTLS_STATE state, void *data, size_t sizeofdata, int flags); +ssize_t gnutls_write(SOCKET cd, GNUTLS_STATE state, void *data, size_t sizeofdata); +ssize_t gnutls_read(SOCKET cd, GNUTLS_STATE state, void *data, size_t sizeofdata); /* functions to set priority of cipher suites */ void gnutls_set_cipher_priority( GNUTLS_STATE state, LIST); diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index db40ae6632..e9314f39ae 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -92,23 +92,23 @@ struct gnutls_cipher_entry { BulkCipherAlgorithm id; size_t blocksize; size_t keysize; - size_t block; + CipherType block; size_t iv; }; typedef struct gnutls_cipher_entry gnutls_cipher_entry; /* Note that all algorithms are in CBC or STREAM modes. - * Do not add any algorithms in other modes. + * Do not add any algorithms in other modes (avoid modified algorithms). * View first: "The order of encryption and authentication for * protecting communications" by Hugo Krawczyk - CRYPTO 2001 */ static const gnutls_cipher_entry algorithms[] = { - GNUTLS_CIPHER_ENTRY(GNUTLS_3DES_CBC, 8, 24, 1, 8), - GNUTLS_CIPHER_ENTRY(GNUTLS_RIJNDAEL_CBC, 16, 16, 1, 16), - GNUTLS_CIPHER_ENTRY(GNUTLS_RIJNDAEL256_CBC, 16, 32, 1, 16), - GNUTLS_CIPHER_ENTRY(GNUTLS_TWOFISH_CBC, 16, 16, 1, 16), - GNUTLS_CIPHER_ENTRY(GNUTLS_ARCFOUR, 1, 16, 0, 0), - GNUTLS_CIPHER_ENTRY(GNUTLS_NULL_CIPHER, 1, 0, 0, 0), + GNUTLS_CIPHER_ENTRY(GNUTLS_3DES_CBC, 8, 24, CIPHER_BLOCK, 8), + GNUTLS_CIPHER_ENTRY(GNUTLS_RIJNDAEL_CBC, 16, 16, CIPHER_BLOCK, 16), + GNUTLS_CIPHER_ENTRY(GNUTLS_RIJNDAEL256_CBC, 16, 32, CIPHER_BLOCK, 16), + GNUTLS_CIPHER_ENTRY(GNUTLS_TWOFISH_CBC, 16, 16, CIPHER_BLOCK, 16), + GNUTLS_CIPHER_ENTRY(GNUTLS_ARCFOUR, 1, 16, CIPHER_STREAM, 0), + GNUTLS_CIPHER_ENTRY(GNUTLS_NULL_CIPHER, 1, 0, CIPHER_STREAM, 0), {0} }; @@ -222,6 +222,8 @@ typedef struct { MACAlgorithm mac_algorithm; } gnutls_cipher_suite_entry; +#define GNUTLS_RSA_NULL_MD5 { 0x00, 0x01 } + #define GNUTLS_DH_anon_3DES_EDE_CBC_SHA { 0x00, 0x1B } #define GNUTLS_DH_anon_ARCFOUR_MD5 { 0x00, 0x18 } #define GNUTLS_DH_anon_RIJNDAEL_128_CBC_SHA { 0x00, 0x34 } @@ -366,6 +368,10 @@ static const gnutls_cipher_suite_entry cs_algorithms[] = { GNUTLS_MAC_SHA), /* RSA */ + GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_RSA_NULL_MD5, + GNUTLS_NULL_CIPHER, + GNUTLS_KX_RSA, GNUTLS_MAC_MD5), + GNUTLS_CIPHER_SUITE_ENTRY(GNUTLS_RSA_ARCFOUR_SHA, GNUTLS_ARCFOUR, GNUTLS_KX_RSA, GNUTLS_MAC_SHA), diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index ece8fcf625..69240d174c 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -22,7 +22,7 @@ #include "gnutls_int.h" #include "gnutls_errors.h" #ifdef HAVE_ERRNO_H -# include <errno.h> + # include <errno.h> #endif int gnutls_insertDataBuffer(ContentType type, GNUTLS_STATE state, char *data, int length) @@ -35,7 +35,7 @@ int gnutls_insertDataBuffer(ContentType type, GNUTLS_STATE state, char *data, in state->gnutls_internals.buffer.size += length; #ifdef BUFFERS_DEBUG - fprintf(stderr, "Inserted %d bytes of Data(%d) into buffer\n", length, type); + fprintf(stderr, "BUFFER: Inserted %d bytes of Data(%d)\n", length, type); #endif state->gnutls_internals.buffer.data = gnutls_realloc(state->gnutls_internals.buffer.data, @@ -47,7 +47,7 @@ int gnutls_insertDataBuffer(ContentType type, GNUTLS_STATE state, char *data, in state->gnutls_internals.buffer_handshake.size += length; #ifdef BUFFERS_DEBUG - fprintf(stderr, "Inserted %d bytes of Data(%d) into buffer\n", length, type); + fprintf(stderr, "BUFFER: Inserted %d bytes of Data(%d)\n", length, type); #endif state->gnutls_internals.buffer_handshake.data = gnutls_realloc(state->gnutls_internals.buffer_handshake.data, @@ -91,7 +91,7 @@ int gnutls_getDataFromBuffer(ContentType type, GNUTLS_STATE state, char *data, i length = state->gnutls_internals.buffer.size; } #ifdef BUFFERS_DEBUG - fprintf(stderr, "Read %d bytes of Data(%d) from buffer\n", length, type); + fprintf(stderr, "BUFFER: Read %d bytes of Data(%d)\n", length, type); #endif state->gnutls_internals.buffer.size -= length; memmove(data, state->gnutls_internals.buffer.data, length); @@ -109,7 +109,7 @@ int gnutls_getDataFromBuffer(ContentType type, GNUTLS_STATE state, char *data, i length = state->gnutls_internals.buffer_handshake.size; } #ifdef BUFFERS_DEBUG - fprintf(stderr, "Read %d bytes of Data(%d) from buffer\n", length, type); + fprintf(stderr, "BUFFER: Read %d bytes of Data(%d)\n", length, type); #endif state->gnutls_internals.buffer_handshake.size -= length; memmove(data, state->gnutls_internals.buffer_handshake.data, length); @@ -155,7 +155,7 @@ ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag) } #ifdef READ_DEBUG - fprintf(stderr, "read %d bytes from %d\n", (sizeOfPtr-left), fd); + fprintf(stderr, "READ: read %d bytes from %d\n", (sizeOfPtr-left), fd); for (x=0;x<((sizeOfPtr-left)/16)+1;x++) { fprintf(stderr, "%.4x - ",x); for (j=0;j<16;j++) { @@ -186,7 +186,7 @@ ssize_t _gnutls_Write(int fd, const void *iptr, size_t n) const char *ptr = iptr; #ifdef WRITE_DEBUG - fprintf(stderr, "wrote %d bytes to %d\n", n, fd); + fprintf(stderr, "WRITE: wrote %d bytes to %d\n", n, fd); for (x=0;x<(n/16)+1;x++) { fprintf(stderr, "%.4x - ",x); for (j=0;j<16;j++) { @@ -261,7 +261,7 @@ int gnutls_insertHashDataBuffer( GNUTLS_STATE state, char *data, int length) state->gnutls_internals.hash_buffer.size += length; #ifdef BUFFERS_DEBUG - fprintf(stderr, "Inserted %d bytes of Hash Data into buffer\n", length); + fprintf(stderr, "HASH_BUFFER: Inserted %d bytes of Data\n", length); #endif state->gnutls_internals.hash_buffer.data = gnutls_realloc(state->gnutls_internals.hash_buffer.data, @@ -283,7 +283,7 @@ int gnutls_getHashDataFromBuffer( GNUTLS_STATE state, char *data, int length) length = state->gnutls_internals.hash_buffer.size; } #ifdef BUFFERS_DEBUG - fprintf(stderr, "Got %d bytes of Hash Data from buffer\n", length); + fprintf(stderr, "HASH BUFFER: Got %d bytes of Data\n", length); #endif state->gnutls_internals.hash_buffer.size -= length; memmove(data, state->gnutls_internals.hash_buffer.data, length); @@ -299,13 +299,15 @@ int gnutls_getHashDataFromBuffer( GNUTLS_STATE state, char *data, int length) } +/* this function does not touch the buffer + */ int gnutls_readHashDataFromBuffer( GNUTLS_STATE state, char *data, int length) { if (length > state->gnutls_internals.hash_buffer.size) { length = state->gnutls_internals.hash_buffer.size; } #ifdef BUFFERS_DEBUG - fprintf(stderr, "Read %d bytes of Hash Data from buffer\n", length); + fprintf(stderr, "HASH BUFFER: Read %d bytes of Data\n", length); #endif memmove(data, state->gnutls_internals.hash_buffer.data, length); return length; @@ -317,7 +319,7 @@ int gnutls_clearHashDataBuffer( GNUTLS_STATE state) { #ifdef BUFFERS_DEBUG - fprintf(stderr, "Cleared Hash Data from buffer\n"); + fprintf(stderr, "HASH BUFFER: Cleared Data from buffer\n"); #endif state->gnutls_internals.hash_buffer.size = 0; if (state->gnutls_internals.hash_buffer.data!=NULL) diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index 2c9b24eeb5..12d8eecc1b 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -26,101 +26,71 @@ #include "gnutls_algorithms.h" #include "gnutls_hash_int.h" #include "gnutls_cipher_int.h" -#include "gnutls_plaintext.h" #include "debug.h" #include "gnutls_random.h" #include "gnutls_num.h" +#include "gnutls_datum.h" int _gnutls_encrypt(GNUTLS_STATE state, const char *data, size_t data_size, uint8 ** ciphertext, ContentType type) { - GNUTLSPlaintext *gtxt; - GNUTLSCompressed *gcomp; - GNUTLSCiphertext *gcipher; - int total_length, err; + gnutls_datum plain = { (char*)data, data_size }; + gnutls_datum comp, ciph; + int err; if (data_size == 0) return 0; - err = - _gnutls_text2TLSPlaintext(state, type, >xt, data, data_size); + err = _gnutls_plaintext2TLSCompressed(state, &comp, plain); if (err < 0) { gnutls_assert(); return err; } - err = _gnutls_TLSPlaintext2TLSCompressed(state, &gcomp, gtxt); + err = _gnutls_compressed2TLSCiphertext(state, &ciph, comp, type); if (err < 0) { gnutls_assert(); return err; } - _gnutls_freeTLSPlaintext(gtxt); + gnutls_free_datum(&comp); - err = _gnutls_TLSCompressed2TLSCiphertext(state, &gcipher, gcomp); - if (err < 0) { - gnutls_assert(); - return err; - } - - _gnutls_freeTLSCompressed(gcomp); + *ciphertext = ciph.data; - total_length = HEADER_SIZE + gcipher->length; - *ciphertext = gnutls_malloc(total_length); - if (*ciphertext == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - memmove( &(*ciphertext)[HEADER_SIZE], gcipher->fragment, gcipher->length); - _gnutls_freeTLSCiphertext(gcipher); - - return total_length - HEADER_SIZE; - /* notice that the headers are not present in the retun value, - * but there is space for them - */ + return ciph.size; } int _gnutls_decrypt(GNUTLS_STATE state, char *ciphertext, size_t ciphertext_size, uint8 ** data, ContentType type) { - GNUTLSPlaintext *gtxt; - GNUTLSCompressed *gcomp; - GNUTLSCiphertext gcipher; + gnutls_datum gtxt; + gnutls_datum gcomp; + gnutls_datum gcipher; int ret; if (ciphertext_size == 0) return 0; - gcipher.type = type; - gcipher.length = ciphertext_size; - gcipher.version.major = _gnutls_version_get_major(state->connection_state.version); - gcipher.version.minor = _gnutls_version_get_minor(state->connection_state.version); - gcipher.fragment = gnutls_malloc(ciphertext_size); - memmove(gcipher.fragment, ciphertext, ciphertext_size); + gcipher.size = ciphertext_size; + gcipher.data = ciphertext; - ret = _gnutls_TLSCiphertext2TLSCompressed(state, &gcomp, &gcipher); + ret = _gnutls_ciphertext2TLSCompressed(state, &gcomp, gcipher, type); if (ret < 0) { - gnutls_free(gcipher.fragment); return ret; } - gnutls_free(gcipher.fragment); - ret = _gnutls_TLSCompressed2TLSPlaintext(state, >xt, gcomp); + ret = _gnutls_TLSCompressed2plaintext(state, >xt, gcomp); if (ret < 0) { return ret; } - _gnutls_freeTLSCompressed(gcomp); - - ret = _gnutls_TLSPlaintext2text((void *) data, gtxt); - if (ret < 0) { - return ret; - } - ret = gtxt->length; + gnutls_free_datum(&gcomp); - _gnutls_freeTLSPlaintext(gtxt); + ret = gtxt.size; + *data = gtxt.data; + return ret; } @@ -136,13 +106,6 @@ int _gnutls_set_cipher(GNUTLS_STATE state, BulkCipherAlgorithm algo) } state->security_parameters.bulk_cipher_algorithm = algo; - if (_gnutls_cipher_is_block(algo) == 1) { - state->security_parameters.cipher_type = - CIPHER_BLOCK; - } else { - state->security_parameters.cipher_type = - CIPHER_STREAM; - } state->security_parameters.key_material_length = state->security_parameters.key_size = @@ -316,8 +279,10 @@ int _gnutls_connection_state_init(GNUTLS_STATE state) if (mac_size > 0) { state->connection_state.read_mac_secret = gnutls_malloc(mac_size); + if (state->connection_state.read_mac_secret==NULL) return GNUTLS_E_MEMORY_ERROR; state->connection_state.write_mac_secret = gnutls_malloc(mac_size); + if (state->connection_state.write_mac_secret==NULL) return GNUTLS_E_MEMORY_ERROR; } } else { gnutls_assert(); @@ -424,14 +389,15 @@ int _gnutls_connection_state_init(GNUTLS_STATE state) return 0; } -/* This is the actual encryption */ -int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, - GNUTLSCiphertext ** +/* This is the actual encryption + * (and also keeps some space for headers in the encrypted data) + */ +int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state, + gnutls_datum* cipher, - GNUTLSCompressed * compressed) + gnutls_datum compressed, ContentType _type) { - GNUTLSCiphertext *ciphertext; - uint8 *content, *MAC = NULL; + uint8 *MAC = NULL; uint16 c_length; uint8 *data; uint8 pad; @@ -439,15 +405,14 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, uint64 seq_num; int length; GNUTLS_MAC_HANDLE td; + uint8 type = _type; + uint8 major, minor; int blocksize = _gnutls_cipher_get_block_size(state->security_parameters. bulk_cipher_algorithm); - content = gnutls_malloc(compressed->length); - memmove(content, compressed->fragment, compressed->length); - - *cipher = gnutls_malloc(sizeof(GNUTLSCiphertext)); - ciphertext = *cipher; + minor = _gnutls_version_get_minor(state->connection_state.version); + major = _gnutls_version_get_major(state->connection_state.version); if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ td = @@ -468,50 +433,49 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, } if (td == GNUTLS_MAC_FAILED && state->security_parameters.mac_algorithm != GNUTLS_NULL_MAC) { - gnutls_free(*cipher); - gnutls_free(content); gnutls_assert(); return GNUTLS_E_UNKNOWN_MAC_ALGORITHM; } - c_length = CONVuint16(compressed->length); + c_length = CONVuint16(compressed.size); seq_num = CONVuint64(&state->connection_state.write_sequence_number); if (td != GNUTLS_MAC_FAILED) { /* actually when the algorithm in not the NULL one */ gnutls_hmac(td, UINT64DATA(seq_num), 8); - gnutls_hmac(td, &compressed->type, 1); + gnutls_hmac(td, &type, 1); if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 only */ - gnutls_hmac(td, &compressed->version.major, 1); - gnutls_hmac(td, &compressed->version.minor, 1); + gnutls_hmac(td, &major, 1); + gnutls_hmac(td, &minor, 1); } gnutls_hmac(td, &c_length, 2); - gnutls_hmac(td, compressed->fragment, compressed->length); + gnutls_hmac(td, compressed.data, compressed.size); if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ MAC = gnutls_mac_deinit_ssl3(td); } else { MAC = gnutls_hmac_deinit(td); } } - switch (state->security_parameters.cipher_type) { + switch (_gnutls_cipher_is_block(state->security_parameters.bulk_cipher_algorithm)) { case CIPHER_STREAM: length = - compressed->length + + compressed.size + state->security_parameters.hash_size; data = gnutls_malloc(length); - memmove(data, content, compressed->length); - memmove(&data[compressed->length], MAC, + if (data==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + memmove(data, compressed.data, compressed.size); + memmove(&data[compressed.size], MAC, state->security_parameters.hash_size); gnutls_cipher_encrypt(state->connection_state. write_cipher_state, data, length); - ciphertext->fragment = data; - ciphertext->length = length; - ciphertext->type = compressed->type; - ciphertext->version.major = compressed->version.major; - ciphertext->version.minor = compressed->version.minor; + cipher->data = data; + cipher->size = length; break; case CIPHER_BLOCK: @@ -532,66 +496,60 @@ int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, } length = - compressed->length + + compressed.size + state->security_parameters.hash_size; pad = (uint8) (blocksize - (length % blocksize)) + rand; length += pad; data = gnutls_malloc(length); - + if (data==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } memset(&data[length - pad], pad - 1, pad); - memmove(data, content, compressed->length); - memmove(&data[compressed->length], MAC, + memmove(data, compressed.data, compressed.size); + memmove(&data[compressed.size], MAC, state->security_parameters.hash_size); gnutls_cipher_encrypt(state->connection_state. write_cipher_state, data, length); - ciphertext->fragment = data; - ciphertext->length = length; - ciphertext->type = compressed->type; - ciphertext->version.major = compressed->version.major; - ciphertext->version.minor = compressed->version.minor; + cipher->data = data; + cipher->size = length; break; default: - gnutls_free(*cipher); - gnutls_free(content); gnutls_assert(); return GNUTLS_E_UNKNOWN_CIPHER_TYPE; } if (td != GNUTLS_MAC_FAILED) gnutls_free(MAC); - gnutls_free(content); return 0; } -int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state, - GNUTLSCompressed ** +int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state, + gnutls_datum * compress, - GNUTLSCiphertext * ciphertext) + gnutls_datum ciphertext, uint8 type) { - GNUTLSCompressed *compressed; - uint8 *content, *MAC = NULL; + uint8 *MAC = NULL; uint16 c_length; uint8 *data; uint8 pad; uint64 seq_num; uint16 length; GNUTLS_MAC_HANDLE td; - int blocksize = - _gnutls_cipher_get_block_size(state->security_parameters. - bulk_cipher_algorithm); - - content = gnutls_malloc(ciphertext->length); - memmove(content, ciphertext->fragment, ciphertext->length); + int blocksize; + uint8 major, minor; - *compress = gnutls_malloc(sizeof(GNUTLSCompressed)); - compressed = *compress; + minor = _gnutls_version_get_minor(state->connection_state.version); + major = _gnutls_version_get_major(state->connection_state.version); + blocksize = _gnutls_cipher_get_block_size(state->security_parameters. + bulk_cipher_algorithm); if (_gnutls_version_ssl3(state->connection_state.version) == 0) { td = @@ -612,76 +570,75 @@ int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state, } if (td == GNUTLS_MAC_FAILED && state->security_parameters.mac_algorithm != GNUTLS_NULL_MAC) { - gnutls_free(*compress); - gnutls_free(content); gnutls_assert(); return GNUTLS_E_UNKNOWN_MAC_ALGORITHM; } - - switch (state->security_parameters.cipher_type) { + switch (_gnutls_cipher_is_block(state->security_parameters.bulk_cipher_algorithm)) { case CIPHER_STREAM: length = - ciphertext->length - + ciphertext.size - state->security_parameters.hash_size; data = gnutls_malloc(length); - memmove(data, content, length); + if (data==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + memmove(data, ciphertext.data, length); - compressed->fragment = data; - compressed->length = length; - compressed->type = ciphertext->type; - compressed->version.major = ciphertext->version.major; - compressed->version.minor = ciphertext->version.minor; + compress->data = data; + compress->size = length; break; case CIPHER_BLOCK: - if ((ciphertext->length < blocksize) - || (ciphertext->length % blocksize != 0)) { + if ((ciphertext.size < blocksize) + || (ciphertext.size % blocksize != 0)) { gnutls_assert(); return GNUTLS_E_DECRYPTION_FAILED; } gnutls_cipher_decrypt(state->connection_state. - read_cipher_state, content, - ciphertext->length); + read_cipher_state, ciphertext.data, + ciphertext.size); - pad = content[ciphertext->length - 1] + 1; /* pad */ + pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */ length = - ciphertext->length - + ciphertext.size - state->security_parameters.hash_size - pad; if (pad > - ciphertext->length - + ciphertext.size - state->security_parameters.hash_size) { gnutls_assert(); return GNUTLS_E_RECEIVED_BAD_MESSAGE; } data = gnutls_malloc(length); - memmove(data, content, length); - compressed->fragment = data; - compressed->length = length; - compressed->type = ciphertext->type; - compressed->version.major = ciphertext->version.major; - compressed->version.minor = ciphertext->version.minor; + if (data==NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + memmove(data, ciphertext.data, length); + compress->data = data; + compress->size = length; break; default: - gnutls_free(*compress); - gnutls_free(content); gnutls_assert(); return GNUTLS_E_UNKNOWN_CIPHER_TYPE; } - c_length = CONVuint16((uint16) compressed->length); + c_length = CONVuint16((uint16) compress->size); seq_num = CONVuint64( &state->connection_state.read_sequence_number); if (td != GNUTLS_MAC_FAILED) { gnutls_hmac(td, UINT64DATA(seq_num), 8); - gnutls_hmac(td, &compressed->type, 1); + gnutls_hmac(td, &type, 1); if (_gnutls_version_ssl3(state->connection_state.version) != 0) { /* TLS 1.0 only */ - gnutls_hmac(td, &compressed->version.major, 1); - gnutls_hmac(td, &compressed->version.minor, 1); + gnutls_hmac(td, &major, 1); + gnutls_hmac(td, &minor, 1); } gnutls_hmac(td, &c_length, 2); - gnutls_hmac(td, data, compressed->length); + gnutls_hmac(td, data, compress->size); if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3.0 */ MAC = gnutls_mac_deinit_ssl3(td); } else { @@ -690,7 +647,7 @@ int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state, } /* HMAC was not the same. */ if (memcmp - (MAC, &content[compressed->length], + (MAC, &ciphertext.data[compress->size], state->security_parameters.hash_size) != 0) { gnutls_assert(); return GNUTLS_E_MAC_FAILED; @@ -699,18 +656,7 @@ int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state, if (td != GNUTLS_MAC_FAILED) gnutls_free(MAC); - gnutls_free(content); return 0; } -int _gnutls_freeTLSCiphertext(GNUTLSCiphertext * ciphertext) -{ - if (ciphertext == NULL) - return 0; - - gnutls_free(ciphertext->fragment); - gnutls_free(ciphertext); - - return 0; -} diff --git a/lib/gnutls_cipher.h b/lib/gnutls_cipher.h index 3176b22e38..e348e7cf4a 100644 --- a/lib/gnutls_cipher.h +++ b/lib/gnutls_cipher.h @@ -22,18 +22,9 @@ int _gnutls_encrypt( GNUTLS_STATE state, const char* data, size_t data_size, uin int _gnutls_decrypt(GNUTLS_STATE state, char *ciphertext, size_t ciphertext_size, uint8 ** data, ContentType type); -int _gnutls_TLSCompressed2TLSCiphertext(GNUTLS_STATE state, - GNUTLSCiphertext** - cipher, - GNUTLSCompressed * - compressed); -int _gnutls_freeTLSCiphertext(GNUTLSCiphertext * ciphertext); +int _gnutls_compressed2TLSCiphertext(GNUTLS_STATE state, gnutls_datum* cipher, gnutls_datum compressed, ContentType _type); int _gnutls_set_cipher( GNUTLS_STATE state, BulkCipherAlgorithm algo); int _gnutls_set_mac( GNUTLS_STATE state, MACAlgorithm algo); int _gnutls_set_compression( GNUTLS_STATE state, CompressionMethod algo); int _gnutls_connection_state_init(GNUTLS_STATE state); -int _gnutls_TLSCiphertext2TLSCompressed(GNUTLS_STATE state, - GNUTLSCompressed** - compress, - GNUTLSCiphertext * - ciphertext); +int _gnutls_ciphertext2TLSCompressed(GNUTLS_STATE state, gnutls_datum * compress, gnutls_datum ciphertext, uint8 type); diff --git a/lib/gnutls_cipher_int.c b/lib/gnutls_cipher_int.c index c107b9ea51..97d3600bc0 100644 --- a/lib/gnutls_cipher_int.c +++ b/lib/gnutls_cipher_int.c @@ -85,7 +85,7 @@ return ret; } int gnutls_cipher_encrypt(GNUTLS_CIPHER_HANDLE handle, void* text, int textlen) { - if (handle!=NULL) { + if (handle!=GNUTLS_CIPHER_FAILED) { #ifdef USE_MCRYPT mcrypt_generic( handle, text, textlen); #else @@ -99,7 +99,7 @@ int gnutls_cipher_encrypt(GNUTLS_CIPHER_HANDLE handle, void* text, int textlen) } int gnutls_cipher_decrypt(GNUTLS_CIPHER_HANDLE handle, void* ciphertext, int ciphertextlen) { - if (handle!=NULL) { + if (handle!=GNUTLS_CIPHER_FAILED) { #ifdef USE_MCRYPT mdecrypt_generic( handle, ciphertext, ciphertextlen); #else @@ -113,7 +113,7 @@ int gnutls_cipher_decrypt(GNUTLS_CIPHER_HANDLE handle, void* ciphertext, int cip } void gnutls_cipher_deinit(GNUTLS_CIPHER_HANDLE handle) { - if (handle!=NULL) { + if (handle!=GNUTLS_CIPHER_FAILED) { #ifdef USE_MCRYPT mcrypt_generic_end( handle); #else diff --git a/lib/gnutls_compress.c b/lib/gnutls_compress.c index 806f3ff3ea..fe0fcc5ef7 100644 --- a/lib/gnutls_compress.c +++ b/lib/gnutls_compress.c @@ -24,62 +24,44 @@ #include "gnutls_errors.h" #include "gnutls_compress_int.h" -int _gnutls_TLSPlaintext2TLSCompressed(GNUTLS_STATE state, - GNUTLSCompressed ** +int _gnutls_plaintext2TLSCompressed(GNUTLS_STATE state, + gnutls_datum* compress, - GNUTLSPlaintext * - plaintext) + gnutls_datum plaintext) { int size; - GNUTLSCompressed *compressed; char *data; - *compress = gnutls_malloc(sizeof(GNUTLSCompressed)); - compressed = *compress; - data=NULL; - size = gnutls_compress( state->security_parameters.compression_algorithm, plaintext->fragment, plaintext->length, &data); + size = gnutls_compress( state->security_parameters.compression_algorithm, plaintext.data, plaintext.size, &data); if (size < 0) { if (data!=NULL) gnutls_free(data); - gnutls_free(*compress); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } - compressed->fragment = data; - compressed->length = size; - compressed->type = plaintext->type; - compressed->version.major = plaintext->version.major; - compressed->version.minor = plaintext->version.minor; + compress->data = data; + compress->size = size; return 0; } -int _gnutls_TLSCompressed2TLSPlaintext(GNUTLS_STATE state, - GNUTLSPlaintext** - plain, - GNUTLSCompressed * +int _gnutls_TLSCompressed2plaintext(GNUTLS_STATE state, + gnutls_datum* plain, + gnutls_datum compressed) { - GNUTLSPlaintext *plaintext; int size; char* data; - *plain = gnutls_malloc(sizeof(GNUTLSPlaintext)); - plaintext = *plain; - data=NULL; - size = gnutls_decompress( state->security_parameters.compression_algorithm, compressed->fragment, compressed->length, &data); + size = gnutls_decompress( state->security_parameters.compression_algorithm, compressed.data, compressed.size, &data); if (size < 0) { if (data!=NULL) gnutls_free(data); - gnutls_free(*plain); return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM; } - plaintext->fragment = data; - plaintext->length = size; - plaintext->type = compressed->type; - plaintext->version.major = compressed->version.major; - plaintext->version.minor = compressed->version.minor; + plain->data = data; + plain->size = size; return 0; } @@ -87,13 +69,3 @@ int _gnutls_TLSCompressed2TLSPlaintext(GNUTLS_STATE state, -int _gnutls_freeTLSCompressed(GNUTLSCompressed * compressed) -{ - if (compressed == NULL) - return 0; - - gnutls_free(compressed->fragment); - gnutls_free(compressed); - - return 0; -} diff --git a/lib/gnutls_compress.h b/lib/gnutls_compress.h index 91143e073e..e526a2a481 100644 --- a/lib/gnutls_compress.h +++ b/lib/gnutls_compress.h @@ -18,14 +18,5 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -int _gnutls_freeTLSCompressed(GNUTLSCompressed * compressed); -int _gnutls_TLSPlaintext2TLSCompressed(GNUTLS_STATE state, - GNUTLSCompressed ** - compress, - GNUTLSPlaintext * - plaintext); -int _gnutls_TLSCompressed2TLSPlaintext(GNUTLS_STATE state, - GNUTLSPlaintext** - plain, - GNUTLSCompressed * - compressed); +int _gnutls_plaintext2TLSCompressed(GNUTLS_STATE state, gnutls_datum* compress, gnutls_datum plaintext); +int _gnutls_TLSCompressed2plaintext(GNUTLS_STATE state, gnutls_datum* plain, gnutls_datum compressed); diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index ff1e254e7e..c33356db78 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -25,7 +25,6 @@ #include "debug.h" #include "gnutls_algorithms.h" #include "gnutls_compress.h" -#include "gnutls_plaintext.h" #include "gnutls_cipher.h" #include "gnutls_buffers.h" #include "gnutls_kx.h" @@ -51,14 +50,14 @@ static int SelectSuite(GNUTLS_STATE state, opaque ret[2], char *data, int datale int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret, opaque * data, int datalen); void _gnutls_set_server_random( GNUTLS_STATE state, uint8* random) { - memcpy( state->security_parameters.server_random, random, 32); + memcpy( state->security_parameters.server_random, random, TLS_RANDOM_SIZE); if (state->gnutls_key!=NULL) - memcpy( state->gnutls_key->server_random, random, 32); + memcpy( state->gnutls_key->server_random, random, TLS_RANDOM_SIZE); } void _gnutls_set_client_random( GNUTLS_STATE state, uint8* random) { - memcpy( state->security_parameters.client_random, random, 32); + memcpy( state->security_parameters.client_random, random, TLS_RANDOM_SIZE); if (state->gnutls_key!=NULL) - memcpy( state->gnutls_key->client_random, random, 32); + memcpy( state->gnutls_key->client_random, random, TLS_RANDOM_SIZE); } /* Calculate The SSL3 Finished message */ @@ -155,18 +154,18 @@ void *_gnutls_finished(GNUTLS_STATE state, int type, int skip) return data; } -/* this function will produce 32 bytes of random data +/* this function will produce TLS_RANDOM_SIZE bytes of random data * and put it to dst. */ int _gnutls_create_random( opaque* dst) { uint32 tim; -opaque rand[28]; +opaque rand[TLS_RANDOM_SIZE-4]; tim = time(NULL); /* generate server random value */ WRITEuint32( tim, dst); - if (_gnutls_get_random(rand, 28, GNUTLS_STRONG_RANDOM) < 0) { + if (_gnutls_get_random(rand, TLS_RANDOM_SIZE-4, GNUTLS_STRONG_RANDOM) < 0) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } @@ -177,8 +176,8 @@ opaque rand[28]; /* Read a client hello * client hello must be a known version client hello - * or version 2.0 client hello (only for compatibility) - * version 2.0 is not supported. + * or version 2.0 client hello (only for compatibility + * since SSL version 2.0 is not supported). */ #define DECR_LEN(len, x) len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;} @@ -193,8 +192,8 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data, GNUTLS_Version version; int len = datalen; int err; - opaque random[32]; - + opaque random[TLS_RANDOM_SIZE]; + if (state->gnutls_internals.v2_hello!=0) { /* version 2.0 */ return _gnutls_read_client_hello_v2(state, data, datalen); } @@ -218,9 +217,9 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data, pos += 2; - DECR_LEN(len, 32); + DECR_LEN(len, TLS_RANDOM_SIZE); _gnutls_set_client_random( state, &data[pos]); - pos += 32; + pos += TLS_RANDOM_SIZE; _gnutls_create_random( random); _gnutls_set_server_random( state, random); @@ -231,7 +230,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data, memcpy(&session_id_len, &data[pos++], 1); /* RESUME SESSION */ - if (session_id_len > 32) { + if (session_id_len > TLS_MAX_SESSION_ID_SIZE) { gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } @@ -246,10 +245,10 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data, /* get the new random values */ memcpy(state->gnutls_internals.resumed_security_parameters. server_random, - state->security_parameters.server_random, 32); + state->security_parameters.server_random, TLS_RANDOM_SIZE); memcpy(state->gnutls_internals.resumed_security_parameters. client_random, - state->security_parameters.client_random, 32); + state->security_parameters.client_random, TLS_RANDOM_SIZE); state->gnutls_internals.resumed = RESUME_TRUE; return 0; @@ -337,7 +336,7 @@ int _gnutls_read_client_hello(GNUTLS_STATE state, opaque * data, * and initializing encryption. This is the first encrypted message * we send. */ -int _gnutls_send_finished(int cd, GNUTLS_STATE state) +int _gnutls_send_finished(SOCKET cd, GNUTLS_STATE state) { uint8 *data; int ret; @@ -368,7 +367,7 @@ int _gnutls_send_finished(int cd, GNUTLS_STATE state) * went fine we have negotiated a secure connection */ #define HANDSHAKE_HEADERS_SIZE 4 -int _gnutls_recv_finished(int cd, GNUTLS_STATE state) +int _gnutls_recv_finished(SOCKET cd, GNUTLS_STATE state) { uint8 *data, *vrfy; int data_size; @@ -503,7 +502,7 @@ int _gnutls_SelectCompMethod(GNUTLS_STATE state, CompressionMethod * ret, } -int _gnutls_send_handshake(int cd, GNUTLS_STATE state, void *i_data, +int _gnutls_send_handshake(SOCKET cd, GNUTLS_STATE state, void *i_data, uint32 i_datasize, HandshakeType type) { int ret; @@ -548,7 +547,7 @@ int _gnutls_send_handshake(int cd, GNUTLS_STATE state, void *i_data, * send to _gnutls_recv_hello(). */ #define SSL2_HEADERS 1 -int _gnutls_recv_handshake(int cd, GNUTLS_STATE state, uint8 ** data, +int _gnutls_recv_handshake(SOCKET cd, GNUTLS_STATE state, uint8 ** data, int *datalen, HandshakeType type) { int ret; @@ -617,18 +616,21 @@ int _gnutls_recv_handshake(int cd, GNUTLS_STATE state, uint8 ** data, } else { /* v2 hello */ - length32 = state->gnutls_internals.v2_hello - 1; /* we've read the first byte */ + length32 = state->gnutls_internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */ handshake_headers = SSL2_HEADERS; /* we've already read one byte */ + recv_type = dataptr[0]; #ifdef HANDSHAKE_DEBUG fprintf(stderr, "Handshake: %s(v2) was received [%ld bytes]\n", - _gnutls_handshake2str(dataptr[0]), + _gnutls_handshake2str(recv_type), length32 + handshake_headers); #endif - recv_type = dataptr[0]; - if (dataptr[0] != GNUTLS_CLIENT_HELLO) /* it should be one or nothing */ + + if (recv_type != GNUTLS_CLIENT_HELLO) { /* it should be one or nothing */ + gnutls_assert(); return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET; + } } dataptr = @@ -719,7 +721,7 @@ int _gnutls_recv_handshake(int cd, GNUTLS_STATE state, uint8 ** data, * GNUTLS_E_WARNING_ALERT_RECEIVED and the alert will be * GNUTLS_NO_RENEGOTIATION. **/ -int gnutls_rehandshake(int cd, GNUTLS_STATE state) +int gnutls_rehandshake(SOCKET cd, GNUTLS_STATE state) { int ret; @@ -741,7 +743,7 @@ int ret; return ret; } -int _gnutls_send_client_certificate(int cd, GNUTLS_STATE state) +int _gnutls_send_client_certificate(SOCKET cd, GNUTLS_STATE state) { char data[1]; int ret; @@ -795,9 +797,9 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale } pos += 2; - DECR_LEN(len, 32); + DECR_LEN(len, TLS_RANDOM_SIZE); _gnutls_set_server_random( state, &data[pos]); - pos += 32; + pos += TLS_RANDOM_SIZE; DECR_LEN(len, 1); memcpy(&session_id_len, &data[pos++], 1); @@ -824,11 +826,11 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale memcpy(state->gnutls_internals. resumed_security_parameters.server_random, state->security_parameters.server_random, - 32); + TLS_RANDOM_SIZE); memcpy(state->gnutls_internals. resumed_security_parameters.client_random, state->security_parameters.client_random, - 32); + TLS_RANDOM_SIZE); state->gnutls_internals.resumed = RESUME_TRUE; /* we are resuming */ return 0; @@ -934,7 +936,7 @@ static int _gnutls_read_server_hello( GNUTLS_STATE state, char *data, int datale return ret; } -int _gnutls_send_hello(int cd, GNUTLS_STATE state) +int _gnutls_send_hello(SOCKET cd, GNUTLS_STATE state) { char *data = NULL; opaque *extdata; @@ -945,7 +947,7 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state) uint8 *compression_methods; int i, datalen, ret = 0; uint16 x; - opaque random[32]; + opaque random[TLS_RANDOM_SIZE]; if (state->security_parameters.entity == GNUTLS_CLIENT) { opaque * SessionID = state->gnutls_internals.resumed_security_parameters.session_id; @@ -972,8 +974,8 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state) state->security_parameters.timestamp = time(0); memcpy(&data[pos], - state->security_parameters.client_random, 32); - pos += 32; + state->security_parameters.client_random, TLS_RANDOM_SIZE); + pos += TLS_RANDOM_SIZE; memcpy(&data[pos++], &session_id_len, 1); @@ -1034,7 +1036,7 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state) if (SessionID==NULL) session_id_len = 0; - datalen = 2 + session_id_len + 1 + 32; + datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE; data = gnutls_malloc(datalen); data[pos++] = @@ -1045,8 +1047,8 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state) version); memcpy(&data[pos], - state->security_parameters.server_random, 32); - pos += 32; + state->security_parameters.server_random, TLS_RANDOM_SIZE); + pos += TLS_RANDOM_SIZE; memcpy(&data[pos++], &session_id_len, sizeof(uint8)); if (session_id_len > 0) { @@ -1089,7 +1091,7 @@ int _gnutls_send_hello(int cd, GNUTLS_STATE state) * hello message is expected. It uses the gnutls_internals.current_cipher_suite * and gnutls_internals.compression_method. */ -int _gnutls_recv_hello(int cd, GNUTLS_STATE state, char *data, int datalen) +int _gnutls_recv_hello(SOCKET cd, GNUTLS_STATE state, char *data, int datalen) { int ret; @@ -1113,7 +1115,7 @@ int ret; return ret; } -int _gnutls_recv_certificate(int cd, GNUTLS_STATE state, char *data, +int _gnutls_recv_certificate(SOCKET cd, GNUTLS_STATE state, char *data, int datalen) { int pos = 0; @@ -1167,7 +1169,7 @@ int _gnutls_recv_certificate(int cd, GNUTLS_STATE state, char *data, * This function will fail if any problem is encountered, * and the connection should be terminated. **/ -int gnutls_handshake(int cd, GNUTLS_STATE state) +int gnutls_handshake(SOCKET cd, GNUTLS_STATE state) { int ret; @@ -1198,7 +1200,7 @@ int gnutls_handshake(int cd, GNUTLS_STATE state) * continue the handshake - eg. even if the certificate cannot * be verified- by calling gnutls_handshake_finish(). */ -int gnutls_handshake_begin(int cd, GNUTLS_STATE state) +int gnutls_handshake_begin(SOCKET cd, GNUTLS_STATE state) { int ret; @@ -1316,7 +1318,7 @@ int gnutls_handshake_begin(int cd, GNUTLS_STATE state) /* This function sends the final handshake packets and initializes connection */ -static int _gnutls_send_handshake_final(int cd, GNUTLS_STATE state, +static int _gnutls_send_handshake_final(SOCKET cd, GNUTLS_STATE state, int init) { int ret = 0; @@ -1351,7 +1353,7 @@ static int _gnutls_send_handshake_final(int cd, GNUTLS_STATE state, /* This function receives the final handshake packets */ -static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state, +static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state, int init) { int ret = 0; @@ -1394,7 +1396,7 @@ static int _gnutls_recv_handshake_final(int cd, GNUTLS_STATE state, * you have somehow verified the identity of the peer. * This function will fail if any problem is encountered. */ -int gnutls_handshake_finish(int cd, GNUTLS_STATE state) +int gnutls_handshake_finish(SOCKET cd, GNUTLS_STATE state) { int ret = 0; @@ -1562,23 +1564,23 @@ int gnutls_handshake_finish(int cd, GNUTLS_STATE state) int _gnutls_generate_session_id(char *session_id, uint8 * len) { - opaque rand[32]; - if (_gnutls_get_random(rand, 32, GNUTLS_WEAK_RANDOM) < 0) { + opaque rand[TLS_RANDOM_SIZE]; + if (_gnutls_get_random(rand, TLS_RANDOM_SIZE, GNUTLS_WEAK_RANDOM) < 0) { gnutls_assert(); return GNUTLS_E_MEMORY_ERROR; } - memcpy(session_id, rand, 32); - *len = 32; + memcpy(session_id, rand, TLS_RANDOM_SIZE); + *len = TLS_RANDOM_SIZE; #ifdef HARD_DEBUG fprintf(stderr, "Generated SessionID: %s\n", - _gnutls_bin2hex(session_id, 32)); + _gnutls_bin2hex(session_id, TLS_RANDOM_SIZE)); #endif return 0; } #define RENEGOTIATE -int _gnutls_recv_hello_request(int cd, GNUTLS_STATE state, void* data, uint32 data_size) { +int _gnutls_recv_hello_request(SOCKET cd, GNUTLS_STATE state, void* data, uint32 data_size) { #ifndef RENEGOTIATE int ret; diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index a55e1be5ec..dadc825e85 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -23,20 +23,25 @@ #define GNUTLS_INT_H +/* #define READ_DEBUG -//#define WRITE_DEBUG -//#define HARD_DEBUG +#define WRITE_DEBUG #define BUFFERS_DEBUG #define HANDSHAKE_DEBUG +#define HARD_DEBUG #define DEBUG +*/ - +#define SOCKET int #define LIST ... #define MAX32 4294967295 #define MAX24 16777215 #define MAX16 65535 +#define TLS_RANDOM_SIZE 32 +#define TLS_MAX_SESSION_ID_SIZE 32 + /* the default for TCP */ #define DEFAULT_LOWAT 1 @@ -164,8 +169,8 @@ typedef struct { /* These are needed in RSA and DH signature calculation */ - opaque server_random[32]; - opaque client_random[32]; + opaque server_random[TLS_RANDOM_SIZE]; + opaque client_random[TLS_RANDOM_SIZE]; ProtocolVersion version; opaque dnsname[256]; @@ -185,7 +190,6 @@ typedef struct { ConnectionEnd entity; BulkCipherAlgorithm bulk_cipher_algorithm; KXAlgorithm kx_algorithm; - CipherType cipher_type; MACAlgorithm mac_algorithm; CompressionMethod compression_algorithm; uint8 IV_size; @@ -193,9 +197,9 @@ typedef struct { uint8 key_material_length; uint8 hash_size; opaque master_secret[48]; - opaque client_random[32]; - opaque server_random[32]; - opaque session_id[32]; + opaque client_random[TLS_RANDOM_SIZE]; + opaque server_random[TLS_RANDOM_SIZE]; + opaque session_id[TLS_MAX_SESSION_ID_SIZE]; uint8 session_id_size; time_t timestamp; } SecurityParameters; @@ -287,42 +291,19 @@ typedef GNUTLS_STATE_INT *GNUTLS_STATE; typedef enum ContentType { GNUTLS_CHANGE_CIPHER_SPEC=20, GNUTLS_ALERT, GNUTLS_HANDSHAKE, GNUTLS_APPLICATION_DATA } ContentType; -typedef struct { - uint8 type; - ProtocolVersion version; - uint16 length; - opaque* fragment; -} GNUTLSPlaintext; - -typedef struct { - uint8 type; - ProtocolVersion version; - uint16 length; - opaque* fragment; -} GNUTLSCompressed; - -typedef struct { - uint8 type; - ProtocolVersion version; - uint16 length; - void* fragment; /* points GenericStreamCipher - * or GenericBlockCipher - */ -} GNUTLSCiphertext; - /* functions */ -int _gnutls_send_alert( int cd, GNUTLS_STATE state, AlertLevel level, AlertDescription desc); -int gnutls_close(int cd, GNUTLS_STATE state); +int _gnutls_send_alert( SOCKET cd, GNUTLS_STATE state, AlertLevel level, AlertDescription desc); +int gnutls_close(SOCKET 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); 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, const void* data, size_t sizeofdata, int flags); -ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char* data, size_t sizeofdata, int flags); -int _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state); +ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, const void* data, size_t sizeofdata, int flags); +ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, char* data, size_t sizeofdata, int flags); +int _gnutls_send_change_cipher_spec(SOCKET cd, GNUTLS_STATE state); int _gnutls_version_cmp(GNUTLS_Version ver1, GNUTLS_Version ver2); #define _gnutls_version_ssl3(x) _gnutls_version_cmp(x, GNUTLS_SSL3) diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 6108926c8b..ec97246f09 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -81,7 +81,7 @@ char random[64]; * server. It does nothing if this type of message is not required * by the selected ciphersuite. */ -int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state) +int _gnutls_send_server_kx_message(SOCKET cd, GNUTLS_STATE state) { uint8 *data = NULL; int data_size = 0; @@ -113,7 +113,7 @@ int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state) } /* Currently only used in SRP */ -int _gnutls_send_server_kx_message2(int cd, GNUTLS_STATE state) +int _gnutls_send_server_kx_message2(SOCKET cd, GNUTLS_STATE state) { uint8 *data = NULL; int data_size = 0; @@ -154,7 +154,7 @@ int _gnutls_send_server_kx_message2(int cd, GNUTLS_STATE state) /* This is the function for the client to send the key * exchange message */ -int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state) +int _gnutls_send_client_kx_message(SOCKET cd, GNUTLS_STATE state) { uint8 *data; int data_size; @@ -198,7 +198,7 @@ int _gnutls_send_client_kx_message(int cd, GNUTLS_STATE state) /* Only used in SRP currently */ -int _gnutls_send_client_kx_message0(int cd, GNUTLS_STATE state) +int _gnutls_send_client_kx_message0(SOCKET cd, GNUTLS_STATE state) { uint8 *data; int data_size; @@ -234,7 +234,7 @@ int _gnutls_send_client_kx_message0(int cd, GNUTLS_STATE state) * FIXME: this function does almost nothing except sending garbage to * peer. */ -int _gnutls_send_client_certificate_verify(int cd, GNUTLS_STATE state) +int _gnutls_send_client_certificate_verify(SOCKET cd, GNUTLS_STATE state) { uint8 *data; int ret = 0; @@ -266,7 +266,7 @@ int _gnutls_send_client_certificate_verify(int cd, GNUTLS_STATE state) } -int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state) +int _gnutls_recv_server_kx_message(SOCKET cd, GNUTLS_STATE state) { KXAlgorithm algorithm; uint8 *data; @@ -298,7 +298,7 @@ int _gnutls_recv_server_kx_message(int cd, GNUTLS_STATE state) return ret; } -int _gnutls_recv_server_kx_message2(int cd, GNUTLS_STATE state) +int _gnutls_recv_server_kx_message2(SOCKET cd, GNUTLS_STATE state) { KXAlgorithm algorithm; uint8 *data; @@ -335,7 +335,7 @@ int _gnutls_recv_server_kx_message2(int cd, GNUTLS_STATE state) return ret; } -int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state) +int _gnutls_recv_client_kx_message(SOCKET cd, GNUTLS_STATE state) { KXAlgorithm algorithm; uint8 *data; @@ -379,7 +379,7 @@ int _gnutls_recv_client_kx_message(int cd, GNUTLS_STATE state) } /* only used in SRP */ -int _gnutls_recv_client_kx_message0(int cd, GNUTLS_STATE state) +int _gnutls_recv_client_kx_message0(SOCKET cd, GNUTLS_STATE state) { KXAlgorithm algorithm; uint8 *data; @@ -418,7 +418,7 @@ int _gnutls_recv_client_kx_message0(int cd, GNUTLS_STATE state) /* This is called when we want send our certificate */ -int _gnutls_send_certificate(int cd, GNUTLS_STATE state) +int _gnutls_send_certificate(SOCKET cd, GNUTLS_STATE state) { uint8 *data = NULL; int data_size = 0; diff --git a/lib/gnutls_plaintext.c b/lib/gnutls_plaintext.c deleted file mode 100644 index fdea5406fc..0000000000 --- a/lib/gnutls_plaintext.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2000 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUTLS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <defines.h> -#include "gnutls_int.h" -#include "gnutls_errors.h" -#include "gnutls_algorithms.h" - -/* Plaintext Handling */ -int _gnutls_text2TLSPlaintext(GNUTLS_STATE state, ContentType type, GNUTLSPlaintext** plain, const char *text, uint16 length) -{ - GNUTLSPlaintext *plaintext; - - if (length > 16384) - return GNUTLS_E_LARGE_PACKET; - - *plain = gnutls_malloc(sizeof(GNUTLSPlaintext)); - plaintext = *plain; - - plaintext->fragment = gnutls_malloc(length); - memmove(plaintext->fragment, text, length); - plaintext->length = length; - plaintext->type = type; - plaintext->version.major = _gnutls_version_get_major(state->connection_state.version); - plaintext->version.minor = _gnutls_version_get_minor(state->connection_state.version); - - return 0; -} - -int _gnutls_TLSPlaintext2text( char** txt, GNUTLSPlaintext* plaintext) -{ - char *text; - - if (plaintext->length > 16384) - return GNUTLS_E_LARGE_PACKET; - - *txt = gnutls_malloc(plaintext->length); - text = *txt; - - memmove(text, plaintext->fragment, plaintext->length); - - return 0; -} - -int _gnutls_freeTLSPlaintext(GNUTLSPlaintext * plaintext) -{ - if (plaintext == NULL) - return 0; - - gnutls_free(plaintext->fragment); - gnutls_free(plaintext); - - return 0; -} diff --git a/lib/gnutls_plaintext.h b/lib/gnutls_plaintext.h deleted file mode 100644 index 7878790061..0000000000 --- a/lib/gnutls_plaintext.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2000 Nikos Mavroyanopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GNUTLS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -int _gnutls_text2TLSPlaintext(GNUTLS_STATE state, ContentType type, GNUTLSPlaintext**, const char *text, uint16 length); -int _gnutls_freeTLSPlaintext(GNUTLSPlaintext* plaintext); -int _gnutls_TLSPlaintext2text( char**, GNUTLSPlaintext* plaintext); diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index d05aa55aab..3928142085 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -23,7 +23,6 @@ #include "gnutls_errors.h" #include "debug.h" #include "gnutls_compress.h" -#include "gnutls_plaintext.h" #include "gnutls_cipher.h" #include "gnutls_buffers.h" #include "gnutls_handshake.h" @@ -353,7 +352,7 @@ int _gnutls_set_keys(GNUTLS_STATE state) { char *key_block; char keyexp[] = "key expansion"; - char random[64]; + char random[2*TLS_RANDOM_SIZE]; int hash_size; int IV_size; int key_size; @@ -362,8 +361,8 @@ int _gnutls_set_keys(GNUTLS_STATE state) IV_size = state->security_parameters.IV_size; key_size = state->security_parameters.key_material_length; - memmove(random, state->security_parameters.server_random, 32); - memmove(&random[32], state->security_parameters.client_random, 32); + memmove(random, state->security_parameters.server_random, TLS_RANDOM_SIZE); + memmove(&random[TLS_RANDOM_SIZE], state->security_parameters.client_random, 32); if (_gnutls_version_ssl3(state->connection_state.version) == 0) { /* SSL 3 */ key_block = gnutls_ssl3_generate_random( state->security_parameters.master_secret, 48, random, 64, @@ -373,24 +372,41 @@ int _gnutls_set_keys(GNUTLS_STATE state) gnutls_PRF( state->security_parameters.master_secret, 48, keyexp, strlen(keyexp), random, 64, 2 * hash_size + 2 * key_size + 2 * IV_size); } - - state->cipher_specs.client_write_mac_secret = secure_malloc(hash_size); - memmove(state->cipher_specs.client_write_mac_secret, &key_block[0], hash_size); - - state->cipher_specs.server_write_mac_secret = secure_malloc(hash_size); - memmove(state->cipher_specs.server_write_mac_secret, &key_block[hash_size], hash_size); - - state->cipher_specs.client_write_key = secure_malloc(key_size); - memmove(state->cipher_specs.client_write_key, &key_block[2 * hash_size], key_size); - - state->cipher_specs.server_write_key = secure_malloc(key_size); - memmove(state->cipher_specs.server_write_key, &key_block[2 * hash_size + key_size], key_size); - + + if (key_block==NULL) return GNUTLS_E_MEMORY_ERROR; + + if (hash_size>0) { + state->cipher_specs.client_write_mac_secret = secure_malloc(hash_size); + if (state->cipher_specs.client_write_mac_secret==NULL) + return GNUTLS_E_MEMORY_ERROR; + memmove(state->cipher_specs.client_write_mac_secret, &key_block[0], hash_size); + + state->cipher_specs.server_write_mac_secret = secure_malloc(hash_size); + if (state->cipher_specs.server_write_mac_secret==NULL) + return GNUTLS_E_MEMORY_ERROR; + memmove(state->cipher_specs.server_write_mac_secret, &key_block[hash_size], hash_size); + } + + if (key_size>0) { + state->cipher_specs.client_write_key = secure_malloc(key_size); + if (state->cipher_specs.client_write_key==NULL) + return GNUTLS_E_MEMORY_ERROR; + memmove(state->cipher_specs.client_write_key, &key_block[2 * hash_size], key_size); + + state->cipher_specs.server_write_key = secure_malloc(key_size); + if (state->cipher_specs.server_write_key==NULL) + return GNUTLS_E_MEMORY_ERROR; + memmove(state->cipher_specs.server_write_key, &key_block[2 * hash_size + key_size], key_size); + } if (IV_size > 0) { state->cipher_specs.client_write_IV = secure_malloc(IV_size); + if (state->cipher_specs.client_write_IV==NULL) + return GNUTLS_E_MEMORY_ERROR; memmove(state->cipher_specs.client_write_IV, &key_block[2 * key_size + 2 * hash_size], IV_size); state->cipher_specs.server_write_IV = secure_malloc(IV_size); + if (state->cipher_specs.server_write_IV==NULL) + return GNUTLS_E_MEMORY_ERROR; memmove(state->cipher_specs.server_write_IV, &key_block[2 * hash_size + 2 * key_size + IV_size], IV_size); } @@ -398,7 +414,7 @@ int _gnutls_set_keys(GNUTLS_STATE state) return 0; } -int _gnutls_send_alert(int cd, GNUTLS_STATE state, AlertLevel level, AlertDescription desc) +int _gnutls_send_alert(SOCKET cd, GNUTLS_STATE state, AlertLevel level, AlertDescription desc) { uint8 data[2]; @@ -406,7 +422,7 @@ int _gnutls_send_alert(int cd, GNUTLS_STATE state, AlertLevel level, AlertDescri memmove(&data[1], &desc, 1); #ifdef DEBUG - fprintf(stderr, "Record: Sending Alert[%d|%d] - %s - was received\n", data[0], data[1], _gnutls_alert2str((int)data[1])); + fprintf(stderr, "Record: Sending Alert[%d|%d] - %s\n", data[0], data[1], _gnutls_alert2str((int)data[1])); #endif return gnutls_send_int(cd, state, GNUTLS_ALERT, data, 2, 0); @@ -421,7 +437,7 @@ int _gnutls_send_alert(int cd, GNUTLS_STATE state, AlertLevel level, AlertDescri * you may continue using the TCP connection. The connection should * have been initiated using gnutls_handshake() or similar function. **/ -int gnutls_bye(int cd, GNUTLS_STATE state) +int gnutls_bye(SOCKET cd, GNUTLS_STATE state) { int ret; @@ -435,7 +451,7 @@ int gnutls_bye(int cd, GNUTLS_STATE state) return ret; } -int gnutls_close_nowait(int cd, GNUTLS_STATE state) +int gnutls_close_nowait(SOCKET cd, GNUTLS_STATE state) { int ret; @@ -451,7 +467,7 @@ 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, const void *_data, size_t sizeofdata, int flags) +ssize_t gnutls_send_int(SOCKET cd, GNUTLS_STATE state, ContentType type, const void *_data, size_t sizeofdata, int flags) { uint8 *cipher; int i, cipher_size; @@ -464,6 +480,7 @@ ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, const void if (sizeofdata == 0) return 0; if (state->gnutls_internals.valid_connection == VALID_FALSE) { + gnutls_assert(); return GNUTLS_E_INVALID_SESSION; } @@ -486,16 +503,20 @@ ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, const void for (i = 0; i < iterations; i++) { cipher_size = _gnutls_encrypt( state, &data[i*Size], Size, &cipher, type); - if (cipher_size <= 0) return cipher_size; /* error */ - + if (cipher_size <= 0) { + gnutls_assert(); + return cipher_size; /* error */ + } + WRITEuint16( cipher_size, &headers[3]); - /* cipher does not have headers - * and DOES have size for them - */ - memmove( cipher, headers, HEADER_SIZE); + if (_gnutls_Write(cd, headers, HEADER_SIZE) != HEADER_SIZE) { + state->gnutls_internals.valid_connection = VALID_FALSE; + state->gnutls_internals.resumable = RESUME_FALSE; + gnutls_assert(); + return GNUTLS_E_UNABLE_SEND_DATA; + } - cipher_size += HEADER_SIZE; if (_gnutls_Write(cd, cipher, cipher_size) != cipher_size) { state->gnutls_internals.valid_connection = VALID_FALSE; state->gnutls_internals.resumable = RESUME_FALSE; @@ -554,7 +575,7 @@ ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, const void /* This function is to be called if the handshake was successfully * completed. This sends a Change Cipher Spec packet to the peer. */ -ssize_t _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state) +ssize_t _gnutls_send_change_cipher_spec(SOCKET cd, GNUTLS_STATE state) { int ret = 0; uint8 type=GNUTLS_CHANGE_CIPHER_SPEC; @@ -562,6 +583,7 @@ ssize_t _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state) uint8 headers[5]; if (state->gnutls_internals.valid_connection == VALID_FALSE) { + gnutls_assert(); return GNUTLS_E_INVALID_SESSION; } @@ -595,7 +617,7 @@ ssize_t _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state) #define RCVLOWAT state->gnutls_internals.lowat /* this is the default for TCP - just don't change that! */ -static int _gnutls_clear_peeked_data( int cd, GNUTLS_STATE state) { +static int _gnutls_clear_peeked_data( SOCKET cd, GNUTLS_STATE state) { char peekdata; /* this was already read by using MSG_PEEK - so it shouldn't fail */ @@ -611,8 +633,7 @@ char peekdata; * flags is the sockets flags to use. Currently only MSG_DONTWAIT is * supported. */ -#define SSL2_HSIZE -ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data, size_t sizeofdata, int flags) +ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, char *data, size_t sizeofdata, int flags) { uint8 *tmpdata; int tmplen; @@ -639,6 +660,7 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data } if (state->gnutls_internals.valid_connection == VALID_FALSE) { + gnutls_assert(); return GNUTLS_E_INVALID_SESSION; } @@ -665,6 +687,7 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data */ version = GNUTLS_VERSION_UNKNOWN; /* assume unknown version */ length = (((headers[0] & 0x7f) << 8)) | headers[1]; + header_size = 2; recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello */ @@ -686,7 +709,13 @@ ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char *data #ifdef DEBUG fprintf(stderr, "Record: INVALID VERSION PACKET: (%d) %d.%d\n", headers[0], headers[1], headers[2]); #endif - _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_PROTOCOL_VERSION); + if (type!=GNUTLS_ALERT) { + /* some browsers return garbage, when + * we send them a close notify. + * silently ignore that. + */ + _gnutls_send_alert(cd, state, GNUTLS_FATAL, GNUTLS_PROTOCOL_VERSION); + } state->gnutls_internals.resumable = RESUME_FALSE; gnutls_assert(); return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; @@ -1054,7 +1083,7 @@ AlertDescription gnutls_get_last_alert( GNUTLS_STATE state) { * difference is that is accepts a GNUTLS state. Currently flags cannot * be anything except 0. **/ -ssize_t gnutls_send(int cd, GNUTLS_STATE state, const void *data, size_t sizeofdata, int flags) { +ssize_t gnutls_send(SOCKET cd, GNUTLS_STATE state, const void *data, size_t sizeofdata, int flags) { return gnutls_send_int( cd, state, GNUTLS_APPLICATION_DATA, data, sizeofdata, flags); } @@ -1073,7 +1102,7 @@ ssize_t gnutls_send(int cd, GNUTLS_STATE state, const void *data, size_t sizeofd * if the socket is set to non blocking IO it will return GNUTLS_E_AGAIN, * if there are no data in the socket. **/ -ssize_t gnutls_recv(int cd, GNUTLS_STATE state, void *data, size_t sizeofdata, int flags) { +ssize_t gnutls_recv(SOCKET cd, GNUTLS_STATE state, void *data, size_t sizeofdata, int flags) { return gnutls_recv_int( cd, state, GNUTLS_APPLICATION_DATA, data, sizeofdata, flags); } @@ -1087,7 +1116,7 @@ ssize_t gnutls_recv(int cd, GNUTLS_STATE state, void *data, size_t sizeofdata, i * This function has the same semantics as write() has. The only * difference is that is accepts a GNUTLS state. **/ -ssize_t gnutls_write(int cd, GNUTLS_STATE state, const void *data, size_t sizeofdata) { +ssize_t gnutls_write(SOCKET cd, GNUTLS_STATE state, const void *data, size_t sizeofdata) { return gnutls_send_int( cd, state, GNUTLS_APPLICATION_DATA, data, sizeofdata, 0); } @@ -1101,6 +1130,6 @@ ssize_t gnutls_write(int cd, GNUTLS_STATE state, const void *data, size_t sizeof * This function has the same semantics as read() has. The only * difference is that is accepts a GNUTLS state. **/ -ssize_t gnutls_read(int cd, GNUTLS_STATE state, void *data, size_t sizeofdata) { +ssize_t gnutls_read(SOCKET cd, GNUTLS_STATE state, void *data, size_t sizeofdata) { return gnutls_recv_int( cd, state, GNUTLS_APPLICATION_DATA, data, sizeofdata, 0); } diff --git a/lib/gnutls_v2_compat.c b/lib/gnutls_v2_compat.c index efeaa5aa47..455b18db1a 100644 --- a/lib/gnutls_v2_compat.c +++ b/lib/gnutls_v2_compat.c @@ -25,7 +25,6 @@ #include "debug.h" #include "gnutls_algorithms.h" #include "gnutls_compress.h" -#include "gnutls_plaintext.h" #include "gnutls_cipher.h" #include "gnutls_buffers.h" #include "gnutls_kx.h" @@ -97,8 +96,8 @@ static int SelectSuite_v2(GNUTLS_STATE state, opaque ret[2], char *data, #define DECR_LEN(len, x) len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;} -/* Read a v2 client hello. Some browsers still use that beast!!! - * However they set their version to 3.0 or 3.1 --- that's cool! +/* Read a v2 client hello. Some browsers still use that beast! + * However they set their version to 3.0 or 3.1. */ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data, int datalen) @@ -108,19 +107,18 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data, int ret = 0; uint16 sizeOfSuites; GNUTLS_Version version; - opaque random[32]; + opaque random[TLS_RANDOM_SIZE]; int len = datalen; int err; uint16 challenge; - opaque session_id[32]; + opaque session_id[TLS_MAX_SESSION_ID_SIZE]; /* we only want to get here once - only in client hello */ state->gnutls_internals.v2_hello = 0; - DECR_LEN(len, 2); #ifdef DEBUG - fprintf(stderr, "Client's version: %d.%d\n", data[pos], + fprintf(stderr, "V2 Handshake: Client's version: %d.%d\n", data[pos], data[pos + 1]); #endif @@ -141,26 +139,23 @@ int _gnutls_read_client_hello_v2(GNUTLS_STATE state, opaque * data, DECR_LEN(len, 2); sizeOfSuites = READuint16( &data[pos]); pos += 2; -fprintf(stderr, "suites: %d\n", sizeOfSuites); /* read session id length */ DECR_LEN(len, 2); session_id_len = READuint16( &data[pos]); pos += 2; - if (session_id_len > 32) { + if (session_id_len > TLS_MAX_SESSION_ID_SIZE) { gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } -fprintf(stderr, "sessid: %d\n", session_id_len); /* read challenge length */ DECR_LEN(len, 2); challenge = READuint16( &data[pos]); pos += 2; -fprintf(stderr, "challenge: %d\n", challenge); - if ( challenge < 16 || challenge > 32) { + if ( challenge < 16 || challenge > TLS_RANDOM_SIZE) { gnutls_assert(); return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; } @@ -196,7 +191,7 @@ fprintf(stderr, "challenge: %d\n", challenge); if (state->gnutls_internals.auth_struct == NULL) { #ifdef DEBUG fprintf(stderr, - "Cannot find the appropriate handler for the KX algorithm\n"); + "V2 Handshake: Cannot find the appropriate handler for the KX algorithm\n"); #endif gnutls_assert(); return GNUTLS_E_UNKNOWN_CIPHER_TYPE; @@ -210,9 +205,13 @@ fprintf(stderr, "challenge: %d\n", challenge); pos+=session_id_len; DECR_LEN(len, challenge); - memset( random, 0, 32); - memcpy( random, &data[pos], challenge); -fprintf(stderr, "challenge: %s\n", _gnutls_bin2hex(random, 32)); + memset( random, 0, TLS_RANDOM_SIZE); + + /* Well, I think that this is not what TLS 1.0 defines, + * but with this, we are compatible with netscape browser! + */ + memcpy( &random[TLS_RANDOM_SIZE-challenge], &data[pos], challenge); + _gnutls_set_client_random( state, random); /* generate server random value */ @@ -231,9 +230,9 @@ fprintf(stderr, "challenge: %s\n", _gnutls_bin2hex(random, 32)); if (ret == 0) { /* resumed! */ /* get the new random values */ memcpy(state->gnutls_internals.resumed_security_parameters.server_random, - state->security_parameters.server_random, 32); + state->security_parameters.server_random, TLS_RANDOM_SIZE); memcpy(state->gnutls_internals.resumed_security_parameters.client_random, - state->security_parameters.client_random, 32); + state->security_parameters.client_random, TLS_RANDOM_SIZE); state->gnutls_internals.resumed = RESUME_TRUE; return 0; diff --git a/src/serv.c b/src/serv.c index 91c2d63882..7225a31b3b 100644 --- a/src/serv.c +++ b/src/serv.c @@ -29,6 +29,7 @@ #include <unistd.h> #include "../lib/gnutls.h" #include <port.h> +#include <signal.h> #define PKIX "pkix.asn" #define PKCS "pkcs1.asn" @@ -50,6 +51,8 @@ void PARSE() /* this is to be moved to gnutls */ int result = parser_asn1(PKIX); + signal( SIGPIPE, SIG_IGN); + if (result == ASN_SYNTAX_ERROR) { printf("%s: PARSE ERROR\n", PKIX); return; @@ -113,9 +116,12 @@ GNUTLS_STATE initialize_state() if ((ret = gnutls_set_db_name(state, "gnutls-rsm.db")) < 0) fprintf(stderr, "*** DB error (%d)\n", ret); - gnutls_set_cipher_priority(state, GNUTLS_ARCFOUR, + /* null cipher is here only for debuging + * purposes. + */ + gnutls_set_cipher_priority(state, GNUTLS_NULL_CIPHER, GNUTLS_ARCFOUR, GNUTLS_RIJNDAEL_CBC, GNUTLS_3DES_CBC, 0); - gnutls_set_compression_priority(state, GNUTLS_NULL_COMPRESSION, 0); + gnutls_set_compression_priority(state, GNUTLS_ZLIB, GNUTLS_NULL_COMPRESSION, 0); gnutls_set_kx_priority(state, GNUTLS_KX_RSA, GNUTLS_KX_SRP, GNUTLS_KX_DH_ANON, 0); gnutls_set_cred(state, GNUTLS_ANON, &dh_cred); |