ssl_exporter_unittest.cc (6993B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "ssl.h" 8 9 #include "gtest_utils.h" 10 #include "tls_connect.h" 11 12 namespace nss_test { 13 14 static const char* kExporterLabel = "EXPORTER-duck"; 15 static const uint8_t kExporterContext[] = {0x12, 0x34, 0x56}; 16 17 static void ExportAndCompare(std::shared_ptr<TlsAgent>& client, 18 std::shared_ptr<TlsAgent>& server, bool context) { 19 static const size_t exporter_len = 10; 20 uint8_t client_value[exporter_len] = {0}; 21 EXPECT_EQ(SECSuccess, 22 SSL_ExportKeyingMaterial( 23 client->ssl_fd(), kExporterLabel, strlen(kExporterLabel), 24 context ? PR_TRUE : PR_FALSE, kExporterContext, 25 sizeof(kExporterContext), client_value, sizeof(client_value))); 26 uint8_t server_value[exporter_len] = {0xff}; 27 EXPECT_EQ(SECSuccess, 28 SSL_ExportKeyingMaterial( 29 server->ssl_fd(), kExporterLabel, strlen(kExporterLabel), 30 context ? PR_TRUE : PR_FALSE, kExporterContext, 31 sizeof(kExporterContext), server_value, sizeof(server_value))); 32 EXPECT_EQ(0, memcmp(client_value, server_value, sizeof(client_value))); 33 } 34 35 TEST_P(TlsConnectGeneric, ExporterBasic) { 36 EnsureTlsSetup(); 37 if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { 38 server_->EnableSingleCipher(TLS_AES_128_GCM_SHA256); 39 } else { 40 server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA); 41 } 42 Connect(); 43 CheckKeys(); 44 ExportAndCompare(client_, server_, false); 45 } 46 47 TEST_P(TlsConnectGeneric, ExporterContext) { 48 EnsureTlsSetup(); 49 if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { 50 server_->EnableSingleCipher(TLS_AES_128_GCM_SHA256); 51 } else { 52 server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA); 53 } 54 Connect(); 55 CheckKeys(); 56 ExportAndCompare(client_, server_, true); 57 } 58 59 // Bug 1312976 - SHA-384 doesn't work in 1.2 right now. 60 TEST_P(TlsConnectTls13, ExporterSha384) { 61 EnsureTlsSetup(); 62 client_->EnableSingleCipher(TLS_AES_256_GCM_SHA384); 63 Connect(); 64 CheckKeys(); 65 ExportAndCompare(client_, server_, false); 66 } 67 68 TEST_P(TlsConnectTls13, ExporterContextEmptyIsSameAsNone) { 69 EnsureTlsSetup(); 70 if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { 71 server_->EnableSingleCipher(TLS_AES_128_GCM_SHA256); 72 } else { 73 server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA); 74 } 75 Connect(); 76 CheckKeys(); 77 ExportAndCompare(client_, server_, false); 78 } 79 80 TEST_P(TlsConnectGenericPre13, ExporterContextLengthTooLong) { 81 static const uint8_t kExporterContextTooLong[PR_UINT16_MAX] = { 82 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFF}; 83 84 EnsureTlsSetup(); 85 Connect(); 86 CheckKeys(); 87 88 static const size_t exporter_len = 10; 89 uint8_t client_value[exporter_len] = {0}; 90 EXPECT_EQ(SECFailure, 91 SSL_ExportKeyingMaterial(client_->ssl_fd(), kExporterLabel, 92 strlen(kExporterLabel), PR_TRUE, 93 kExporterContextTooLong, 94 sizeof(kExporterContextTooLong), 95 client_value, sizeof(client_value))); 96 EXPECT_EQ(PORT_GetError(), SEC_ERROR_INVALID_ARGS); 97 uint8_t server_value[exporter_len] = {0xff}; 98 EXPECT_EQ(SECFailure, 99 SSL_ExportKeyingMaterial(server_->ssl_fd(), kExporterLabel, 100 strlen(kExporterLabel), PR_TRUE, 101 kExporterContextTooLong, 102 sizeof(kExporterContextTooLong), 103 server_value, sizeof(server_value))); 104 EXPECT_EQ(PORT_GetError(), SEC_ERROR_INVALID_ARGS); 105 } 106 107 // This has a weird signature so that it can be passed to the SNI callback. 108 int32_t RegularExporterShouldFail(TlsAgent* agent, const SECItem* srvNameArr, 109 PRUint32 srvNameArrSize) { 110 uint8_t val[10]; 111 EXPECT_EQ(SECFailure, SSL_ExportKeyingMaterial( 112 agent->ssl_fd(), kExporterLabel, 113 strlen(kExporterLabel), PR_TRUE, kExporterContext, 114 sizeof(kExporterContext), val, sizeof(val))) 115 << "regular exporter should fail"; 116 return 0; 117 } 118 119 TEST_P(TlsConnectTls13, EarlyExporter) { 120 SetupForZeroRtt(); 121 client_->Set0RttEnabled(true); 122 server_->Set0RttEnabled(true); 123 ExpectResumption(RESUME_TICKET); 124 125 client_->Handshake(); // Send ClientHello. 126 uint8_t client_value[10] = {0}; 127 RegularExporterShouldFail(client_.get(), nullptr, 0); 128 129 EXPECT_EQ(SECSuccess, 130 SSL_ExportEarlyKeyingMaterial( 131 client_->ssl_fd(), kExporterLabel, strlen(kExporterLabel), 132 kExporterContext, sizeof(kExporterContext), client_value, 133 sizeof(client_value))); 134 135 server_->SetSniCallback(RegularExporterShouldFail); 136 server_->Handshake(); // Handle ClientHello. 137 uint8_t server_value[10] = {0}; 138 EXPECT_EQ(SECSuccess, 139 SSL_ExportEarlyKeyingMaterial( 140 server_->ssl_fd(), kExporterLabel, strlen(kExporterLabel), 141 kExporterContext, sizeof(kExporterContext), server_value, 142 sizeof(server_value))); 143 EXPECT_EQ(0, memcmp(client_value, server_value, sizeof(client_value))); 144 145 Handshake(); 146 ExpectEarlyDataAccepted(true); 147 CheckConnected(); 148 SendReceive(); 149 } 150 151 TEST_P(TlsConnectTls13, EarlyExporterExternalPsk) { 152 RolloverAntiReplay(); 153 ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); 154 ASSERT_TRUE(!!slot); 155 ScopedPK11SymKey scoped_psk( 156 PK11_KeyGen(slot.get(), CKM_HKDF_KEY_GEN, nullptr, 16, nullptr)); 157 AddPsk(scoped_psk, std::string("foo"), ssl_hash_sha256, 158 TLS_CHACHA20_POLY1305_SHA256); 159 StartConnect(); 160 client_->Set0RttEnabled(true); 161 server_->Set0RttEnabled(true); 162 client_->Handshake(); // Send ClientHello. 163 uint8_t client_value[10] = {0}; 164 RegularExporterShouldFail(client_.get(), nullptr, 0); 165 166 EXPECT_EQ(SECSuccess, 167 SSL_ExportEarlyKeyingMaterial( 168 client_->ssl_fd(), kExporterLabel, strlen(kExporterLabel), 169 kExporterContext, sizeof(kExporterContext), client_value, 170 sizeof(client_value))); 171 172 server_->SetSniCallback(RegularExporterShouldFail); 173 server_->Handshake(); // Handle ClientHello. 174 uint8_t server_value[10] = {0}; 175 EXPECT_EQ(SECSuccess, 176 SSL_ExportEarlyKeyingMaterial( 177 server_->ssl_fd(), kExporterLabel, strlen(kExporterLabel), 178 kExporterContext, sizeof(kExporterContext), server_value, 179 sizeof(server_value))); 180 EXPECT_EQ(0, memcmp(client_value, server_value, sizeof(client_value))); 181 182 Handshake(); 183 ExpectEarlyDataAccepted(true); 184 CheckConnected(); 185 SendReceive(); 186 } 187 188 } // namespace nss_test