Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  tls_subcerts_unittest.cc   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


#include <ctime>

#include "prtime.h"
#include "secerr.h"
#include "ssl.h"
#include "nss.h"
#include "blapit.h"

#include "gtest_utils.h"
#include "tls_agent.h"
#include "tls_connect.h"

namespace nss_test {

const std::string kEcdsaDelegatorId = TlsAgent::kDelegatorEcdsa256;
const std::string kRsaeDelegatorId = TlsAgent::kDelegatorRsae2048;
const std::string kPssDelegatorId = TlsAgent::kDelegatorRsaPss2048;
const std::string kDCId = TlsAgent::kServerEcdsa256;
const SSLSignatureScheme kDCScheme = ssl_sig_ecdsa_secp256r1_sha256;
const PRUint32 kDCValidFor = 60 * 60 * 24 * 7 /* 1 week (seconds) */;

static void CheckPreliminaryPeerDelegCred(
    const std::shared_ptr<TlsAgent>& client, bool expected,
    PRUint32 key_bits = 0, SSLSignatureScheme sig_scheme = ssl_sig_none) {
  EXPECT_NE(0U, (client->pre_info().valuesSet & ssl_preinfo_peer_auth));
  EXPECT_EQ(expected, client->pre_info().peerDelegCred);
  if (expected) {
    EXPECT_EQ(key_bits, client->pre_info().authKeyBits);
    EXPECT_EQ(sig_scheme, client->pre_info().signatureScheme);
  }
}

static void CheckPeerDelegCred(const std::shared_ptr<TlsAgent>& client,
                               bool expected, PRUint32 key_bits = 0) {
  EXPECT_EQ(expected, client->info().peerDelegCred);
  EXPECT_EQ(expected, client->pre_info().peerDelegCred);
  if (expected) {
    EXPECT_EQ(key_bits, client->info().authKeyBits);
    EXPECT_EQ(key_bits, client->pre_info().authKeyBits);
    EXPECT_EQ(client->info().signatureScheme,
              client->pre_info().signatureScheme);
  }
}

// AuthCertificate callbacks to simulate DC validation
static SECStatus CheckPreliminaryDC(TlsAgent* agent, bool checksig,
                                    bool isServer) {
  agent->UpdatePreliminaryChannelInfo();
  EXPECT_EQ(PR_TRUE, agent->pre_info().peerDelegCred);
  EXPECT_EQ(256U, agent->pre_info().authKeyBits);
  EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, agent->pre_info().signatureScheme);
  return SECSuccess;
}

static SECStatus CheckPreliminaryNoDC(TlsAgent* agent, bool checksig,
                                      bool isServer) {
  agent->UpdatePreliminaryChannelInfo();
  EXPECT_EQ(PR_FALSE, agent->pre_info().peerDelegCred);
  return SECSuccess;
}

// AuthCertificate callbacks for modifying DC attributes.
// This allows testing tls13_CertificateVerify for rejection
// of DC attributes that have changed since AuthCertificateHook
// may have handled them.
static SECStatus ModifyDCAuthKeyBits(TlsAgent* agent, bool checksig,
                                     bool isServer) {
  return SSLInt_TweakChannelInfoForDC(agent->ssl_fd(),
                                      PR_TRUE,    // Change authKeyBits
                                      PR_FALSE);  // Change scheme
}

static SECStatus ModifyDCScheme(TlsAgent* agent, bool checksig, bool isServer) {
  return SSLInt_TweakChannelInfoForDC(agent->ssl_fd(),
                                      PR_FALSE,  // Change authKeyBits
                                      PR_TRUE);  // Change scheme
}

