summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2015-04-30 11:11:04 +0100
committerMatt Caswell <matt@openssl.org>2015-05-05 20:07:48 +0100
commitf3c4abb3773efcee81768a5913cba5189a589eff (patch)
tree0a8eb8a086aac19f924816ac84742f8d579c92fd
parent189e20c68c2399782034fec9f65d6b9ee88aac3d (diff)
Add more error state transitions
Ensure all fatal errors transition into the new error state on the server side. Reviewed-by: Rich Salz <rsalz@openssl.org> (cherry picked from commit cf9b0b6fb253fd40225d7c648a08646686e62d2d) Conflicts: ssl/s3_srvr.c
-rw-r--r--ssl/s3_srvr.c74
1 files changed, 61 insertions, 13 deletions
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 306959bcbe..65d7a359b3 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -266,6 +266,7 @@ int ssl3_accept(SSL *s)
if ((s->version >> 8) != 3) {
SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return -1;
}
s->type = SSL_ST_ACCEPT;
@@ -273,11 +274,13 @@ int ssl3_accept(SSL *s)
if (s->init_buf == NULL) {
if ((buf = BUF_MEM_new()) == NULL) {
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
BUF_MEM_free(buf);
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
s->init_buf = buf;
@@ -285,6 +288,7 @@ int ssl3_accept(SSL *s)
if (!ssl3_setup_buffers(s)) {
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
@@ -303,6 +307,7 @@ int ssl3_accept(SSL *s)
*/
if (!ssl_init_wbio_buffer(s, 1)) {
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
@@ -320,6 +325,7 @@ int ssl3_accept(SSL *s)
SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
} else {
/*
@@ -379,6 +385,7 @@ int ssl3_accept(SSL *s)
SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT);
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
}
@@ -529,9 +536,12 @@ int ssl3_accept(SSL *s)
skip = 1;
s->s3->tmp.cert_request = 0;
s->state = SSL3_ST_SW_SRVR_DONE_A;
- if (s->s3->handshake_buffer)
- if (!ssl3_digest_cached_records(s))
+ if (s->s3->handshake_buffer) {
+ if (!ssl3_digest_cached_records(s)) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
+ }
} else {
s->s3->tmp.cert_request = 1;
ret = ssl3_send_certificate_request(s);
@@ -629,11 +639,14 @@ int ssl3_accept(SSL *s)
*/
if (!s->s3->handshake_buffer) {
SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return -1;
}
s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
- if (!ssl3_digest_cached_records(s))
+ if (!ssl3_digest_cached_records(s)) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
} else {
int offset = 0;
int dgst_num;
@@ -647,9 +660,12 @@ int ssl3_accept(SSL *s)
* CertificateVerify should be generalized. But it is next
* step
*/
- if (s->s3->handshake_buffer)
- if (!ssl3_digest_cached_records(s))
+ if (s->s3->handshake_buffer) {
+ if (!ssl3_digest_cached_records(s)) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
+ }
for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++)
if (s->s3->handshake_dgst[dgst_num]) {
int dgst_size;
@@ -665,6 +681,7 @@ int ssl3_accept(SSL *s)
dgst_size =
EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
if (dgst_size < 0) {
+ s->state = SSL_ST_ERR;
ret = -1;
goto end;
}
@@ -779,6 +796,7 @@ int ssl3_accept(SSL *s)
s->session->cipher = s->s3->tmp.new_cipher;
if (!s->method->ssl3_enc->setup_key_block(s)) {
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
@@ -795,6 +813,7 @@ int ssl3_accept(SSL *s)
SSL3_CHANGE_CIPHER_SERVER_WRITE))
{
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
@@ -1510,8 +1529,10 @@ int ssl3_send_server_hello(SSL *s)
buf = (unsigned char *)s->init_buf->data;
#ifdef OPENSSL_NO_TLSEXT
p = s->s3->server_random;
- if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0)
+ if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
#endif
/* Do the message type and length last */
d = p = &(buf[4]);
@@ -1546,6 +1567,7 @@ int ssl3_send_server_hello(SSL *s)
sl = s->session->session_id_length;
if (sl > (int)sizeof(s->session->session_id)) {
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return -1;
}
*(p++) = sl;
@@ -1568,6 +1590,7 @@ int ssl3_send_server_hello(SSL *s)
#ifndef OPENSSL_NO_TLSEXT
if (ssl_prepare_serverhello_tlsext(s) <= 0) {
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT);
+ s->state = SSL_ST_ERR;
return -1;
}
if ((p =
@@ -1575,6 +1598,7 @@ int ssl3_send_server_hello(SSL *s)
buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
NULL) {
SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return -1;
}
#endif
@@ -2058,6 +2082,7 @@ int ssl3_send_server_key_exchange(SSL *s)
BN_CTX_free(bn_ctx);
#endif
EVP_MD_CTX_cleanup(&md_ctx);
+ s->state = SSL_ST_ERR;
return (-1);
}
@@ -2155,6 +2180,7 @@ int ssl3_send_certificate_request(SSL *s)
/* SSL3_ST_SW_CERT_REQ_B */
return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
err:
+ s->state = SSL_ST_ERR;
return (-1);
}
@@ -2921,6 +2947,7 @@ int ssl3_get_client_key_exchange(SSL *s)
EC_KEY_free(srvr_ecdh);
BN_CTX_free(bn_ctx);
#endif
+ s->state = SSL_ST_ERR;
return (-1);
}
@@ -3135,6 +3162,7 @@ int ssl3_get_cert_verify(SSL *s)
if (0) {
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ s->state = SSL_ST_ERR;
}
end:
if (s->s3->handshake_buffer) {
@@ -3293,8 +3321,10 @@ int ssl3_get_client_certificate(SSL *s)
if (0) {
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
- }
err:
+ s->state = SSL_ST_ERR;
+ }
+
if (x != NULL)
X509_free(x);
if (sk != NULL)
@@ -3315,6 +3345,7 @@ int ssl3_send_server_certificate(SSL *s)
(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) {
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,
ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return (0);
}
}
@@ -3322,6 +3353,7 @@ int ssl3_send_server_certificate(SSL *s)
l = ssl3_output_cert_chain(s, x);
if (!l) {
SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+ s->state = SSL_ST_ERR;
return (0);
}
s->state = SSL3_ST_SW_CERT_B;
@@ -3357,11 +3389,15 @@ int ssl3_send_newsession_ticket(SSL *s)
* Some length values are 16 bits, so forget it if session is too
* long
*/
- if (slen_full == 0 || slen_full > 0xFF00)
+ if (slen_full == 0 || slen_full > 0xFF00) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
senc = OPENSSL_malloc(slen_full);
- if (!senc)
+ if (!senc) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
EVP_CIPHER_CTX_init(&ctx);
HMAC_CTX_init(&hctx);
@@ -3484,6 +3520,7 @@ int ssl3_send_newsession_ticket(SSL *s)
OPENSSL_free(senc);
EVP_CIPHER_CTX_cleanup(&ctx);
HMAC_CTX_cleanup(&hctx);
+ s->state = SSL_ST_ERR;
return -1;
}
@@ -3497,8 +3534,10 @@ int ssl3_send_cert_status(SSL *s)
* 1 (ocsp response type) + 3 (ocsp response length)
* + (ocsp response)
*/
- if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen))
+ if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) {
+ s->state = SSL_ST_ERR;
return -1;
+ }
p = (unsigned char *)s->init_buf->data;
@@ -3541,6 +3580,7 @@ int ssl3_get_next_proto(SSL *s)
if (!s->s3->next_proto_neg_seen) {
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,
SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
+ s->state = SSL_ST_ERR;
return -1;
}
@@ -3560,11 +3600,14 @@ int ssl3_get_next_proto(SSL *s)
*/
if (!s->s3->change_cipher_spec) {
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
+ s->state = SSL_ST_ERR;
return -1;
}
- if (n < 2)
+ if (n < 2) {
+ s->state = SSL_ST_ERR;
return 0; /* The body must be > 1 bytes long */
+ }
p = (unsigned char *)s->init_msg;
@@ -3576,15 +3619,20 @@ int ssl3_get_next_proto(SSL *s)
* uint8 padding[padding_len];
*/
proto_len = p[0];
- if (proto_len + 2 > s->init_num)
+ if (proto_len + 2 > s->init_num) {
+ s->state = SSL_ST_ERR;
return 0;
+ }
padding_len = p[proto_len + 1];
- if (proto_len + padding_len + 2 != s->init_num)
+ if (proto_len + padding_len + 2 != s->init_num) {
+ s->state = SSL_ST_ERR;
return 0;
+ }
s->next_proto_negotiated = OPENSSL_malloc(proto_len);
if (!s->next_proto_negotiated) {
SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE);
+ s->state = SSL_ST_ERR;
return 0;
}
memcpy(s->next_proto_negotiated, p + 1, proto_len);