diff options
Diffstat (limited to 'lib/libssl/t1_lib.c')
-rw-r--r-- | lib/libssl/t1_lib.c | 173 |
1 files changed, 34 insertions, 139 deletions
diff --git a/lib/libssl/t1_lib.c b/lib/libssl/t1_lib.c index eb2314ac26a..e3046fec099 100644 --- a/lib/libssl/t1_lib.c +++ b/lib/libssl/t1_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t1_lib.c,v 1.117 2017/05/07 04:22:24 beck Exp $ */ +/* $OpenBSD: t1_lib.c,v 1.118 2017/07/16 18:14:37 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -117,7 +117,9 @@ #include <openssl/ocsp.h> #include "ssl_locl.h" + #include "bytestring.h" +#include "ssl_tlsext.h" static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, const unsigned char *sess_id, int sesslen, @@ -678,6 +680,8 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) int extdatalen = 0; unsigned char *ret = p; int using_ecc = 0; + size_t len; + CBB cbb; /* See if we support any ECC ciphersuites. */ if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) { @@ -699,43 +703,21 @@ ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) } ret += 2; - if (ret >= limit) return NULL; /* this really never occurs, but ... */ - if (s->tlsext_hostname != NULL) { - /* Add TLS extension servername to the Client Hello message */ - size_t size_str, lenmax; - - /* check for enough space. - 4 for the servername type and extension length - 2 for servernamelist length - 1 for the hostname type - 2 for hostname length - + hostname length - */ - - if ((size_t)(limit - ret) < 9) - return NULL; - - lenmax = limit - ret - 9; - if ((size_str = strlen(s->tlsext_hostname)) > lenmax) - return NULL; - - /* extension type and length */ - s2n(TLSEXT_TYPE_server_name, ret); - - s2n(size_str + 5, ret); - - /* length of servername list */ - s2n(size_str + 3, ret); - - /* hostname type, length and hostname */ - *(ret++) = (unsigned char) TLSEXT_NAMETYPE_host_name; - s2n(size_str, ret); - memcpy(ret, s->tlsext_hostname, size_str); - ret += size_str; + CBB_init_fixed(&cbb, ret, limit - ret); + if (!tlsext_clienthello_build(s, &cbb)) { + CBB_cleanup(&cbb); + return NULL; + } + if (!CBB_finish(&cbb, NULL, &len)) { + CBB_cleanup(&cbb); + return NULL; } + if (len > (limit - ret)) + return NULL; + ret += len; /* Add RI if renegotiating */ if (s->internal->renegotiate) { @@ -997,6 +979,8 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) unsigned long alg_a, alg_k; unsigned char *ret = p; int next_proto_neg_seen; + size_t len; + CBB cbb; alg_a = S3I(s)->hs.new_cipher->algorithm_auth; alg_k = S3I(s)->hs.new_cipher->algorithm_mkey; @@ -1007,14 +991,18 @@ ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit) if (ret >= limit) return NULL; /* this really never occurs, but ... */ - if (!s->internal->hit && s->internal->servername_done == 1 && - s->session->tlsext_hostname != NULL) { - if ((size_t)(limit - ret) < 4) - return NULL; - - s2n(TLSEXT_TYPE_server_name, ret); - s2n(0, ret); + CBB_init_fixed(&cbb, ret, limit - ret); + if (!tlsext_serverhello_build(s, &cbb)) { + CBB_cleanup(&cbb); + return NULL; } + if (!CBB_finish(&cbb, NULL, &len)) { + CBB_cleanup(&cbb); + return NULL; + } + if (len > (limit - ret)) + return NULL; + ret += len; if (S3I(s)->send_connection_binding) { int el; @@ -1241,6 +1229,7 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, unsigned char *end = d + n; int renegotiate_seen = 0; int sigalg_seen = 0; + CBS cbs; s->internal->servername_done = 0; s->tlsext_status_type = -1; @@ -1269,106 +1258,12 @@ ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, if (s->internal->tlsext_debug_cb) s->internal->tlsext_debug_cb(s, 0, type, data, size, s->internal->tlsext_debug_arg); -/* The servername extension is treated as follows: - - - Only the hostname type is supported with a maximum length of 255. - - The servername is rejected if too long or if it contains zeros, - in which case an fatal alert is generated. - - The servername field is maintained together with the session cache. - - When a session is resumed, the servername call back invoked in order - to allow the application to position itself to the right context. - - The servername is acknowledged if it is new for a session or when - it is identical to a previously used for the same session. - Applications can control the behaviour. They can at any time - set a 'desirable' servername for a new SSL object. This can be the - case for example with HTTPS when a Host: header field is received and - a renegotiation is requested. In this case, a possible servername - presented in the new client hello is only acknowledged if it matches - the value of the Host: field. - - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION - if they provide for changing an explicit servername context for the session, - i.e. when the session has been established with a servername extension. - - On session reconnect, the servername extension may be absent. - -*/ - - if (type == TLSEXT_TYPE_server_name) { - unsigned char *sdata; - int servname_type; - int dsize; - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - n2s(data, dsize); - - size -= 2; - if (dsize > size) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - sdata = data; - while (dsize > 3) { - servname_type = *(sdata++); - - n2s(sdata, len); - dsize -= 3; - - if (len > dsize) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - if (s->internal->servername_done == 0) - switch (servname_type) { - case TLSEXT_NAMETYPE_host_name: - if (!s->internal->hit) { - if (s->session->tlsext_hostname) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - if (len > TLSEXT_MAXLEN_host_name) { - *al = TLS1_AD_UNRECOGNIZED_NAME; - return 0; - } - if ((s->session->tlsext_hostname = - malloc(len + 1)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->session->tlsext_hostname, sdata, len); - s->session->tlsext_hostname[len] = '\0'; - if (strlen(s->session->tlsext_hostname) != len) { - free(s->session->tlsext_hostname); - s->session->tlsext_hostname = NULL; - *al = TLS1_AD_UNRECOGNIZED_NAME; - return 0; - } - s->internal->servername_done = 1; - - - } else { - s->internal->servername_done = s->session->tlsext_hostname && - strlen(s->session->tlsext_hostname) == len && - strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0; - } - break; - - default: - break; - } - - dsize -= len; - } - if (dsize != 0) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - } + CBS_init(&cbs, data, size); + if (!tlsext_clienthello_parse_one(s, &cbs, type, al)) + return 0; - else if (type == TLSEXT_TYPE_ec_point_formats && + if (type == TLSEXT_TYPE_ec_point_formats && s->version != DTLS1_VERSION) { unsigned char *sdata = data; size_t formatslen; |