Commit 173e72e6 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

DTLS revision.

Revise DTLS code. There was a *lot* of code duplication in the
DTLS code that generates records. This makes it harder to maintain and
sometimes a TLS update is omitted by accident from the DTLS code.

Specifically almost all of the record generation functions have code like
this:

some_pointer = buffer + HANDSHAKE_HEADER_LENGTH;
... Record creation stuff ...
set_handshake_header(ssl, SSL_MT_SOMETHING, message_len);

...

write_handshake_message(ssl);

Where the "Record creation stuff" is identical between SSL/TLS and DTLS or
in some cases has very minor differences.

By adding a few fields to SSL3_ENC to include the header length, some flags
and function pointers for handshake header setting and handshake writing the
code can cope with both cases.

Note: although this passes "make test" and some simple DTLS tests there may
be some minor differences in the DTLS code that have to be accounted for.
parent 80ccc66d
Loading
Loading
Loading
Loading
+0 −78
Original line number Diff line number Diff line
@@ -896,63 +896,6 @@ f_err:
	return(-1);
	}

int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
	{
	unsigned char *p,*d;
	int i;
	unsigned long l;

	if (s->state == a)
		{
		d=(unsigned char *)s->init_buf->data;
		p= &(d[DTLS1_HM_HEADER_LENGTH]);

		i=s->method->ssl3_enc->final_finish_mac(s,
			sender,slen,s->s3->tmp.finish_md);
		s->s3->tmp.finish_md_len = i;
		memcpy(p, s->s3->tmp.finish_md, i);
		p+=i;
		l=i;

	/* Copy the finished so we can use it for
	 * renegotiation checks
	 */
	if(s->type == SSL_ST_CONNECT)
		{
		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
		memcpy(s->s3->previous_client_finished, 
		       s->s3->tmp.finish_md, i);
		s->s3->previous_client_finished_len=i;
		}
	else
		{
		OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
		memcpy(s->s3->previous_server_finished, 
		       s->s3->tmp.finish_md, i);
		s->s3->previous_server_finished_len=i;
		}

#ifdef OPENSSL_SYS_WIN16
		/* MSVC 1.5 does not clear the top bytes of the word unless
		 * I do this.
		 */
		l&=0xffff;
#endif

		d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l);
		s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH;
		s->init_off=0;

		/* buffer the message to handle re-xmits */
		dtls1_buffer_message(s, 0);

		s->state=b;
		}

	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
	}

/* for these 2 messages, we need to
 * ssl->enc_read_ctx			re-init
 * ssl->s3->read_sequence		zero
@@ -993,27 +936,6 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
	return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
	}

unsigned long dtls1_output_cert_chain(SSL *s, CERT_PKEY *cpk)
	{
	unsigned char *p;
	unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
	BUF_MEM *buf=s->init_buf;

	if (!ssl_add_cert_chain(s, cpk, &l))
		return 0;

	l-= (3 + DTLS1_HM_HEADER_LENGTH);

	p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
	l2n3(l,p);
	l+=3;
	p=(unsigned char *)&(buf->data[0]);
	p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);

	l+=DTLS1_HM_HEADER_LENGTH;
	return(l);
	}

int dtls1_read_failed(SSL *s, int code)
	{
	if ( code > 0)
+5 −894

File changed.

Preview size limit exceeded, changes collapsed.

+23 −0
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@
#endif

static void get_current_time(struct timeval *t);
static void dtls1_set_handshake_header(SSL *s, int type, unsigned long len);
static int dtls1_handshake_write(SSL *s);
const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT;
int dtls1_listen(SSL *s, struct sockaddr *client);

@@ -83,6 +85,10 @@ SSL3_ENC_METHOD DTLSv1_enc_data={
	TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE,
	tls1_alert_code,
	tls1_export_keying_material,
	SSL_ENC_FLAG_DTLS|SSL_ENC_FLAG_EXPLICIT_IV,
	DTLS1_HM_HEADER_LENGTH,
	dtls1_set_handshake_header,
	dtls1_handshake_write	
	};

long dtls1_default_timeout(void)
@@ -484,3 +490,20 @@ int dtls1_listen(SSL *s, struct sockaddr *client)
	(void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
	return 1;
	}

static void dtls1_set_handshake_header(SSL *s, int htype, unsigned long len)
	{
	unsigned char *p = (unsigned char *)s->init_buf->data;
	dtls1_set_message_header(s, p, htype, len, 0, len);
	s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
	s->init_off = 0;
	/* Buffer the message to handle re-xmits */
	dtls1_buffer_message(s, 0);
	}

static int dtls1_handshake_write(SSL *s)
	{
	return dtls1_do_write(s, SSL3_RT_HANDSHAKE);
	}
	
	
+8 −834

File changed.

Preview size limit exceeded, changes collapsed.

+10 −21
Original line number Diff line number Diff line
@@ -150,20 +150,18 @@ int ssl3_do_write(SSL *s, int type)

int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
	{
	unsigned char *p,*d;
	unsigned char *p;
	int i;
	unsigned long l;

	if (s->state == a)
		{
		d=(unsigned char *)s->init_buf->data;
		p= &(d[4]);
		p = ssl_handshake_start(s);

		i=s->method->ssl3_enc->final_finish_mac(s,
			sender,slen,s->s3->tmp.finish_md);
		s->s3->tmp.finish_md_len = i;
		memcpy(p, s->s3->tmp.finish_md, i);
		p+=i;
		l=i;

                /* Copy the finished so we can use it for
@@ -189,17 +187,12 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
		 */
		l&=0xffff;
#endif

		*(d++)=SSL3_MT_FINISHED;
		l2n3(l,d);
		s->init_num=(int)l+4;
		s->init_off=0;

		ssl_set_handshake_header(s, SSL3_MT_FINISHED, l);
		s->state=b;
		}

	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
	return ssl_do_write(s);
	}

#ifndef OPENSSL_NO_NEXTPROTONEG
@@ -324,21 +317,17 @@ int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk)
	{
	unsigned char *p;
	unsigned long l=7;
	BUF_MEM *buf = s->init_buf;
	unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s);

	if (!ssl_add_cert_chain(s, cpk, &l))
		return 0;

	l-=7;
	p=(unsigned char *)&(buf->data[4]);
	l -= 3 + SSL_HM_HEADER_LENGTH(s);
	p = ssl_handshake_start(s);
	l2n3(l,p);
	l += 3;
	p=(unsigned char *)&(buf->data[0]);
	*(p++)=SSL3_MT_CERTIFICATE;
	l2n3(l,p);
	l+=4;
	return(l);
	ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l);
	return l + SSL_HM_HEADER_LENGTH(s);
	}

/* Obtain handshake message of message type 'mt' (any if mt == -1),
Loading