tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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