From: Jonathan Bastien-Filiatrault Date: Tue, 28 Jul 2009 15:50:56 +0000 (-0400) Subject: dtls: Add epoch and sequence number to DTLS packets. X-Git-Tag: gnutls_2_99_0~252 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a311c2bc2b1a9c80b00671f4077265b8f1bd5be9;p=thirdparty%2Fgnutls.git dtls: Add epoch and sequence number to DTLS packets. Signed-off-by: Nikos Mavrogiannopoulos --- diff --git a/lib/gnutls_cipher.c b/lib/gnutls_cipher.c index f238fd4b5c..4ba03bfb39 100644 --- a/lib/gnutls_cipher.c +++ b/lib/gnutls_cipher.c @@ -40,6 +40,7 @@ #include "gnutls_kx.h" #include "gnutls_record.h" #include "gnutls_constate.h" +#include #include static int _gnutls_compressed2ciphertext (gnutls_session_t session, @@ -125,7 +126,11 @@ _gnutls_encrypt (gnutls_session_t session, const opaque * headers, /* copy the headers */ memcpy (ciphertext, headers, headers_size); - _gnutls_write_uint16 (ret, &ciphertext[3]); + + if(_gnutls_is_dtls(session)) + _gnutls_write_uint16 (ret, &ciphertext[11]); + else + _gnutls_write_uint16 (ret, &ciphertext[3]); return ret + headers_size; } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 2409776e8f..c9def019b5 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -151,8 +151,14 @@ typedef enum transport_t } transport_t; /* the maximum size of encrypted packets */ +#define IS_DTLS (session->internals.transport == GNUTLS_DGRAM) + #define DEFAULT_MAX_RECORD_SIZE 16384 -#define RECORD_HEADER_SIZE 5 +#define TLS_RECORD_HEADER_SIZE 5 +#define DTLS_RECORD_HEADER_SIZE (TLS_RECORD_HEADER_SIZE+8) +#define RECORD_HEADER_SIZE (IS_DTLS ? DTLS_RECORD_HEADER_SIZE : TLS_RECORD_HEADER_SIZE) +#define MAX_RECORD_HEADER_SIZE DTLS_RECORD_HEADER_SIZE + #define MAX_RECORD_SEND_SIZE (size_t)session->security_parameters.max_record_send_size #define MAX_RECORD_RECV_SIZE (size_t)session->security_parameters.max_record_recv_size #define MAX_PAD_SIZE 255 @@ -160,7 +166,10 @@ typedef enum transport_t #define MAX_RECORD_OVERHEAD (MAX_CIPHER_BLOCK_SIZE/*iv*/+MAX_PAD_SIZE+EXTRA_COMP_SIZE) #define MAX_RECV_SIZE (MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE+RECORD_HEADER_SIZE) -#define HANDSHAKE_HEADER_SIZE 4 +#define TLS_HANDSHAKE_HEADER_SIZE 4 +#define DTLS_HANDSHAKE_HEADER_SIZE (TLS_HANDSHAKE_HEADER_SIZE+8) +#define HANDSHAKE_HEADER_SIZE (IS_DTLS ? DTLS_HANDSHAKE_HEADER_SIZE : TLS_HANDSHAKE_HEADER_SIZE) +#define MAX_HANDSHAKE_HEADER_SIZE DTLS_HANDSHAKE_HEADER_SIZE /* the maximum size of the DTLS cookie */ #define DTLS_MAX_COOKIE_SIZE 32 @@ -526,7 +535,7 @@ typedef struct typedef struct { - opaque header[HANDSHAKE_HEADER_SIZE]; + opaque header[MAX_HANDSHAKE_HEADER_SIZE]; /* this holds the number of bytes in the handshake_header[] */ size_t header_size; /* this holds the length of the handshake packet */ diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 0219436ded..3186690c70 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -375,7 +375,8 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type, size_t cipher_size; int retval, ret; int data2send_size; - uint8_t headers[5]; + uint8_t headers[MAX_RECORD_HEADER_SIZE]; + int header_size; const uint8_t *data = _data; record_parameters_st *record_params; record_state_st *record_state; @@ -421,6 +422,9 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type, */ copy_record_version (session, htype, &headers[1]); + header_size = RECORD_HEADER_SIZE; + /* Adjust header length and add sequence for DTLS */ + sequence_write(&record_state->sequence_number, &headers[3]); _gnutls_record_log ("REC[%p]: Sending Packet[%d] %s(%d) with length: %d\n", session, @@ -459,7 +463,7 @@ _gnutls_send_int (gnutls_session_t session, content_type_t type, } cipher_size = - _gnutls_encrypt (session, headers, RECORD_HEADER_SIZE, data, + _gnutls_encrypt (session, headers, header_size, data, data2send_size, _mbuffer_get_udata_ptr (bufel), cipher_size, type, (session->internals.priorities.no_padding == @@ -604,11 +608,12 @@ check_buffers (gnutls_session_t session, content_type_t type, */ static int record_check_headers (gnutls_session_t session, - uint8_t headers[RECORD_HEADER_SIZE], + uint8_t headers[MAX_RECORD_HEADER_SIZE], content_type_t type, gnutls_handshake_description_t htype, /*output */ content_type_t * recv_type, - opaque version[2], uint16_t * length, + opaque version[2], uint64* sequence, + uint16_t * length, uint16_t * header_size) { @@ -642,6 +647,17 @@ record_check_headers (gnutls_session_t session, session, *length); } + else if(_gnutls_is_dtls(session)) + { + /* dtls version 1.0 */ + *recv_type = headers[0]; + version[0] = headers[1]; + version[1] = headers[2]; + + sequence_read(sequence, &headers[3]); + + *length = _gnutls_read_uint16 (&headers[11]); + } else { /* version 3.x @@ -904,6 +920,7 @@ _gnutls_recv_int (gnutls_session_t session, content_type_t type, { int decrypted_length; opaque version[2]; + uint64 sequence; content_type_t recv_type; uint16_t length; uint8_t *ciphertext; @@ -1000,7 +1017,7 @@ begin: if ((ret = record_check_headers (session, data_enc.data, type, htype, &recv_type, - version, &length, &header_size)) < 0) + version, &sequence, &length, &header_size)) < 0) { gnutls_assert (); return ret;