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