summaryrefslogtreecommitdiff
path: root/thirdparty/openssl/ssl/s3_pkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/openssl/ssl/s3_pkt.c')
-rw-r--r--thirdparty/openssl/ssl/s3_pkt.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/thirdparty/openssl/ssl/s3_pkt.c b/thirdparty/openssl/ssl/s3_pkt.c
index 379890237e..0290c991d8 100644
--- a/thirdparty/openssl/ssl/s3_pkt.c
+++ b/thirdparty/openssl/ssl/s3_pkt.c
@@ -136,6 +136,9 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
unsigned int len, int create_empty_fragment);
static int ssl3_get_record(SSL *s);
+/*
+ * Return values are as per SSL_read()
+ */
int ssl3_read_n(SSL *s, int n, int max, int extend)
{
/*
@@ -667,7 +670,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
* promptly send beyond the end of the users buffer ... so we trap and
* report the error in a way the user will notice
*/
- if (len < tot) {
+ if ((len < tot) || ((wb->left != 0) && (len < (tot + s->s3->wpend_tot)))) {
SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH);
return (-1);
}
@@ -696,6 +699,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
len >= 4 * (int)(max_send_fragment = s->max_send_fragment) &&
s->compress == NULL && s->msg_callback == NULL &&
SSL_USE_EXPLICIT_IV(s) &&
+ s->enc_write_ctx != NULL &&
EVP_CIPHER_flags(s->enc_write_ctx->cipher) &
EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) {
unsigned char aad[13];
@@ -1082,7 +1086,10 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
return -1;
}
-/* if s->s3->wbuf.left != 0, we need to call this */
+/* if s->s3->wbuf.left != 0, we need to call this
+ *
+ * Return values are as per SSL_write(), i.e.
+ */
int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
unsigned int len)
{
@@ -1122,7 +1129,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
*/
wb->left = 0;
}
- return (i);
+ return i;
}
wb->offset += i;
wb->left -= i;
@@ -1229,6 +1236,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
return (ret);
}
+ /*
+ * Reset the count of consecutive warning alerts if we've got a non-empty
+ * record that isn't an alert.
+ */
+ if (rr->type != SSL3_RT_ALERT && rr->length != 0)
+ s->cert->alert_count = 0;
+
/* we now have a packet which can be read and processed */
if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -1443,6 +1457,14 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
if (alert_level == SSL3_AL_WARNING) {
s->s3->warn_alert = alert_descr;
+
+ s->cert->alert_count++;
+ if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+ goto f_err;
+ }
+
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return (0);
@@ -1473,7 +1495,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
- SSL_CTX_remove_session(s->ctx, s->session);
+ SSL_CTX_remove_session(s->session_ctx, s->session);
return (0);
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
@@ -1578,16 +1600,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
switch (rr->type) {
default:
-#ifndef OPENSSL_NO_TLS
/*
- * TLS up to v1.1 just ignores unknown message types: TLS v1.2 give
- * an unexpected message alert.
+ * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but
+ * TLS 1.2 says you MUST send an unexpected message alert. We use the
+ * TLS 1.2 behaviour for all protocol versions to prevent issues where
+ * no progress is being made and the peer continually sends unrecognised
+ * record types, using up resources processing them.
*/
- if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) {
- rr->length = 0;
- goto start;
- }
-#endif
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
goto f_err;
@@ -1698,7 +1717,7 @@ int ssl3_send_alert(SSL *s, int level, int desc)
return -1;
/* If a fatal one, remove from cache */
if ((level == 2) && (s->session != NULL))
- SSL_CTX_remove_session(s->ctx, s->session);
+ SSL_CTX_remove_session(s->session_ctx, s->session);
s->s3->alert_dispatch = 1;
s->s3->send_alert[0] = level;