c70942
# HG changeset patch
c70942
# User Daiki Ueno <dueno@redhat.com>
c70942
# Date 1559121620 -7200
c70942
#      Wed May 29 11:20:20 2019 +0200
c70942
# Node ID 29a48b604602a523defd6f9322a5adeca7e284a5
c70942
# Parent  43a7fb4f994a31222c308113b0fccdd5480d5b8e
c70942
Bug 1553443, send session ticket only after handshake is marked as finished
c70942
c70942
Reviewers: mt
c70942
c70942
Reviewed By: mt
c70942
c70942
Bug #: 1553443
c70942
c70942
Differential Revision: https://phabricator.services.mozilla.com/D32128
c70942
c70942
diff --git a/gtests/ssl_gtest/ssl_auth_unittest.cc b/gtests/ssl_gtest/ssl_auth_unittest.cc
c70942
--- a/gtests/ssl_gtest/ssl_auth_unittest.cc
c70942
+++ b/gtests/ssl_gtest/ssl_auth_unittest.cc
c70942
@@ -537,6 +537,40 @@ TEST_F(TlsConnectStreamTls13, PostHandsh
c70942
                       capture_cert_req->buffer().len()));
c70942
 }
c70942
 
c70942
+// Check if post-handshake auth still works when session tickets are enabled:
c70942
+// https://bugzilla.mozilla.org/show_bug.cgi?id=1553443
c70942
+TEST_F(TlsConnectStreamTls13, PostHandshakeAuthWithSessionTicketsEnabled) {
c70942
+  EnsureTlsSetup();
c70942
+  client_->SetupClientAuth();
c70942
+  EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
c70942
+                                      SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE));
c70942
+  EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(),
c70942
+                                      SSL_ENABLE_SESSION_TICKETS, PR_TRUE));
c70942
+  EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(),
c70942
+                                      SSL_ENABLE_SESSION_TICKETS, PR_TRUE));
c70942
+  size_t called = 0;
c70942
+  server_->SetAuthCertificateCallback(
c70942
+      [&called](TlsAgent*, PRBool, PRBool) -> SECStatus {
c70942
+        called++;
c70942
+        return SECSuccess;
c70942
+      });
c70942
+  Connect();
c70942
+  EXPECT_EQ(0U, called);
c70942
+  // Send CertificateRequest.
c70942
+  EXPECT_EQ(SECSuccess, SSL_GetClientAuthDataHook(
c70942
+                            client_->ssl_fd(), GetClientAuthDataHook, nullptr));
c70942
+  EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd()))
c70942
+      << "Unexpected error: " << PORT_ErrorToName(PORT_GetError());
c70942
+  server_->SendData(50);
c70942
+  client_->ReadBytes(50);
c70942
+  client_->SendData(50);
c70942
+  server_->ReadBytes(50);
c70942
+  EXPECT_EQ(1U, called);
c70942
+  ScopedCERTCertificate cert1(SSL_PeerCertificate(server_->ssl_fd()));
c70942
+  ScopedCERTCertificate cert2(SSL_LocalCertificate(client_->ssl_fd()));
c70942
+  EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
c70942
+}
c70942
+
c70942
 // In TLS 1.3, the client sends its cert rejection on the
c70942
 // second flight, and since it has already received the
c70942
 // server's Finished, it transitions to complete and
c70942
diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c
c70942
--- a/lib/ssl/tls13con.c
c70942
+++ b/lib/ssl/tls13con.c
c70942
@@ -4561,6 +4561,11 @@ tls13_ServerHandleFinished(sslSocket *ss
c70942
         return SECFailure;
c70942
     }
c70942
 
c70942
+    rv = tls13_FinishHandshake(ss);
c70942
+    if (rv != SECSuccess) {
c70942
+        return SECFailure;
c70942
+    }
c70942
+
c70942
     ssl_GetXmitBufLock(ss);
c70942
     if (ss->opt.enableSessionTickets) {
c70942
         rv = tls13_SendNewSessionTicket(ss, NULL, 0);
c70942
@@ -4573,8 +4578,7 @@ tls13_ServerHandleFinished(sslSocket *ss
c70942
         }
c70942
     }
c70942
     ssl_ReleaseXmitBufLock(ss);
c70942
-
c70942
-    return tls13_FinishHandshake(ss);
c70942
+    return SECSuccess;
c70942
 
c70942
 loser:
c70942
     ssl_ReleaseXmitBufLock(ss);
c70942
diff --git a/tests/ssl/sslauth.txt b/tests/ssl/sslauth.txt
c70942
--- a/tests/ssl/sslauth.txt
c70942
+++ b/tests/ssl/sslauth.txt
c70942
@@ -42,6 +42,7 @@
c70942
   noECC     0       -r_-r_-r_-r_-E  -V_tls1.3:tls1.3_-E_-n_TestUser_-w_nss TLS 1.3 Require client auth on post hs (client auth)
c70942
   noECC     0       -r_-r_-r_-E  -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 Request don't require client auth on post hs (client does not provide auth)
c70942
   noECC     1       -r_-r_-r_-r_-E  -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 Require client auth on post hs (client does not provide auth)
c70942
+  noECC     0       -r_-r_-r_-E_-u  -V_tls1.3:tls1.3_-E_-n_TestUser_-w_nss TLS 1.3 Request don't require client auth on post hs with session ticket (client auth)
c70942
 #
c70942
 # Use EC cert for client authentication
c70942
 #