[M73 Dev][EFL] Disable VizDisplayCompositor for EFL port
[platform/framework/web/chromium-efl.git] / components / cast_channel / cast_auth_util_unittest.cc
1 // Copyright 2014 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 "components/cast_channel/cast_auth_util.h"
6
7 #include <string>
8
9 #include "base/logging.h"
10 #include "base/macros.h"
11 #include "base/test/scoped_feature_list.h"
12 #include "base/time/time.h"
13 #include "components/cast_certificate/cast_cert_validator.h"
14 #include "components/cast_certificate/cast_cert_validator_test_helpers.h"
15 #include "components/cast_certificate/cast_crl.h"
16 #include "components/cast_certificate/proto/test_suite.pb.h"
17 #include "components/cast_channel/proto/cast_channel.pb.h"
18 #include "net/cert/internal/trust_store_in_memory.h"
19 #include "net/cert/x509_certificate.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace cast_channel {
23 namespace {
24
25 class CastAuthUtilTest : public testing::Test {
26  public:
27   CastAuthUtilTest() {}
28   ~CastAuthUtilTest() override {}
29
30   void SetUp() override {}
31
32  protected:
33   static AuthResponse CreateAuthResponse(std::string* signed_data,
34                                          HashAlgorithm digest_algorithm) {
35     auto chain = cast_certificate::testing::ReadCertificateChainFromFile(
36         "certificates/chromecast_gen1.pem");
37     CHECK(!chain.empty());
38
39     auto signature_data = cast_certificate::testing::ReadSignatureTestData(
40         "signeddata/2ZZBG9_FA8FCA3EF91A.pem");
41
42     AuthResponse response;
43
44     response.set_client_auth_certificate(chain[0]);
45     for (size_t i = 1; i < chain.size(); ++i)
46       response.add_intermediate_certificate(chain[i]);
47
48     response.set_hash_algorithm(digest_algorithm);
49     switch (digest_algorithm) {
50       case SHA1:
51         response.set_signature(signature_data.signature_sha1);
52         break;
53       case SHA256:
54         response.set_signature(signature_data.signature_sha256);
55         break;
56     }
57     *signed_data = signature_data.message;
58
59     return response;
60   }
61
62   // Mangles a string by inverting the first byte.
63   static void MangleString(std::string* str) { (*str)[0] = ~(*str)[0]; }
64 };
65
66 // Note on expiration: VerifyCredentials() depends on the system clock. In
67 // practice this shouldn't be a problem though since the certificate chain
68 // being verified doesn't expire until 2032!
69 TEST_F(CastAuthUtilTest, VerifySuccess) {
70   std::string signed_data;
71   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256);
72   base::Time now = base::Time::Now();
73   AuthResult result = VerifyCredentialsForTest(
74       auth_response, signed_data, cast_certificate::CRLPolicy::CRL_OPTIONAL,
75       nullptr, nullptr, now);
76   EXPECT_TRUE(result.success());
77   EXPECT_EQ(static_cast<unsigned>(AuthResult::POLICY_NONE),
78             result.channel_policies);
79 }
80
81 TEST_F(CastAuthUtilTest, VerifyBadCA) {
82   std::string signed_data;
83   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256);
84   MangleString(auth_response.mutable_intermediate_certificate(0));
85   AuthResult result = VerifyCredentials(auth_response, signed_data);
86   EXPECT_FALSE(result.success());
87   EXPECT_EQ(AuthResult::ERROR_CERT_PARSING_FAILED, result.error_type);
88 }
89
90 TEST_F(CastAuthUtilTest, VerifyBadClientAuthCert) {
91   std::string signed_data;
92   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256);
93   MangleString(auth_response.mutable_client_auth_certificate());
94   AuthResult result = VerifyCredentials(auth_response, signed_data);
95   EXPECT_FALSE(result.success());
96   // TODO(eroman): Not quite right of an error.
97   EXPECT_EQ(AuthResult::ERROR_CERT_PARSING_FAILED, result.error_type);
98 }
99
100 TEST_F(CastAuthUtilTest, VerifyBadSignature) {
101   std::string signed_data;
102   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256);
103   MangleString(auth_response.mutable_signature());
104   AuthResult result = VerifyCredentials(auth_response, signed_data);
105   EXPECT_FALSE(result.success());
106   EXPECT_EQ(AuthResult::ERROR_SIGNED_BLOBS_MISMATCH, result.error_type);
107 }
108
109 TEST_F(CastAuthUtilTest, VerifyEmptySignature) {
110   std::string signed_data;
111   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256);
112   auth_response.mutable_signature()->clear();
113   AuthResult result = VerifyCredentials(auth_response, signed_data);
114   EXPECT_FALSE(result.success());
115   EXPECT_EQ(AuthResult::ERROR_SIGNATURE_EMPTY, result.error_type);
116 }
117
118 TEST_F(CastAuthUtilTest, VerifyUnsupportedDigest) {
119   base::test::ScopedFeatureList scoped_feature_list;
120   scoped_feature_list.InitAndEnableFeature(
121       base::Feature{"CastSHA256Enforced", base::FEATURE_DISABLED_BY_DEFAULT});
122   std::string signed_data;
123   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA1);
124   base::Time now = base::Time::Now();
125   AuthResult result = VerifyCredentialsForTest(
126       auth_response, signed_data, cast_certificate::CRLPolicy::CRL_OPTIONAL,
127       nullptr, nullptr, now);
128   EXPECT_FALSE(result.success());
129   EXPECT_EQ(AuthResult::ERROR_DIGEST_UNSUPPORTED, result.error_type);
130 }
131
132 TEST_F(CastAuthUtilTest, VerifyBackwardsCompatibleDigest) {
133   std::string signed_data;
134   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA1);
135   base::Time now = base::Time::Now();
136   AuthResult result = VerifyCredentialsForTest(
137       auth_response, signed_data, cast_certificate::CRLPolicy::CRL_OPTIONAL,
138       nullptr, nullptr, now);
139   EXPECT_TRUE(result.success());
140 }
141
142 TEST_F(CastAuthUtilTest, VerifyBadPeerCert) {
143   std::string signed_data;
144   AuthResponse auth_response = CreateAuthResponse(&signed_data, SHA256);
145   MangleString(&signed_data);
146   AuthResult result = VerifyCredentials(auth_response, signed_data);
147   EXPECT_FALSE(result.success());
148   EXPECT_EQ(AuthResult::ERROR_SIGNED_BLOBS_MISMATCH, result.error_type);
149 }
150
151 TEST_F(CastAuthUtilTest, VerifySenderNonceMatch) {
152   base::test::ScopedFeatureList scoped_feature_list;
153   scoped_feature_list.InitAndEnableFeature(
154       base::Feature{"CastNonceEnforced", base::FEATURE_DISABLED_BY_DEFAULT});
155   AuthContext context = AuthContext::Create();
156   AuthResult result = context.VerifySenderNonce(context.nonce());
157   EXPECT_TRUE(result.success());
158 }
159
160 TEST_F(CastAuthUtilTest, VerifySenderNonceMismatch) {
161   base::test::ScopedFeatureList scoped_feature_list;
162   scoped_feature_list.InitAndEnableFeature(
163       base::Feature{"CastNonceEnforced", base::FEATURE_DISABLED_BY_DEFAULT});
164   AuthContext context = AuthContext::Create();
165   std::string received_nonce = "test2";
166   EXPECT_NE(received_nonce, context.nonce());
167   AuthResult result = context.VerifySenderNonce(received_nonce);
168   EXPECT_FALSE(result.success());
169   EXPECT_EQ(AuthResult::ERROR_SENDER_NONCE_MISMATCH, result.error_type);
170 }
171
172 TEST_F(CastAuthUtilTest, VerifySenderNonceMissing) {
173   base::test::ScopedFeatureList scoped_feature_list;
174   scoped_feature_list.InitAndEnableFeature(
175       base::Feature{"CastNonceEnforced", base::FEATURE_DISABLED_BY_DEFAULT});
176   AuthContext context = AuthContext::Create();
177   std::string received_nonce;
178   EXPECT_FALSE(context.nonce().empty());
179   AuthResult result = context.VerifySenderNonce(received_nonce);
180   EXPECT_FALSE(result.success());
181   EXPECT_EQ(AuthResult::ERROR_SENDER_NONCE_MISMATCH, result.error_type);
182 }
183
184 TEST_F(CastAuthUtilTest, VerifyTLSCertificateSuccess) {
185   auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile(
186       "certificates/test_tls_cert.pem");
187
188   scoped_refptr<net::X509Certificate> tls_cert =
189       net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
190                                             tls_cert_der[0].size());
191   std::string peer_cert_der;
192   AuthResult result =
193       VerifyTLSCertificate(*tls_cert, &peer_cert_der, tls_cert->valid_start());
194   EXPECT_TRUE(result.success());
195 }
196
197 TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooEarly) {
198   auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile(
199       "certificates/test_tls_cert.pem");
200
201   scoped_refptr<net::X509Certificate> tls_cert =
202       net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
203                                             tls_cert_der[0].size());
204   std::string peer_cert_der;
205   AuthResult result = VerifyTLSCertificate(
206       *tls_cert, &peer_cert_der,
207       tls_cert->valid_start() - base::TimeDelta::FromSeconds(1));
208   EXPECT_FALSE(result.success());
209   EXPECT_EQ(AuthResult::ERROR_TLS_CERT_VALID_START_DATE_IN_FUTURE,
210             result.error_type);
211 }
212
213 TEST_F(CastAuthUtilTest, VerifyTLSCertificateTooLate) {
214   auto tls_cert_der = cast_certificate::testing::ReadCertificateChainFromFile(
215       "certificates/test_tls_cert.pem");
216
217   scoped_refptr<net::X509Certificate> tls_cert =
218       net::X509Certificate::CreateFromBytes(tls_cert_der[0].data(),
219                                             tls_cert_der[0].size());
220   std::string peer_cert_der;
221   AuthResult result = VerifyTLSCertificate(
222       *tls_cert, &peer_cert_der,
223       tls_cert->valid_expiry() + base::TimeDelta::FromSeconds(2));
224   EXPECT_FALSE(result.success());
225   EXPECT_EQ(AuthResult::ERROR_TLS_CERT_EXPIRED, result.error_type);
226 }
227
228 // Indicates the expected result of test step's verification.
229 enum TestStepResult {
230   RESULT_SUCCESS,
231   RESULT_FAIL,
232 };
233
234 // Verifies that the certificate chain provided is not revoked according to
235 // the provided Cast CRL at |verification_time|.
236 // The provided CRL is verified at |verification_time|.
237 // If |crl_required| is set, then a valid Cast CRL must be provided.
238 // Otherwise, a missing CRL is be ignored.
239 AuthResult TestVerifyRevocation(
240     const std::vector<std::string>& certificate_chain,
241     const std::string& crl_bundle,
242     const base::Time& verification_time,
243     bool crl_required,
244     net::TrustStore* cast_trust_store,
245     net::TrustStore* crl_trust_store) {
246   AuthResponse response;
247
248   if (certificate_chain.size() > 0) {
249     response.set_client_auth_certificate(certificate_chain[0]);
250     for (size_t i = 1; i < certificate_chain.size(); ++i)
251       response.add_intermediate_certificate(certificate_chain[i]);
252   }
253
254   response.set_crl(crl_bundle);
255
256   cast_certificate::CRLPolicy crl_policy =
257       cast_certificate::CRLPolicy::CRL_REQUIRED;
258   if (!crl_required && crl_bundle.empty())
259     crl_policy = cast_certificate::CRLPolicy::CRL_OPTIONAL;
260   AuthResult result =
261       VerifyCredentialsForTest(response, "", crl_policy, cast_trust_store,
262                                crl_trust_store, verification_time);
263   // This test doesn't set the signature so it will just fail there.
264   EXPECT_FALSE(result.success());
265   return result;
266 }
267
268 // Runs a single test case.
269 bool RunTest(const cast_certificate::DeviceCertTest& test_case) {
270   std::unique_ptr<net::TrustStore> crl_trust_store;
271   std::unique_ptr<net::TrustStore> cast_trust_store;
272   if (test_case.use_test_trust_anchors()) {
273     crl_trust_store = cast_certificate::testing::CreateTrustStoreFromFile(
274         "certificates/cast_crl_test_root_ca.pem");
275     cast_trust_store = cast_certificate::testing::CreateTrustStoreFromFile(
276         "certificates/cast_test_root_ca.pem");
277
278     EXPECT_TRUE(crl_trust_store.get());
279     EXPECT_TRUE(cast_trust_store.get());
280   }
281
282   std::vector<std::string> certificate_chain;
283   for (auto const& cert : test_case.der_cert_path()) {
284     certificate_chain.push_back(cert);
285   }
286
287   // CastAuthUtil verifies the CRL at the same time as the certificate.
288   base::Time verification_time;
289   uint64_t cert_verify_time = test_case.cert_verification_time_seconds();
290   if (cert_verify_time) {
291     verification_time = cast_certificate::testing::ConvertUnixTimestampSeconds(
292         cert_verify_time);
293   } else {
294     verification_time = cast_certificate::testing::ConvertUnixTimestampSeconds(
295         test_case.crl_verification_time_seconds());
296   }
297
298   std::string crl_bundle = test_case.crl_bundle();
299   AuthResult result;
300   switch (test_case.expected_result()) {
301     case cast_certificate::PATH_VERIFICATION_FAILED:
302       result = TestVerifyRevocation(
303           certificate_chain, crl_bundle, verification_time, false,
304           cast_trust_store.get(), crl_trust_store.get());
305       EXPECT_EQ(result.error_type,
306                 AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA);
307       return result.error_type ==
308              AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA;
309     case cast_certificate::CRL_VERIFICATION_FAILED:
310     // Fall-through intended.
311     case cast_certificate::REVOCATION_CHECK_FAILED_WITHOUT_CRL:
312       result = TestVerifyRevocation(
313           certificate_chain, crl_bundle, verification_time, true,
314           cast_trust_store.get(), crl_trust_store.get());
315       EXPECT_EQ(result.error_type, AuthResult::ERROR_CRL_INVALID);
316       return result.error_type == AuthResult::ERROR_CRL_INVALID;
317     case cast_certificate::CRL_EXPIRED_AFTER_INITIAL_VERIFICATION:
318       // By-pass this test because CRL is always verified at the time the
319       // certificate is verified.
320       return true;
321     case cast_certificate::REVOCATION_CHECK_FAILED:
322       result = TestVerifyRevocation(
323           certificate_chain, crl_bundle, verification_time, true,
324           cast_trust_store.get(), crl_trust_store.get());
325       EXPECT_EQ(result.error_type, AuthResult::ERROR_CERT_REVOKED);
326       return result.error_type == AuthResult::ERROR_CERT_REVOKED;
327     case cast_certificate::SUCCESS:
328       result = TestVerifyRevocation(
329           certificate_chain, crl_bundle, verification_time, false,
330           cast_trust_store.get(), crl_trust_store.get());
331       EXPECT_EQ(result.error_type, AuthResult::ERROR_SIGNED_BLOBS_MISMATCH);
332       return result.error_type == AuthResult::ERROR_SIGNED_BLOBS_MISMATCH;
333     case cast_certificate::UNSPECIFIED:
334       return false;
335   }
336   return false;
337 }
338
339 // Parses the provided test suite provided in wire-format proto.
340 // Each test contains the inputs and the expected output.
341 // To see the description of the test, execute the test.
342 // These tests are generated by a test generator in google3.
343 void RunTestSuite(const std::string& test_suite_file_name) {
344   std::string testsuite_raw =
345       cast_certificate::testing::ReadTestFileToString(test_suite_file_name);
346   cast_certificate::DeviceCertTestSuite test_suite;
347   EXPECT_TRUE(test_suite.ParseFromString(testsuite_raw));
348   uint16_t success = 0;
349   uint16_t failed = 0;
350   std::vector<std::string> failed_tests;
351
352   for (auto const& test_case : test_suite.tests()) {
353     LOG(INFO) << "[ RUN      ] " << test_case.description();
354     bool result = RunTest(test_case);
355     EXPECT_TRUE(result);
356     if (!result) {
357       LOG(INFO) << "[  FAILED  ] " << test_case.description();
358       ++failed;
359       failed_tests.push_back(test_case.description());
360     } else {
361       LOG(INFO) << "[  PASSED  ] " << test_case.description();
362       ++success;
363     }
364   }
365   LOG(INFO) << "[  PASSED  ] " << success << " test(s).";
366   if (failed) {
367     LOG(INFO) << "[  FAILED  ] " << failed << " test(s), listed below:";
368     for (const auto& failed_test : failed_tests) {
369       LOG(INFO) << "[  FAILED  ] " << failed_test;
370     }
371   }
372 }
373
374 TEST_F(CastAuthUtilTest, CRLTestSuite) {
375   RunTestSuite("testsuite/testsuite1.pb");
376 }
377
378 }  // namespace
379 }  // namespace cast_channel