TlsLib should inspect the return from the SSL_do_handshake and return
EFI_PROTOCOL_ERROR on certain conditions that are not recoverable.

For example, if a client is configured with a certain set of ciphers
that the TLS server does not support, the server will send a fatal
alert before the handshake finishes.  Our TLS protocol only expects
an alert to come after the handshake, so we would have continued TLS
operations.

Please note I am using types int and unsigned long to match the
OpenSSL api.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Thomas Palmer <[email protected]>
---
 CryptoPkg/Library/TlsLib/TlsLib.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/CryptoPkg/Library/TlsLib/TlsLib.c 
b/CryptoPkg/Library/TlsLib/TlsLib.c
index b76dd20..8b441a5 100644
--- a/CryptoPkg/Library/TlsLib/TlsLib.c
+++ b/CryptoPkg/Library/TlsLib/TlsLib.c
@@ -616,6 +616,8 @@ TlsDoHandshake (
 {
   TLS_CONNECTION  *TlsConn;
   UINTN           PendingBufferSize;
+  int             ret;
+  unsigned long   e;
 
   TlsConn           = (TLS_CONNECTION *) Tls;
   PendingBufferSize = 0;
@@ -638,18 +640,41 @@ TlsDoHandshake (
     PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
     if (PendingBufferSize == 0) {
       SSL_set_connect_state (TlsConn->Ssl);
-      SSL_do_handshake (TlsConn->Ssl);
+      ret = SSL_do_handshake (TlsConn->Ssl);
       PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
     }
   } else {
     PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
     if (PendingBufferSize == 0) {
       BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
-      SSL_do_handshake (TlsConn->Ssl);
+      ret = SSL_do_handshake (TlsConn->Ssl);
       PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
     }
   }
 
+  if (ret < 1) {
+    ret = SSL_get_error (TlsConn->Ssl, ret);
+    if (ret == SSL_ERROR_SSL ||
+        ret == SSL_ERROR_SYSCALL ||
+        ret == SSL_ERROR_ZERO_RETURN) {
+      DEBUG ((DEBUG_ERROR, "%a SSL_HANDSHAKE_ERROR State=0x%x SSL_ERROR_%a\n", 
__FUNCTION__, SSL_state (TlsConn->Ssl),
+            ret == SSL_ERROR_SSL ? "SSL":
+            ret == SSL_ERROR_SYSCALL ? "SYSCALL":
+            "ZERO_RETURN"
+            ));
+      DEBUG_CODE_BEGIN ();
+      while (1) {
+        e = ERR_get_error ();
+        if (e == 0) {
+          break;
+        }
+        DEBUG ((DEBUG_ERROR, "%a ERROR 0x%x=L%x:F%x:R%x\n", __FUNCTION__, e, 
ERR_GET_LIB (e), ERR_GET_FUNC (e), ERR_GET_REASON (e)));
+      }
+      DEBUG_CODE_END ();
+      return EFI_PROTOCOL_ERROR;
+    }
+  }
+
   if (PendingBufferSize > *BufferOutSize) {
     *BufferOutSize = PendingBufferSize;
     return EFI_BUFFER_TOO_SMALL;
-- 
1.9.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to