Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>
Approved by: steve@openssl.org

Add Renegotiation extension to DTLS, fix DTLS ClientHello processing bug.
This commit is contained in:
Dr. Stephen Henson
2009-12-01 17:40:46 +00:00
parent b172352b52
commit 82e448b92b
7 changed files with 258 additions and 3 deletions

View File

@@ -404,3 +404,194 @@ int dtls1_listen(SSL *s, struct sockaddr *client)
(void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
return 1;
}
#ifndef OPENSSL_NO_TLSEXT
unsigned char *ssl_add_clienthello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit)
{
int extdatalen = 0;
unsigned char *ret = p;
int el;
ret+=2;
if (ret>=limit) return NULL; /* this really never occurs, but ... */
/* Renegotiate extension */
if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
{
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return NULL;
}
if((limit - p - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_renegotiate,ret);
s2n(el,ret);
if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
{
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return NULL;
}
ret += el;
if ((extdatalen = ret-p-2)== 0)
return p;
s2n(extdatalen,p);
return ret;
}
int ssl_parse_clienthello_dtlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
{
unsigned short type;
unsigned short size;
unsigned short len;
unsigned char *data = *p;
int renegotiate_seen = 0;
if (data >= (d+n-2))
{
if (s->new_session
&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
{
/* We should always see one extension: the renegotiate extension */
SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
return 0;
}
return 1;
}
n2s(data,len);
if (data > (d+n-len))
return 1;
while (data <= (d+n-4))
{
n2s(data,type);
n2s(data,size);
if (data+size > (d+n))
return 1;
if (type == TLSEXT_TYPE_renegotiate)
{
if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
return 0;
renegotiate_seen = 1;
}
data+=size;
}
if (s->new_session && !renegotiate_seen
&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
{
*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
return 0;
}
*p = data;
return 1;
}
unsigned char *ssl_add_serverhello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit)
{
int extdatalen = 0;
unsigned char *ret = p;
ret+=2;
if (ret>=limit) return NULL; /* this really never occurs, but ... */
if(s->s3->send_connection_binding)
{
int el;
if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
{
SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return NULL;
}
if((limit - p - 4 - el) < 0) return NULL;
s2n(TLSEXT_TYPE_renegotiate,ret);
s2n(el,ret);
if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
{
SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return NULL;
}
ret += el;
}
if ((extdatalen = ret-p-2)== 0)
return p;
s2n(extdatalen,p);
return ret;
}
int ssl_parse_serverhello_dtlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
{
unsigned short type;
unsigned short size;
unsigned short len;
unsigned char *data = *p;
int renegotiate_seen = 0;
if (data >= (d+n-2))
{
if (s->new_session
&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
{
/* We should always see one extension: the renegotiate extension */
SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
return 0;
}
return 1;
}
n2s(data,len);
if (data > (d+n-len))
return 1;
while (data <= (d+n-4))
{
n2s(data,type);
n2s(data,size);
if (data+size > (d+n))
return 1;
if (type == TLSEXT_TYPE_renegotiate)
{
if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
return 0;
renegotiate_seen = 1;
}
data+=size;
}
if (s->new_session && !renegotiate_seen
&& !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
{
*al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
return 0;
}
*p = data;
return 1;
}
#endif