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
ExportAndCompare(TlsAgent * client,TlsAgent * server,bool context)17 static void ExportAndCompare(TlsAgent* client, TlsAgent* server, bool context) {
18 static const size_t exporter_len = 10;
19 uint8_t client_value[exporter_len] = {0};
20 EXPECT_EQ(SECSuccess,
21 SSL_ExportKeyingMaterial(
22 client->ssl_fd(), kExporterLabel, strlen(kExporterLabel),
23 context ? PR_TRUE : PR_FALSE, kExporterContext,
24 sizeof(kExporterContext), client_value, sizeof(client_value)));
25 uint8_t server_value[exporter_len] = {0xff};
26 EXPECT_EQ(SECSuccess,
27 SSL_ExportKeyingMaterial(
28 server->ssl_fd(), kExporterLabel, strlen(kExporterLabel),
29 context ? PR_TRUE : PR_FALSE, kExporterContext,
30 sizeof(kExporterContext), server_value, sizeof(server_value)));
31 EXPECT_EQ(0, memcmp(client_value, server_value, sizeof(client_value)));
32 }
33
TEST_P(TlsConnectGeneric,ExporterBasic)34 TEST_P(TlsConnectGeneric, ExporterBasic) {
35 EnsureTlsSetup();
36 if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
37 server_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
38 } else {
39 server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
40 }
41 Connect();
42 CheckKeys();
43 ExportAndCompare(client_, server_, false);
44 }
45
TEST_P(TlsConnectGeneric,ExporterContext)46 TEST_P(TlsConnectGeneric, ExporterContext) {
47 EnsureTlsSetup();
48 if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
49 server_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
50 } else {
51 server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
52 }
53 Connect();
54 CheckKeys();
55 ExportAndCompare(client_, server_, true);
56 }
57
58 // Bug 1312976 - SHA-384 doesn't work in 1.2 right now.
TEST_P(TlsConnectTls13,ExporterSha384)59 TEST_P(TlsConnectTls13, ExporterSha384) {
60 EnsureTlsSetup();
61 client_->EnableSingleCipher(TLS_AES_256_GCM_SHA384);
62 Connect();
63 CheckKeys();
64 ExportAndCompare(client_, server_, false);
65 }
66
TEST_P(TlsConnectTls13,ExporterContextEmptyIsSameAsNone)67 TEST_P(TlsConnectTls13, ExporterContextEmptyIsSameAsNone) {
68 EnsureTlsSetup();
69 if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
70 server_->EnableSingleCipher(TLS_AES_128_GCM_SHA256);
71 } else {
72 server_->EnableSingleCipher(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
73 }
74 Connect();
75 CheckKeys();
76 ExportAndCompare(client_, server_, false);
77 }
78
79 // This has a weird signature so that it can be passed to the SNI callback.
RegularExporterShouldFail(TlsAgent * agent,const SECItem * srvNameArr,PRUint32 srvNameArrSize)80 int32_t RegularExporterShouldFail(TlsAgent* agent, const SECItem* srvNameArr,
81 PRUint32 srvNameArrSize) {
82 uint8_t val[10];
83 EXPECT_EQ(SECFailure, SSL_ExportKeyingMaterial(
84 agent->ssl_fd(), kExporterLabel,
85 strlen(kExporterLabel), PR_TRUE, kExporterContext,
86 sizeof(kExporterContext), val, sizeof(val)))
87 << "regular exporter should fail";
88 return 0;
89 }
90
TEST_P(TlsConnectTls13,EarlyExporter)91 TEST_P(TlsConnectTls13, EarlyExporter) {
92 SetupForZeroRtt();
93 client_->Set0RttEnabled(true);
94 server_->Set0RttEnabled(true);
95 ExpectResumption(RESUME_TICKET);
96
97 client_->Handshake(); // Send ClientHello.
98 uint8_t client_value[10] = {0};
99 RegularExporterShouldFail(client_, nullptr, 0);
100 EXPECT_EQ(SECSuccess,
101 SSL_ExportEarlyKeyingMaterial(
102 client_->ssl_fd(), kExporterLabel, strlen(kExporterLabel),
103 kExporterContext, sizeof(kExporterContext), client_value,
104 sizeof(client_value)));
105
106 server_->SetSniCallback(RegularExporterShouldFail);
107 server_->Handshake(); // Handle ClientHello.
108 uint8_t server_value[10] = {0};
109 EXPECT_EQ(SECSuccess,
110 SSL_ExportEarlyKeyingMaterial(
111 server_->ssl_fd(), kExporterLabel, strlen(kExporterLabel),
112 kExporterContext, sizeof(kExporterContext), server_value,
113 sizeof(server_value)));
114 EXPECT_EQ(0, memcmp(client_value, server_value, sizeof(client_value)));
115
116 Handshake();
117 ExpectEarlyDataAccepted(true);
118 CheckConnected();
119 SendReceive();
120 }
121
122 } // namespace nss_test
123