Avoid using ERR_put_error() directly in OpenSSL code
[openssl.git] / ssl / statem / statem.c
index d75f9ea036086478e06d0dbff0ebf8850b08c344..bd9277b71ec3281bc924c852fe439bca9e9d7b78 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
- * Licensed under the OpenSSL license (the "License").  You may not use
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
@@ -118,11 +118,13 @@ void ossl_statem_set_renegotiate(SSL *s)
 void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file,
                        int line)
 {
+    ERR_raise(ERR_LIB_SSL, reason);
+    ERR_set_debug(file, line, NULL); /* Override what ERR_raise set */
     /* We shouldn't call SSLfatal() twice. Once is enough */
-    assert(s->statem.state != MSG_FLOW_ERROR);
+    if (s->statem.in_init && s->statem.state == MSG_FLOW_ERROR)
+      return;
     s->statem.in_init = 1;
     s->statem.state = MSG_FLOW_ERROR;
-    ERR_put_error(ERR_LIB_SSL, func, reason, file, line);
     if (al != SSL_AD_NO_ALERT
             && s->statem.enc_write_state != ENC_WRITE_STATE_INVALID)
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -318,7 +320,7 @@ static int state_machine(SSL *s, int server)
          * If we are stateless then we already called SSL_clear() - don't do
          * it again and clear the STATELESS flag itself.
          */
-        if ((s->s3->flags & TLS1_FLAGS_STATELESS) == 0 && !SSL_clear(s))
+        if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0 && !SSL_clear(s))
             return -1;
     }
 #ifndef OPENSSL_NO_SCTP
@@ -341,8 +343,10 @@ static int state_machine(SSL *s, int server)
         }
 
         s->server = server;
-        if (cb != NULL)
-            cb(s, SSL_CB_HANDSHAKE_START, 1);
+        if (cb != NULL) {
+            if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_IS_TLS13(s))
+                cb(s, SSL_CB_HANDSHAKE_START, 1);
+        }
 
         /*
          * Fatal errors in this block don't send an alert because we have
@@ -396,7 +400,7 @@ static int state_machine(SSL *s, int server)
         /*
          * Should have been reset by tls_process_finished, too.
          */
-        s->s3->change_cipher_spec = 0;
+        s->s3.change_cipher_spec = 0;
 
         /*
          * Ok, we now need to push on a buffering BIO ...but not with
@@ -595,7 +599,7 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
             if (!transition(s, mt))
                 return SUB_STATE_ERROR;
 
-            if (s->s3->tmp.message_size > max_message_size(s)) {
+            if (s->s3.tmp.message_size > max_message_size(s)) {
                 SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_READ_STATE_MACHINE,
                          SSL_R_EXCESSIVE_MESSAGE_SIZE);
                 return SUB_STATE_ERROR;
@@ -603,8 +607,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s)
 
             /* dtls_get_message already did this */
             if (!SSL_IS_DTLS(s)
-                    && s->s3->tmp.message_size > 0
-                    && !grow_init_buf(s, s->s3->tmp.message_size
+                    && s->s3.tmp.message_size > 0
+                    && !grow_init_buf(s, s->s3.tmp.message_size
                                          + SSL3_HM_HEADER_LENGTH)) {
                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_READ_STATE_MACHINE,
                          ERR_R_BUF_LIB);
@@ -920,7 +924,7 @@ int ossl_statem_app_data_allowed(SSL *s)
     if (st->state == MSG_FLOW_UNINITED)
         return 0;
 
-    if (!s->s3->in_read_app_data || (s->s3->total_renegotiations == 0))
+    if (!s->s3.in_read_app_data || (s->s3.total_renegotiations == 0))
         return 0;
 
     if (s->server) {
@@ -949,7 +953,7 @@ int ossl_statem_app_data_allowed(SSL *s)
  */
 int ossl_statem_export_allowed(SSL *s)
 {
-    return s->s3->previous_server_finished_len != 0
+    return s->s3.previous_server_finished_len != 0
            && s->statem.hand_state != TLS_ST_SW_FINISHED;
 }