xref: /aosp_15_r20/external/cronet/net/cert/internal/test_helpers.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/cert/internal/test_helpers.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/base_paths.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/path_service.h"
10*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
11*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/pool.h"
12*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/cert_errors.h"
13*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/pem.h"
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker namespace net {
16*6777b538SAndroid Build Coastguard Worker 
ReadTestDataFromPemFile(const std::string & file_path_ascii,const PemBlockMapping * mappings,size_t mappings_length)17*6777b538SAndroid Build Coastguard Worker ::testing::AssertionResult ReadTestDataFromPemFile(
18*6777b538SAndroid Build Coastguard Worker     const std::string& file_path_ascii,
19*6777b538SAndroid Build Coastguard Worker     const PemBlockMapping* mappings,
20*6777b538SAndroid Build Coastguard Worker     size_t mappings_length) {
21*6777b538SAndroid Build Coastguard Worker   std::string file_data = ReadTestFileToString(file_path_ascii);
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker   // mappings_copy is used to keep track of which mappings have already been
24*6777b538SAndroid Build Coastguard Worker   // satisfied (by nulling the |value| field). This is used to track when
25*6777b538SAndroid Build Coastguard Worker   // blocks are multiply defined.
26*6777b538SAndroid Build Coastguard Worker   std::vector<PemBlockMapping> mappings_copy(mappings,
27*6777b538SAndroid Build Coastguard Worker                                              mappings + mappings_length);
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker   // Build the |pem_headers| vector needed for PEMTokenzier.
30*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> pem_headers;
31*6777b538SAndroid Build Coastguard Worker   for (const auto& mapping : mappings_copy) {
32*6777b538SAndroid Build Coastguard Worker     pem_headers.push_back(mapping.block_name);
33*6777b538SAndroid Build Coastguard Worker   }
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker   bssl::PEMTokenizer pem_tokenizer(file_data, pem_headers);
36*6777b538SAndroid Build Coastguard Worker   while (pem_tokenizer.GetNext()) {
37*6777b538SAndroid Build Coastguard Worker     for (auto& mapping : mappings_copy) {
38*6777b538SAndroid Build Coastguard Worker       // Find the mapping for this block type.
39*6777b538SAndroid Build Coastguard Worker       if (pem_tokenizer.block_type() == mapping.block_name) {
40*6777b538SAndroid Build Coastguard Worker         if (!mapping.value) {
41*6777b538SAndroid Build Coastguard Worker           return ::testing::AssertionFailure()
42*6777b538SAndroid Build Coastguard Worker                  << "PEM block defined multiple times: " << mapping.block_name;
43*6777b538SAndroid Build Coastguard Worker         }
44*6777b538SAndroid Build Coastguard Worker 
45*6777b538SAndroid Build Coastguard Worker         // Copy the data to the result.
46*6777b538SAndroid Build Coastguard Worker         mapping.value->assign(pem_tokenizer.data());
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker         // Mark the mapping as having been satisfied.
49*6777b538SAndroid Build Coastguard Worker         mapping.value = nullptr;
50*6777b538SAndroid Build Coastguard Worker       }
51*6777b538SAndroid Build Coastguard Worker     }
52*6777b538SAndroid Build Coastguard Worker   }
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   // Ensure that all specified blocks were found.
55*6777b538SAndroid Build Coastguard Worker   for (const auto& mapping : mappings_copy) {
56*6777b538SAndroid Build Coastguard Worker     if (mapping.value && !mapping.optional) {
57*6777b538SAndroid Build Coastguard Worker       return ::testing::AssertionFailure()
58*6777b538SAndroid Build Coastguard Worker              << "PEM block missing: " << mapping.block_name;
59*6777b538SAndroid Build Coastguard Worker     }
60*6777b538SAndroid Build Coastguard Worker   }
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker   return ::testing::AssertionSuccess();
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker 
ReadCertChainFromFile(const std::string & file_path_ascii,bssl::ParsedCertificateList * chain)65*6777b538SAndroid Build Coastguard Worker bool ReadCertChainFromFile(const std::string& file_path_ascii,
66*6777b538SAndroid Build Coastguard Worker                            bssl::ParsedCertificateList* chain) {
67*6777b538SAndroid Build Coastguard Worker   // Reset all the out parameters to their defaults.
68*6777b538SAndroid Build Coastguard Worker   chain->clear();
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker   std::string file_data = ReadTestFileToString(file_path_ascii);
71*6777b538SAndroid Build Coastguard Worker   if (file_data.empty()) {
72*6777b538SAndroid Build Coastguard Worker     return false;
73*6777b538SAndroid Build Coastguard Worker   }
74*6777b538SAndroid Build Coastguard Worker 
75*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> pem_headers = {"CERTIFICATE"};
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker   bssl::PEMTokenizer pem_tokenizer(file_data, pem_headers);
78*6777b538SAndroid Build Coastguard Worker   while (pem_tokenizer.GetNext()) {
79*6777b538SAndroid Build Coastguard Worker     const std::string& block_data = pem_tokenizer.data();
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker     bssl::CertErrors errors;
82*6777b538SAndroid Build Coastguard Worker     if (!bssl::ParsedCertificate::CreateAndAddToVector(
83*6777b538SAndroid Build Coastguard Worker             bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
84*6777b538SAndroid Build Coastguard Worker                 reinterpret_cast<const uint8_t*>(block_data.data()),
85*6777b538SAndroid Build Coastguard Worker                 block_data.size(), nullptr)),
86*6777b538SAndroid Build Coastguard Worker             {}, chain, &errors)) {
87*6777b538SAndroid Build Coastguard Worker       ADD_FAILURE() << errors.ToDebugString();
88*6777b538SAndroid Build Coastguard Worker       return false;
89*6777b538SAndroid Build Coastguard Worker     }
90*6777b538SAndroid Build Coastguard Worker   }
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   return true;
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker 
ReadCertFromFile(const std::string & file_path_ascii)95*6777b538SAndroid Build Coastguard Worker std::shared_ptr<const bssl::ParsedCertificate> ReadCertFromFile(
96*6777b538SAndroid Build Coastguard Worker     const std::string& file_path_ascii) {
97*6777b538SAndroid Build Coastguard Worker   bssl::ParsedCertificateList chain;
98*6777b538SAndroid Build Coastguard Worker   if (!ReadCertChainFromFile(file_path_ascii, &chain)) {
99*6777b538SAndroid Build Coastguard Worker     return nullptr;
100*6777b538SAndroid Build Coastguard Worker   }
101*6777b538SAndroid Build Coastguard Worker   if (chain.size() != 1) {
102*6777b538SAndroid Build Coastguard Worker     return nullptr;
103*6777b538SAndroid Build Coastguard Worker   }
104*6777b538SAndroid Build Coastguard Worker   return chain[0];
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker 
ReadTestFileToString(const std::string & file_path_ascii)107*6777b538SAndroid Build Coastguard Worker std::string ReadTestFileToString(const std::string& file_path_ascii) {
108*6777b538SAndroid Build Coastguard Worker   // Compute the full path, relative to the src/ directory.
109*6777b538SAndroid Build Coastguard Worker   base::FilePath src_root;
110*6777b538SAndroid Build Coastguard Worker   base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &src_root);
111*6777b538SAndroid Build Coastguard Worker   base::FilePath filepath = src_root.AppendASCII(file_path_ascii);
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker   // Read the full contents of the file.
114*6777b538SAndroid Build Coastguard Worker   std::string file_data;
115*6777b538SAndroid Build Coastguard Worker   if (!base::ReadFileToString(filepath, &file_data)) {
116*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE() << "Couldn't read file: " << filepath.value();
117*6777b538SAndroid Build Coastguard Worker     return std::string();
118*6777b538SAndroid Build Coastguard Worker   }
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker   return file_data;
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker }  // namespace net
124