cert_verify_proc_android_unittest.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // Copyright 2017 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. #include "net/cert/cert_verify_proc_android.h"
  5. #include <memory>
  6. #include <vector>
  7. #include "net/cert/cert_net_fetcher.h"
  8. #include "net/cert/cert_verify_proc_android.h"
  9. #include "net/cert/cert_verify_result.h"
  10. #include "net/cert/crl_set.h"
  11. #include "net/cert/mock_cert_net_fetcher.h"
  12. #include "net/cert/pki/test_helpers.h"
  13. #include "net/cert/test_root_certs.h"
  14. #include "net/cert/x509_certificate.h"
  15. #include "net/cert/x509_util.h"
  16. #include "net/log/net_log_with_source.h"
  17. #include "net/test/cert_test_util.h"
  18. #include "net/test/test_certificate_data.h"
  19. #include "net/test/test_data_directory.h"
  20. #include "testing/gmock/include/gmock/gmock-matchers.h"
  21. #include "testing/gmock/include/gmock/gmock.h"
  22. #include "testing/gtest/include/gtest/gtest.h"
  23. #include "url/gurl.h"
  24. using ::testing::ByMove;
  25. using ::testing::Return;
  26. using ::testing::_;
  27. namespace net {
  28. namespace {
  29. std::unique_ptr<CertNetFetcher::Request>
  30. CreateMockRequestWithInvalidCertificate() {
  31. return MockCertNetFetcherRequest::Create(std::vector<uint8_t>({1, 2, 3}));
  32. }
  33. ::testing::AssertionResult ReadTestPem(const std::string& file_name,
  34. const std::string& block_name,
  35. std::string* result) {
  36. const PemBlockMapping mappings[] = {
  37. {block_name.c_str(), result},
  38. };
  39. return ReadTestDataFromPemFile(file_name, mappings);
  40. }
  41. ::testing::AssertionResult ReadTestCert(
  42. const std::string& file_name,
  43. scoped_refptr<X509Certificate>* result) {
  44. std::string der;
  45. ::testing::AssertionResult r =
  46. ReadTestPem("net/data/cert_issuer_source_aia_unittest/" + file_name,
  47. "CERTIFICATE", &der);
  48. if (!r)
  49. return r;
  50. *result =
  51. X509Certificate::CreateFromBytes(base::as_bytes(base::make_span(der)));
  52. if (!result) {
  53. return ::testing::AssertionFailure()
  54. << "X509Certificate::CreateFromBytes() failed";
  55. }
  56. return ::testing::AssertionSuccess();
  57. }
  58. ::testing::AssertionResult ReadTestAIARoot(
  59. scoped_refptr<X509Certificate>* result) {
  60. return ReadTestCert("root.pem", result);
  61. }
  62. ::testing::AssertionResult CreateCertificateChainFromFiles(
  63. const std::vector<std::string>& files,
  64. scoped_refptr<X509Certificate>* result) {
  65. scoped_refptr<X509Certificate> leaf;
  66. ::testing::AssertionResult r = ReadTestCert(files[0], &leaf);
  67. if (!r)
  68. return r;
  69. std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_buffers;
  70. for (size_t i = 1; i < files.size(); i++) {
  71. scoped_refptr<X509Certificate> intermediate;
  72. r = ReadTestCert(files[i], &intermediate);
  73. if (!r)
  74. return r;
  75. intermediate_buffers.push_back(bssl::UpRef(intermediate->cert_buffer()));
  76. }
  77. *result = X509Certificate::CreateFromBuffer(bssl::UpRef(leaf->cert_buffer()),
  78. std::move(intermediate_buffers));
  79. return ::testing::AssertionSuccess();
  80. }
  81. // A test fixture for testing CertVerifyProcAndroid AIA fetching. It creates,
  82. // sets up, and shuts down a MockCertNetFetcher for CertVerifyProcAndroid to
  83. // use, and enables the field trial for AIA fetching.
  84. class CertVerifyProcAndroidTestWithAIAFetching : public testing::Test {
  85. public:
  86. void SetUp() override {
  87. fetcher_ = base::MakeRefCounted<MockCertNetFetcher>();
  88. }
  89. void TearDown() override {
  90. // Ensure that mock expectations are checked, since the CertNetFetcher is
  91. // global and leaky.
  92. ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(fetcher_.get()));
  93. }
  94. protected:
  95. ::testing::AssertionResult SetUpTestRoot() {
  96. ::testing::AssertionResult r = ReadTestAIARoot(&root_);
  97. if (!r)
  98. return r;
  99. scoped_test_root_ = std::make_unique<ScopedTestRoot>(root_.get());
  100. return ::testing::AssertionSuccess();
  101. }
  102. scoped_refptr<MockCertNetFetcher> fetcher_;
  103. const CertificateList empty_cert_list_;
  104. private:
  105. scoped_refptr<X509Certificate> root_;
  106. std::unique_ptr<ScopedTestRoot> scoped_test_root_;
  107. };
  108. } // namespace
  109. // Tests that if the proper intermediates are supplied in the server-sent chain,
  110. // no AIA fetch occurs.
  111. TEST_F(CertVerifyProcAndroidTestWithAIAFetching,
  112. NoFetchIfProperIntermediatesSupplied) {
  113. ASSERT_TRUE(SetUpTestRoot());
  114. scoped_refptr<CertVerifyProcAndroid> proc =
  115. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  116. scoped_refptr<X509Certificate> leaf;
  117. ASSERT_TRUE(
  118. CreateCertificateChainFromFiles({"target_one_aia.pem", "i.pem"}, &leaf));
  119. CertVerifyResult verify_result;
  120. EXPECT_EQ(
  121. OK,
  122. proc->Verify(leaf.get(), "target", /*ocsp_response=*/std::string(),
  123. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  124. empty_cert_list_, &verify_result, NetLogWithSource()));
  125. }
  126. // Tests that if the certificate does not contain an AIA URL, no AIA fetch
  127. // occurs.
  128. TEST_F(CertVerifyProcAndroidTestWithAIAFetching, NoAIAURL) {
  129. ASSERT_TRUE(SetUpTestRoot());
  130. scoped_refptr<CertVerifyProcAndroid> proc =
  131. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  132. scoped_refptr<X509Certificate> cert;
  133. ASSERT_TRUE(ReadTestCert("target_no_aia.pem", &cert));
  134. CertVerifyResult verify_result;
  135. EXPECT_EQ(
  136. ERR_CERT_AUTHORITY_INVALID,
  137. proc->Verify(cert.get(), "target", /*ocsp_response=*/std::string(),
  138. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  139. empty_cert_list_, &verify_result, NetLogWithSource()));
  140. }
  141. // Tests that if a certificate contains one file:// URL and one http:// URL,
  142. // there are two fetches, with the latter resulting in a successful
  143. // verification.
  144. TEST_F(CertVerifyProcAndroidTestWithAIAFetching, OneFileAndOneHTTPURL) {
  145. ASSERT_TRUE(SetUpTestRoot());
  146. scoped_refptr<CertVerifyProcAndroid> proc =
  147. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  148. scoped_refptr<X509Certificate> cert;
  149. ASSERT_TRUE(ReadTestCert("target_file_and_http_aia.pem", &cert));
  150. scoped_refptr<X509Certificate> intermediate;
  151. ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate));
  152. // Expect two fetches: the file:// URL (which returns an error), and the
  153. // http:// URL that returns a valid intermediate signed by |root_|. Though the
  154. // intermediate itself contains an AIA URL, it should not be fetched because
  155. // |root_| is in the test trust store.
  156. EXPECT_CALL(*fetcher_, FetchCaIssuers(GURL("file:///dev/null"), _, _))
  157. .WillOnce(Return(ByMove(
  158. MockCertNetFetcherRequest::Create(ERR_DISALLOWED_URL_SCHEME))));
  159. EXPECT_CALL(*fetcher_,
  160. FetchCaIssuers(GURL("http://url-for-aia2/I2.foo"), _, _))
  161. .WillOnce(Return(ByMove(
  162. MockCertNetFetcherRequest::Create(intermediate->cert_buffer()))));
  163. CertVerifyResult verify_result;
  164. EXPECT_EQ(
  165. OK,
  166. proc->Verify(cert.get(), "target", /*ocsp_response=*/std::string(),
  167. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  168. empty_cert_list_, &verify_result, NetLogWithSource()));
  169. }
  170. // Tests that if an AIA request returns the wrong intermediate, certificate
  171. // verification should fail.
  172. TEST_F(CertVerifyProcAndroidTestWithAIAFetching,
  173. UnsuccessfulVerificationWithLeafOnly) {
  174. ASSERT_TRUE(SetUpTestRoot());
  175. scoped_refptr<CertVerifyProcAndroid> proc =
  176. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  177. scoped_refptr<X509Certificate> cert;
  178. ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
  179. const scoped_refptr<X509Certificate> bad_intermediate =
  180. ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
  181. EXPECT_CALL(*fetcher_, FetchCaIssuers(GURL("http://url-for-aia/I.cer"), _, _))
  182. .WillOnce(Return(ByMove(
  183. MockCertNetFetcherRequest::Create(bad_intermediate->cert_buffer()))));
  184. CertVerifyResult verify_result;
  185. EXPECT_EQ(
  186. ERR_CERT_AUTHORITY_INVALID,
  187. proc->Verify(cert.get(), "target", /*ocsp_response=*/std::string(),
  188. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  189. empty_cert_list_, &verify_result, NetLogWithSource()));
  190. }
  191. // Tests that if an AIA request returns an error, certificate verification
  192. // should fail.
  193. TEST_F(CertVerifyProcAndroidTestWithAIAFetching,
  194. UnsuccessfulVerificationWithLeafOnlyAndErrorOnFetch) {
  195. ASSERT_TRUE(SetUpTestRoot());
  196. scoped_refptr<CertVerifyProcAndroid> proc =
  197. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  198. scoped_refptr<X509Certificate> cert;
  199. ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
  200. EXPECT_CALL(*fetcher_, FetchCaIssuers(GURL("http://url-for-aia/I.cer"), _, _))
  201. .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(ERR_FAILED))));
  202. CertVerifyResult verify_result;
  203. EXPECT_EQ(
  204. ERR_CERT_AUTHORITY_INVALID,
  205. proc->Verify(cert.get(), "target", /*ocsp_response=*/std::string(),
  206. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  207. empty_cert_list_, &verify_result, NetLogWithSource()));
  208. }
  209. // Tests that if an AIA request returns an unparseable cert, certificate
  210. // verification should fail.
  211. TEST_F(CertVerifyProcAndroidTestWithAIAFetching,
  212. UnsuccessfulVerificationWithLeafOnlyAndUnparseableFetch) {
  213. ASSERT_TRUE(SetUpTestRoot());
  214. scoped_refptr<CertVerifyProcAndroid> proc =
  215. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  216. scoped_refptr<X509Certificate> cert;
  217. ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
  218. EXPECT_CALL(*fetcher_, FetchCaIssuers(GURL("http://url-for-aia/I.cer"), _, _))
  219. .WillOnce(Return(ByMove(CreateMockRequestWithInvalidCertificate())));
  220. CertVerifyResult verify_result;
  221. EXPECT_EQ(
  222. ERR_CERT_AUTHORITY_INVALID,
  223. proc->Verify(cert.get(), "target", /*ocsp_response=*/std::string(),
  224. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  225. empty_cert_list_, &verify_result, NetLogWithSource()));
  226. }
  227. // Tests that if a certificate has two HTTP AIA URLs, they are both fetched. If
  228. // one serves an unrelated certificate and one serves a proper intermediate, the
  229. // latter should be used to build a valid chain.
  230. TEST_F(CertVerifyProcAndroidTestWithAIAFetching, TwoHTTPURLs) {
  231. ASSERT_TRUE(SetUpTestRoot());
  232. scoped_refptr<CertVerifyProcAndroid> proc =
  233. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  234. scoped_refptr<X509Certificate> cert;
  235. ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
  236. scoped_refptr<X509Certificate> intermediate;
  237. ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate));
  238. scoped_refptr<X509Certificate> unrelated;
  239. ASSERT_TRUE(ReadTestCert("target_three_aia.pem", &unrelated));
  240. // Expect two fetches, the first of which returns an unrelated certificate
  241. // that is not useful in chain-building, and the second of which returns a
  242. // valid intermediate signed by |root_|. Though the intermediate itself
  243. // contains an AIA URL, it should not be fetched because |root_| is in the
  244. // trust store.
  245. EXPECT_CALL(*fetcher_, FetchCaIssuers(GURL("http://url-for-aia/I.cer"), _, _))
  246. .WillOnce(Return(
  247. ByMove(MockCertNetFetcherRequest::Create(unrelated->cert_buffer()))));
  248. EXPECT_CALL(*fetcher_,
  249. FetchCaIssuers(GURL("http://url-for-aia2/I2.foo"), _, _))
  250. .WillOnce(Return(ByMove(
  251. MockCertNetFetcherRequest::Create(intermediate->cert_buffer()))));
  252. CertVerifyResult verify_result;
  253. EXPECT_EQ(
  254. OK,
  255. proc->Verify(cert.get(), "target", /*ocsp_response=*/std::string(),
  256. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  257. empty_cert_list_, &verify_result, NetLogWithSource()));
  258. }
  259. // Tests that if an intermediate is fetched via AIA, and the intermediate itself
  260. // has an AIA URL, that URL is fetched if necessary.
  261. TEST_F(CertVerifyProcAndroidTestWithAIAFetching,
  262. AIAFetchForFetchedIntermediate) {
  263. // Do not set up the test root to be trusted. If the test root were trusted,
  264. // then the intermediate i2.pem would not require an AIA fetch. With the test
  265. // root untrusted, i2.pem does not verify and so it will trigger an AIA fetch.
  266. scoped_refptr<CertVerifyProcAndroid> proc =
  267. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  268. scoped_refptr<X509Certificate> cert;
  269. ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
  270. scoped_refptr<X509Certificate> intermediate;
  271. ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate));
  272. scoped_refptr<X509Certificate> root;
  273. ASSERT_TRUE(ReadTestAIARoot(&root));
  274. // Expect two fetches, the first of which returns an intermediate that itself
  275. // has an AIA URL.
  276. EXPECT_CALL(*fetcher_, FetchCaIssuers(GURL("http://url-for-aia/I.cer"), _, _))
  277. .WillOnce(Return(ByMove(
  278. MockCertNetFetcherRequest::Create(intermediate->cert_buffer()))));
  279. EXPECT_CALL(*fetcher_,
  280. FetchCaIssuers(GURL("http://url-for-aia/Root.cer"), _, _))
  281. .WillOnce(Return(
  282. ByMove(MockCertNetFetcherRequest::Create(root->cert_buffer()))));
  283. CertVerifyResult verify_result;
  284. // This chain results in an AUTHORITY_INVALID root because |root_| is not
  285. // trusted.
  286. EXPECT_EQ(
  287. ERR_CERT_AUTHORITY_INVALID,
  288. proc->Verify(cert.get(), "target", /*ocsp_response=*/std::string(),
  289. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  290. empty_cert_list_, &verify_result, NetLogWithSource()));
  291. }
  292. // Tests that if a certificate contains six AIA URLs, only the first five are
  293. // fetched, since the maximum number of fetches per Verify() call is five.
  294. TEST_F(CertVerifyProcAndroidTestWithAIAFetching, MaxAIAFetches) {
  295. ASSERT_TRUE(SetUpTestRoot());
  296. scoped_refptr<CertVerifyProcAndroid> proc =
  297. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  298. scoped_refptr<X509Certificate> cert;
  299. ASSERT_TRUE(ReadTestCert("target_six_aia.pem", &cert));
  300. EXPECT_CALL(*fetcher_, FetchCaIssuers(_, _, _))
  301. .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(ERR_FAILED))))
  302. .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(ERR_FAILED))))
  303. .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(ERR_FAILED))))
  304. .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(ERR_FAILED))))
  305. .WillOnce(Return(ByMove(MockCertNetFetcherRequest::Create(ERR_FAILED))));
  306. CertVerifyResult verify_result;
  307. EXPECT_EQ(
  308. ERR_CERT_AUTHORITY_INVALID,
  309. proc->Verify(cert.get(), "target", /*ocsp_response=*/std::string(),
  310. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  311. empty_cert_list_, &verify_result, NetLogWithSource()));
  312. }
  313. // Tests that if the supplied chain contains an intermediate with an AIA URL,
  314. // that AIA URL is fetched if necessary.
  315. TEST_F(CertVerifyProcAndroidTestWithAIAFetching, FetchForSuppliedIntermediate) {
  316. // Do not set up the test root to be trusted. If the test root were trusted,
  317. // then the intermediate i.pem would not require an AIA fetch. With the test
  318. // root untrusted, i.pem does not verify and so it will trigger an AIA fetch.
  319. scoped_refptr<CertVerifyProcAndroid> proc =
  320. base::MakeRefCounted<CertVerifyProcAndroid>(fetcher_);
  321. scoped_refptr<X509Certificate> leaf;
  322. ASSERT_TRUE(
  323. CreateCertificateChainFromFiles({"target_one_aia.pem", "i.pem"}, &leaf));
  324. scoped_refptr<X509Certificate> root;
  325. ASSERT_TRUE(ReadTestAIARoot(&root));
  326. EXPECT_CALL(*fetcher_,
  327. FetchCaIssuers(GURL("http://url-for-aia/Root.cer"), _, _))
  328. .WillOnce(Return(
  329. ByMove(MockCertNetFetcherRequest::Create(root->cert_buffer()))));
  330. CertVerifyResult verify_result;
  331. // This chain results in an AUTHORITY_INVALID root because |root_| is not
  332. // trusted.
  333. EXPECT_EQ(
  334. ERR_CERT_AUTHORITY_INVALID,
  335. proc->Verify(leaf.get(), "target", /*ocsp_response=*/std::string(),
  336. /*sct_list=*/std::string(), 0, CRLSet::BuiltinCRLSet().get(),
  337. empty_cert_list_, &verify_result, NetLogWithSource()));
  338. }
  339. } // namespace net