// Attempt to configure a DC when either the DC or DC private key is missing.
TEST_P(TlsConnectTls13, DCNotConfigured) {
  // Load and delegate the credential.
  ScopedSECKEYPublicKey pub;
  ScopedSECKEYPrivateKey priv;
  EXPECT_TRUE(TlsAgent::LoadKeyPairFromCert(kDCId, &pub, &priv));

  StackSECItem dc;
  TlsAgent::DelegateCredential(kEcdsaDelegatorId, pub, kDCScheme, kDCValidFor,
                               now(), &dc);

  // Attempt to install the certificate and DC with a missing DC private key.
  EnsureTlsSetup();
  SSLExtraServerCertData extra_data_missing_dc_priv_key = {
      ssl_auth_null, nullptr, nullptr, nullptr, &dc, nullptr};
  EXPECT_FALSE(server_->ConfigServerCert(kEcdsaDelegatorId, true,
                                         &extra_data_missing_dc_priv_key));

  // Attempt to install the certificate and with only the DC private key.
  EnsureTlsSetup();
  SSLExtraServerCertData extra_data_missing_dc = {
      ssl_auth_null, nullptr, nullptr, nullptr, nullptr, priv.get()};
  EXPECT_FALSE(server_->ConfigServerCert(kEcdsaDelegatorId, true,
                                         &extra_data_missing_dc));
}

// Connected with ECDSA-P256.
TEST_P(TlsConnectTls13, DCConnectEcdsaP256) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
                                  ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
                                  now());

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, true, 256);
  EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
}

// Connected with ECDSA-P384.
TEST_P(TlsConnectTls13, DCConnectEcdsaP483) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa384,
                                  ssl_sig_ecdsa_secp384r1_sha384, kDCValidFor,
                                  now());

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, true, 384);
  EXPECT_EQ(ssl_sig_ecdsa_secp384r1_sha384, client_->info().signatureScheme);
}

// Connected with ECDSA-P521.
TEST_P(TlsConnectTls13, DCConnectEcdsaP521) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa521,
                                  ssl_sig_ecdsa_secp521r1_sha512, kDCValidFor,
                                  now());
  client_->EnableDelegatedCredentials();

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, true, 521);
  EXPECT_EQ(ssl_sig_ecdsa_secp521r1_sha512, client_->info().signatureScheme);
}

// Connected with RSA-PSS, using a PSS SPKI and ECDSA delegation cert.
TEST_P(TlsConnectTls13, DCConnectRsaPssEcdsa) {
  Reset(kEcdsaDelegatorId);

  // Need to enable PSS-PSS, which is not on by default.
  static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
                                                ssl_sig_rsa_pss_pss_sha256};
  client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
  server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));

  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(
      TlsAgent::kServerRsaPss, ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now());

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, true, 1024);
  EXPECT_EQ(ssl_sig_rsa_pss_pss_sha256, client_->info().signatureScheme);
}

// Connected with RSA-PSS, using a PSS SPKI and PSS delegation cert.
TEST_P(TlsConnectTls13, DCConnectRsaPssRsaPss) {
  Reset(kPssDelegatorId);

  // Need to enable PSS-PSS, which is not on by default.
  static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
                                                ssl_sig_rsa_pss_pss_sha256};
  client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
  server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));

  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(
      TlsAgent::kServerRsaPss, ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now());

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, true, 1024);
  EXPECT_EQ(ssl_sig_rsa_pss_pss_sha256, client_->info().signatureScheme);
}

// Connected with ECDSA-P256 using a PSS delegation cert.
TEST_P(TlsConnectTls13, DCConnectEcdsaP256RsaPss) {
  Reset(kPssDelegatorId);

  // Need to enable PSS-PSS, which is not on by default.
  static const SSLSignatureScheme kSchemes[] = {ssl_sig_ecdsa_secp256r1_sha256,
                                                ssl_sig_rsa_pss_pss_sha256};
  client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
  server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));

  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
                                  ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
                                  now());

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, true, 256);
  EXPECT_EQ(ssl_sig_ecdsa_secp256r1_sha256, client_->info().signatureScheme);
}

