From d45ba43dab962bdc84158efc0cdddd5f5a08cf5e Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 24 Apr 2015 15:05:27 +0100 Subject: [PATCH] Updates following review comments Miscellaneous updates following review comments on the version negotiation rewrite patches. Reviewed-by: Kurt Roeckx --- include/openssl/ssl.h | 10 +- ssl/install-ssl.com | 2 +- ssl/record/rec_layer_s3.c | 9 +- ssl/record/ssl3_record.c | 41 ++----- ssl/s3_both.c | 21 ++-- ssl/s3_clnt.c | 245 +++++++++++++++++++++++++++----------- ssl/s3_srvr.c | 130 ++++++++++++++++++-- ssl/ssl_err.c | 11 +- ssl/ssl_lib.c | 178 --------------------------- ssl/ssl_locl.h | 8 -- ssl/t1_clnt.c | 6 +- ssl/t1_meth.c | 5 + ssl/t1_srvr.c | 4 + 13 files changed, 345 insertions(+), 325 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index c778624364..a93145bf86 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1931,14 +1931,6 @@ void ERR_load_SSL_strings(void); # define SSL_F_DTLS1_SEND_SERVER_HELLO 266 # define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE 267 # define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 -# define SSL_F_SSL23_ACCEPT 115 -# define SSL_F_SSL23_CLIENT_HELLO 116 -# define SSL_F_SSL23_CONNECT 117 -# define SSL_F_SSL23_GET_CLIENT_HELLO 118 -# define SSL_F_SSL23_GET_SERVER_HELLO 119 -# define SSL_F_SSL23_PEEK 237 -# define SSL_F_SSL23_READ 120 -# define SSL_F_SSL23_WRITE 121 # define SSL_F_SSL3_ACCEPT 128 # define SSL_F_SSL3_ADD_CERT_TO_BUF 296 # define SSL_F_SSL3_CALLBACK_CTRL 233 @@ -2076,6 +2068,7 @@ void ERR_load_SSL_strings(void); # define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 # define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 # define SSL_F_SSL_SET_TRUST 228 +# define SSL_F_SSL_SET_VERSION 347 # define SSL_F_SSL_SET_WFD 196 # define SSL_F_SSL_SHUTDOWN 224 # define SSL_F_SSL_SRP_CTX_INIT 313 @@ -2292,7 +2285,6 @@ void ERR_load_SSL_strings(void); # define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 # define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 # define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 -# define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 # define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 # define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 # define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 diff --git a/ssl/install-ssl.com b/ssl/install-ssl.com index 55e1a6a036..c213357acc 100755 --- a/ssl/install-ssl.com +++ b/ssl/install-ssl.com @@ -70,7 +70,7 @@ $ if f$parse("wrk_sslinclude:") .eqs. "" then - $ if f$parse("wrk_sslxlib:") .eqs. "" then - create /directory /log wrk_sslxlib: $! -$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, srtp.h +$ exheader := ssl.h, ssl2.h, ssl3.h, tls1.h, dtls1.h, srtp.h $ libs := ssl_libssl $! $ xexe_dir := [-.'archd'.exe.ssl] diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index c20af880e3..456fac46d0 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -1124,7 +1124,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) goto f_err; } - if(s->version == TLS_ANY_VERSION + if(s->method->version == TLS_ANY_VERSION && (s->server || rr->type != SSL3_RT_ALERT)) { /* * If we've got this far and still haven't decided on what version @@ -1493,11 +1493,18 @@ void ssl3_record_sequence_update(unsigned char *seq) } } +/* + * Returns true if the current rrec was sent in SSLv2 backwards compatible + * format and false otherwise. + */ int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl) { return SSL3_RECORD_is_sslv2_record(&rl->rrec); } +/* + * Returns the length in bytes of the current rrec + */ int RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl) { return SSL3_RECORD_get_length(&rl->rrec); diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index ff09f0b16a..b0eb7cce92 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -220,16 +220,13 @@ int ssl3_get_record(SSL *s) /* * Check whether this is a regular record or an SSLv2 style record. The - * latter is only used in an initial ClientHello for old clients. + * latter is only used in an initial ClientHello for old clients. We + * check s->read_hash and s->enc_read_ctx to ensure this does not apply + * during renegotiation */ if (s->first_packet && s->server && !s->read_hash && !s->enc_read_ctx && (p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { /* SSLv2 style record */ - if (s->msg_callback) - s->msg_callback(0, SSL2_VERSION, 0, p + 2, - RECORD_LAYER_get_packet_length(&s->rlayer) - 2, - s, s->msg_callback_arg); - rr->type = SSL3_RT_HANDSHAKE; rr->rec_version = SSL2_VERSION; @@ -262,19 +259,16 @@ int ssl3_get_record(SSL *s) n2s(p, rr->length); /* Lets check version */ - if (!s->first_packet) { - if (version != s->version - && s->method->version != TLS_ANY_VERSION) { - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); - if ((s->version & 0xFF00) == (version & 0xFF00) - && !s->enc_write_ctx && !s->write_hash) - /* - * Send back error using their minor version number :-) - */ - s->version = (unsigned short)version; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } + if (!s->first_packet && version != s->version) { + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); + if ((s->version & 0xFF00) == (version & 0xFF00) + && !s->enc_write_ctx && !s->write_hash) + /* + * Send back error using their minor version number :-) + */ + s->version = (unsigned short)version; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; } if ((version >> 8) != SSL3_VERSION_MAJOR) { @@ -309,15 +303,6 @@ int ssl3_get_record(SSL *s) n = ssl3_read_n(s, i, i, 1); if (n <= 0) return (n); /* error or non-blocking io */ - /* - * now n == rr->length, and - * s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length - * or - * s->packet_length == SSL2_RT_HEADER_LENGTH + rr->length - * (if SSLv2 packet) - */ - } else { - n = 0; } /* set state for later operations */ diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 193270b315..17a8054868 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -363,7 +363,8 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) p = (unsigned char *)s->init_buf->data; - if (s->state == st1) { /* s->init_num < 4 */ + if (s->state == st1) { + /* s->init_num < SSL3_HM_HEADER_LENGTH */ int skip_message; do { @@ -393,12 +394,11 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, 4, s, s->msg_callback_arg); + p, SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); } - } - while (skip_message); - - /* s->init_num == 4 */ + } while (skip_message); + /* s->init_num == SSL3_HM_HEADER_LENGTH */ if ((mt >= 0) && (*p != mt)) { al = SSL_AD_UNEXPECTED_MESSAGE; @@ -441,7 +441,8 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } - if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) { + if (l && !BUF_MEM_grow_clean(s->init_buf, + (int)l + SSL3_HM_HEADER_LENGTH)) { SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); goto err; } @@ -480,12 +481,6 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) /* Feed this message into MAC computation. */ if(RECORD_LAYER_is_sslv2_record(&s->rlayer)) { ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num); - /* - * In previous versions we would have rewritten the SSLv2 record into - * something that looked like a SSLv3+ record and passed that to the - * callback. As we're not doing the rewriting anymore it's not clear - * what we should do here. - */ if (s->msg_callback) s->msg_callback(0, SSL2_VERSION, 0, s->init_buf->data, (size_t)s->init_num, s, s->msg_callback_arg); diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 1bc5bcd9b1..c05e9b1473 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -163,10 +163,15 @@ # include #endif +static int ssl_set_version(SSL *s); static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b); #ifndef OPENSSL_NO_TLSEXT static int ssl3_check_finished(SSL *s); #endif +static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, + unsigned char *p, + int (*put_cb) (const SSL_CIPHER *, + unsigned char *)); #ifndef OPENSSL_NO_SSL3_METHOD static const SSL_METHOD *ssl3_get_client_method(int ver) @@ -242,7 +247,8 @@ int ssl3_connect(SSL *s) goto end; } - if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { + if (s->version != TLS_ANY_VERSION && + !ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { SSLerr(SSL_F_SSL3_CONNECT, SSL_R_VERSION_TOO_LOW); return -1; } @@ -669,6 +675,105 @@ int ssl3_connect(SSL *s) return (ret); } +/* + * Work out what version we should be using for the initial ClientHello if + * the version is currently set to (D)TLS_ANY_VERSION. + * Returns 1 on success + * Returns 0 on error + */ +static int ssl_set_version(SSL *s) +{ + unsigned long mask, options = s->options; + + if (s->method->version == TLS_ANY_VERSION) { + /* + * SSL_OP_NO_X disables all protocols above X *if* there are + * some protocols below X enabled. This is required in order + * to maintain "version capability" vector contiguous. So + * that if application wants to disable TLS1.0 in favour of + * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the + * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3. + */ + mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 +#if !defined(OPENSSL_NO_SSL3) + | SSL_OP_NO_SSLv3 +#endif + ; +#if !defined(OPENSSL_NO_TLS1_2_CLIENT) + if (options & SSL_OP_NO_TLSv1_2) { + if ((options & mask) != mask) { + s->version = TLS1_1_VERSION; + } else { + SSLerr(SSL_F_SSL_SET_VERSION, SSL_R_NO_PROTOCOLS_AVAILABLE); + return 0; + } + } else { + s->version = TLS1_2_VERSION; + } +#else + if ((options & mask) == mask) { + SSLerr(SSL_F_SSL_SET_VERSION, SSL_R_NO_PROTOCOLS_AVAILABLE); + return 0; + } + s->version = TLS1_1_VERSION; +#endif + + mask &= ~SSL_OP_NO_TLSv1_1; + if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) + s->version = TLS1_VERSION; + mask &= ~SSL_OP_NO_TLSv1; +#if !defined(OPENSSL_NO_SSL3) + if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) + s->version = SSL3_VERSION; +#endif + + if (s->version != TLS1_2_VERSION && tls1_suiteb(s)) { + SSLerr(SSL_F_SSL_SET_VERSION, + SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); + return 0; + } + + if (s->version == SSL3_VERSION && FIPS_mode()) { + SSLerr(SSL_F_SSL_SET_VERSION, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return 0; + } + + } else if (s->method->version == DTLS_ANY_VERSION) { + /* Determine which DTLS version to use */ + /* If DTLS 1.2 disabled correct the version number */ + if (options & SSL_OP_NO_DTLSv1_2) { + if (tls1_suiteb(s)) { + SSLerr(SSL_F_SSL_SET_VERSION, + SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); + return 0; + } + /* + * Disabling all versions is silly: return an error. + */ + if (options & SSL_OP_NO_DTLSv1) { + SSLerr(SSL_F_SSL_SET_VERSION, SSL_R_WRONG_SSL_VERSION); + return 0; + } + /* + * Update method so we don't use any DTLS 1.2 features. + */ + s->method = DTLSv1_client_method(); + s->version = DTLS1_VERSION; + } else { + /* + * We only support one version: update method + */ + if (options & SSL_OP_NO_DTLSv1) + s->method = DTLSv1_2_client_method(); + s->version = DTLS1_2_VERSION; + } + } + + s->client_version = s->version; + + return 1; +} + int ssl3_client_hello(SSL *s) { unsigned char *buf; @@ -680,75 +785,14 @@ int ssl3_client_hello(SSL *s) int j; SSL_COMP *comp; #endif - unsigned long mask, options = s->options; buf = (unsigned char *)s->init_buf->data; if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { SSL_SESSION *sess = s->session; - if (s->method->version == TLS_ANY_VERSION ) { - /* - * SSL_OP_NO_X disables all protocols above X *if* there are - * some protocols below X enabled. This is required in order - * to maintain "version capability" vector contiguous. So - * that if application wants to disable TLS1.0 in favour of - * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the - * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3. - */ - mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 -#if !defined(OPENSSL_NO_SSL3) - | SSL_OP_NO_SSLv3 -#endif - ; -#if !defined(OPENSSL_NO_TLS1_2_CLIENT) - s->version = TLS1_2_VERSION; - - if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) - s->version = TLS1_1_VERSION; -#else - s->version = TLS1_1_VERSION; -#endif - mask &= ~SSL_OP_NO_TLSv1_1; - if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) - s->version = TLS1_VERSION; - mask &= ~SSL_OP_NO_TLSv1; -#if !defined(OPENSSL_NO_SSL3) - if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) - s->version = SSL3_VERSION; - mask &= ~SSL_OP_NO_SSLv3; -#endif - s->client_version = s->version; - } else if (s->method->version == DTLS_ANY_VERSION) { - /* Determine which DTLS version to use */ - /* If DTLS 1.2 disabled correct the version number */ - if (options & SSL_OP_NO_DTLSv1_2) { - if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - goto err; - } - /* - * Disabling all versions is silly: return an error. - */ - if (options & SSL_OP_NO_DTLSv1) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_WRONG_SSL_VERSION); - goto err; - } - /* - * Update method so we don't use any DTLS 1.2 features. - */ - s->method = DTLSv1_client_method(); - s->version = DTLS1_VERSION; - } else { - /* - * We only support one version: update method - */ - if (options & SSL_OP_NO_DTLSv1) - s->method = DTLSv1_2_client_method(); - s->version = DTLS1_2_VERSION; - } - s->client_version = s->version; - } + /* Work out what SSL/TLS/DTLS version to use */ + if (ssl_set_version(s) == 0) + goto err; if ((sess == NULL) || (sess->ssl_version != s->version) || #ifdef OPENSSL_NO_TLSEXT @@ -981,7 +1025,8 @@ int ssl3_get_server_hello(SSL *s) if (FIPS_mode()) { SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - goto err; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; } s->method = SSLv3_client_method(); } else @@ -996,13 +1041,15 @@ int ssl3_get_server_hello(SSL *s) s->method = TLSv1_2_client_method(); } else { SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; } s->session->ssl_version = s->version = s->method->version; if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) { SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_VERSION_TOO_LOW); - goto err; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; } } else if (s->method->version == DTLS_ANY_VERSION) { /* Work out correct protocol version to use */ @@ -3512,3 +3559,65 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) i = s->ctx->client_cert_cb(s, px509, ppkey); return i; } + +int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, + unsigned char *p, + int (*put_cb) (const SSL_CIPHER *, + unsigned char *)) +{ + int i, j = 0; + SSL_CIPHER *c; + unsigned char *q; + int empty_reneg_info_scsv = !s->renegotiate; + /* Set disabled masks for this session */ + ssl_set_client_disabled(s); + + if (sk == NULL) + return (0); + q = p; + if (put_cb == NULL) + put_cb = s->method->put_cipher_by_char; + + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + /* Skip disabled ciphers */ + if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED)) + continue; +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + if (c->id == SSL3_CK_SCSV) { + if (!empty_reneg_info_scsv) + continue; + else + empty_reneg_info_scsv = 0; + } +#endif + j = put_cb(c, p); + p += j; + } + /* + * If p == q, no ciphers; caller indicates an error. Otherwise, add + * applicable SCSVs. + */ + if (p != q) { + if (empty_reneg_info_scsv) { + static SSL_CIPHER scsv = { + 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + j = put_cb(&scsv, p); + p += j; +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); +#endif + } + if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { + static SSL_CIPHER scsv = { + 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + j = put_cb(&scsv, p); + p += j; + } + } + + return (p - q); +} diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 14daf8fe4e..9835f50262 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -164,6 +164,9 @@ #include #include +static STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, + int num, STACK_OF(SSL_CIPHER) **skp, int sslv2format); + #ifndef OPENSSL_NO_SSL3_METHOD static const SSL_METHOD *ssl3_get_server_method(int ver); @@ -901,7 +904,7 @@ int ssl3_get_client_hello(SSL *s) unsigned char *p, *d; SSL_CIPHER *c; #ifndef OPENSSL_NO_COMP - unsigned char *q; + unsigned char *q = NULL; SSL_COMP *comp = NULL; #endif STACK_OF(SSL_CIPHER) *ciphers = NULL; @@ -960,9 +963,8 @@ int ssl3_get_client_hello(SSL *s) * layer in order to have determined that this is a SSLv2 record * in the first place */ - al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto f_err; + goto err; } if ((p[1] == 0x00) && (p[2] == 0x02)) { @@ -1002,11 +1004,7 @@ int ssl3_get_client_hello(SSL *s) && (((s->client_version >> 8) & 0xff) == SSL3_VERSION_MAJOR)) { protverr = 0; } - } else { - /* - * We already know that this is an SSL3_VERSION_MAJOR protocol, - * so we're just testing the minor versions here - */ + } else if (((s->client_version >> 8) & 0xff) == SSL3_VERSION_MAJOR) { switch(s->client_version) { default: case TLS1_2_VERSION: @@ -3556,3 +3554,119 @@ int ssl3_get_next_proto(SSL *s) # endif #endif + +#define SSLV2_CIPHER_LEN 3 + +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, + int num, + STACK_OF(SSL_CIPHER) **skp, + int sslv2format) +{ + const SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + int i, n; + + if (s->s3) + s->s3->send_connection_binding = 0; + + if(sslv2format) { + n = SSLV2_CIPHER_LEN; + } else { + n = ssl_put_cipher_by_char(s, NULL, NULL); + } + if (n == 0 || (num % n) != 0) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + return (NULL); + } + if ((skp == NULL) || (*skp == NULL)) { + sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ + if(sk == NULL) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return NULL; + } + } else { + sk = *skp; + sk_SSL_CIPHER_zero(sk); + } + + OPENSSL_free(s->cert->ciphers_raw); + s->cert->ciphers_raw = BUF_memdup(p, num); + if (s->cert->ciphers_raw == NULL) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + s->cert->ciphers_rawlen = (size_t)num; + + for (i = 0; i < num; i += n) { + /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ + if (s->s3 && (n != 3 || !p[0]) && + (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && + (p[n - 1] == (SSL3_CK_SCSV & 0xff))) { + /* SCSV fatal if renegotiating */ + if (s->renegotiate) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + s->s3->send_connection_binding = 1; + p += n; +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "SCSV received by server\n"); +#endif + continue; + } + + /* Check for TLS_FALLBACK_SCSV */ + if ((n != 3 || !p[0]) && + (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && + (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { + /* + * The SCSV indicates that the client previously tried a higher + * version. Fail if the current version is an unexpected + * downgrade. + */ + if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_INAPPROPRIATE_FALLBACK); + if (s->s3) + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_INAPPROPRIATE_FALLBACK); + goto err; + } + p += n; + continue; + } + + if(sslv2format) { + /* + * We only support SSLv2 format ciphers in SSLv3+ using a + * SSLv2 backward compatible ClientHello. In this case the first + * byte is always 0 for SSLv3 compatible ciphers. Anything else + * is an SSLv2 cipher and we ignore it + */ + if(p[0] == 0) + c = ssl_get_cipher_by_char(s, &p[1]); + else + c = NULL; + } else { + c = ssl_get_cipher_by_char(s, p); + } + p += n; + if (c != NULL) { + if (!sk_SSL_CIPHER_push(sk, c)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + } + } + + if (skp != NULL) + *skp = sk; + return (sk); + err: + if ((skp == NULL) || (*skp == NULL)) + sk_SSL_CIPHER_free(sk); + return (NULL); +} diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 24891ad69e..86f8fa891a 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -111,14 +111,6 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE), "dtls1_send_server_key_exchange"}, {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES), "dtls1_write_app_data_bytes"}, - {ERR_FUNC(SSL_F_SSL23_ACCEPT), "ssl23_accept"}, - {ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO), "SSL23_CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_CONNECT), "ssl23_connect"}, - {ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO), "SSL23_GET_CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO), "SSL23_GET_SERVER_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_PEEK), "ssl23_peek"}, - {ERR_FUNC(SSL_F_SSL23_READ), "ssl23_read"}, - {ERR_FUNC(SSL_F_SSL23_WRITE), "ssl23_write"}, {ERR_FUNC(SSL_F_SSL3_ACCEPT), "ssl3_accept"}, {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "ssl3_callback_ctrl"}, @@ -297,6 +289,7 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT), "SSL_set_session_id_context"}, {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"}, {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, + {ERR_FUNC(SSL_F_SSL_SET_VERSION), "SSL_SET_VERSION"}, {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"}, @@ -564,8 +557,6 @@ static ERR_STRING_DATA SSL_str_reasons[] = { "srtp protection profile list too long"}, {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), "srtp unknown protection profile"}, - {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), - "ssl23 doing session id reuse"}, {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), "ssl3 ext invalid ecpointformat"}, {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 0969368c46..b9ae0258a0 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1394,184 +1394,6 @@ char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) return (buf); } -int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, - unsigned char *p, - int (*put_cb) (const SSL_CIPHER *, - unsigned char *)) -{ - int i, j = 0; - SSL_CIPHER *c; - unsigned char *q; - int empty_reneg_info_scsv = !s->renegotiate; - /* Set disabled masks for this session */ - ssl_set_client_disabled(s); - - if (sk == NULL) - return (0); - q = p; - if (put_cb == NULL) - put_cb = s->method->put_cipher_by_char; - - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - c = sk_SSL_CIPHER_value(sk, i); - /* Skip disabled ciphers */ - if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED)) - continue; -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (c->id == SSL3_CK_SCSV) { - if (!empty_reneg_info_scsv) - continue; - else - empty_reneg_info_scsv = 0; - } -#endif - j = put_cb(c, p); - p += j; - } - /* - * If p == q, no ciphers; caller indicates an error. Otherwise, add - * applicable SCSVs. - */ - if (p != q) { - if (empty_reneg_info_scsv) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, - "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); -#endif - } - if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; - } - } - - return (p - q); -} - -#define SSLV2_CIPHER_LEN 3 - -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, - int num, - STACK_OF(SSL_CIPHER) **skp, - int sslv2format) -{ - const SSL_CIPHER *c; - STACK_OF(SSL_CIPHER) *sk; - int i, n; - - if (s->s3) - s->s3->send_connection_binding = 0; - - if(sslv2format) { - n = SSLV2_CIPHER_LEN; - } else { - n = ssl_put_cipher_by_char(s, NULL, NULL); - } - if (n == 0 || (num % n) != 0) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); - return (NULL); - } - if ((skp == NULL) || (*skp == NULL)) { - sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ - if(sk == NULL) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - return NULL; - } - } else { - sk = *skp; - sk_SSL_CIPHER_zero(sk); - } - - OPENSSL_free(s->cert->ciphers_raw); - s->cert->ciphers_raw = BUF_memdup(p, num); - if (s->cert->ciphers_raw == NULL) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - s->cert->ciphers_rawlen = (size_t)num; - - for (i = 0; i < num; i += n) { - /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ - if (s->s3 && (n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_SCSV & 0xff))) { - /* SCSV fatal if renegotiating */ - if (s->renegotiate) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - goto err; - } - s->s3->send_connection_binding = 1; - p += n; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "SCSV received by server\n"); -#endif - continue; - } - - /* Check for TLS_FALLBACK_SCSV */ - if ((n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { - /* - * The SCSV indicates that the client previously tried a higher - * version. Fail if the current version is an unexpected - * downgrade. - */ - if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_INAPPROPRIATE_FALLBACK); - if (s->s3) - ssl3_send_alert(s, SSL3_AL_FATAL, - SSL_AD_INAPPROPRIATE_FALLBACK); - goto err; - } - p += n; - continue; - } - - if(sslv2format) { - /* - * We only support SSLv2 format ciphers in SSLv3+ using a - * SSLv2 backward compatible ClientHello. In this case the first - * byte is always 0 for SSLv3 compatible ciphers. Anything else - * is an SSLv2 cipher and we ignore it - */ - if(p[0] == 0) - c = ssl_get_cipher_by_char(s, &p[1]); - else - c = NULL; - } else { - c = ssl_get_cipher_by_char(s, p); - } - p += n; - if (c != NULL) { - if (!sk_SSL_CIPHER_push(sk, c)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - } - } - - if (skp != NULL) - *skp = sk; - return (sk); - err: - if ((skp == NULL) || (*skp == NULL)) - sk_SSL_CIPHER_free(sk); - return (NULL); -} - #ifndef OPENSSL_NO_TLSEXT /** return a servername extension value if provided in Client Hello, or NULL. * So far, only host_name types are defined (RFC 3546). diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 0f8a4c8480..91eb1196f7 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1882,14 +1882,6 @@ __owur int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); __owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, const SSL_CIPHER *const *bp); -__owur STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, - int num, - STACK_OF(SSL_CIPHER) **skp, - int sslv2format); -__owur int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, - unsigned char *p, - int (*put_cb) (const SSL_CIPHER *, - unsigned char *)); __owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, STACK_OF(SSL_CIPHER) **pref, STACK_OF(SSL_CIPHER) **sorted, diff --git a/ssl/t1_clnt.c b/ssl/t1_clnt.c index 7ead372bc3..be9759ae93 100644 --- a/ssl/t1_clnt.c +++ b/ssl/t1_clnt.c @@ -67,13 +67,17 @@ static const SSL_METHOD *tls1_get_client_method(int ver); static const SSL_METHOD *tls1_get_client_method(int ver) { if (ver == TLS_ANY_VERSION) - return TLS_server_method(); + return TLS_client_method(); if (ver == TLS1_2_VERSION) return TLSv1_2_client_method(); if (ver == TLS1_1_VERSION) return TLSv1_1_client_method(); if (ver == TLS1_VERSION) return TLSv1_client_method(); +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_client_method()); +#endif return NULL; } diff --git a/ssl/t1_meth.c b/ssl/t1_meth.c index 0726274ba3..044bac53f1 100644 --- a/ssl/t1_meth.c +++ b/ssl/t1_meth.c @@ -70,6 +70,11 @@ static const SSL_METHOD *tls1_get_method(int ver) return TLSv1_1_method(); if (ver == TLS1_VERSION) return TLSv1_method(); +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_method()); + else +#endif return NULL; } diff --git a/ssl/t1_srvr.c b/ssl/t1_srvr.c index 451f384ecc..5206ce9028 100644 --- a/ssl/t1_srvr.c +++ b/ssl/t1_srvr.c @@ -75,6 +75,10 @@ static const SSL_METHOD *tls1_get_server_method(int ver) return TLSv1_1_server_method(); if (ver == TLS1_VERSION) return TLSv1_server_method(); +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_server_method()); +#endif return NULL; } -- 2.25.1