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