// Simulate the client receiving a DC containing algorithms not advertised.
// Do this by tweaking the client's supported sigSchemes after the CH.
TEST_P(TlsConnectTls13, DCReceiveUnadvertisedScheme) {
  Reset(kEcdsaDelegatorId);
  static const SSLSignatureScheme kClientSchemes[] = {
      ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384};
  static const SSLSignatureScheme kServerSchemes[] = {
      ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_ecdsa_secp256r1_sha256};
  static const SSLSignatureScheme kEcdsaP256Only[] = {
      ssl_sig_ecdsa_secp256r1_sha256};
  client_->SetSignatureSchemes(kClientSchemes, PR_ARRAY_SIZE(kClientSchemes));
  server_->SetSignatureSchemes(kServerSchemes, PR_ARRAY_SIZE(kServerSchemes));
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa384,
                                  ssl_sig_ecdsa_secp384r1_sha384, kDCValidFor,
                                  now());
  StartConnect();
  client_->Handshake();  // CH with P256/P384.
  server_->Handshake();  // Respond with P384 DC.
                         // Tell the client it only advertised P256.
  SECStatus rv = SSLInt_SetDCAdvertisedSigSchemes(
      client_->ssl_fd(), kEcdsaP256Only, PR_ARRAY_SIZE(kEcdsaP256Only));
  EXPECT_EQ(SECSuccess, rv);
  ExpectAlert(client_, kTlsAlertIllegalParameter);
  Handshake();
  client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}

// Server schemes includes only RSAE schemes. Connection should succeed
// without delegation.
TEST_P(TlsConnectTls13, DCConnectServerRsaeOnly) {
  Reset(kRsaeDelegatorId);
  static const SSLSignatureScheme kClientSchemes[] = {
      ssl_sig_rsa_pss_rsae_sha256, ssl_sig_rsa_pss_pss_sha256};
  static const SSLSignatureScheme kServerSchemes[] = {
      ssl_sig_rsa_pss_rsae_sha256};
  client_->SetSignatureSchemes(kClientSchemes, PR_ARRAY_SIZE(kClientSchemes));
  server_->SetSignatureSchemes(kServerSchemes, PR_ARRAY_SIZE(kServerSchemes));
  client_->EnableDelegatedCredentials();
  Connect();

  CheckPeerDelegCred(client_, false);
}

// Connect with an RSA-PSS DC SPKI, and an RSAE Delegator SPKI.
TEST_P(TlsConnectTls13, DCConnectRsaeDelegator) {
  Reset(kRsaeDelegatorId);

  static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pss_rsae_sha256,
                                                ssl_sig_rsa_pss_pss_sha256};
  client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
  server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));

  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(
      TlsAgent::kServerRsaPss, ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now());
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
  client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
}

// Client schemes includes only RSAE schemes. Connection should succeed
// without delegation, and no DC extension should be present in the CH.
TEST_P(TlsConnectTls13, DCConnectClientRsaeOnly) {
  Reset(kRsaeDelegatorId);
  static const SSLSignatureScheme kClientSchemes[] = {
      ssl_sig_rsa_pss_rsae_sha256};
  static const SSLSignatureScheme kServerSchemes[] = {
      ssl_sig_rsa_pss_rsae_sha256, ssl_sig_rsa_pss_pss_sha256};
  client_->SetSignatureSchemes(kClientSchemes, PR_ARRAY_SIZE(kClientSchemes));
  server_->SetSignatureSchemes(kServerSchemes, PR_ARRAY_SIZE(kServerSchemes));
  client_->EnableDelegatedCredentials();
  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();
  EXPECT_FALSE(cfilter->captured());
  CheckPeerDelegCred(client_, false);
}

