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 <functional>
8 #include <memory>
9 #include "secerr.h"
10 #include "ssl.h"
11 #include "sslerr.h"
12 #include "sslproto.h"
13 
14 extern "C" {
15 // This is not something that should make you happy.
16 #include "libssl_internals.h"
17 }
18 
19 #include "gtest_utils.h"
20 #include "tls_connect.h"
21 #include "tls_parser.h"
22 
23 namespace nss_test {
24 
25 // variant, version, cipher suite
26 typedef std::tuple<SSLProtocolVariant, uint16_t, uint16_t, SSLNamedGroup,
27                    SSLSignatureScheme>
28     CipherSuiteProfile;
29 
30 class TlsCipherSuiteTestBase : public TlsConnectTestBase {
31  public:
TlsCipherSuiteTestBase(SSLProtocolVariant variant,uint16_t version,uint16_t cipher_suite,SSLNamedGroup group,SSLSignatureScheme sig_scheme)32   TlsCipherSuiteTestBase(SSLProtocolVariant variant, uint16_t version,
33                          uint16_t cipher_suite, SSLNamedGroup group,
34                          SSLSignatureScheme sig_scheme)
35       : TlsConnectTestBase(variant, version),
36         cipher_suite_(cipher_suite),
37         group_(group),
38         sig_scheme_(sig_scheme),
39         csinfo_({0}) {
40     SECStatus rv =
41         SSL_GetCipherSuiteInfo(cipher_suite_, &csinfo_, sizeof(csinfo_));
42     EXPECT_EQ(SECSuccess, rv);
43     if (rv == SECSuccess) {
44       std::cerr << "Cipher suite: " << csinfo_.cipherSuiteName << std::endl;
45     }
46     auth_type_ = csinfo_.authType;
47     kea_type_ = csinfo_.keaType;
48   }
49 
50  protected:
EnableSingleCipher()51   void EnableSingleCipher() {
52     EnsureTlsSetup();
53     // It doesn't matter which does this, but the test is better if both do it.
54     client_->EnableSingleCipher(cipher_suite_);
55     server_->EnableSingleCipher(cipher_suite_);
56 
57     if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
58       std::vector<SSLNamedGroup> groups = {group_};
59       if (cert_group_ != ssl_grp_none) {
60         groups.push_back(cert_group_);
61       }
62       client_->ConfigNamedGroups(groups);
63       server_->ConfigNamedGroups(groups);
64       kea_type_ = SSLInt_GetKEAType(group_);
65 
66       client_->SetSignatureSchemes(&sig_scheme_, 1);
67       server_->SetSignatureSchemes(&sig_scheme_, 1);
68     }
69   }
70 
SetupCertificate()71   virtual void SetupCertificate() {
72     if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
73       switch (sig_scheme_) {
74         case ssl_sig_rsa_pss_rsae_sha256:
75           std::cerr << "Signature scheme: rsa_pss_rsae_sha256" << std::endl;
76           Reset(TlsAgent::kServerRsaSign);
77           auth_type_ = ssl_auth_rsa_sign;
78           break;
79         case ssl_sig_rsa_pss_rsae_sha384:
80           std::cerr << "Signature scheme: rsa_pss_rsae_sha384" << std::endl;
81           Reset(TlsAgent::kServerRsaSign);
82           auth_type_ = ssl_auth_rsa_sign;
83           break;
84         case ssl_sig_rsa_pss_rsae_sha512:
85           // You can't fit SHA-512 PSS in a 1024-bit key.
86           std::cerr << "Signature scheme: rsa_pss_rsae_sha512" << std::endl;
87           Reset(TlsAgent::kRsa2048);
88           auth_type_ = ssl_auth_rsa_sign;
89           break;
90         case ssl_sig_rsa_pss_pss_sha256:
91           std::cerr << "Signature scheme: rsa_pss_pss_sha256" << std::endl;
92           Reset(TlsAgent::kServerRsaPss);
93           auth_type_ = ssl_auth_rsa_pss;
94           break;
95         case ssl_sig_rsa_pss_pss_sha384:
96           std::cerr << "Signature scheme: rsa_pss_pss_sha384" << std::endl;
97           Reset("rsa_pss384");
98           auth_type_ = ssl_auth_rsa_pss;
99           break;
100         case ssl_sig_rsa_pss_pss_sha512:
101           std::cerr << "Signature scheme: rsa_pss_pss_sha512" << std::endl;
102           Reset("rsa_pss512");
103           auth_type_ = ssl_auth_rsa_pss;
104           break;
105         case ssl_sig_ecdsa_secp256r1_sha256:
106           std::cerr << "Signature scheme: ecdsa_secp256r1_sha256" << std::endl;
107           Reset(TlsAgent::kServerEcdsa256);
108           auth_type_ = ssl_auth_ecdsa;
109           cert_group_ = ssl_grp_ec_secp256r1;
110           break;
111         case ssl_sig_ecdsa_secp384r1_sha384:
112           std::cerr << "Signature scheme: ecdsa_secp384r1_sha384" << std::endl;
113           Reset(TlsAgent::kServerEcdsa384);
114           auth_type_ = ssl_auth_ecdsa;
115           cert_group_ = ssl_grp_ec_secp384r1;
116           break;
117         default:
118           ADD_FAILURE() << "Unsupported signature scheme: " << sig_scheme_;
119           break;
120       }
121     } else {
122       switch (csinfo_.authType) {
123         case ssl_auth_rsa_sign:
124           Reset(TlsAgent::kServerRsaSign);
125           break;
126         case ssl_auth_rsa_decrypt:
127           Reset(TlsAgent::kServerRsaDecrypt);
128           break;
129         case ssl_auth_ecdsa:
130           Reset(TlsAgent::kServerEcdsa256);
131           cert_group_ = ssl_grp_ec_secp256r1;
132           break;
133         case ssl_auth_ecdh_ecdsa:
134           Reset(TlsAgent::kServerEcdhEcdsa);
135           cert_group_ = ssl_grp_ec_secp256r1;
136           break;
137         case ssl_auth_ecdh_rsa:
138           Reset(TlsAgent::kServerEcdhRsa);
139           break;
140         case ssl_auth_dsa:
141           Reset(TlsAgent::kServerDsa);
142           break;
143         default:
144           ASSERT_TRUE(false) << "Unsupported cipher suite: " << cipher_suite_;
145           break;
146       }
147     }
148   }
149 
ConnectAndCheckCipherSuite()150   void ConnectAndCheckCipherSuite() {
151     Connect();
152     SendReceive();
153 
154     // Check that we used the right cipher suite, auth type and kea type.
155     uint16_t actual;
156     EXPECT_TRUE(client_->cipher_suite(&actual));
157     EXPECT_EQ(cipher_suite_, actual);
158     EXPECT_TRUE(server_->cipher_suite(&actual));
159     EXPECT_EQ(cipher_suite_, actual);
160     SSLAuthType auth;
161     EXPECT_TRUE(client_->auth_type(&auth));
162     EXPECT_EQ(auth_type_, auth);
163     EXPECT_TRUE(server_->auth_type(&auth));
164     EXPECT_EQ(auth_type_, auth);
165     SSLKEAType kea;
166     EXPECT_TRUE(client_->kea_type(&kea));
167     EXPECT_EQ(kea_type_, kea);
168     EXPECT_TRUE(server_->kea_type(&kea));
169     EXPECT_EQ(kea_type_, kea);
170   }
171 
172   // Get the expected limit on the number of records that can be sent for the
173   // cipher suite.
record_limit() const174   uint64_t record_limit() const {
175     switch (csinfo_.symCipher) {
176       case ssl_calg_rc4:
177       case ssl_calg_3des:
178         return 1ULL << 20;
179       case ssl_calg_aes:
180       case ssl_calg_aes_gcm:
181         return 0x5aULL << 28;
182       case ssl_calg_null:
183       case ssl_calg_chacha20:
184         return (1ULL << 48) - 1;
185       case ssl_calg_rc2:
186       case ssl_calg_des:
187       case ssl_calg_idea:
188       case ssl_calg_fortezza:
189       case ssl_calg_camellia:
190       case ssl_calg_seed:
191         break;
192     }
193     ADD_FAILURE() << "No limit for " << csinfo_.cipherSuiteName;
194     return 0;
195   }
196 
last_safe_write() const197   uint64_t last_safe_write() const {
198     uint64_t limit = record_limit() - 1;
199     if (version_ < SSL_LIBRARY_VERSION_TLS_1_1 &&
200         (csinfo_.symCipher == ssl_calg_3des ||
201          csinfo_.symCipher == ssl_calg_aes)) {
202       // 1/n-1 record splitting needs space for two records.
203       limit--;
204     }
205     return limit;
206   }
207 
208  protected:
209   uint16_t cipher_suite_;
210   SSLAuthType auth_type_;
211   SSLKEAType kea_type_;
212   SSLNamedGroup group_;
213   SSLNamedGroup cert_group_ = ssl_grp_none;
214   SSLSignatureScheme sig_scheme_;
215   SSLCipherSuiteInfo csinfo_;
216 };
217 
218 class TlsCipherSuiteTest
219     : public TlsCipherSuiteTestBase,
220       public ::testing::WithParamInterface<CipherSuiteProfile> {
221  public:
TlsCipherSuiteTest()222   TlsCipherSuiteTest()
223       : TlsCipherSuiteTestBase(std::get<0>(GetParam()), std::get<1>(GetParam()),
224                                std::get<2>(GetParam()), std::get<3>(GetParam()),
225                                std::get<4>(GetParam())) {}
226 
227  protected:
SkipIfCipherSuiteIsDSA()228   bool SkipIfCipherSuiteIsDSA() {
229     bool isDSA = csinfo_.authType == ssl_auth_dsa;
230     if (isDSA) {
231       std::cerr << "Skipping DSA suite: " << csinfo_.cipherSuiteName
232                 << std::endl;
233     }
234     return isDSA;
235   }
236 };
237 
TEST_P(TlsCipherSuiteTest,SingleCipherSuite)238 TEST_P(TlsCipherSuiteTest, SingleCipherSuite) {
239   SetupCertificate();
240   EnableSingleCipher();
241   ConnectAndCheckCipherSuite();
242 }
243 
TEST_P(TlsCipherSuiteTest,ResumeCipherSuite)244 TEST_P(TlsCipherSuiteTest, ResumeCipherSuite) {
245   if (SkipIfCipherSuiteIsDSA()) {
246     GTEST_SKIP() << "Tickets not supported with DSA (bug 1174677).";
247   }
248 
249   SetupCertificate();  // This is only needed once.
250 
251   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
252   EnableSingleCipher();
253 
254   ConnectAndCheckCipherSuite();
255 
256   Reset();
257   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
258   EnableSingleCipher();
259   ExpectResumption(RESUME_TICKET);
260   ConnectAndCheckCipherSuite();
261 }
262 
TEST_P(TlsCipherSuiteTest,ReadLimit)263 TEST_P(TlsCipherSuiteTest, ReadLimit) {
264   SetupCertificate();
265   EnableSingleCipher();
266   TlsSendCipherSpecCapturer capturer(client_);
267   ConnectAndCheckCipherSuite();
268   if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
269     uint64_t last = last_safe_write();
270     EXPECT_EQ(SECSuccess, SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), last));
271     EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last));
272 
273     client_->SendData(10, 10);
274     server_->ReadBytes();  // This should be OK.
275     server_->ReadBytes();  // Read twice to flush any 1,N-1 record splitting.
276   } else {
277     // In TLS 1.3, reading or writing triggers a KeyUpdate.  That would mean
278     // that the sequence numbers would reset and we wouldn't hit the limit.  So
279     // move the sequence number to the limit directly and don't test sending and
280     // receiving just before the limit.
281     uint64_t last = record_limit();
282     EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last));
283   }
284 
285   // The payload needs to be big enough to pass for encrypted.  The code checks
286   // the limit before it tries to decrypt.
287   static const uint8_t payload[32] = {6};
288   DataBuffer record;
289   uint64_t epoch;
290   if (variant_ == ssl_variant_datagram) {
291     if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
292       epoch = 3;  // Application traffic keys.
293     } else {
294       epoch = 1;
295     }
296   } else {
297     epoch = 0;
298   }
299 
300   uint64_t seqno = (epoch << 48) | record_limit();
301 
302   // DTLS 1.3 masks the sequence number
303   if (variant_ == ssl_variant_datagram &&
304       version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
305     auto spec = capturer.spec(1);
306     ASSERT_NE(nullptr, spec.get());
307     ASSERT_EQ(3, spec->epoch());
308 
309     DataBuffer pt, ct;
310     uint8_t dtls13_ctype = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno |
311                            kCtDtlsCiphertextLengthPresent;
312     TlsRecordHeader hdr(variant_, version_, dtls13_ctype, seqno);
313     pt.Assign(payload, sizeof(payload));
314     TlsRecordHeader out_hdr;
315     spec->Protect(hdr, pt, &ct, &out_hdr);
316 
317     auto rv = out_hdr.Write(&record, 0, ct);
318     EXPECT_EQ(out_hdr.header_length() + ct.len(), rv);
319   } else {
320     TlsAgentTestBase::MakeRecord(variant_, ssl_ct_application_data, version_,
321                                  payload, sizeof(payload), &record, seqno);
322   }
323 
324   client_->SendDirect(record);
325   server_->ExpectReadWriteError();
326   server_->ReadBytes();
327   EXPECT_EQ(SSL_ERROR_TOO_MANY_RECORDS, server_->error_code());
328 }
329 
TEST_P(TlsCipherSuiteTest,WriteLimit)330 TEST_P(TlsCipherSuiteTest, WriteLimit) {
331   // This asserts in TLS 1.3 because we expect an automatic update.
332   if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
333     GTEST_SKIP();
334   }
335   SetupCertificate();
336   EnableSingleCipher();
337   ConnectAndCheckCipherSuite();
338   EXPECT_EQ(SECSuccess,
339             SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), last_safe_write()));
340   client_->SendData(10, 10);
341   client_->ExpectReadWriteError();
342   client_->SendData(10, 10);
343   EXPECT_EQ(SSL_ERROR_TOO_MANY_RECORDS, client_->error_code());
344 }
345 
346 // This awful macro makes the test instantiations easier to read.
347 #define INSTANTIATE_CIPHER_TEST_P(name, modes, versions, groups, sigalgs, ...) \
348   static const uint16_t k##name##CiphersArr[] = {__VA_ARGS__};                 \
349   static const ::testing::internal::ParamGenerator<uint16_t>                   \
350       k##name##Ciphers = ::testing::ValuesIn(k##name##CiphersArr);             \
351   INSTANTIATE_TEST_SUITE_P(                                                    \
352       CipherSuite##name, TlsCipherSuiteTest,                                   \
353       ::testing::Combine(TlsConnectTestBase::kTlsVariants##modes,              \
354                          TlsConnectTestBase::kTls##versions, k##name##Ciphers, \
355                          groups, sigalgs));
356 
357 static const auto kDummyNamedGroupParams = ::testing::Values(ssl_grp_none);
358 static const auto kDummySignatureSchemesParams =
359     ::testing::Values(ssl_sig_none);
360 
361 static SSLSignatureScheme kSignatureSchemesParamsArr[] = {
362     ssl_sig_rsa_pkcs1_sha256,       ssl_sig_rsa_pkcs1_sha384,
363     ssl_sig_rsa_pkcs1_sha512,       ssl_sig_ecdsa_secp256r1_sha256,
364     ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_rsa_pss_rsae_sha256,
365     ssl_sig_rsa_pss_rsae_sha384,    ssl_sig_rsa_pss_rsae_sha512,
366     ssl_sig_rsa_pss_pss_sha256,     ssl_sig_rsa_pss_pss_sha384,
367     ssl_sig_rsa_pss_pss_sha512};
368 
369 static SSLSignatureScheme kSignatureSchemesParamsArrTls13[] = {
370     ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384,
371     ssl_sig_rsa_pss_rsae_sha256,    ssl_sig_rsa_pss_rsae_sha384,
372     ssl_sig_rsa_pss_rsae_sha512,    ssl_sig_rsa_pss_pss_sha256,
373     ssl_sig_rsa_pss_pss_sha384,     ssl_sig_rsa_pss_pss_sha512};
374 
375 INSTANTIATE_CIPHER_TEST_P(RC4, Stream, V10ToV12, kDummyNamedGroupParams,
376                           kDummySignatureSchemesParams,
377                           TLS_RSA_WITH_RC4_128_SHA,
378                           TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
379                           TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
380                           TLS_ECDH_RSA_WITH_RC4_128_SHA,
381                           TLS_ECDHE_RSA_WITH_RC4_128_SHA);
382 INSTANTIATE_CIPHER_TEST_P(AEAD12, All, V12, kDummyNamedGroupParams,
383                           kDummySignatureSchemesParams,
384                           TLS_RSA_WITH_AES_128_GCM_SHA256,
385                           TLS_RSA_WITH_AES_256_GCM_SHA384,
386                           TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
387                           TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,
388                           TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
389                           TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384);
390 INSTANTIATE_CIPHER_TEST_P(AEAD, All, V12, kDummyNamedGroupParams,
391                           kDummySignatureSchemesParams,
392                           TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
393                           TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
394                           TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
395                           TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
396                           TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
397                           TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
398                           TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
399                           TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
400                           TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256);
401 INSTANTIATE_CIPHER_TEST_P(
402     CBC12, All, V12, kDummyNamedGroupParams, kDummySignatureSchemesParams,
403     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256,
404     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
405     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
406     TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
407     TLS_DHE_DSS_WITH_AES_256_CBC_SHA256);
408 INSTANTIATE_CIPHER_TEST_P(
409     CBCStream, Stream, V10ToV12, kDummyNamedGroupParams,
410     kDummySignatureSchemesParams, TLS_ECDH_ECDSA_WITH_NULL_SHA,
411     TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
412     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_NULL_SHA,
413     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
414     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_NULL_SHA,
415     TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
416     TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_NULL_SHA,
417     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
418     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
419 INSTANTIATE_CIPHER_TEST_P(
420     CBCDatagram, Datagram, V11V12, kDummyNamedGroupParams,
421     kDummySignatureSchemesParams, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
422     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
423     TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
424     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
425     TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
426     TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
427     TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
428 INSTANTIATE_CIPHER_TEST_P(
429     TLS12SigSchemes, All, V12, ::testing::ValuesIn(kFasterDHEGroups),
430     ::testing::ValuesIn(kSignatureSchemesParamsArr),
431     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256,
432     TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
433     TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
434     TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
435     TLS_DHE_DSS_WITH_AES_256_CBC_SHA256);
436 #ifndef NSS_DISABLE_TLS_1_3
437 INSTANTIATE_CIPHER_TEST_P(TLS13, All, V13,
438                           ::testing::ValuesIn(kFasterDHEGroups),
439                           ::testing::ValuesIn(kSignatureSchemesParamsArrTls13),
440                           TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256,
441                           TLS_AES_256_GCM_SHA384);
442 INSTANTIATE_CIPHER_TEST_P(TLS13AllGroups, All, V13,
443                           ::testing::ValuesIn(kAllDHEGroups),
444                           ::testing::Values(ssl_sig_ecdsa_secp384r1_sha384),
445                           TLS_AES_256_GCM_SHA384);
446 #endif
447 
448 // Fields are: version, cipher suite, bulk cipher name, secretKeySize
449 struct SecStatusParams {
450   uint16_t version;
451   uint16_t cipher_suite;
452   std::string name;
453   int keySize;
454 };
455 
operator <<(std::ostream & stream,const SecStatusParams & vals)456 inline std::ostream &operator<<(std::ostream &stream,
457                                 const SecStatusParams &vals) {
458   SSLCipherSuiteInfo csinfo;
459   SECStatus rv =
460       SSL_GetCipherSuiteInfo(vals.cipher_suite, &csinfo, sizeof(csinfo));
461   if (rv != SECSuccess) {
462     return stream << "Error invoking SSL_GetCipherSuiteInfo()";
463   }
464 
465   return stream << "TLS " << VersionString(vals.version) << ", "
466                 << csinfo.cipherSuiteName << ", name = \"" << vals.name
467                 << "\", key size = " << vals.keySize;
468 }
469 
470 class SecurityStatusTest
471     : public TlsCipherSuiteTestBase,
472       public ::testing::WithParamInterface<SecStatusParams> {
473  public:
SecurityStatusTest()474   SecurityStatusTest()
475       : TlsCipherSuiteTestBase(ssl_variant_stream, GetParam().version,
476                                GetParam().cipher_suite, ssl_grp_none,
477                                ssl_sig_none) {}
478 };
479 
480 // SSL_SecurityStatus produces fairly useless output when compared to
481 // SSL_GetCipherSuiteInfo and SSL_GetChannelInfo, but we can't break it, so we
482 // need to check it.
TEST_P(SecurityStatusTest,CheckSecurityStatus)483 TEST_P(SecurityStatusTest, CheckSecurityStatus) {
484   SetupCertificate();
485   EnableSingleCipher();
486   ConnectAndCheckCipherSuite();
487 
488   int on;
489   char *cipher;
490   int keySize;
491   int secretKeySize;
492   char *issuer;
493   char *subject;
494   EXPECT_EQ(SECSuccess,
495             SSL_SecurityStatus(client_->ssl_fd(), &on, &cipher, &keySize,
496                                &secretKeySize, &issuer, &subject));
497   if (std::string(cipher) == "NULL") {
498     EXPECT_EQ(0, on);
499   } else {
500     EXPECT_NE(0, on);
501   }
502   EXPECT_EQ(GetParam().name, std::string(cipher));
503   // All the ciphers we support have secret key size == key size.
504   EXPECT_EQ(GetParam().keySize, keySize);
505   EXPECT_EQ(GetParam().keySize, secretKeySize);
506   EXPECT_LT(0U, strlen(issuer));
507   EXPECT_LT(0U, strlen(subject));
508 
509   PORT_Free(cipher);
510   PORT_Free(issuer);
511   PORT_Free(subject);
512 }
513 
514 static const SecStatusParams kSecStatusTestValuesArr[] = {
515     {SSL_LIBRARY_VERSION_TLS_1_0, TLS_ECDHE_RSA_WITH_NULL_SHA, "NULL", 0},
516     {SSL_LIBRARY_VERSION_TLS_1_0, TLS_RSA_WITH_RC4_128_SHA, "RC4", 128},
517     {SSL_LIBRARY_VERSION_TLS_1_0, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
518      "3DES-EDE-CBC", 168},
519     {SSL_LIBRARY_VERSION_TLS_1_0, TLS_RSA_WITH_AES_128_CBC_SHA, "AES-128", 128},
520     {SSL_LIBRARY_VERSION_TLS_1_2, TLS_RSA_WITH_AES_256_CBC_SHA256, "AES-256",
521      256},
522     {SSL_LIBRARY_VERSION_TLS_1_2, TLS_RSA_WITH_AES_128_GCM_SHA256,
523      "AES-128-GCM", 128},
524     {SSL_LIBRARY_VERSION_TLS_1_2, TLS_RSA_WITH_AES_256_GCM_SHA384,
525      "AES-256-GCM", 256},
526     {SSL_LIBRARY_VERSION_TLS_1_2, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
527      "ChaCha20-Poly1305", 256}};
528 INSTANTIATE_TEST_SUITE_P(TestSecurityStatus, SecurityStatusTest,
529                          ::testing::ValuesIn(kSecStatusTestValuesArr));
530 
531 }  // namespace nss_test
532