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