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 cbd64894ec)

Conflicts:

	ssl/ssl_locl.h
This commit is contained in:
Dr. Stephen Henson 2013-03-13 15:33:24 +00:00
parent d88d98edd3
commit 1b6ab411d3
10 changed files with 52 additions and 45 deletions

View File

@ -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.

View File

@ -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; 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 @@ 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.

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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; 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--)
{

View File

@ -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)

View File

@ -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;