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.
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c index 87cdc3b..ea46c39 100644 --- a/ssl/s3_cbc.c +++ b/ssl/s3_cbc.c
@@ -146,7 +146,7 @@ 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 1bbe994..dbf790c 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c
@@ -1030,10 +1030,10 @@ } } 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 @@ /* 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 @@ } #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 @@ for (i=0; i<ctype_num; i++) s->s3->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 @@ 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 @@ /* 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 @@ 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 2fe30d7..b92d879 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c
@@ -4458,14 +4458,14 @@ } 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 ffd9c19..8056291 100644 --- a/ssl/s3_pkt.c +++ b/ssl/s3_pkt.c
@@ -180,7 +180,7 @@ /* 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 @@ { 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 @@ /* 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 */ @@ -757,8 +757,8 @@ /* 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) @@ -895,7 +895,7 @@ 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 5d7ab13..0c322cb 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c
@@ -640,13 +640,13 @@ #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) @@ -1037,7 +1037,7 @@ p+=j; - if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { /* cookie stuff */ cookie_len = *(p++); @@ -1409,7 +1409,7 @@ 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; @@ -1941,8 +1941,7 @@ /* 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; @@ -1973,9 +1972,8 @@ #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)) { @@ -2002,7 +2000,7 @@ } s2n(i,p); n+=i+2; - if (TLS1_get_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) n+= 2; } else @@ -2052,7 +2050,7 @@ 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); @@ -3024,7 +3022,7 @@ } 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) @@ -3060,7 +3058,7 @@ 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 3fbb489..1de2625 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c
@@ -1112,8 +1112,7 @@ 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 b4d84a0..f9c5544 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h
@@ -440,7 +440,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 @@ -702,8 +709,10 @@ #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 e313355..c6942ff 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c
@@ -779,7 +779,7 @@ 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 @@ mac_ctx = &hmac; } - if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER) + if (SSL_IS_DTLS(ssl)) { unsigned char dtlsseq[8],*p=dtlsseq; @@ -1071,7 +1071,7 @@ {unsigned int z; for (z=0; z<rec->length; 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 359edbc..99d452a 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c
@@ -178,7 +178,7 @@ 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 @@ -1297,7 +1297,7 @@ } skip_ext: - if (TLS1_get_client_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { size_t salglen; const unsigned char *salg; @@ -3031,7 +3031,7 @@ 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; @@ -3458,8 +3458,8 @@ 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 e766095a..e471272 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c
@@ -531,7 +531,7 @@ { 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); @@ -1046,7 +1046,7 @@ 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;