// Test fallback. DC extension will not advertise RSAE schemes.
// The server will attempt to set one, but decline to after seeing
// the client-advertised schemes does not include it. Expect non-
// delegated success.
TEST_P(TlsConnectTls13, DCConnectRsaeDcSpki) {
  Reset(kRsaeDelegatorId);

  static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pss_rsae_sha256,
                                                ssl_sig_rsa_pss_pss_sha256};
  client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
  server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
  client_->EnableDelegatedCredentials();

  EnsureTlsSetup();
  ScopedSECKEYPublicKey pub;
  ScopedSECKEYPrivateKey priv;
  EXPECT_TRUE(
      TlsAgent::LoadKeyPairFromCert(TlsAgent::kDelegatorRsae2048, &pub, &priv));

  StackSECItem dc;
  server_->DelegateCredential(server_->name(), pub, ssl_sig_rsa_pss_rsae_sha256,
                              kDCValidFor, now(), &dc);

  SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr,
                                       nullptr,       &dc,     priv.get()};
  EXPECT_TRUE(server_->ConfigServerCert(server_->name(), true, &extra_data));
  auto sfilter = MakeTlsFilter<TlsExtensionCapture>(
      server_, ssl_delegated_credentials_xtn);
  Connect();
  EXPECT_FALSE(sfilter->captured());
  CheckPeerDelegCred(client_, false);
}

// Generate a weak key.  We can't do this in the fixture because certutil
// won't sign with such a tiny key.  That's OK, because this is fast(ish).
static void GenerateWeakRsaKey(ScopedSECKEYPrivateKey& priv,
                               ScopedSECKEYPublicKey& pub) {
  ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
  ASSERT_TRUE(slot);
  PK11RSAGenParams rsaparams;
// The absolute minimum size of RSA key that we can use with SHA-256 is
// 256bit (hash) + 256bit (salt) + 8 (start byte) + 8 (end byte) = 528.
#define RSA_WEAK_KEY 528
#if RSA_MIN_MODULUS_BITS < RSA_WEAK_KEY
  rsaparams.keySizeInBits = 528;
#else
  rsaparams.keySizeInBits = RSA_MIN_MODULUS_BITS + 1;
#endif
  rsaparams.pe = 65537;

  SECKEYPublicKey* p_pub = nullptr;
  priv.reset(PK11_GenerateKeyPair(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN,
                                  &rsaparams, &p_pub, falsefalse, nullptr));
  pub.reset(p_pub);
  PR_ASSERT(priv);
  return;
}

// Fail to connect with a weak RSA key.
TEST_P(TlsConnectTls13, DCWeakKey) {
  Reset(kPssDelegatorId);
  EnsureTlsSetup();
  static const SSLSignatureScheme kSchemes[] = {ssl_sig_rsa_pss_rsae_sha256,
                                                ssl_sig_rsa_pss_pss_sha256};
  client_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
  server_->SetSignatureSchemes(kSchemes, PR_ARRAY_SIZE(kSchemes));
#if RSA_MIN_MODULUS_BITS > RSA_WEAK_KEY
  // save the MIN POLICY length.
  PRInt32 minRsa;

  ASSERT_EQ(SECSuccess, NSS_OptionGet(NSS_RSA_MIN_KEY_SIZE, &minRsa));
#if RSA_MIN_MODULUS_BITS >= 2048
  ASSERT_EQ(SECSuccess,
            NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, RSA_MIN_MODULUS_BITS + 1024));
#else
  ASSERT_EQ(SECSuccess, NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, 2048));
#endif
#endif

  ScopedSECKEYPrivateKey dc_priv;
  ScopedSECKEYPublicKey dc_pub;
  GenerateWeakRsaKey(dc_priv, dc_pub);
  ASSERT_TRUE(dc_priv);

  // Construct a DC.
  StackSECItem dc;
  TlsAgent::DelegateCredential(kPssDelegatorId, dc_pub,
                               ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now(),
                               &dc);

  // Configure the DC on the server.
  SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr,
                                       nullptr,       &dc,     dc_priv.get()};
  EXPECT_TRUE(server_->ConfigServerCert(kPssDelegatorId, true, &extra_data));

  client_->EnableDelegatedCredentials();

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  ConnectExpectAlert(client_, kTlsAlertInsufficientSecurity);
#if RSA_MIN_MODULUS_BITS > RSA_WEAK_KEY
  ASSERT_EQ(SECSuccess, NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, minRsa));
