From 1b6ab411d32f5fb07e8c69d50f22c298ba95e0ba Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 13 Mar 2013 15:33:24 +0000 Subject: [PATCH] Use enc_flags when deciding protocol variations. Use the enc_flags field to determine whether we should use explicit IV, signature algorithms or SHA256 default PRF instead of hard coding which versions support each requirement. (cherry picked from commit cbd64894ec687c6f37d8e43c16dff78e63f6be87) Conflicts: ssl/ssl_locl.h --- ssl/s3_cbc.c | 2 +- ssl/s3_clnt.c | 16 ++++++++-------- ssl/s3_lib.c | 8 ++++---- ssl/s3_pkt.c | 12 ++++++------ ssl/s3_srvr.c | 24 +++++++++++------------- ssl/ssl_lib.c | 3 +-- ssl/ssl_locl.h | 12 +++++++++++- ssl/t1_enc.c | 6 +++--- ssl/t1_lib.c | 10 +++++----- ssl/t1_trce.c | 4 ++-- 10 files changed, 52 insertions(+), 45 deletions(-) diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c index 443a31e746..1a07e1511f 100644 --- a/ssl/s3_cbc.c +++ b/ssl/s3_cbc.c @@ -148,7 +148,7 @@ int tls1_cbc_remove_padding(const SSL* s, unsigned padding_length, good, to_check, i; const unsigned overhead = 1 /* padding length byte */ + mac_size; /* Check if version requires explicit IV */ - if (s->version >= TLS1_1_VERSION || s->version == DTLS1_BAD_VER) + if (SSL_USE_EXPLICIT_IV(s)) { /* These lengths are all public so we can test them in * non-constant time. diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 88384bf5da..76f21b4b1b 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -1030,10 +1030,10 @@ int ssl3_get_server_hello(SSL *s) } } s->s3->tmp.new_cipher=c; - /* Don't digest cached records if TLS v1.2: we may need them for + /* Don't digest cached records if no sigalgs: we may need them for * client authentication. */ - if (TLS1_get_version(s) < TLS1_2_VERSION && !ssl3_digest_cached_records(s)) + if (!SSL_USE_SIGALGS(s) && !ssl3_digest_cached_records(s)) goto f_err; /* lets get the compression algorithm */ /* COMPRESSION */ @@ -1785,7 +1785,7 @@ int ssl3_get_key_exchange(SSL *s) /* if it was signed, check the signature */ if (pkey != NULL) { - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { int rv = tls12_check_peer_sigalg(&md, s, p, pkey); if (rv == -1) @@ -1817,7 +1817,7 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); } #ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA && TLS1_get_version(s) < TLS1_2_VERSION) + if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { int num; @@ -1991,7 +1991,7 @@ int ssl3_get_certificate_request(SSL *s) for (i=0; is3->tmp.ctype[i]= p[i]; p+=p[-1]; - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { n2s(p, llen); /* Check we have enough room for signature algorithms and @@ -3051,7 +3051,7 @@ int ssl3_send_client_verify(SSL *s) EVP_PKEY_sign_init(pctx); if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1())>0) { - if (TLS1_get_version(s) < TLS1_2_VERSION) + if (!SSL_USE_SIGALGS(s)) s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, &(data[MD5_DIGEST_LENGTH])); @@ -3063,7 +3063,7 @@ int ssl3_send_client_verify(SSL *s) /* For TLS v1.2 send signature algorithm and signature * using agreed digest and cached handshake records. */ - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { long hdatalen = 0; void *hdata; @@ -3193,7 +3193,7 @@ static int ssl3_check_client_certificate(SSL *s) if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey) return 0; /* If no suitable signature algorithm can't use certificate */ - if (TLS1_get_version(s) >= TLS1_2_VERSION && !s->cert->key->digest) + if (SSL_USE_SIGALGS(s) && !s->cert->key->digest) return 0; /* If strict mode check suitability of chain before using it. * This also adjusts suite B digest if necessary. diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index c026c7b697..59d2fbbfac 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -4474,14 +4474,14 @@ need to go to SSL_ST_ACCEPT. } return(ret); } -/* If we are using TLS v1.2 or later and default SHA1+MD5 algorithms switch - * to new SHA256 PRF and handshake macs +/* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF + * and handshake macs if required. */ long ssl_get_algorithm2(SSL *s) { long alg2 = s->s3->tmp.new_cipher->algorithm2; - if (TLS1_get_version(s) >= TLS1_2_VERSION && - alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) + if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF + && alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF)) return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; return alg2; } diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c index 35fcddf5b1..02a5f9df75 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c @@ -180,7 +180,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) /* For DTLS/UDP reads should not span multiple packets * because the read operation returns the whole packet * at once (as long as it fits into the buffer). */ - if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { if (left > 0 && n > left) n = left; @@ -248,7 +248,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) { rb->left = left; if (s->mode & SSL_MODE_RELEASE_BUFFERS && - SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER) + !SSL_IS_DTLS(s)) if (len+left == 0) ssl3_release_read_buffer(s); return(i); @@ -257,7 +257,7 @@ int ssl3_read_n(SSL *s, int n, int max, int extend) /* reads should *never* span multiple packets for DTLS because * the underlying transport protocol is message oriented as opposed * to byte oriented as in the TLS case. */ - if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { if (n > left) n = left; /* makes the while condition false */ @@ -759,8 +759,8 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* field where we are to write out packet length */ plen=p; p+=2; - /* Explicit IV length, block ciphers and TLS version 1.1 or later */ - if (s->enc_write_ctx && s->version >= TLS1_1_VERSION) + /* Explicit IV length, block ciphers appropriate version flag */ + if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); if (mode == EVP_CIPH_CBC_MODE) @@ -897,7 +897,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, wb->left=0; wb->offset+=i; if (s->mode & SSL_MODE_RELEASE_BUFFERS && - SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER) + !SSL_IS_DTLS(s)) ssl3_release_write_buffer(s); s->rwstate=SSL_NOTHING; return(s->s3->wpend_ret); diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 526924d27e..27e745c225 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -641,13 +641,13 @@ int ssl3_accept(SSL *s) #endif s->init_num = 0; } - else if (TLS1_get_version(s) >= TLS1_2_VERSION) + else if (SSL_USE_SIGALGS(s)) { s->state=SSL3_ST_SR_CERT_VRFY_A; s->init_num=0; if (!s->session->peer) break; - /* For TLS v1.2 freeze the handshake buffer + /* For sigalgs freeze the handshake buffer * at this point and digest cached records. */ if (!s->s3->handshake_buffer) @@ -1038,7 +1038,7 @@ int ssl3_get_client_hello(SSL *s) p+=j; - if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { /* cookie stuff */ cookie_len = *(p++); @@ -1403,7 +1403,7 @@ int ssl3_get_client_hello(SSL *s) s->s3->tmp.new_cipher=s->session->cipher; } - if (TLS1_get_version(s) < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER)) + if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) { if (!ssl3_digest_cached_records(s)) goto f_err; @@ -1934,8 +1934,7 @@ int ssl3_send_server_key_exchange(SSL *s) /* n is the length of the params, they start at &(d[4]) * and p points to the space at the end. */ #ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA - && TLS1_get_version(s) < TLS1_2_VERSION) + if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { q=md_buf; j=0; @@ -1966,9 +1965,8 @@ int ssl3_send_server_key_exchange(SSL *s) #endif if (md) { - /* For TLS1.2 and later send signature - * algorithm */ - if (TLS1_get_version(s) >= TLS1_2_VERSION) + /* send signature algorithm */ + if (SSL_USE_SIGALGS(s)) { if (!tls12_get_sigandhash(p, pkey, md)) { @@ -1995,7 +1993,7 @@ int ssl3_send_server_key_exchange(SSL *s) } s2n(i,p); n+=i+2; - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) n+= 2; } else @@ -2045,7 +2043,7 @@ int ssl3_send_certificate_request(SSL *s) p+=n; n++; - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { const unsigned char *psigs; nl = tls12_get_psigalgs(s, &psigs); @@ -3017,7 +3015,7 @@ int ssl3_get_cert_verify(SSL *s) } else { - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { int rv = tls12_check_peer_sigalg(&md, s, p, pkey); if (rv == -1) @@ -3053,7 +3051,7 @@ fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); goto f_err; } - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { long hdatalen = 0; void *hdata; diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index dad33fa14b..197f31f6c6 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1116,8 +1116,7 @@ long SSL_ctrl(SSL *s,int cmd,long larg,void *parg) return 0; #endif - if (SSL_version(s) == DTLS1_VERSION || - SSL_version(s) == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { s->d1->mtu = larg; return larg; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 920c4f209f..af7930943e 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -442,6 +442,14 @@ /* Check if an SSL structure is using DTLS */ #define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) +/* See if we need explicit IV */ +#define SSL_USE_EXPLICIT_IV(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) +/* See if we use signature algorithms extension + * and signature algorithm before signatures. + */ +#define SSL_USE_SIGALGS(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) /* Mostly for SSLv3 */ #define SSL_PKEY_RSA_ENC 0 @@ -711,8 +719,10 @@ typedef struct ssl3_enc_method #define SSL_ENC_FLAG_EXPLICIT_IV 0x1 /* Uses signature algorithms extension */ #define SSL_ENC_FLAG_SIGALGS 0x2 +/* Uses SHA256 default PRF */ +#define SSL_ENC_FLAG_SHA256_PRF 0x4 /* Is DTLS */ -#define SSL_ENC_FLAG_DTLS 0x4 +#define SSL_ENC_FLAG_DTLS 0x8 #ifndef OPENSSL_NO_COMP /* Used for holding the relevant compression methods loaded into SSL_CTX */ diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 4e23bbf77b..63761e5c72 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -779,7 +779,7 @@ int tls1_enc(SSL *s, int send) seq = send?s->s3->write_sequence:s->s3->read_sequence; - if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { unsigned char dtlsseq[9],*p=dtlsseq; @@ -1008,7 +1008,7 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send) mac_ctx = &hmac; } - if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER) + if (SSL_IS_DTLS(ssl)) { unsigned char dtlsseq[8],*p=dtlsseq; @@ -1075,7 +1075,7 @@ printf("rec="); {unsigned int z; for (z=0; zlength; z++) printf("%02X ",buf[z]); printf("\n"); } #endif - if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER) + if (!SSL_IS_DTLS(ssl)) { for (i=7; i>=0; i--) { diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 047583ba81..1aa59c2f72 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -178,7 +178,7 @@ SSL3_ENC_METHOD TLSv1_2_enc_data={ TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, tls1_alert_code, tls1_export_keying_material, - SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS, + SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF, SSL3_HM_HEADER_LENGTH, ssl3_set_handshake_header, ssl3_handshake_write @@ -1307,7 +1307,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha } skip_ext: - if (TLS1_get_client_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { size_t salglen; const unsigned char *salg; @@ -3282,7 +3282,7 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, if (p >= limit) return -1; /* Skip past DTLS cookie */ - if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { i = *(p++); p+= i; @@ -3709,8 +3709,8 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) const EVP_MD *md; CERT *c = s->cert; TLS_SIGALGS *sigptr; - /* Extension ignored for TLS versions below 1.2 */ - if (TLS1_get_version(s) < TLS1_2_VERSION) + /* Extension ignored for inappropriate versions */ + if (!SSL_USE_SIGALGS(s)) return 1; /* Should never happen */ if (!c) diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index c603134821..f1efde2640 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -532,7 +532,7 @@ static int ssl_print_signature(BIO *bio, int indent, SSL *s, { if (*pmsglen < 2) return 0; - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { const unsigned char *p = *pmsg; BIO_indent(bio, indent, 80); @@ -1032,7 +1032,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, SSL *s, return 0; msg += xlen; msglen -= xlen + 1; - if (TLS1_get_version(s) < TLS1_2_VERSION) + if (!SSL_USE_SIGALGS(s)) goto skip_sig; if (msglen < 2) return 0; -- 2.25.1