blob: 94b761a1afe047d3d83390b8e86c621b93a81da7 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/token_validator_base.h"
#include <vector>
#include "base/atomic_sequence_num.h"
#include "crypto/rsa_private_key.h"
#include "net/cert/x509_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kTokenUrl[] = "https://example.com/token";
const char kTokenValidationUrl[] = "https://example.com/validate";
const char kTokenValidationCertIssuer[] = "*";
base::StaticAtomicSequenceNumber g_serial_number;
scoped_refptr<net::X509Certificate> CreateFakeCert(base::Time valid_start,
base::Time valid_expiry) {
std::unique_ptr<crypto::RSAPrivateKey> unused_key;
std::string cert_der;
net::x509_util::CreateKeyAndSelfSignedCert(
"CN=subject", g_serial_number.GetNext(), valid_start, valid_expiry,
&unused_key, &cert_der);
return net::X509Certificate::CreateFromBytes(cert_der.data(),
cert_der.size());
}
} // namespace
namespace remoting {
class TestTokenValidator : TokenValidatorBase {
public:
explicit TestTokenValidator(const ThirdPartyAuthConfig& config);
~TestTokenValidator() override;
void SelectCertificates(net::CertificateList* selected_certs);
void ExpectContinueWithCertificate(net::X509Certificate* client_cert);
protected:
void ContinueWithCertificate(net::X509Certificate* client_cert,
net::SSLPrivateKey* client_private_key) override;
private:
void StartValidateRequest(const std::string& token) override {}
net::X509Certificate* expected_client_cert_ = nullptr;
};
TestTokenValidator::TestTokenValidator(const ThirdPartyAuthConfig& config) :
TokenValidatorBase(config, "", nullptr) {
}
TestTokenValidator::~TestTokenValidator() {}
void TestTokenValidator::SelectCertificates(
net::CertificateList* selected_certs) {
OnCertificatesSelected(selected_certs, nullptr);
}
void TestTokenValidator::ExpectContinueWithCertificate(
net::X509Certificate* client_cert) {
expected_client_cert_ = client_cert;
}
void TestTokenValidator::ContinueWithCertificate(
net::X509Certificate* client_cert,
net::SSLPrivateKey* client_private_key) {
EXPECT_EQ(expected_client_cert_, client_cert);
}
class TokenValidatorBaseTest : public testing::Test {
public:
void SetUp() override;
protected:
std::unique_ptr<TestTokenValidator> token_validator_;
};
void TokenValidatorBaseTest::SetUp() {
ThirdPartyAuthConfig config;
config.token_url = GURL(kTokenUrl);
config.token_validation_url = GURL(kTokenValidationUrl);
config.token_validation_cert_issuer = kTokenValidationCertIssuer;
token_validator_.reset(new TestTokenValidator(config));
}
TEST_F(TokenValidatorBaseTest, TestSelectCertificate) {
base::Time now = base::Time::Now();
scoped_refptr<net::X509Certificate> cert_expired_5_minutes_ago =
CreateFakeCert(now - base::TimeDelta::FromMinutes(10),
now - base::TimeDelta::FromMinutes(5));
scoped_refptr<net::X509Certificate> cert_start_5min_expire_5min =
CreateFakeCert(now - base::TimeDelta::FromMinutes(5),
now + base::TimeDelta::FromMinutes(5));
scoped_refptr<net::X509Certificate> cert_start_10min_expire_5min =
CreateFakeCert(now - base::TimeDelta::FromMinutes(10),
now + base::TimeDelta::FromMinutes(5));
scoped_refptr<net::X509Certificate> cert_start_5min_expire_10min =
CreateFakeCert(now - base::TimeDelta::FromMinutes(5),
now + base::TimeDelta::FromMinutes(10));
// No certificate.
net::CertificateList certificates {};
token_validator_->ExpectContinueWithCertificate(nullptr);
token_validator_->SelectCertificates(&certificates);
// One invalid certificate.
certificates = { cert_expired_5_minutes_ago };
token_validator_->ExpectContinueWithCertificate(nullptr);
token_validator_->SelectCertificates(&certificates);
// One valid certificate.
certificates = { cert_start_5min_expire_5min };
token_validator_->ExpectContinueWithCertificate(
cert_start_5min_expire_5min.get());
token_validator_->SelectCertificates(&certificates);
// One valid one invalid.
certificates = { cert_expired_5_minutes_ago, cert_start_5min_expire_5min };
token_validator_->ExpectContinueWithCertificate(
cert_start_5min_expire_5min.get());
token_validator_->SelectCertificates(&certificates);
// Two valid certs. Choose latest created.
certificates = { cert_start_10min_expire_5min, cert_start_5min_expire_5min };
token_validator_->ExpectContinueWithCertificate(
cert_start_5min_expire_5min.get());
token_validator_->SelectCertificates(&certificates);
// Two valid certs. Choose latest expires.
certificates = { cert_start_5min_expire_5min, cert_start_5min_expire_10min };
token_validator_->ExpectContinueWithCertificate(
cert_start_5min_expire_10min.get());
token_validator_->SelectCertificates(&certificates);
// Pick the best given all certificates.
certificates = { cert_expired_5_minutes_ago, cert_start_5min_expire_5min,
cert_start_5min_expire_10min, cert_start_10min_expire_5min };
token_validator_->ExpectContinueWithCertificate(
cert_start_5min_expire_10min.get());
token_validator_->SelectCertificates(&certificates);
}
} // namespace remoting