#endif
}

class ReplaceDCSigScheme : public TlsHandshakeFilter {
 public:
  ReplaceDCSigScheme(const std::shared_ptr<TlsAgent>& a)
      : TlsHandshakeFilter(a, {ssl_hs_certificate_verify}) {}

 protected:
  PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
                                       const DataBuffer& input,
                                       DataBuffer* output) override {
    *output = input;
    output->Write(0, ssl_sig_ecdsa_secp384r1_sha384, 2);
    return CHANGE;
  }
};

// Aborted because of incorrect DC signature algorithm indication.
TEST_P(TlsConnectTls13, DCAbortBadExpectedCertVerifyAlg) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
                                  ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
                                  now());
  auto filter = MakeTlsFilter<ReplaceDCSigScheme>(server_);
  filter->EnableDecryption();
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  client_->CheckErrorCode(SSL_ERROR_DC_CERT_VERIFY_ALG_MISMATCH);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}

// Aborted because of invalid DC signature.
TEST_P(TlsConnectTls13, DCAbortBadSignature) {
  Reset(kEcdsaDelegatorId);
  EnsureTlsSetup();
  client_->EnableDelegatedCredentials();

  ScopedSECKEYPublicKey pub;
  ScopedSECKEYPrivateKey priv;
  EXPECT_TRUE(TlsAgent::LoadKeyPairFromCert(kDCId, &pub, &priv));

  StackSECItem dc;
  TlsAgent::DelegateCredential(kEcdsaDelegatorId, pub, kDCScheme, kDCValidFor,
                               now(), &dc);
  ASSERT_TRUE(dc.data != nullptr);

  // Flip the last bit of the DC so that the signature is invalid.
  dc.data[dc.len - 1] ^= 0x01;

  SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr,
                                       nullptr,       &dc,     priv.get()};
  EXPECT_TRUE(server_->ConfigServerCert(kEcdsaDelegatorId, true, &extra_data));

  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  client_->CheckErrorCode(SSL_ERROR_DC_BAD_SIGNATURE);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}

// Aborted because of expired DC.
TEST_P(TlsConnectTls13, DCAbortExpired) {
  Reset(kEcdsaDelegatorId);
  server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());
  client_->EnableDelegatedCredentials();
  // When the client checks the time, it will be at least one second after the
  // DC expired.
  AdvanceTime((static_cast<PRTime>(kDCValidFor) + 1) * PR_USEC_PER_SEC);
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  client_->CheckErrorCode(SSL_ERROR_DC_EXPIRED);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}

// Aborted due to remaining TTL > max validity period.
TEST_P(TlsConnectTls13, DCAbortExcessiveTTL) {
  Reset(kEcdsaDelegatorId);
  server_->AddDelegatedCredential(kDCId, kDCScheme,
                                  kDCValidFor + 1 /* seconds */, now());
  client_->EnableDelegatedCredentials();
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  client_->CheckErrorCode(SSL_ERROR_DC_INAPPROPRIATE_VALIDITY_PERIOD);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
}

// Aborted because of invalid key usage.
TEST_P(TlsConnectTls13, DCAbortBadKeyUsage) {
  // The sever does not have the delegationUsage extension.
  Reset(TlsAgent::kServerEcdsa256);
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
}

// Connected without DC because of no client indication.
TEST_P(TlsConnectTls13, DCConnectNoClientSupport) {
  Reset(kEcdsaDelegatorId);
  server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  EXPECT_FALSE(cfilter->captured());
  CheckPeerDelegCred(client_, false);
}

