|
|
2b5643 |
Use version in SSL_METHOD not SSL structure.
|
|
|
2b5643 |
|
|
|
2b5643 |
When deciding whether to use TLS 1.2 PRF and record hash algorithms
|
|
|
2b5643 |
use the version number in the corresponding SSL_METHOD structure
|
|
|
2b5643 |
instead of the SSL structure. The SSL structure version is sometimes
|
|
|
2b5643 |
inaccurate. Note: OpenSSL 1.0.2 and later effectively do this already.
|
|
|
2b5643 |
(CVE-2013-6449)
|
|
|
2b5643 |
|
|
|
2b5643 |
Also preventively check EVP errors for handshake digests.
|
|
|
2b5643 |
|
|
|
2b5643 |
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
|
|
|
2b5643 |
index bf832bb..c4ef273 100644
|
|
|
2b5643 |
--- a/ssl/s3_lib.c
|
|
|
2b5643 |
+++ b/ssl/s3_lib.c
|
|
|
2b5643 |
@@ -4286,7 +4286,7 @@ need to go to SSL_ST_ACCEPT.
|
|
|
2b5643 |
long ssl_get_algorithm2(SSL *s)
|
|
|
2b5643 |
{
|
|
|
2b5643 |
long alg2 = s->s3->tmp.new_cipher->algorithm2;
|
|
|
2b5643 |
- if (TLS1_get_version(s) >= TLS1_2_VERSION &&
|
|
|
2b5643 |
+ if (s->method->version == TLS1_2_VERSION &&
|
|
|
2b5643 |
alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
|
|
|
2b5643 |
return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
|
|
|
2b5643 |
return alg2;
|
|
|
2b5643 |
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
|
|
|
2b5643 |
index ead01c8..1e5dcab 100644
|
|
|
2b5643 |
--- a/ssl/s3_both.c
|
|
|
2b5643 |
+++ b/ssl/s3_both.c
|
|
|
2b5643 |
@@ -161,6 +161,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
|
|
|
2b5643 |
|
|
|
2b5643 |
i=s->method->ssl3_enc->final_finish_mac(s,
|
|
|
2b5643 |
sender,slen,s->s3->tmp.finish_md);
|
|
|
2b5643 |
+ if (i == 0)
|
|
|
2b5643 |
+ return 0;
|
|
|
2b5643 |
s->s3->tmp.finish_md_len = i;
|
|
|
2b5643 |
memcpy(p, s->s3->tmp.finish_md, i);
|
|
|
2b5643 |
p+=i;
|
|
|
2b5643 |
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
|
|
|
2b5643 |
index 804291e..c4bc4e7 100644
|
|
|
2b5643 |
--- a/ssl/s3_pkt.c
|
|
|
2b5643 |
+++ b/ssl/s3_pkt.c
|
|
|
2b5643 |
@@ -335,7 +335,7 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
|
|
|
2b5643 |
if (version != s->version)
|
|
|
2b5643 |
{
|
|
|
2b5643 |
SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
|
|
|
2b5643 |
- if ((s->version & 0xFF00) == (version & 0xFF00))
|
|
|
2b5643 |
+ if ((s->version & 0xFF00) == (version & 0xFF00) && !s->enc_write_ctx && !s->write_hash)
|
|
|
2b5643 |
/* Send back error using their minor version number :-) */
|
|
|
2b5643 |
s->version = (unsigned short)version;
|
|
|
2b5643 |
al=SSL_AD_PROTOCOL_VERSION;
|
|
|
2b5643 |
@@ -1459,8 +1459,14 @@ int ssl3_do_change_cipher_spec(SSL *s)
|
|
|
2b5643 |
slen=s->method->ssl3_enc->client_finished_label_len;
|
|
|
2b5643 |
}
|
|
|
2b5643 |
|
|
|
2b5643 |
- s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
|
|
|
2b5643 |
+ i = s->method->ssl3_enc->final_finish_mac(s,
|
|
|
2b5643 |
sender,slen,s->s3->tmp.peer_finish_md);
|
|
|
2b5643 |
+ if (i == 0)
|
|
|
2b5643 |
+ {
|
|
|
2b5643 |
+ SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
|
|
|
2b5643 |
+ return 0;
|
|
|
2b5643 |
+ }
|
|
|
2b5643 |
+ s->s3->tmp.peer_finish_md_len = i;
|
|
|
2b5643 |
|
|
|
2b5643 |
return(1);
|
|
|
2b5643 |
}
|
|
|
2b5643 |
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
|
|
|
2b5643 |
index e5a8b3f..52efed3 100644
|
|
|
2b5643 |
--- a/ssl/s3_srvr.c
|
|
|
2b5643 |
+++ b/ssl/s3_srvr.c
|
|
|
2b5643 |
@@ -958,7 +958,8 @@ int ssl3_get_client_hello(SSL *s)
|
|
|
2b5643 |
(s->version != DTLS1_VERSION && s->client_version < s->version))
|
|
|
2b5643 |
{
|
|
|
2b5643 |
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
|
|
|
2b5643 |
- if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
|
|
|
2b5643 |
+ if ((s->client_version>>8) == SSL3_VERSION_MAJOR &&
|
|
|
2b5643 |
+ !s->enc_write_ctx && !s->write_hash)
|
|
|
2b5643 |
{
|
|
|
2b5643 |
/* similar to ssl3_get_record, send alert using remote version number */
|
|
|
2b5643 |
s->version = s->client_version;
|
|
|
2b5643 |
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
|
|
|
2b5643 |
index 809ad2e..72015f5 100644
|
|
|
2b5643 |
--- a/ssl/t1_enc.c
|
|
|
2b5643 |
+++ b/ssl/t1_enc.c
|
|
|
2b5643 |
@@ -915,18 +915,19 @@ int tls1_final_finish_mac(SSL *s,
|
|
|
2b5643 |
if (mask & ssl_get_algorithm2(s))
|
|
|
2b5643 |
{
|
|
|
2b5643 |
int hashsize = EVP_MD_size(md);
|
|
|
2b5643 |
- if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
|
|
|
2b5643 |
+ EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
|
|
|
2b5643 |
+ if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
|
|
|
2b5643 |
{
|
|
|
2b5643 |
/* internal error: 'buf' is too small for this cipersuite! */
|
|
|
2b5643 |
err = 1;
|
|
|
2b5643 |
}
|
|
|
2b5643 |
else
|
|
|
2b5643 |
{
|
|
|
2b5643 |
- EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
|
|
|
2b5643 |
- EVP_DigestFinal_ex(&ctx,q,&i);
|
|
|
2b5643 |
- if (i != (unsigned int)hashsize) /* can't really happen */
|
|
|
2b5643 |
+ if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
|
|
|
2b5643 |
+ !EVP_DigestFinal_ex(&ctx,q,&i) ||
|
|
|
2b5643 |
+ (i != (unsigned int)hashsize))
|
|
|
2b5643 |
err = 1;
|
|
|
2b5643 |
- q+=i;
|
|
|
2b5643 |
+ q+=hashsize;
|
|
|
2b5643 |
}
|
|
|
2b5643 |
}
|
|
|
2b5643 |
}
|
|
|
2b5643 |
--
|
|
|
2b5643 |
1.8.3.1
|
|
|
2b5643 |
|