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 <ctime>
8 
9 #include "prtime.h"
10 #include "secerr.h"
11 #include "ssl.h"
12 
13 #include "gtest_utils.h"
14 #include "tls_agent.h"
15 #include "tls_connect.h"
16 
17 namespace nss_test {
18 
19 const std::string kEcdsaDelegatorId = TlsAgent::kDelegatorEcdsa256;
20 const std::string kRsaeDelegatorId = TlsAgent::kDelegatorRsae2048;
21 const std::string kPssDelegatorId = TlsAgent::kDelegatorRsaPss2048;
22 const std::string kDCId = TlsAgent::kServerEcdsa256;
23 const SSLSignatureScheme kDCScheme = ssl_sig_ecdsa_secp256r1_sha256;
24 const PRUint32 kDCValidFor = 60 * 60 * 24 * 7 /* 1 week (seconds) */;
25 
CheckPreliminaryPeerDelegCred(const std::shared_ptr<TlsAgent> & client,bool expected,PRUint32 key_bits=0,SSLSignatureScheme sig_scheme=ssl_sig_none)26 static void CheckPreliminaryPeerDelegCred(
27     const std::shared_ptr<TlsAgent>& client, bool expected,
28     PRUint32 key_bits = 0, SSLSignatureScheme sig_scheme = ssl_sig_none) {
29   EXPECT_NE(0U, (client->pre_info().valuesSet & ssl_preinfo_peer_auth));
30   EXPECT_EQ(expected, client->pre_info().peerDelegCred);
31   if (expected) {
32     EXPECT_EQ(key_bits, client->pre_info().authKeyBits);
33     EXPECT_EQ(sig_scheme, client->pre_info().signatureScheme);
34   }
35 }
36 
CheckPeerDelegCred(const std::shared_ptr<TlsAgent> & client,bool expected,PRUint32 key_bits=0)37 static void CheckPeerDelegCred(const std::shared_ptr<TlsAgent>& client,
38                                bool expected, PRUint32 key_bits = 0) {
39   EXPECT_EQ(expected, client->info().peerDelegCred);
40   EXPECT_EQ(expected, client->pre_info().peerDelegCred);
41   if (expected) {
42     EXPECT_EQ(key_bits, client->info().authKeyBits);
43     EXPECT_EQ(key_bits, client->pre_info().authKeyBits);
44     EXPECT_EQ(client->info().signatureScheme,
45               client->pre_info().signatureScheme);
46   }
47 }
48 
49 // AuthCertificate callbacks to simulate DC validation
CheckPreliminaryDC(TlsAgent * agent,bool checksig,bool isServer)50 static SECStatus CheckPreliminaryDC(TlsAgent* agent, bool checksig,
51                                     bool isServer) {
52   agent->UpdatePreliminaryChannelInfo();
53   EXPECT_EQ(PR_TRUE, agent->pre_info().peerDelegCred);
54   EXPECT_EQ(256U, agent->pre_info().authKeyBits);
55   EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, agent->pre_info().signatureScheme);
56   return SECSuccess;
57 }
58 
CheckPreliminaryNoDC(TlsAgent * agent,bool checksig,bool isServer)59 static SECStatus CheckPreliminaryNoDC(TlsAgent* agent, bool checksig,
60                                       bool isServer) {
61   agent->UpdatePreliminaryChannelInfo();
62   EXPECT_EQ(PR_FALSE, agent->pre_info().peerDelegCred);
63   return SECSuccess;
64 }
65 
66 // AuthCertificate callbacks for modifying DC attributes.
67 // This allows testing tls13_CertificateVerify for rejection
68 // of DC attributes that have changed since AuthCertificateHook
69 // may have handled them.
ModifyDCAuthKeyBits(TlsAgent * agent,bool checksig,bool isServer)70 static SECStatus ModifyDCAuthKeyBits(TlsAgent* agent, bool checksig,
71                                      bool isServer) {
72   return SSLInt_TweakChannelInfoForDC(agent->ssl_fd(),
73                                       PR_TRUE,    // Change authKeyBits
74                                       PR_FALSE);  // Change scheme
75 }
76 
ModifyDCScheme(TlsAgent * agent,bool checksig,bool isServer)77 static SECStatus ModifyDCScheme(TlsAgent* agent, bool checksig, bool isServer) {
78   return SSLInt_TweakChannelInfoForDC(agent->ssl_fd(),
79                                       PR_FALSE,  // Change authKeyBits
80                                       PR_TRUE);  // Change scheme
81 }
82 
83 // Attempt to configure a DC when either the DC or DC private key is missing.
TEST_P(TlsConnectTls13,DCNotConfigured)84 TEST_P(TlsConnectTls13, DCNotConfigured) {
85   // Load and delegate the credential.
86   ScopedSECKEYPublicKey pub;
87   ScopedSECKEYPrivateKey priv;
88   EXPECT_TRUE(TlsAgent::LoadKeyPairFromCert(kDCId, &pub, &priv));
89 
90   StackSECItem dc;
91   TlsAgent::DelegateCredential(kEcdsaDelegatorId, pub, kDCScheme, kDCValidFor,
92                                now(), &dc);
93 
94   // Attempt to install the certificate and DC with a missing DC private key.
95   EnsureTlsSetup();
96   SSLExtraServerCertData extra_data_missing_dc_priv_key = {
97       ssl_auth_null, nullptr, nullptr, nullptr, &dc, nullptr};
98   EXPECT_FALSE(server_->ConfigServerCert(kEcdsaDelegatorId, true,
99                                          &extra_data_missing_dc_priv_key));
100 
101   // Attempt to install the certificate and with only the DC private key.
102   EnsureTlsSetup();
103   SSLExtraServerCertData extra_data_missing_dc = {
104       ssl_auth_null, nullptr, nullptr, nullptr, nullptr, priv.get()};
105   EXPECT_FALSE(server_->ConfigServerCert(kEcdsaDelegatorId, true,
106                                          &extra_data_missing_dc));
107 }
108 
109 // Connected with ECDSA-P256.
TEST_P(TlsConnectTls13,DCConnectEcdsaP256)110 TEST_P(TlsConnectTls13, DCConnectEcdsaP256) {
111   Reset(kEcdsaDelegatorId);
112   client_->EnableDelegatedCredentials();
113   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
114                                   ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
115                                   now());
116 
117   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
118       client_, ssl_delegated_credentials_xtn);
119   Connect();
120 
121   EXPECT_TRUE(cfilter->captured());
122   CheckPeerDelegCred(client_, true, 256);
123   EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
124 }
125 
126 // Connected with ECDSA-P384.
TEST_P(TlsConnectTls13,DCConnectEcdsaP483)127 TEST_P(TlsConnectTls13, DCConnectEcdsaP483) {
128   Reset(kEcdsaDelegatorId);
129   client_->EnableDelegatedCredentials();
130   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa384,
131                                   ssl_sig_ecdsa_secp384r1_sha384, kDCValidFor,
132                                   now());
133 
134   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
135       client_, ssl_delegated_credentials_xtn);
136   Connect();
137 
138   EXPECT_TRUE(cfilter->captured());
139   CheckPeerDelegCred(client_, true, 384);
140   EXPECT_EQ(ssl_sig_ecdsa_secp384r1_sha384, client_->info().signatureScheme);
141 }
142 
143 // Connected with ECDSA-P521.
TEST_P(TlsConnectTls13,DCConnectEcdsaP521)144 TEST_P(TlsConnectTls13, DCConnectEcdsaP521) {
145   Reset(kEcdsaDelegatorId);
146   client_->EnableDelegatedCredentials();
147   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa521,
148                                   ssl_sig_ecdsa_secp521r1_sha512, kDCValidFor,
149                                   now());
150   client_->EnableDelegatedCredentials();
151 
152   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
153       client_, ssl_delegated_credentials_xtn);
154   Connect();
155 
156   EXPECT_TRUE(cfilter->captured());
157   CheckPeerDelegCred(client_, true, 521);
158   EXPECT_EQ(ssl_sig_ecdsa_secp521r1_sha512, client_->info().signatureScheme);
159 }
160 
161 // Connected with RSA-PSS, using a PSS SPKI and ECDSA delegation cert.
TEST_P(TlsConnectTls13,DCConnectRsaPssEcdsa)162 TEST_P(TlsConnectTls13, DCConnectRsaPssEcdsa) {
163   Reset(kEcdsaDelegatorId);
164 
165   // Need to enable PSS-PSS, which is not on by default.
166   static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
167                                                 ssl_sig_rsa_pss_pss_sha256};
168   client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
169   server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
170 
171   client_->EnableDelegatedCredentials();
172   server_->AddDelegatedCredential(
173       TlsAgent::kServerRsaPss, ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now());
174 
175   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
176       client_, ssl_delegated_credentials_xtn);
177   Connect();
178 
179   EXPECT_TRUE(cfilter->captured());
180   CheckPeerDelegCred(client_, true, 1024);
181   EXPECT_EQ(ssl_sig_rsa_pss_pss_sha256, client_->info().signatureScheme);
182 }
183 
184 // Connected with RSA-PSS, using a PSS SPKI and PSS delegation cert.
TEST_P(TlsConnectTls13,DCConnectRsaPssRsaPss)185 TEST_P(TlsConnectTls13, DCConnectRsaPssRsaPss) {
186   Reset(kPssDelegatorId);
187 
188   // Need to enable PSS-PSS, which is not on by default.
189   static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
190                                                 ssl_sig_rsa_pss_pss_sha256};
191   client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
192   server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
193 
194   client_->EnableDelegatedCredentials();
195   server_->AddDelegatedCredential(
196       TlsAgent::kServerRsaPss, ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now());
197 
198   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
199       client_, ssl_delegated_credentials_xtn);
200   Connect();
201 
202   EXPECT_TRUE(cfilter->captured());
203   CheckPeerDelegCred(client_, true, 1024);
204   EXPECT_EQ(ssl_sig_rsa_pss_pss_sha256, client_->info().signatureScheme);
205 }
206 
207 // Connected with ECDSA-P256 using a PSS delegation cert.
TEST_P(TlsConnectTls13,DCConnectEcdsaP256RsaPss)208 TEST_P(TlsConnectTls13, DCConnectEcdsaP256RsaPss) {
209   Reset(kPssDelegatorId);
210 
211   // Need to enable PSS-PSS, which is not on by default.
212   static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
213                                                 ssl_sig_rsa_pss_pss_sha256};
214   client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
215   server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
216 
217   client_->EnableDelegatedCredentials();
218   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
219                                   ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
220                                   now());
221 
222   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
223       client_, ssl_delegated_credentials_xtn);
224   Connect();
225 
226   EXPECT_TRUE(cfilter->captured());
227   CheckPeerDelegCred(client_, true, 256);
228   EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
229 }
230 
231 // Simulate the client receiving a DC containing algorithms not advertised.
232 // Do this by tweaking the client's supported sigSchemes after the CH.
TEST_P(TlsConnectTls13,DCReceiveUnadvertisedScheme)233 TEST_P(TlsConnectTls13, DCReceiveUnadvertisedScheme) {
234   Reset(kEcdsaDelegatorId);
235   static const SSLSignatureScheme kClientSchemes[] = {
236       ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384};
237   static const SSLSignatureScheme kServerSchemes[] = {
238       ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_ecdsa_secp256r1_sha256};
239   static const SSLSignatureScheme kEcdsaP256Only[] = {
240       ssl_sig_ecdsa_secp256r1_sha256};
241   client_->SetSignatureSchemes(kClientSchemes, PR_ARRAY_SIZE(kClientSchemes));
242   server_->SetSignatureSchemes(kServerSchemes, PR_ARRAY_SIZE(kServerSchemes));
243   client_->EnableDelegatedCredentials();
244   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa384,
245                                   ssl_sig_ecdsa_secp384r1_sha384, kDCValidFor,
246                                   now());
247   StartConnect();
248   client_->Handshake();  // CH with P256/P384.
249   server_->Handshake();  // Respond with P384 DC.
250                          // Tell the client it only advertised P256.
251   SECStatus rv = SSLInt_SetDCAdvertisedSigSchemes(
252       client_->ssl_fd(), kEcdsaP256Only, PR_ARRAY_SIZE(kEcdsaP256Only));
253   EXPECT_EQ(SECSuccess, rv);
254   ExpectAlert(client_, kTlsAlertIllegalParameter);
255   Handshake();
256   client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
257   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
258 }
259 
260 // Server schemes includes only RSAE schemes. Connection should succeed
261 // without delegation.
TEST_P(TlsConnectTls13,DCConnectServerRsaeOnly)262 TEST_P(TlsConnectTls13, DCConnectServerRsaeOnly) {
263   Reset(kRsaeDelegatorId);
264   static const SSLSignatureScheme kClientSchemes[] = {
265       ssl_sig_rsa_pss_rsae_sha256, ssl_sig_rsa_pss_pss_sha256};
266   static const SSLSignatureScheme kServerSchemes[] = {
267       ssl_sig_rsa_pss_rsae_sha256};
268   client_->SetSignatureSchemes(kClientSchemes, PR_ARRAY_SIZE(kClientSchemes));
269   server_->SetSignatureSchemes(kServerSchemes, PR_ARRAY_SIZE(kServerSchemes));
270   client_->EnableDelegatedCredentials();
271   Connect();
272 
273   CheckPeerDelegCred(client_, false);
274 }
275 
276 // Connect with an RSA-PSS DC SPKI, and an RSAE Delegator SPKI.
TEST_P(TlsConnectTls13,DCConnectRsaeDelegator)277 TEST_P(TlsConnectTls13, DCConnectRsaeDelegator) {
278   Reset(kRsaeDelegatorId);
279 
280   static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pss_rsae_sha256,
281                                                 ssl_sig_rsa_pss_pss_sha256};
282   client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
283   server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
284 
285   client_->EnableDelegatedCredentials();
286   server_->AddDelegatedCredential(
287       TlsAgent::kServerRsaPss, ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now());
288   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
289   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
290   client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
291 }
292 
293 // Client schemes includes only RSAE schemes. Connection should succeed
294 // without delegation, and no DC extension should be present in the CH.
TEST_P(TlsConnectTls13,DCConnectClientRsaeOnly)295 TEST_P(TlsConnectTls13, DCConnectClientRsaeOnly) {
296   Reset(kRsaeDelegatorId);
297   static const SSLSignatureScheme kClientSchemes[] = {
298       ssl_sig_rsa_pss_rsae_sha256};
299   static const SSLSignatureScheme kServerSchemes[] = {
300       ssl_sig_rsa_pss_rsae_sha256, ssl_sig_rsa_pss_pss_sha256};
301   client_->SetSignatureSchemes(kClientSchemes, PR_ARRAY_SIZE(kClientSchemes));
302   server_->SetSignatureSchemes(kServerSchemes, PR_ARRAY_SIZE(kServerSchemes));
303   client_->EnableDelegatedCredentials();
304   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
305       client_, ssl_delegated_credentials_xtn);
306   Connect();
307   EXPECT_FALSE(cfilter->captured());
308   CheckPeerDelegCred(client_, false);
309 }
310 
311 // Test fallback. DC extension will not advertise RSAE schemes.
312 // The server will attempt to set one, but decline to after seeing
313 // the client-advertised schemes does not include it. Expect non-
314 // delegated success.
TEST_P(TlsConnectTls13,DCConnectRsaeDcSpki)315 TEST_P(TlsConnectTls13, DCConnectRsaeDcSpki) {
316   Reset(kRsaeDelegatorId);
317 
318   static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pss_rsae_sha256,
319                                                 ssl_sig_rsa_pss_pss_sha256};
320   client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
321   server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
322   client_->EnableDelegatedCredentials();
323 
324   EnsureTlsSetup();
325   ScopedSECKEYPublicKey pub;
326   ScopedSECKEYPrivateKey priv;
327   EXPECT_TRUE(
328       TlsAgent::LoadKeyPairFromCert(TlsAgent::kDelegatorRsae2048, &pub, &priv));
329 
330   StackSECItem dc;
331   server_->DelegateCredential(server_->name(), pub, ssl_sig_rsa_pss_rsae_sha256,
332                               kDCValidFor, now(), &dc);
333 
334   SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr,
335                                        nullptr,       &dc,     priv.get()};
336   EXPECT_TRUE(server_->ConfigServerCert(server_->name(), true, &extra_data));
337   auto sfilter = MakeTlsFilter<TlsExtensionCapture>(
338       server_, ssl_delegated_credentials_xtn);
339   Connect();
340   EXPECT_FALSE(sfilter->captured());
341   CheckPeerDelegCred(client_, false);
342 }
343 
344 // Generate a weak key.  We can't do this in the fixture because certutil
345 // won't sign with such a tiny key.  That's OK, because this is fast(ish).
GenerateWeakRsaKey(ScopedSECKEYPrivateKey & priv,ScopedSECKEYPublicKey & pub)346 static void GenerateWeakRsaKey(ScopedSECKEYPrivateKey& priv,
347                                ScopedSECKEYPublicKey& pub) {
348   ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
349   ASSERT_TRUE(slot);
350   PK11RSAGenParams rsaparams;
351   // The absolute minimum size of RSA key that we can use with SHA-256 is
352   // 256bit (hash) + 256bit (salt) + 8 (start byte) + 8 (end byte) = 528.
353   rsaparams.keySizeInBits = 528;
354   rsaparams.pe = 65537;
355 
356   // Bug 1012786: PK11_GenerateKeyPair can fail if there is insufficient
357   // entropy to generate a random key. We can fake some.
358   for (int retry = 0; retry < 10; ++retry) {
359     SECKEYPublicKey* p_pub = nullptr;
360     priv.reset(PK11_GenerateKeyPair(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN,
361                                     &rsaparams, &p_pub, false, false, nullptr));
362     pub.reset(p_pub);
363     if (priv) {
364       return;
365     }
366 
367     ASSERT_FALSE(pub);
368     if (PORT_GetError() != SEC_ERROR_PKCS11_FUNCTION_FAILED) {
369       break;
370     }
371 
372     // https://xkcd.com/221/
373     static const uint8_t FRESH_ENTROPY[16] = {4};
374     ASSERT_EQ(
375         SECSuccess,
376         PK11_RandomUpdate(
377             const_cast<void*>(reinterpret_cast<const void*>(FRESH_ENTROPY)),
378             sizeof(FRESH_ENTROPY)));
379     break;
380   }
381   ADD_FAILURE() << "Unable to generate an RSA key: "
382                 << PORT_ErrorToName(PORT_GetError());
383 }
384 
385 // Fail to connect with a weak RSA key.
TEST_P(TlsConnectTls13,DCWeakKey)386 TEST_P(TlsConnectTls13, DCWeakKey) {
387   Reset(kPssDelegatorId);
388   EnsureTlsSetup();
389   static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pss_rsae_sha256,
390                                                 ssl_sig_rsa_pss_pss_sha256};
391   client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
392   server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
393 
394   ScopedSECKEYPrivateKey dc_priv;
395   ScopedSECKEYPublicKey dc_pub;
396   GenerateWeakRsaKey(dc_priv, dc_pub);
397   ASSERT_TRUE(dc_priv);
398 
399   // Construct a DC.
400   StackSECItem dc;
401   TlsAgent::DelegateCredential(kPssDelegatorId, dc_pub,
402                                ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now(),
403                                &dc);
404 
405   // Configure the DC on the server.
406   SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr,
407                                        nullptr,       &dc,     dc_priv.get()};
408   EXPECT_TRUE(server_->ConfigServerCert(kPssDelegatorId, true, &extra_data));
409 
410   client_->EnableDelegatedCredentials();
411 
412   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
413       client_, ssl_delegated_credentials_xtn);
414   ConnectExpectAlert(client_, kTlsAlertInsufficientSecurity);
415 }
416 
417 class ReplaceDCSigScheme : public TlsHandshakeFilter {
418  public:
ReplaceDCSigScheme(const std::shared_ptr<TlsAgent> & a)419   ReplaceDCSigScheme(const std::shared_ptr<TlsAgent>& a)
420       : TlsHandshakeFilter(a, {ssl_hs_certificate_verify}) {}
421 
422  protected:
FilterHandshake(const HandshakeHeader & header,const DataBuffer & input,DataBuffer * output)423   PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
424                                        const DataBuffer& input,
425                                        DataBuffer* output) override {
426     *output = input;
427     output->Write(0, ssl_sig_ecdsa_secp384r1_sha384, 2);
428     return CHANGE;
429   }
430 };
431 
432 // Aborted because of incorrect DC signature algorithm indication.
TEST_P(TlsConnectTls13,DCAbortBadExpectedCertVerifyAlg)433 TEST_P(TlsConnectTls13, DCAbortBadExpectedCertVerifyAlg) {
434   Reset(kEcdsaDelegatorId);
435   client_->EnableDelegatedCredentials();
436   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
437                                   ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
438                                   now());
439   auto filter = MakeTlsFilter<ReplaceDCSigScheme>(server_);
440   filter->EnableDecryption();
441   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
442   client_->CheckErrorCode(SSL_ERROR_DC_CERT_VERIFY_ALG_MISMATCH);
443   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
444 }
445 
446 // Aborted because of invalid DC signature.
TEST_P(TlsConnectTls13,DCAbortBadSignature)447 TEST_P(TlsConnectTls13, DCAbortBadSignature) {
448   Reset(kEcdsaDelegatorId);
449   EnsureTlsSetup();
450   client_->EnableDelegatedCredentials();
451 
452   ScopedSECKEYPublicKey pub;
453   ScopedSECKEYPrivateKey priv;
454   EXPECT_TRUE(TlsAgent::LoadKeyPairFromCert(kDCId, &pub, &priv));
455 
456   StackSECItem dc;
457   TlsAgent::DelegateCredential(kEcdsaDelegatorId, pub, kDCScheme, kDCValidFor,
458                                now(), &dc);
459   ASSERT_TRUE(dc.data != nullptr);
460 
461   // Flip the last bit of the DC so that the signature is invalid.
462   dc.data[dc.len - 1] ^= 0x01;
463 
464   SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr,
465                                        nullptr,       &dc,     priv.get()};
466   EXPECT_TRUE(server_->ConfigServerCert(kEcdsaDelegatorId, true, &extra_data));
467 
468   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
469   client_->CheckErrorCode(SSL_ERROR_DC_BAD_SIGNATURE);
470   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
471 }
472 
473 // Aborted because of expired DC.
TEST_P(TlsConnectTls13,DCAbortExpired)474 TEST_P(TlsConnectTls13, DCAbortExpired) {
475   Reset(kEcdsaDelegatorId);
476   server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());
477   client_->EnableDelegatedCredentials();
478   // When the client checks the time, it will be at least one second after the
479   // DC expired.
480   AdvanceTime((static_cast<PRTime>(kDCValidFor) + 1) * PR_USEC_PER_SEC);
481   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
482   client_->CheckErrorCode(SSL_ERROR_DC_EXPIRED);
483   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
484 }
485 
486 // Aborted due to remaining TTL > max validity period.
TEST_P(TlsConnectTls13,DCAbortExcessiveTTL)487 TEST_P(TlsConnectTls13, DCAbortExcessiveTTL) {
488   Reset(kEcdsaDelegatorId);
489   server_->AddDelegatedCredential(kDCId, kDCScheme,
490                                   kDCValidFor + 1 /* seconds */, now());
491   client_->EnableDelegatedCredentials();
492   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
493   client_->CheckErrorCode(SSL_ERROR_DC_INAPPROPRIATE_VALIDITY_PERIOD);
494   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
495 }
496 
497 // Aborted because of invalid key usage.
TEST_P(TlsConnectTls13,DCAbortBadKeyUsage)498 TEST_P(TlsConnectTls13, DCAbortBadKeyUsage) {
499   // The sever does not have the delegationUsage extension.
500   Reset(TlsAgent::kServerEcdsa256);
501   client_->EnableDelegatedCredentials();
502   server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());
503   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
504 }
505 
506 // Connected without DC because of no client indication.
TEST_P(TlsConnectTls13,DCConnectNoClientSupport)507 TEST_P(TlsConnectTls13, DCConnectNoClientSupport) {
508   Reset(kEcdsaDelegatorId);
509   server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());
510 
511   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
512       client_, ssl_delegated_credentials_xtn);
513   Connect();
514 
515   EXPECT_FALSE(cfilter->captured());
516   CheckPeerDelegCred(client_, false);
517 }
518 
519 // Connected without DC because of no server DC.
TEST_P(TlsConnectTls13,DCConnectNoServerSupport)520 TEST_P(TlsConnectTls13, DCConnectNoServerSupport) {
521   Reset(kEcdsaDelegatorId);
522   client_->EnableDelegatedCredentials();
523 
524   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
525       client_, ssl_delegated_credentials_xtn);
526   Connect();
527 
528   EXPECT_TRUE(cfilter->captured());
529   CheckPeerDelegCred(client_, false);
530 }
531 
532 // Connected without DC because client doesn't support TLS 1.3.
TEST_P(TlsConnectTls13,DCConnectClientNoTls13)533 TEST_P(TlsConnectTls13, DCConnectClientNoTls13) {
534   Reset(kEcdsaDelegatorId);
535   client_->EnableDelegatedCredentials();
536   server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());
537 
538   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
539                            SSL_LIBRARY_VERSION_TLS_1_2);
540   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
541                            SSL_LIBRARY_VERSION_TLS_1_3);
542 
543   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
544       client_, ssl_delegated_credentials_xtn);
545   Connect();
546 
547   // Should fallback to TLS 1.2 and not negotiate a DC.
548   EXPECT_FALSE(cfilter->captured());
549   CheckPeerDelegCred(client_, false);
550 }
551 
552 // Connected without DC because server doesn't support TLS 1.3.
TEST_P(TlsConnectTls13,DCConnectServerNoTls13)553 TEST_P(TlsConnectTls13, DCConnectServerNoTls13) {
554   Reset(kEcdsaDelegatorId);
555   client_->EnableDelegatedCredentials();
556   server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());
557 
558   client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
559                            SSL_LIBRARY_VERSION_TLS_1_3);
560   server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
561                            SSL_LIBRARY_VERSION_TLS_1_2);
562 
563   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
564       client_, ssl_delegated_credentials_xtn);
565   Connect();
566 
567   // Should fallback to TLS 1.2 and not negotiate a DC. The client will still
568   // send the indication because it supports 1.3.
569   EXPECT_TRUE(cfilter->captured());
570   CheckPeerDelegCred(client_, false);
571 }
572 
573 // Connected without DC because client doesn't support the signature scheme.
TEST_P(TlsConnectTls13,DCConnectExpectedCertVerifyAlgNotSupported)574 TEST_P(TlsConnectTls13, DCConnectExpectedCertVerifyAlgNotSupported) {
575   Reset(kEcdsaDelegatorId);
576   client_->EnableDelegatedCredentials();
577   static const SSLSignatureScheme kClientSchemes[] = {
578       ssl_sig_ecdsa_secp256r1_sha256,
579   };
580   client_->SetSignatureSchemes(kClientSchemes, PR_ARRAY_SIZE(kClientSchemes));
581 
582   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa521,
583                                   ssl_sig_ecdsa_secp521r1_sha512, kDCValidFor,
584                                   now());
585 
586   auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
587       client_, ssl_delegated_credentials_xtn);
588   Connect();
589 
590   // Client sends indication, but the server doesn't send a DC.
591   EXPECT_TRUE(cfilter->captured());
592   CheckPeerDelegCred(client_, false);
593 }
594 
595 // Check that preliminary channel info properly reflects the DC.
TEST_P(TlsConnectTls13,DCCheckPreliminaryInfo)596 TEST_P(TlsConnectTls13, DCCheckPreliminaryInfo) {
597   Reset(kEcdsaDelegatorId);
598   EnsureTlsSetup();
599   client_->EnableDelegatedCredentials();
600   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
601                                   ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
602                                   now());
603 
604   auto filter = MakeTlsFilter<TlsHandshakeDropper>(server_);
605   filter->SetHandshakeTypes(
606       {kTlsHandshakeCertificateVerify, kTlsHandshakeFinished});
607   filter->EnableDecryption();
608   StartConnect();
609   client_->Handshake();  // Send ClientHello
610   server_->Handshake();  // Send ServerHello
611 
612   client_->SetAuthCertificateCallback(CheckPreliminaryDC);
613   client_->Handshake();  // Process response
614 
615   client_->UpdatePreliminaryChannelInfo();
616   CheckPreliminaryPeerDelegCred(client_, true, 256,
617                                 ssl_sig_ecdsa_secp256r1_sha256);
618 }
619 
620 // Check that preliminary channel info properly reflects a lack of DC.
TEST_P(TlsConnectTls13,DCCheckPreliminaryInfoNoDC)621 TEST_P(TlsConnectTls13, DCCheckPreliminaryInfoNoDC) {
622   Reset(kEcdsaDelegatorId);
623   EnsureTlsSetup();
624   client_->EnableDelegatedCredentials();
625   auto filter = MakeTlsFilter<TlsHandshakeDropper>(server_);
626   filter->SetHandshakeTypes(
627       {kTlsHandshakeCertificateVerify, kTlsHandshakeFinished});
628   filter->EnableDecryption();
629   StartConnect();
630   client_->Handshake();  // Send ClientHello
631   server_->Handshake();  // Send ServerHello
632 
633   client_->SetAuthCertificateCallback(CheckPreliminaryNoDC);
634   client_->Handshake();  // Process response
635 
636   client_->UpdatePreliminaryChannelInfo();
637   CheckPreliminaryPeerDelegCred(client_, false);
638 }
639 
640 // Tweak the scheme in between |Cert| and |CertVerify|.
TEST_P(TlsConnectTls13,DCRejectModifiedDCScheme)641 TEST_P(TlsConnectTls13, DCRejectModifiedDCScheme) {
642   Reset(kEcdsaDelegatorId);
643   client_->EnableDelegatedCredentials();
644   client_->SetAuthCertificateCallback(ModifyDCScheme);
645   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa521,
646                                   ssl_sig_ecdsa_secp521r1_sha512, kDCValidFor,
647                                   now());
648   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
649   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
650   client_->CheckErrorCode(SSL_ERROR_DC_CERT_VERIFY_ALG_MISMATCH);
651 }
652 
653 // Tweak the authKeyBits in between |Cert| and |CertVerify|.
TEST_P(TlsConnectTls13,DCRejectModifiedDCAuthKeyBits)654 TEST_P(TlsConnectTls13, DCRejectModifiedDCAuthKeyBits) {
655   Reset(kEcdsaDelegatorId);
656   client_->EnableDelegatedCredentials();
657   client_->SetAuthCertificateCallback(ModifyDCAuthKeyBits);
658   server_->AddDelegatedCredential(TlsAgent::kServerEcdsa521,
659                                   ssl_sig_ecdsa_secp521r1_sha512, kDCValidFor,
660                                   now());
661   ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
662   server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
663   client_->CheckErrorCode(SSL_ERROR_DC_CERT_VERIFY_ALG_MISMATCH);
664 }
665 
666 class DCDelegation : public ::testing::Test {};
667 
TEST_F(DCDelegation,DCDelegations)668 TEST_F(DCDelegation, DCDelegations) {
669   PRTime now = PR_Now();
670   ScopedCERTCertificate cert;
671   ScopedSECKEYPrivateKey priv;
672   ASSERT_TRUE(TlsAgent::LoadCertificate(kEcdsaDelegatorId, &cert, &priv));
673 
674   ScopedSECKEYPublicKey pub_rsa;
675   ScopedSECKEYPrivateKey priv_rsa;
676   ASSERT_TRUE(
677       TlsAgent::LoadKeyPairFromCert(TlsAgent::kServerRsa, &pub_rsa, &priv_rsa));
678 
679   StackSECItem dc;
680   EXPECT_EQ(SECFailure,
681             SSL_DelegateCredential(cert.get(), priv.get(), pub_rsa.get(),
682                                    ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
683                                    now, &dc));
684   EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
685 
686   // Using different PSS hashes should be OK.
687   EXPECT_EQ(SECSuccess, SSL_DelegateCredential(
688                             cert.get(), priv.get(), pub_rsa.get(),
689                             ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now, &dc));
690   // Make sure to reset |dc| after each success.
691   dc.Reset();
692   EXPECT_EQ(SECSuccess, SSL_DelegateCredential(
693                             cert.get(), priv.get(), pub_rsa.get(),
694                             ssl_sig_rsa_pss_pss_sha384, kDCValidFor, now, &dc));
695   dc.Reset();
696   EXPECT_EQ(SECSuccess, SSL_DelegateCredential(
697                             cert.get(), priv.get(), pub_rsa.get(),
698                             ssl_sig_rsa_pss_pss_sha512, kDCValidFor, now, &dc));
699   dc.Reset();
700 
701   ScopedSECKEYPublicKey pub_ecdsa;
702   ScopedSECKEYPrivateKey priv_ecdsa;
703   ASSERT_TRUE(TlsAgent::LoadKeyPairFromCert(TlsAgent::kServerEcdsa256,
704                                             &pub_ecdsa, &priv_ecdsa));
705 
706   EXPECT_EQ(SECFailure,
707             SSL_DelegateCredential(cert.get(), priv.get(), pub_ecdsa.get(),
708                                    ssl_sig_rsa_pss_rsae_sha256, kDCValidFor,
709                                    now, &dc));
710   EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
711   EXPECT_EQ(SECFailure, SSL_DelegateCredential(
712                             cert.get(), priv.get(), pub_ecdsa.get(),
713                             ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now, &dc));
714   EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
715   EXPECT_EQ(SECFailure,
716             SSL_DelegateCredential(cert.get(), priv.get(), pub_ecdsa.get(),
717                                    ssl_sig_ecdsa_secp384r1_sha384, kDCValidFor,
718                                    now, &dc));
719   EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
720 }
721 
722 }  // namespace nss_test
723