// Connected without DC because of no server DC.
TEST_P(TlsConnectTls13, DCConnectNoServerSupport) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, false);
}

// Connected without DC because client doesn't support TLS 1.3.
TEST_P(TlsConnectTls13, DCConnectClientNoTls13) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());

  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                           SSL_LIBRARY_VERSION_TLS_1_2);
  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                           SSL_LIBRARY_VERSION_TLS_1_3);

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  // Should fallback to TLS 1.2 and not negotiate a DC.
  EXPECT_FALSE(cfilter->captured());
  CheckPeerDelegCred(client_, false);
}

// Connected without DC because server doesn't support TLS 1.3.
TEST_P(TlsConnectTls13, DCConnectServerNoTls13) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(kDCId, kDCScheme, kDCValidFor, now());

  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                           SSL_LIBRARY_VERSION_TLS_1_3);
  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
                           SSL_LIBRARY_VERSION_TLS_1_2);

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  // Should fallback to TLS 1.2 and not negotiate a DC. The client will still
  // send the indication because it supports 1.3.
  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, false);
}

// Connected without DC because client doesn't support the signature scheme.
TEST_P(TlsConnectTls13, DCConnectExpectedCertVerifyAlgNotSupported) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  static const SSLSignatureScheme kClientSchemes[] = {
      ssl_sig_ecdsa_secp256r1_sha256,
  };
  client_->SetSignatureSchemes(kClientSchemes, PR_ARRAY_SIZE(kClientSchemes));

  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa521,
                                  ssl_sig_ecdsa_secp521r1_sha512, kDCValidFor,
                                  now());

  auto cfilter = MakeTlsFilter<TlsExtensionCapture>(
      client_, ssl_delegated_credentials_xtn);
  Connect();

  // Client sends indication, but the server doesn't send a DC.
  EXPECT_TRUE(cfilter->captured());
  CheckPeerDelegCred(client_, false);
}

// Check that preliminary channel info properly reflects the DC.
TEST_P(TlsConnectTls13, DCCheckPreliminaryInfo) {
  Reset(kEcdsaDelegatorId);
  EnsureTlsSetup();
  client_->EnableDelegatedCredentials();
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa256,
                                  ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
                                  now());

  auto filter = MakeTlsFilter<TlsHandshakeDropper>(server_);
  filter->SetHandshakeTypes(
      {kTlsHandshakeCertificateVerify, kTlsHandshakeFinished});
  filter->EnableDecryption();
  StartConnect();
  client_->Handshake();  // Send ClientHello
  server_->Handshake();  // Send ServerHello

  client_->SetAuthCertificateCallback(CheckPreliminaryDC);
  client_->Handshake();  // Process response

  client_->UpdatePreliminaryChannelInfo();
  CheckPreliminaryPeerDelegCred(client_, true, 256,
                                ssl_sig_ecdsa_secp256r1_sha256);
}

// Check that preliminary channel info properly reflects a lack of DC.
TEST_P(TlsConnectTls13, DCCheckPreliminaryInfoNoDC) {
  Reset(kEcdsaDelegatorId);
  EnsureTlsSetup();
  client_->EnableDelegatedCredentials();
  auto filter = MakeTlsFilter<TlsHandshakeDropper>(server_);
  filter->SetHandshakeTypes(
      {kTlsHandshakeCertificateVerify, kTlsHandshakeFinished});
  filter->EnableDecryption();
  StartConnect();
  client_->Handshake();  // Send ClientHello
  server_->Handshake();  // Send ServerHello

  client_->SetAuthCertificateCallback(CheckPreliminaryNoDC);
  client_->Handshake();  // Process response

  client_->UpdatePreliminaryChannelInfo();
  CheckPreliminaryPeerDelegCred(client_, false);
}

