1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/host/token_validator_base.h"
6
7 #include <vector>
8
9 #include "base/atomic_sequence_num.h"
10 #include "crypto/rsa_private_key.h"
11 #include "net/cert/x509_util.h"
12 #include "net/ssl/client_cert_identity_test_util.h"
13 #include "net/ssl/test_ssl_private_key.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace {
17
18 const char kTokenUrl[] = "https://example.com/token";
19 const char kTokenValidationUrl[] = "https://example.com/validate";
20 const char kTokenValidationCertIssuer[] = "*";
21
22 base::AtomicSequenceNumber g_serial_number;
23
CreateFakeCert(base::Time valid_start,base::Time valid_expiry)24 std::unique_ptr<net::FakeClientCertIdentity> CreateFakeCert(
25 base::Time valid_start,
26 base::Time valid_expiry) {
27 std::unique_ptr<crypto::RSAPrivateKey> rsa_private_key;
28 std::string cert_der;
29 net::x509_util::CreateKeyAndSelfSignedCert(
30 "CN=subject", g_serial_number.GetNext(), valid_start, valid_expiry,
31 &rsa_private_key, &cert_der);
32
33 scoped_refptr<net::X509Certificate> cert =
34 net::X509Certificate::CreateFromBytes(cert_der.data(), cert_der.size());
35 if (!cert)
36 return nullptr;
37
38 scoped_refptr<net::SSLPrivateKey> ssl_private_key =
39 net::WrapRSAPrivateKey(rsa_private_key.get());
40 if (!ssl_private_key)
41 return nullptr;
42
43 return std::make_unique<net::FakeClientCertIdentity>(cert, ssl_private_key);
44 }
45
46 } // namespace
47
48 namespace remoting {
49
50 class TestTokenValidator : TokenValidatorBase {
51 public:
52 explicit TestTokenValidator(const ThirdPartyAuthConfig& config);
53 ~TestTokenValidator() override;
54
55 void SelectCertificates(net::ClientCertIdentityList selected_certs);
56
57 void ExpectContinueWithCertificate(
58 const net::FakeClientCertIdentity* identity);
59
60 protected:
61 void ContinueWithCertificate(
62 scoped_refptr<net::X509Certificate> client_cert,
63 scoped_refptr<net::SSLPrivateKey> client_private_key) override;
64
65 private:
StartValidateRequest(const std::string & token)66 void StartValidateRequest(const std::string& token) override {}
67
68 net::X509Certificate* expected_client_cert_ = nullptr;
69 net::SSLPrivateKey* expected_private_key_ = nullptr;
70 };
71
TestTokenValidator(const ThirdPartyAuthConfig & config)72 TestTokenValidator::TestTokenValidator(const ThirdPartyAuthConfig& config) :
73 TokenValidatorBase(config, "", nullptr) {
74 }
75
76 TestTokenValidator::~TestTokenValidator() = default;
77
SelectCertificates(net::ClientCertIdentityList selected_certs)78 void TestTokenValidator::SelectCertificates(
79 net::ClientCertIdentityList selected_certs) {
80 OnCertificatesSelected(nullptr, std::move(selected_certs));
81 }
82
ExpectContinueWithCertificate(const net::FakeClientCertIdentity * identity)83 void TestTokenValidator::ExpectContinueWithCertificate(
84 const net::FakeClientCertIdentity* identity) {
85 if (identity) {
86 expected_client_cert_ = identity->certificate();
87 expected_private_key_ = identity->ssl_private_key();
88 } else {
89 expected_client_cert_ = nullptr;
90 expected_private_key_ = nullptr;
91 }
92 }
93
ContinueWithCertificate(scoped_refptr<net::X509Certificate> client_cert,scoped_refptr<net::SSLPrivateKey> client_private_key)94 void TestTokenValidator::ContinueWithCertificate(
95 scoped_refptr<net::X509Certificate> client_cert,
96 scoped_refptr<net::SSLPrivateKey> client_private_key) {
97 EXPECT_EQ(expected_client_cert_, client_cert.get());
98 EXPECT_EQ(expected_private_key_, client_private_key.get());
99 }
100
101 class TokenValidatorBaseTest : public testing::Test {
102 public:
103 void SetUp() override;
104 protected:
105 std::unique_ptr<TestTokenValidator> token_validator_;
106 };
107
SetUp()108 void TokenValidatorBaseTest::SetUp() {
109 ThirdPartyAuthConfig config;
110 config.token_url = GURL(kTokenUrl);
111 config.token_validation_url = GURL(kTokenValidationUrl);
112 config.token_validation_cert_issuer = kTokenValidationCertIssuer;
113 token_validator_.reset(new TestTokenValidator(config));
114 }
115
TEST_F(TokenValidatorBaseTest,TestSelectCertificate)116 TEST_F(TokenValidatorBaseTest, TestSelectCertificate) {
117 base::Time now = base::Time::Now();
118
119 std::unique_ptr<net::FakeClientCertIdentity> cert_expired_5_minutes_ago =
120 CreateFakeCert(now - base::TimeDelta::FromMinutes(10),
121 now - base::TimeDelta::FromMinutes(5));
122 ASSERT_TRUE(cert_expired_5_minutes_ago);
123
124 std::unique_ptr<net::FakeClientCertIdentity> cert_start_5min_expire_5min =
125 CreateFakeCert(now - base::TimeDelta::FromMinutes(5),
126 now + base::TimeDelta::FromMinutes(5));
127 ASSERT_TRUE(cert_start_5min_expire_5min);
128
129 std::unique_ptr<net::FakeClientCertIdentity> cert_start_10min_expire_5min =
130 CreateFakeCert(now - base::TimeDelta::FromMinutes(10),
131 now + base::TimeDelta::FromMinutes(5));
132 ASSERT_TRUE(cert_start_10min_expire_5min);
133
134 std::unique_ptr<net::FakeClientCertIdentity> cert_start_5min_expire_10min =
135 CreateFakeCert(now - base::TimeDelta::FromMinutes(5),
136 now + base::TimeDelta::FromMinutes(10));
137 ASSERT_TRUE(cert_start_5min_expire_10min);
138
139 // No certificate.
140 token_validator_->ExpectContinueWithCertificate(nullptr);
141 token_validator_->SelectCertificates(net::ClientCertIdentityList());
142 {
143 // One invalid certificate.
144 net::ClientCertIdentityList client_certs;
145 client_certs.push_back(cert_expired_5_minutes_ago->Copy());
146 token_validator_->ExpectContinueWithCertificate(nullptr);
147 token_validator_->SelectCertificates(std::move(client_certs));
148 }
149 {
150 // One valid certificate.
151 net::ClientCertIdentityList client_certs;
152 client_certs.push_back(cert_start_5min_expire_5min->Copy());
153 token_validator_->ExpectContinueWithCertificate(
154 cert_start_5min_expire_5min.get());
155 token_validator_->SelectCertificates(std::move(client_certs));
156 }
157 {
158 // One valid one invalid.
159 net::ClientCertIdentityList client_certs;
160 client_certs.push_back(cert_expired_5_minutes_ago->Copy());
161 client_certs.push_back(cert_start_5min_expire_5min->Copy());
162 token_validator_->ExpectContinueWithCertificate(
163 cert_start_5min_expire_5min.get());
164 token_validator_->SelectCertificates(std::move(client_certs));
165 }
166 {
167 // Two valid certs. Choose latest created.
168 net::ClientCertIdentityList client_certs;
169 client_certs.push_back(cert_start_10min_expire_5min->Copy());
170 client_certs.push_back(cert_start_5min_expire_5min->Copy());
171 token_validator_->ExpectContinueWithCertificate(
172 cert_start_5min_expire_5min.get());
173 token_validator_->SelectCertificates(std::move(client_certs));
174 }
175 {
176 // Two valid certs. Choose latest expires.
177 net::ClientCertIdentityList client_certs;
178 client_certs.push_back(cert_start_5min_expire_5min->Copy());
179 client_certs.push_back(cert_start_5min_expire_10min->Copy());
180 token_validator_->ExpectContinueWithCertificate(
181 cert_start_5min_expire_10min.get());
182 token_validator_->SelectCertificates(std::move(client_certs));
183 }
184 {
185 // Pick the best given all certificates.
186 net::ClientCertIdentityList client_certs;
187 client_certs.push_back(cert_expired_5_minutes_ago->Copy());
188 client_certs.push_back(cert_start_5min_expire_5min->Copy());
189 client_certs.push_back(cert_start_5min_expire_10min->Copy());
190 client_certs.push_back(cert_start_10min_expire_5min->Copy());
191 token_validator_->ExpectContinueWithCertificate(
192 cert_start_5min_expire_10min.get());
193 token_validator_->SelectCertificates(std::move(client_certs));
194 }
195 }
196
197 } // namespace remoting
198