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

View file

@ -486,9 +486,9 @@ int dtls1_get_record(SSL *s)
SSL3_RECORD *rr;
SSL_SESSION *sess;
unsigned char *p;
short version;
unsigned short version;
DTLS1_BITMAP *bitmap;
unsigned int is_next_epoch;
unsigned int is_next_epoch;
rr= &(s->s3->rrec);
sess=s->session;
@ -524,7 +524,7 @@ again:
ssl_minor= *(p++);
version=(ssl_major<<8)|ssl_minor;
/* sequence number is 64 bits, with top 2 bytes = epoch */
/* sequence number is 64 bits, with top 2 bytes = epoch */
n2s(p,rr->epoch);
memcpy(&(s->s3->read_sequence[2]), p, 6);
@ -535,7 +535,7 @@ again:
/* Lets check version */
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);
/* 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);
goto err;
@ -1341,8 +1342,12 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
*(p++)=type&0xff;
wr->type=type;
*(p++)=(s->version>>8);
*(p++)=s->version&0xff;
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;
/* field where we are to write out packet epoch, seq num and len */
pseq=p;

View file

@ -620,19 +620,24 @@ int dtls1_send_hello_verify_request(SSL *s)
buf = (unsigned char *)s->init_buf->data;
msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
*(p++) = s->version >> 8;
*(p++) = s->version & 0xFF;
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++) = (unsigned char) s->d1->cookie_len;
if ( s->ctx->app_gen_cookie_cb != NULL &&
s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
&(s->d1->cookie_len)) == 0)
{
if (s->ctx->app_gen_cookie_cb != NULL &&
s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
&(s->d1->cookie_len)) == 0)
{
SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR);
return 0;
}
/* else the cookie is assumed to have
* been initialized by the application */
return 0;
}
/* else the cookie is assumed to have
* been initialized by the application */
memcpy(p, s->d1->cookie, s->d1->cookie_len);
p += s->d1->cookie_len;
@ -672,8 +677,12 @@ int dtls1_send_server_hello(SSL *s)
/* Do the message type and length last */
d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
*(p++)=s->version>>8;
*(p++)=s->version&0xff;
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;
/* Random stuff */
memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);

View file

@ -67,9 +67,8 @@
extern "C" {
#endif
#define DTLS1_VERSION 0x0100
#define DTLS1_VERSION_MAJOR 0x01
#define DTLS1_VERSION_MINOR 0x00
#define DTLS1_VERSION 0xFEFF
#define DTLS1_BAD_VER 0x0100
#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];
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);
if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
@ -765,7 +766,7 @@ int ssl3_get_client_hello(SSL *s)
p+=j;
if (SSL_version(s) == DTLS1_VERSION)
if (s->version == DTLS1_VERSION)
{
/* cookie stuff */
cookie_len = *(p++);
@ -1748,8 +1749,9 @@ int ssl3_get_client_key_exchange(SSL *s)
rsa=pkey->pkey.rsa;
}
/* TLS */
if (s->version > SSL3_VERSION)
/* TLS and [incidentally] DTLS, including pre-0.9.8f */
if (s->version > SSL3_VERSION &&
s->client_version != DTLS1_BAD_VER)
{
n2s(p,i);
if (n != i+2)