// Tweak the scheme in between |Cert| and |CertVerify|.
TEST_P(TlsConnectTls13, DCRejectModifiedDCScheme) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  client_->SetAuthCertificateCallback(ModifyDCScheme);
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa521,
                                  ssl_sig_ecdsa_secp521r1_sha512, kDCValidFor,
                                  now());
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
  client_->CheckErrorCode(SSL_ERROR_DC_CERT_VERIFY_ALG_MISMATCH);
}

// Tweak the authKeyBits in between |Cert| and |CertVerify|.
TEST_P(TlsConnectTls13, DCRejectModifiedDCAuthKeyBits) {
  Reset(kEcdsaDelegatorId);
  client_->EnableDelegatedCredentials();
  client_->SetAuthCertificateCallback(ModifyDCAuthKeyBits);
  server_->AddDelegatedCredential(TlsAgent::kServerEcdsa521,
                                  ssl_sig_ecdsa_secp521r1_sha512, kDCValidFor,
                                  now());
  ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
  server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
  client_->CheckErrorCode(SSL_ERROR_DC_CERT_VERIFY_ALG_MISMATCH);
}

class DCDelegation : public ::testing::Test {};

TEST_F(DCDelegation, DCDelegations) {
  PRTime now = PR_Now();
  ScopedCERTCertificate cert;
  ScopedSECKEYPrivateKey priv;
  ASSERT_TRUE(TlsAgent::LoadCertificate(kEcdsaDelegatorId, &cert, &priv));

  ScopedSECKEYPublicKey pub_rsa;
  ScopedSECKEYPrivateKey priv_rsa;
  ASSERT_TRUE(
      TlsAgent::LoadKeyPairFromCert(TlsAgent::kServerRsa, &pub_rsa, &priv_rsa));

  StackSECItem dc;
  EXPECT_EQ(SECFailure,
            SSL_DelegateCredential(cert.get(), priv.get(), pub_rsa.get(),
                                   ssl_sig_ecdsa_secp256r1_sha256, kDCValidFor,
                                   now, &dc));
  EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());

  // Using different PSS hashes should be OK.
  EXPECT_EQ(SECSuccess, SSL_DelegateCredential(
                            cert.get(), priv.get(), pub_rsa.get(),
                            ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now, &dc));
  // Make sure to reset |dc| after each success.
  dc.Reset();
  EXPECT_EQ(SECSuccess, SSL_DelegateCredential(
                            cert.get(), priv.get(), pub_rsa.get(),
                            ssl_sig_rsa_pss_pss_sha384, kDCValidFor, now, &dc));
  dc.Reset();
  EXPECT_EQ(SECSuccess, SSL_DelegateCredential(
                            cert.get(), priv.get(), pub_rsa.get(),
                            ssl_sig_rsa_pss_pss_sha512, kDCValidFor, now, &dc));
  dc.Reset();

  ScopedSECKEYPublicKey pub_ecdsa;
  ScopedSECKEYPrivateKey priv_ecdsa;
  ASSERT_TRUE(TlsAgent::LoadKeyPairFromCert(TlsAgent::kServerEcdsa256,
                                            &pub_ecdsa, &priv_ecdsa));

  EXPECT_EQ(SECFailure,
            SSL_DelegateCredential(cert.get(), priv.get(), pub_ecdsa.get(),
                                   ssl_sig_rsa_pss_rsae_sha256, kDCValidFor,
                                   now, &dc));
  EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
  EXPECT_EQ(SECFailure, SSL_DelegateCredential(
                            cert.get(), priv.get(), pub_ecdsa.get(),
                            ssl_sig_rsa_pss_pss_sha256, kDCValidFor, now, &dc));
  EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
  EXPECT_EQ(SECFailure,
            SSL_DelegateCredential(cert.get(), priv.get(), pub_ecdsa.get(),
                                   ssl_sig_ecdsa_secp384r1_sha384, kDCValidFor,
                                   now, &dc));
  EXPECT_EQ(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, PORT_GetError());
}

}  // namespace nss_test

Messung V0.5
C=89 H=100 G=94

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge