Switch for RFC-compliant version encoding in DTLS. From HEAD with a twist:

server accepts even non-compliant encoding in order to enable interop with
pre-0.9.8f clients.
This commit is contained in:
Andy Polyakov
2007-09-30 18:55:59 +00:00
parent aab1ec3f36
commit c4b0d7879e
5 changed files with 43 additions and 28 deletions

View File

@@ -732,7 +732,7 @@ int dtls1_send_client_key_exchange(SSL *s)
s->session->master_key_length=sizeof tmp_buf; s->session->master_key_length=sizeof tmp_buf;
q=p; q=p;
/* Fix buf for TLS and beyond */ /* Fix buf for TLS and [incidentally] DTLS */
if (s->version > SSL3_VERSION) if (s->version > SSL3_VERSION)
p+=2; p+=2;
n=RSA_public_encrypt(sizeof tmp_buf, n=RSA_public_encrypt(sizeof tmp_buf,
@@ -747,7 +747,7 @@ int dtls1_send_client_key_exchange(SSL *s)
goto err; goto err;
} }
/* Fix buf for TLS and beyond */ /* Fix buf for TLS and [incidentally] DTLS */
if (s->version > SSL3_VERSION) if (s->version > SSL3_VERSION)
{ {
s2n(n,q); s2n(n,q);

View File

@@ -486,7 +486,7 @@ int dtls1_get_record(SSL *s)
SSL3_RECORD *rr; SSL3_RECORD *rr;
SSL_SESSION *sess; SSL_SESSION *sess;
unsigned char *p; unsigned char *p;
short version; unsigned short version;
DTLS1_BITMAP *bitmap; DTLS1_BITMAP *bitmap;
unsigned int is_next_epoch; unsigned int is_next_epoch;
@@ -535,7 +535,7 @@ again:
/* Lets check version */ /* Lets check version */
if (!s->first_packet) if (!s->first_packet)
{ {
if (version != s->version) if (version != s->version && version != DTLS1_BAD_VER)
{ {
SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
/* Send back error using their /* Send back error using their
@@ -546,7 +546,8 @@ again:
} }
} }
if ((version & 0xff00) != (DTLS1_VERSION & 0xff00)) if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
(version & 0xff00) != (DTLS1_BAD_VER & 0xff00))
{ {
SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
goto err; goto err;
@@ -1341,7 +1342,11 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
*(p++)=type&0xff; *(p++)=type&0xff;
wr->type=type; wr->type=type;
*(p++)=(s->version>>8); if (s->client_version == DTLS1_BAD_VER)
*(p++) = DTLS1_BAD_VER>>8,
*(p++) = DTLS1_BAD_VER&0xff;
else
*(p++)=(s->version>>8),
*(p++)=s->version&0xff; *(p++)=s->version&0xff;
/* field where we are to write out packet epoch, seq num and len */ /* field where we are to write out packet epoch, seq num and len */

View File

@@ -620,11 +620,16 @@ int dtls1_send_hello_verify_request(SSL *s)
buf = (unsigned char *)s->init_buf->data; buf = (unsigned char *)s->init_buf->data;
msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
*(p++) = s->version >> 8; if (s->client_version == DTLS1_BAD_VER)
*(p++) = DTLS1_BAD_VER>>8,
*(p++) = DTLS1_BAD_VER&0xff;
else
*(p++) = s->version >> 8,
*(p++) = s->version & 0xFF; *(p++) = s->version & 0xFF;
*(p++) = (unsigned char) s->d1->cookie_len; *(p++) = (unsigned char) s->d1->cookie_len;
if ( s->ctx->app_gen_cookie_cb != NULL &&
if (s->ctx->app_gen_cookie_cb != NULL &&
s->ctx->app_gen_cookie_cb(s, s->d1->cookie, s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
&(s->d1->cookie_len)) == 0) &(s->d1->cookie_len)) == 0)
{ {
@@ -672,7 +677,11 @@ int dtls1_send_server_hello(SSL *s)
/* Do the message type and length last */ /* Do the message type and length last */
d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
*(p++)=s->version>>8; if (s->client_version == DTLS1_BAD_VER)
*(p++)=DTLS1_BAD_VER>>8,
*(p++)=DTLS1_BAD_VER&0xff;
else
*(p++)=s->version>>8,
*(p++)=s->version&0xff; *(p++)=s->version&0xff;
/* Random stuff */ /* Random stuff */

View File

@@ -67,9 +67,8 @@
extern "C" { extern "C" {
#endif #endif
#define DTLS1_VERSION 0x0100 #define DTLS1_VERSION 0xFEFF
#define DTLS1_VERSION_MAJOR 0x01 #define DTLS1_BAD_VER 0x0100
#define DTLS1_VERSION_MINOR 0x00
#define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110

View File

@@ -714,7 +714,8 @@ int ssl3_get_client_hello(SSL *s)
s->client_version=(((int)p[0])<<8)|(int)p[1]; s->client_version=(((int)p[0])<<8)|(int)p[1];
p+=2; p+=2;
if (s->client_version < s->version) if ((s->version == DTLS1_VERSION && s->client_version > s->version) ||
(s->version != DTLS1_VERSION && s->client_version < s->version))
{ {
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
if ((s->client_version>>8) == SSL3_VERSION_MAJOR) if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
@@ -765,7 +766,7 @@ int ssl3_get_client_hello(SSL *s)
p+=j; p+=j;
if (SSL_version(s) == DTLS1_VERSION) if (s->version == DTLS1_VERSION)
{ {
/* cookie stuff */ /* cookie stuff */
cookie_len = *(p++); cookie_len = *(p++);
@@ -1748,8 +1749,9 @@ int ssl3_get_client_key_exchange(SSL *s)
rsa=pkey->pkey.rsa; rsa=pkey->pkey.rsa;
} }
/* TLS */ /* TLS and [incidentally] DTLS, including pre-0.9.8f */
if (s->version > SSL3_VERSION) if (s->version > SSL3_VERSION &&
s->client_version != DTLS1_BAD_VER)
{ {
n2s(p,i); n2s(p,i);
if (n != i+2) if (n != i+2)