summaryrefslogtreecommitdiffstats
path: root/ssl/d1_lib.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2009-12-01 17:42:15 +0000
committerDr. Stephen Henson <steve@openssl.org>2009-12-01 17:42:15 +0000
commit499684404ccf27b261cd72770c068fee4ea6f369 (patch)
tree2015a2ec152e195f665cbadf663bc9324322081b /ssl/d1_lib.c
parent606c46fb6f65424ac6eac456f4390a7d87a492b4 (diff)
PR: 2115
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de> Approved by: steve@openssl.org Add Renegotiation extension to DTLS, fix DTLS ClientHello processing bug.
Diffstat (limited to 'ssl/d1_lib.c')
-rw-r--r--ssl/d1_lib.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index 2786b61c29..99935563d1 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -382,3 +382,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