xref: /aosp_15_r20/external/cronet/net/test/cert_builder.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2019 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/test/cert_builder.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <map>
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <optional>
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker #include <string_view>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker #include <vector>
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/memory/scoped_refptr.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/ranges/algorithm.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
23*6777b538SAndroid Build Coastguard Worker #include "crypto/ec_private_key.h"
24*6777b538SAndroid Build Coastguard Worker #include "crypto/openssl_util.h"
25*6777b538SAndroid Build Coastguard Worker #include "crypto/rsa_private_key.h"
26*6777b538SAndroid Build Coastguard Worker #include "crypto/sha2.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/cert/asn1_util.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/cert/ct_objects_extractor.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/cert/ct_serialization.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/cert/signed_certificate_timestamp.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/cert/time_conversions.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/cert/x509_util.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/test/cert_test_util.h"
34*6777b538SAndroid Build Coastguard Worker #include "net/test/key_util.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/test/test_data_directory.h"
36*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
37*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/evp.h"
38*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/mem.h"
39*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/certificate_policies.h"
40*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/extended_key_usage.h"
41*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/input.h"
42*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/parse_certificate.h"
43*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/parse_values.h"
44*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/parser.h"
45*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/verify_signed_data.h"
46*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker namespace net {
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker namespace {
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker constexpr char kSimpleChainHostname[] = "www.example.com";
53*6777b538SAndroid Build Coastguard Worker 
Sha256WithRSAEncryption()54*6777b538SAndroid Build Coastguard Worker std::string Sha256WithRSAEncryption() {
55*6777b538SAndroid Build Coastguard Worker   const uint8_t kSha256WithRSAEncryption[] = {0x30, 0x0D, 0x06, 0x09, 0x2a,
56*6777b538SAndroid Build Coastguard Worker                                               0x86, 0x48, 0x86, 0xf7, 0x0d,
57*6777b538SAndroid Build Coastguard Worker                                               0x01, 0x01, 0x0b, 0x05, 0x00};
58*6777b538SAndroid Build Coastguard Worker   return std::string(std::begin(kSha256WithRSAEncryption),
59*6777b538SAndroid Build Coastguard Worker                      std::end(kSha256WithRSAEncryption));
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker 
Sha1WithRSAEncryption()62*6777b538SAndroid Build Coastguard Worker std::string Sha1WithRSAEncryption() {
63*6777b538SAndroid Build Coastguard Worker   const uint8_t kSha1WithRSAEncryption[] = {0x30, 0x0D, 0x06, 0x09, 0x2a,
64*6777b538SAndroid Build Coastguard Worker                                             0x86, 0x48, 0x86, 0xf7, 0x0d,
65*6777b538SAndroid Build Coastguard Worker                                             0x01, 0x01, 0x05, 0x05, 0x00};
66*6777b538SAndroid Build Coastguard Worker   return std::string(std::begin(kSha1WithRSAEncryption),
67*6777b538SAndroid Build Coastguard Worker                      std::end(kSha1WithRSAEncryption));
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker 
EcdsaWithSha256()70*6777b538SAndroid Build Coastguard Worker std::string EcdsaWithSha256() {
71*6777b538SAndroid Build Coastguard Worker   const uint8_t kDer[] = {0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86,
72*6777b538SAndroid Build Coastguard Worker                           0x48, 0xce, 0x3d, 0x04, 0x03, 0x02};
73*6777b538SAndroid Build Coastguard Worker   return std::string(std::begin(kDer), std::end(kDer));
74*6777b538SAndroid Build Coastguard Worker }
75*6777b538SAndroid Build Coastguard Worker 
EcdsaWithSha1()76*6777b538SAndroid Build Coastguard Worker std::string EcdsaWithSha1() {
77*6777b538SAndroid Build Coastguard Worker   const uint8_t kDer[] = {0x30, 0x09, 0x06, 0x07, 0x2a, 0x86,
78*6777b538SAndroid Build Coastguard Worker                           0x48, 0xce, 0x3d, 0x04, 0x01};
79*6777b538SAndroid Build Coastguard Worker   return std::string(std::begin(kDer), std::end(kDer));
80*6777b538SAndroid Build Coastguard Worker }
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker // Adds bytes (specified as a StringPiece) to the given CBB.
83*6777b538SAndroid Build Coastguard Worker // The argument ordering follows the boringssl CBB_* api style.
CBBAddBytes(CBB * cbb,std::string_view bytes)84*6777b538SAndroid Build Coastguard Worker bool CBBAddBytes(CBB* cbb, std::string_view bytes) {
85*6777b538SAndroid Build Coastguard Worker   return CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(bytes.data()),
86*6777b538SAndroid Build Coastguard Worker                        bytes.size());
87*6777b538SAndroid Build Coastguard Worker }
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker // Adds bytes (from fixed size array) to the given CBB.
90*6777b538SAndroid Build Coastguard Worker // The argument ordering follows the boringssl CBB_* api style.
91*6777b538SAndroid Build Coastguard Worker template <size_t N>
CBBAddBytes(CBB * cbb,const uint8_t (& data)[N])92*6777b538SAndroid Build Coastguard Worker bool CBBAddBytes(CBB* cbb, const uint8_t (&data)[N]) {
93*6777b538SAndroid Build Coastguard Worker   return CBB_add_bytes(cbb, data, N);
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker // Finalizes the CBB to a std::string.
FinishCBB(CBB * cbb)97*6777b538SAndroid Build Coastguard Worker std::string FinishCBB(CBB* cbb) {
98*6777b538SAndroid Build Coastguard Worker   size_t cbb_len;
99*6777b538SAndroid Build Coastguard Worker   uint8_t* cbb_bytes;
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker   if (!CBB_finish(cbb, &cbb_bytes, &cbb_len)) {
102*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE() << "CBB_finish() failed";
103*6777b538SAndroid Build Coastguard Worker     return std::string();
104*6777b538SAndroid Build Coastguard Worker   }
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> delete_bytes(cbb_bytes);
107*6777b538SAndroid Build Coastguard Worker   return std::string(reinterpret_cast<char*>(cbb_bytes), cbb_len);
108*6777b538SAndroid Build Coastguard Worker }
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker // Finalizes the CBB to a std::vector.
FinishCBBToVector(CBB * cbb)111*6777b538SAndroid Build Coastguard Worker std::vector<uint8_t> FinishCBBToVector(CBB* cbb) {
112*6777b538SAndroid Build Coastguard Worker   size_t cbb_len;
113*6777b538SAndroid Build Coastguard Worker   uint8_t* cbb_bytes;
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   if (!CBB_finish(cbb, &cbb_bytes, &cbb_len)) {
116*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE() << "CBB_finish() failed";
117*6777b538SAndroid Build Coastguard Worker     return {};
118*6777b538SAndroid Build Coastguard Worker   }
119*6777b538SAndroid Build Coastguard Worker 
120*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> delete_bytes(cbb_bytes);
121*6777b538SAndroid Build Coastguard Worker   return std::vector<uint8_t>(cbb_bytes, cbb_bytes + cbb_len);
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker }  // namespace
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker CertBuilder::SctConfig::SctConfig() = default;
SctConfig(std::string log_id,bssl::UniquePtr<EVP_PKEY> log_key,base::Time timestamp)127*6777b538SAndroid Build Coastguard Worker CertBuilder::SctConfig::SctConfig(std::string log_id,
128*6777b538SAndroid Build Coastguard Worker                                   bssl::UniquePtr<EVP_PKEY> log_key,
129*6777b538SAndroid Build Coastguard Worker                                   base::Time timestamp)
130*6777b538SAndroid Build Coastguard Worker     : log_id(std::move(log_id)),
131*6777b538SAndroid Build Coastguard Worker       log_key(std::move(log_key)),
132*6777b538SAndroid Build Coastguard Worker       timestamp(timestamp) {}
SctConfig(const SctConfig & other)133*6777b538SAndroid Build Coastguard Worker CertBuilder::SctConfig::SctConfig(const SctConfig& other)
134*6777b538SAndroid Build Coastguard Worker     : SctConfig(other.log_id,
135*6777b538SAndroid Build Coastguard Worker                 bssl::UpRef(other.log_key.get()),
136*6777b538SAndroid Build Coastguard Worker                 other.timestamp) {}
137*6777b538SAndroid Build Coastguard Worker CertBuilder::SctConfig::SctConfig(SctConfig&&) = default;
138*6777b538SAndroid Build Coastguard Worker CertBuilder::SctConfig::~SctConfig() = default;
operator =(const SctConfig & other)139*6777b538SAndroid Build Coastguard Worker CertBuilder::SctConfig& CertBuilder::SctConfig::operator=(
140*6777b538SAndroid Build Coastguard Worker     const SctConfig& other) {
141*6777b538SAndroid Build Coastguard Worker   log_id = other.log_id;
142*6777b538SAndroid Build Coastguard Worker   log_key = bssl::UpRef(other.log_key.get());
143*6777b538SAndroid Build Coastguard Worker   timestamp = other.timestamp;
144*6777b538SAndroid Build Coastguard Worker   return *this;
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker CertBuilder::SctConfig& CertBuilder::SctConfig::operator=(SctConfig&&) =
147*6777b538SAndroid Build Coastguard Worker     default;
148*6777b538SAndroid Build Coastguard Worker 
CertBuilder(CRYPTO_BUFFER * orig_cert,CertBuilder * issuer)149*6777b538SAndroid Build Coastguard Worker CertBuilder::CertBuilder(CRYPTO_BUFFER* orig_cert, CertBuilder* issuer)
150*6777b538SAndroid Build Coastguard Worker     : CertBuilder(orig_cert, issuer, /*unique_subject_key_identifier=*/true) {}
151*6777b538SAndroid Build Coastguard Worker 
152*6777b538SAndroid Build Coastguard Worker // static
FromFile(const base::FilePath & cert_and_key_file,CertBuilder * issuer)153*6777b538SAndroid Build Coastguard Worker std::unique_ptr<CertBuilder> CertBuilder::FromFile(
154*6777b538SAndroid Build Coastguard Worker     const base::FilePath& cert_and_key_file,
155*6777b538SAndroid Build Coastguard Worker     CertBuilder* issuer) {
156*6777b538SAndroid Build Coastguard Worker   scoped_refptr<X509Certificate> cert = ImportCertFromFile(cert_and_key_file);
157*6777b538SAndroid Build Coastguard Worker   if (!cert)
158*6777b538SAndroid Build Coastguard Worker     return nullptr;
159*6777b538SAndroid Build Coastguard Worker 
160*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> private_key(
161*6777b538SAndroid Build Coastguard Worker       key_util::LoadEVP_PKEYFromPEM(cert_and_key_file));
162*6777b538SAndroid Build Coastguard Worker   if (!private_key)
163*6777b538SAndroid Build Coastguard Worker     return nullptr;
164*6777b538SAndroid Build Coastguard Worker 
165*6777b538SAndroid Build Coastguard Worker   auto builder = base::WrapUnique(new CertBuilder(cert->cert_buffer(), issuer));
166*6777b538SAndroid Build Coastguard Worker   builder->key_ = std::move(private_key);
167*6777b538SAndroid Build Coastguard Worker   return builder;
168*6777b538SAndroid Build Coastguard Worker }
169*6777b538SAndroid Build Coastguard Worker 
170*6777b538SAndroid Build Coastguard Worker // static
FromStaticCert(CRYPTO_BUFFER * cert,EVP_PKEY * key)171*6777b538SAndroid Build Coastguard Worker std::unique_ptr<CertBuilder> CertBuilder::FromStaticCert(CRYPTO_BUFFER* cert,
172*6777b538SAndroid Build Coastguard Worker                                                          EVP_PKEY* key) {
173*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<CertBuilder> builder = base::WrapUnique(
174*6777b538SAndroid Build Coastguard Worker       new CertBuilder(cert, nullptr, /*unique_subject_key_identifier=*/false));
175*6777b538SAndroid Build Coastguard Worker   // |cert_|, |key_|, and |subject_tlv_| must be initialized for |builder| to
176*6777b538SAndroid Build Coastguard Worker   // function as the |issuer| of another CertBuilder.
177*6777b538SAndroid Build Coastguard Worker   builder->cert_ = bssl::UpRef(cert);
178*6777b538SAndroid Build Coastguard Worker   builder->key_ = bssl::UpRef(key);
179*6777b538SAndroid Build Coastguard Worker   std::string_view subject_tlv;
180*6777b538SAndroid Build Coastguard Worker   CHECK(asn1::ExtractSubjectFromDERCert(
181*6777b538SAndroid Build Coastguard Worker       x509_util::CryptoBufferAsStringPiece(cert), &subject_tlv));
182*6777b538SAndroid Build Coastguard Worker   builder->subject_tlv_ = std::string(subject_tlv);
183*6777b538SAndroid Build Coastguard Worker   return builder;
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker // static
FromStaticCertFile(const base::FilePath & cert_and_key_file)187*6777b538SAndroid Build Coastguard Worker std::unique_ptr<CertBuilder> CertBuilder::FromStaticCertFile(
188*6777b538SAndroid Build Coastguard Worker     const base::FilePath& cert_and_key_file) {
189*6777b538SAndroid Build Coastguard Worker   scoped_refptr<X509Certificate> cert = ImportCertFromFile(cert_and_key_file);
190*6777b538SAndroid Build Coastguard Worker   if (!cert)
191*6777b538SAndroid Build Coastguard Worker     return nullptr;
192*6777b538SAndroid Build Coastguard Worker 
193*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> private_key(
194*6777b538SAndroid Build Coastguard Worker       key_util::LoadEVP_PKEYFromPEM(cert_and_key_file));
195*6777b538SAndroid Build Coastguard Worker   if (!private_key)
196*6777b538SAndroid Build Coastguard Worker     return nullptr;
197*6777b538SAndroid Build Coastguard Worker 
198*6777b538SAndroid Build Coastguard Worker   return CertBuilder::FromStaticCert(cert->cert_buffer(), private_key.get());
199*6777b538SAndroid Build Coastguard Worker }
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker // static
FromSubjectPublicKeyInfo(base::span<const uint8_t> spki_der,CertBuilder * issuer)202*6777b538SAndroid Build Coastguard Worker std::unique_ptr<CertBuilder> CertBuilder::FromSubjectPublicKeyInfo(
203*6777b538SAndroid Build Coastguard Worker     base::span<const uint8_t> spki_der,
204*6777b538SAndroid Build Coastguard Worker     CertBuilder* issuer) {
205*6777b538SAndroid Build Coastguard Worker   DCHECK(issuer);
206*6777b538SAndroid Build Coastguard Worker   auto builder = std::make_unique<CertBuilder>(/*orig_cert=*/nullptr, issuer);
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker   CBS cbs;
209*6777b538SAndroid Build Coastguard Worker   CBS_init(&cbs, spki_der.data(), spki_der.size());
210*6777b538SAndroid Build Coastguard Worker   builder->key_ = bssl::UniquePtr<EVP_PKEY>(EVP_parse_public_key(&cbs));
211*6777b538SAndroid Build Coastguard Worker   // Check that there was no error in `EVP_parse_public_key` and that it
212*6777b538SAndroid Build Coastguard Worker   // consumed the entire public key.
213*6777b538SAndroid Build Coastguard Worker   if (!builder->key_ || (CBS_len(&cbs) != 0))
214*6777b538SAndroid Build Coastguard Worker     return nullptr;
215*6777b538SAndroid Build Coastguard Worker 
216*6777b538SAndroid Build Coastguard Worker   return builder;
217*6777b538SAndroid Build Coastguard Worker }
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker CertBuilder::~CertBuilder() = default;
220*6777b538SAndroid Build Coastguard Worker 
221*6777b538SAndroid Build Coastguard Worker // static
CreateSimpleChain(size_t chain_length)222*6777b538SAndroid Build Coastguard Worker std::vector<std::unique_ptr<CertBuilder>> CertBuilder::CreateSimpleChain(
223*6777b538SAndroid Build Coastguard Worker     size_t chain_length) {
224*6777b538SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<CertBuilder>> chain;
225*6777b538SAndroid Build Coastguard Worker   base::Time not_before = base::Time::Now() - base::Days(7);
226*6777b538SAndroid Build Coastguard Worker   base::Time not_after = base::Time::Now() + base::Days(7);
227*6777b538SAndroid Build Coastguard Worker   CertBuilder* parent_builder = nullptr;
228*6777b538SAndroid Build Coastguard Worker   for (size_t remaining_chain_length = chain_length; remaining_chain_length;
229*6777b538SAndroid Build Coastguard Worker        remaining_chain_length--) {
230*6777b538SAndroid Build Coastguard Worker     auto builder = std::make_unique<CertBuilder>(nullptr, parent_builder);
231*6777b538SAndroid Build Coastguard Worker     builder->SetValidity(not_before, not_after);
232*6777b538SAndroid Build Coastguard Worker     if (remaining_chain_length > 1) {
233*6777b538SAndroid Build Coastguard Worker       // CA properties:
234*6777b538SAndroid Build Coastguard Worker       builder->SetBasicConstraints(/*is_ca=*/true, /*path_len=*/-1);
235*6777b538SAndroid Build Coastguard Worker       builder->SetKeyUsages(
236*6777b538SAndroid Build Coastguard Worker           {bssl::KEY_USAGE_BIT_KEY_CERT_SIGN, bssl::KEY_USAGE_BIT_CRL_SIGN});
237*6777b538SAndroid Build Coastguard Worker     } else {
238*6777b538SAndroid Build Coastguard Worker       // Leaf properties:
239*6777b538SAndroid Build Coastguard Worker       builder->SetBasicConstraints(/*is_ca=*/false, /*path_len=*/-1);
240*6777b538SAndroid Build Coastguard Worker       builder->SetKeyUsages({bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE});
241*6777b538SAndroid Build Coastguard Worker       builder->SetExtendedKeyUsages({bssl::der::Input(bssl::kServerAuth)});
242*6777b538SAndroid Build Coastguard Worker       builder->SetSubjectAltName(kSimpleChainHostname);
243*6777b538SAndroid Build Coastguard Worker     }
244*6777b538SAndroid Build Coastguard Worker     parent_builder = builder.get();
245*6777b538SAndroid Build Coastguard Worker     chain.push_back(std::move(builder));
246*6777b538SAndroid Build Coastguard Worker   }
247*6777b538SAndroid Build Coastguard Worker   base::ranges::reverse(chain);
248*6777b538SAndroid Build Coastguard Worker   return chain;
249*6777b538SAndroid Build Coastguard Worker }
250*6777b538SAndroid Build Coastguard Worker 
251*6777b538SAndroid Build Coastguard Worker // static
CreateSimpleChain3()252*6777b538SAndroid Build Coastguard Worker std::array<std::unique_ptr<CertBuilder>, 3> CertBuilder::CreateSimpleChain3() {
253*6777b538SAndroid Build Coastguard Worker   auto chain = CreateSimpleChain(3);
254*6777b538SAndroid Build Coastguard Worker   return {std::move(chain[0]), std::move(chain[1]), std::move(chain[2])};
255*6777b538SAndroid Build Coastguard Worker }
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker // static
CreateSimpleChain2()258*6777b538SAndroid Build Coastguard Worker std::array<std::unique_ptr<CertBuilder>, 2> CertBuilder::CreateSimpleChain2() {
259*6777b538SAndroid Build Coastguard Worker   auto chain = CreateSimpleChain(2);
260*6777b538SAndroid Build Coastguard Worker   return {std::move(chain[0]), std::move(chain[1])};
261*6777b538SAndroid Build Coastguard Worker }
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker // static
264*6777b538SAndroid Build Coastguard Worker std::optional<bssl::SignatureAlgorithm>
DefaultSignatureAlgorithmForKey(EVP_PKEY * key)265*6777b538SAndroid Build Coastguard Worker CertBuilder::DefaultSignatureAlgorithmForKey(EVP_PKEY* key) {
266*6777b538SAndroid Build Coastguard Worker   if (EVP_PKEY_id(key) == EVP_PKEY_RSA)
267*6777b538SAndroid Build Coastguard Worker     return bssl::SignatureAlgorithm::kRsaPkcs1Sha256;
268*6777b538SAndroid Build Coastguard Worker   if (EVP_PKEY_id(key) == EVP_PKEY_EC)
269*6777b538SAndroid Build Coastguard Worker     return bssl::SignatureAlgorithm::kEcdsaSha256;
270*6777b538SAndroid Build Coastguard Worker   return std::nullopt;
271*6777b538SAndroid Build Coastguard Worker }
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker // static
SignData(bssl::SignatureAlgorithm signature_algorithm,std::string_view tbs_data,EVP_PKEY * key,CBB * out_signature)274*6777b538SAndroid Build Coastguard Worker bool CertBuilder::SignData(bssl::SignatureAlgorithm signature_algorithm,
275*6777b538SAndroid Build Coastguard Worker                            std::string_view tbs_data,
276*6777b538SAndroid Build Coastguard Worker                            EVP_PKEY* key,
277*6777b538SAndroid Build Coastguard Worker                            CBB* out_signature) {
278*6777b538SAndroid Build Coastguard Worker   if (!key)
279*6777b538SAndroid Build Coastguard Worker     return false;
280*6777b538SAndroid Build Coastguard Worker 
281*6777b538SAndroid Build Coastguard Worker   int expected_pkey_id = 1;
282*6777b538SAndroid Build Coastguard Worker   const EVP_MD* digest;
283*6777b538SAndroid Build Coastguard Worker   switch (signature_algorithm) {
284*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPkcs1Sha1:
285*6777b538SAndroid Build Coastguard Worker       expected_pkey_id = EVP_PKEY_RSA;
286*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha1();
287*6777b538SAndroid Build Coastguard Worker       break;
288*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPkcs1Sha256:
289*6777b538SAndroid Build Coastguard Worker       expected_pkey_id = EVP_PKEY_RSA;
290*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha256();
291*6777b538SAndroid Build Coastguard Worker       break;
292*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPkcs1Sha384:
293*6777b538SAndroid Build Coastguard Worker       expected_pkey_id = EVP_PKEY_RSA;
294*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha384();
295*6777b538SAndroid Build Coastguard Worker       break;
296*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPkcs1Sha512:
297*6777b538SAndroid Build Coastguard Worker       expected_pkey_id = EVP_PKEY_RSA;
298*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha512();
299*6777b538SAndroid Build Coastguard Worker       break;
300*6777b538SAndroid Build Coastguard Worker 
301*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kEcdsaSha1:
302*6777b538SAndroid Build Coastguard Worker       expected_pkey_id = EVP_PKEY_EC;
303*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha1();
304*6777b538SAndroid Build Coastguard Worker       break;
305*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kEcdsaSha256:
306*6777b538SAndroid Build Coastguard Worker       expected_pkey_id = EVP_PKEY_EC;
307*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha256();
308*6777b538SAndroid Build Coastguard Worker       break;
309*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kEcdsaSha384:
310*6777b538SAndroid Build Coastguard Worker       expected_pkey_id = EVP_PKEY_EC;
311*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha384();
312*6777b538SAndroid Build Coastguard Worker       break;
313*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kEcdsaSha512:
314*6777b538SAndroid Build Coastguard Worker       expected_pkey_id = EVP_PKEY_EC;
315*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha512();
316*6777b538SAndroid Build Coastguard Worker       break;
317*6777b538SAndroid Build Coastguard Worker 
318*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPssSha256:
319*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPssSha384:
320*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPssSha512:
321*6777b538SAndroid Build Coastguard Worker       // Unsupported algorithms.
322*6777b538SAndroid Build Coastguard Worker       return false;
323*6777b538SAndroid Build Coastguard Worker   }
324*6777b538SAndroid Build Coastguard Worker 
325*6777b538SAndroid Build Coastguard Worker   return expected_pkey_id == EVP_PKEY_id(key) &&
326*6777b538SAndroid Build Coastguard Worker          SignDataWithDigest(digest, tbs_data, key, out_signature);
327*6777b538SAndroid Build Coastguard Worker }
328*6777b538SAndroid Build Coastguard Worker 
329*6777b538SAndroid Build Coastguard Worker // static
SignDataWithDigest(const EVP_MD * digest,std::string_view tbs_data,EVP_PKEY * key,CBB * out_signature)330*6777b538SAndroid Build Coastguard Worker bool CertBuilder::SignDataWithDigest(const EVP_MD* digest,
331*6777b538SAndroid Build Coastguard Worker                                      std::string_view tbs_data,
332*6777b538SAndroid Build Coastguard Worker                                      EVP_PKEY* key,
333*6777b538SAndroid Build Coastguard Worker                                      CBB* out_signature) {
334*6777b538SAndroid Build Coastguard Worker   const uint8_t* tbs_bytes = reinterpret_cast<const uint8_t*>(tbs_data.data());
335*6777b538SAndroid Build Coastguard Worker   bssl::ScopedEVP_MD_CTX ctx;
336*6777b538SAndroid Build Coastguard Worker   uint8_t* sig_out;
337*6777b538SAndroid Build Coastguard Worker   size_t sig_len;
338*6777b538SAndroid Build Coastguard Worker 
339*6777b538SAndroid Build Coastguard Worker   return EVP_DigestSignInit(ctx.get(), nullptr, digest, nullptr, key) &&
340*6777b538SAndroid Build Coastguard Worker          EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_bytes,
341*6777b538SAndroid Build Coastguard Worker                         tbs_data.size()) &&
342*6777b538SAndroid Build Coastguard Worker          CBB_reserve(out_signature, &sig_out, sig_len) &&
343*6777b538SAndroid Build Coastguard Worker          EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_bytes,
344*6777b538SAndroid Build Coastguard Worker                         tbs_data.size()) &&
345*6777b538SAndroid Build Coastguard Worker          CBB_did_write(out_signature, sig_len);
346*6777b538SAndroid Build Coastguard Worker }
347*6777b538SAndroid Build Coastguard Worker 
348*6777b538SAndroid Build Coastguard Worker // static
SignatureAlgorithmToDer(bssl::SignatureAlgorithm signature_algorithm)349*6777b538SAndroid Build Coastguard Worker std::string CertBuilder::SignatureAlgorithmToDer(
350*6777b538SAndroid Build Coastguard Worker     bssl::SignatureAlgorithm signature_algorithm) {
351*6777b538SAndroid Build Coastguard Worker   switch (signature_algorithm) {
352*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPkcs1Sha1:
353*6777b538SAndroid Build Coastguard Worker       return Sha1WithRSAEncryption();
354*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kRsaPkcs1Sha256:
355*6777b538SAndroid Build Coastguard Worker       return Sha256WithRSAEncryption();
356*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kEcdsaSha1:
357*6777b538SAndroid Build Coastguard Worker       return EcdsaWithSha1();
358*6777b538SAndroid Build Coastguard Worker     case bssl::SignatureAlgorithm::kEcdsaSha256:
359*6777b538SAndroid Build Coastguard Worker       return EcdsaWithSha256();
360*6777b538SAndroid Build Coastguard Worker     default:
361*6777b538SAndroid Build Coastguard Worker       ADD_FAILURE();
362*6777b538SAndroid Build Coastguard Worker       return std::string();
363*6777b538SAndroid Build Coastguard Worker   }
364*6777b538SAndroid Build Coastguard Worker }
365*6777b538SAndroid Build Coastguard Worker 
366*6777b538SAndroid Build Coastguard Worker // static
MakeRandomHexString(size_t num_bytes)367*6777b538SAndroid Build Coastguard Worker std::string CertBuilder::MakeRandomHexString(size_t num_bytes) {
368*6777b538SAndroid Build Coastguard Worker   std::vector<uint8_t> rand_bytes(num_bytes);
369*6777b538SAndroid Build Coastguard Worker   base::RandBytes(rand_bytes);
370*6777b538SAndroid Build Coastguard Worker   return base::HexEncode(rand_bytes);
371*6777b538SAndroid Build Coastguard Worker }
372*6777b538SAndroid Build Coastguard Worker 
373*6777b538SAndroid Build Coastguard Worker // static
BuildNameWithCommonNameOfType(std::string_view common_name,unsigned common_name_tag)374*6777b538SAndroid Build Coastguard Worker std::vector<uint8_t> CertBuilder::BuildNameWithCommonNameOfType(
375*6777b538SAndroid Build Coastguard Worker     std::string_view common_name,
376*6777b538SAndroid Build Coastguard Worker     unsigned common_name_tag) {
377*6777b538SAndroid Build Coastguard Worker   // See RFC 4519.
378*6777b538SAndroid Build Coastguard Worker   static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};
379*6777b538SAndroid Build Coastguard Worker 
380*6777b538SAndroid Build Coastguard Worker   // See RFC 5280, section 4.1.2.4.
381*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
382*6777b538SAndroid Build Coastguard Worker   CBB rdns, rdn, attr, type, value;
383*6777b538SAndroid Build Coastguard Worker   if (!CBB_init(cbb.get(), 64) ||
384*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(cbb.get(), &rdns, CBS_ASN1_SEQUENCE) ||
385*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
386*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
387*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
388*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&type, kCommonName) ||
389*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&attr, &value, common_name_tag) ||
390*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&value, common_name)) {
391*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
392*6777b538SAndroid Build Coastguard Worker     return {};
393*6777b538SAndroid Build Coastguard Worker   }
394*6777b538SAndroid Build Coastguard Worker 
395*6777b538SAndroid Build Coastguard Worker   return FinishCBBToVector(cbb.get());
396*6777b538SAndroid Build Coastguard Worker }
397*6777b538SAndroid Build Coastguard Worker 
SetCertificateVersion(bssl::CertificateVersion version)398*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetCertificateVersion(bssl::CertificateVersion version) {
399*6777b538SAndroid Build Coastguard Worker   version_ = version;
400*6777b538SAndroid Build Coastguard Worker   Invalidate();
401*6777b538SAndroid Build Coastguard Worker }
402*6777b538SAndroid Build Coastguard Worker 
SetExtension(const bssl::der::Input & oid,std::string value,bool critical)403*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetExtension(const bssl::der::Input& oid,
404*6777b538SAndroid Build Coastguard Worker                                std::string value,
405*6777b538SAndroid Build Coastguard Worker                                bool critical) {
406*6777b538SAndroid Build Coastguard Worker   auto& extension_value = extensions_[oid.AsString()];
407*6777b538SAndroid Build Coastguard Worker   extension_value.critical = critical;
408*6777b538SAndroid Build Coastguard Worker   extension_value.value = std::move(value);
409*6777b538SAndroid Build Coastguard Worker 
410*6777b538SAndroid Build Coastguard Worker   Invalidate();
411*6777b538SAndroid Build Coastguard Worker }
412*6777b538SAndroid Build Coastguard Worker 
EraseExtension(const bssl::der::Input & oid)413*6777b538SAndroid Build Coastguard Worker void CertBuilder::EraseExtension(const bssl::der::Input& oid) {
414*6777b538SAndroid Build Coastguard Worker   extensions_.erase(oid.AsString());
415*6777b538SAndroid Build Coastguard Worker 
416*6777b538SAndroid Build Coastguard Worker   Invalidate();
417*6777b538SAndroid Build Coastguard Worker }
418*6777b538SAndroid Build Coastguard Worker 
ClearExtensions()419*6777b538SAndroid Build Coastguard Worker void CertBuilder::ClearExtensions() {
420*6777b538SAndroid Build Coastguard Worker   extensions_.clear();
421*6777b538SAndroid Build Coastguard Worker   Invalidate();
422*6777b538SAndroid Build Coastguard Worker }
423*6777b538SAndroid Build Coastguard Worker 
SetBasicConstraints(bool is_ca,int path_len)424*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetBasicConstraints(bool is_ca, int path_len) {
425*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
426*6777b538SAndroid Build Coastguard Worker   //
427*6777b538SAndroid Build Coastguard Worker   //   BasicConstraints ::= SEQUENCE {
428*6777b538SAndroid Build Coastguard Worker   //        cA                      BOOLEAN DEFAULT FALSE,
429*6777b538SAndroid Build Coastguard Worker   //        pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
430*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
431*6777b538SAndroid Build Coastguard Worker   CBB basic_constraints;
432*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
433*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &basic_constraints, CBS_ASN1_SEQUENCE));
434*6777b538SAndroid Build Coastguard Worker   if (is_ca)
435*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1_bool(&basic_constraints, true));
436*6777b538SAndroid Build Coastguard Worker   if (path_len >= 0)
437*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1_uint64(&basic_constraints, path_len));
438*6777b538SAndroid Build Coastguard Worker 
439*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kBasicConstraintsOid),
440*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()),
441*6777b538SAndroid Build Coastguard Worker                /*critical=*/true);
442*6777b538SAndroid Build Coastguard Worker }
443*6777b538SAndroid Build Coastguard Worker 
444*6777b538SAndroid Build Coastguard Worker namespace {
AddNameConstraintsSubTrees(CBB * cbb,const std::vector<std::string> & dns_names)445*6777b538SAndroid Build Coastguard Worker void AddNameConstraintsSubTrees(CBB* cbb,
446*6777b538SAndroid Build Coastguard Worker                                 const std::vector<std::string>& dns_names) {
447*6777b538SAndroid Build Coastguard Worker   CBB subtrees;
448*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(
449*6777b538SAndroid Build Coastguard Worker       cbb, &subtrees, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
450*6777b538SAndroid Build Coastguard Worker   for (const auto& name : dns_names) {
451*6777b538SAndroid Build Coastguard Worker     CBB subtree;
452*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1(&subtrees, &subtree, CBS_ASN1_SEQUENCE));
453*6777b538SAndroid Build Coastguard Worker     CBB general_name;
454*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
455*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1(&subtree, &general_name, CBS_ASN1_CONTEXT_SPECIFIC | 2));
456*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBBAddBytes(&general_name, name));
457*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_flush(&subtrees));
458*6777b538SAndroid Build Coastguard Worker   }
459*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_flush(cbb));
460*6777b538SAndroid Build Coastguard Worker }
461*6777b538SAndroid Build Coastguard Worker }  // namespace
462*6777b538SAndroid Build Coastguard Worker 
SetNameConstraintsDnsNames(const std::vector<std::string> & permitted_dns_names,const std::vector<std::string> & excluded_dns_names)463*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetNameConstraintsDnsNames(
464*6777b538SAndroid Build Coastguard Worker     const std::vector<std::string>& permitted_dns_names,
465*6777b538SAndroid Build Coastguard Worker     const std::vector<std::string>& excluded_dns_names) {
466*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
467*6777b538SAndroid Build Coastguard Worker   //
468*6777b538SAndroid Build Coastguard Worker   //   id-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-ce 30 }
469*6777b538SAndroid Build Coastguard Worker   //
470*6777b538SAndroid Build Coastguard Worker   //   NameConstraints ::= SEQUENCE {
471*6777b538SAndroid Build Coastguard Worker   //        permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
472*6777b538SAndroid Build Coastguard Worker   //        excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
473*6777b538SAndroid Build Coastguard Worker   //
474*6777b538SAndroid Build Coastguard Worker   //   GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
475*6777b538SAndroid Build Coastguard Worker   //
476*6777b538SAndroid Build Coastguard Worker   //   GeneralSubtree ::= SEQUENCE {
477*6777b538SAndroid Build Coastguard Worker   //        base                    GeneralName,
478*6777b538SAndroid Build Coastguard Worker   //        minimum         [0]     BaseDistance DEFAULT 0,
479*6777b538SAndroid Build Coastguard Worker   //        maximum         [1]     BaseDistance OPTIONAL }
480*6777b538SAndroid Build Coastguard Worker   //
481*6777b538SAndroid Build Coastguard Worker   //   BaseDistance ::= INTEGER (0..MAX)
482*6777b538SAndroid Build Coastguard Worker 
483*6777b538SAndroid Build Coastguard Worker   if (permitted_dns_names.empty() && excluded_dns_names.empty()) {
484*6777b538SAndroid Build Coastguard Worker     EraseExtension(bssl::der::Input(bssl::kNameConstraintsOid));
485*6777b538SAndroid Build Coastguard Worker     return;
486*6777b538SAndroid Build Coastguard Worker   }
487*6777b538SAndroid Build Coastguard Worker 
488*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
489*6777b538SAndroid Build Coastguard Worker   CBB name_constraints;
490*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
491*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &name_constraints, CBS_ASN1_SEQUENCE));
492*6777b538SAndroid Build Coastguard Worker   if (!permitted_dns_names.empty()) {
493*6777b538SAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(
494*6777b538SAndroid Build Coastguard Worker         AddNameConstraintsSubTrees(&name_constraints, permitted_dns_names));
495*6777b538SAndroid Build Coastguard Worker   }
496*6777b538SAndroid Build Coastguard Worker   if (!excluded_dns_names.empty()) {
497*6777b538SAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(
498*6777b538SAndroid Build Coastguard Worker         AddNameConstraintsSubTrees(&name_constraints, excluded_dns_names));
499*6777b538SAndroid Build Coastguard Worker   }
500*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kNameConstraintsOid),
501*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()),
502*6777b538SAndroid Build Coastguard Worker                /*critical=*/true);
503*6777b538SAndroid Build Coastguard Worker }
504*6777b538SAndroid Build Coastguard Worker 
SetCaIssuersUrl(const GURL & url)505*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetCaIssuersUrl(const GURL& url) {
506*6777b538SAndroid Build Coastguard Worker   SetCaIssuersAndOCSPUrls({url}, {});
507*6777b538SAndroid Build Coastguard Worker }
508*6777b538SAndroid Build Coastguard Worker 
SetCaIssuersAndOCSPUrls(const std::vector<GURL> & ca_issuers_urls,const std::vector<GURL> & ocsp_urls)509*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetCaIssuersAndOCSPUrls(
510*6777b538SAndroid Build Coastguard Worker     const std::vector<GURL>& ca_issuers_urls,
511*6777b538SAndroid Build Coastguard Worker     const std::vector<GURL>& ocsp_urls) {
512*6777b538SAndroid Build Coastguard Worker   std::vector<std::pair<bssl::der::Input, GURL>> entries;
513*6777b538SAndroid Build Coastguard Worker   for (const auto& url : ca_issuers_urls)
514*6777b538SAndroid Build Coastguard Worker     entries.emplace_back(bssl::der::Input(bssl::kAdCaIssuersOid), url);
515*6777b538SAndroid Build Coastguard Worker   for (const auto& url : ocsp_urls)
516*6777b538SAndroid Build Coastguard Worker     entries.emplace_back(bssl::der::Input(bssl::kAdOcspOid), url);
517*6777b538SAndroid Build Coastguard Worker 
518*6777b538SAndroid Build Coastguard Worker   if (entries.empty()) {
519*6777b538SAndroid Build Coastguard Worker     EraseExtension(bssl::der::Input(bssl::kAuthorityInfoAccessOid));
520*6777b538SAndroid Build Coastguard Worker     return;
521*6777b538SAndroid Build Coastguard Worker   }
522*6777b538SAndroid Build Coastguard Worker 
523*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
524*6777b538SAndroid Build Coastguard Worker   //
525*6777b538SAndroid Build Coastguard Worker   //   AuthorityInfoAccessSyntax  ::=
526*6777b538SAndroid Build Coastguard Worker   //           SEQUENCE SIZE (1..MAX) OF AccessDescription
527*6777b538SAndroid Build Coastguard Worker   //
528*6777b538SAndroid Build Coastguard Worker   //   AccessDescription  ::=  SEQUENCE {
529*6777b538SAndroid Build Coastguard Worker   //           accessMethod          OBJECT IDENTIFIER,
530*6777b538SAndroid Build Coastguard Worker   //           accessLocation        GeneralName  }
531*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
532*6777b538SAndroid Build Coastguard Worker   CBB aia;
533*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
534*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &aia, CBS_ASN1_SEQUENCE));
535*6777b538SAndroid Build Coastguard Worker 
536*6777b538SAndroid Build Coastguard Worker   for (const auto& entry : entries) {
537*6777b538SAndroid Build Coastguard Worker     CBB access_description, access_method, access_location;
538*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1(&aia, &access_description, CBS_ASN1_SEQUENCE));
539*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
540*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1(&access_description, &access_method, CBS_ASN1_OBJECT));
541*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBBAddBytes(&access_method, entry.first.AsStringView()));
542*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1(&access_description, &access_location,
543*6777b538SAndroid Build Coastguard Worker                              CBS_ASN1_CONTEXT_SPECIFIC | 6));
544*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBBAddBytes(&access_location, entry.second.spec()));
545*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_flush(&aia));
546*6777b538SAndroid Build Coastguard Worker   }
547*6777b538SAndroid Build Coastguard Worker 
548*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kAuthorityInfoAccessOid),
549*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()));
550*6777b538SAndroid Build Coastguard Worker }
551*6777b538SAndroid Build Coastguard Worker 
SetCrlDistributionPointUrl(const GURL & url)552*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetCrlDistributionPointUrl(const GURL& url) {
553*6777b538SAndroid Build Coastguard Worker   SetCrlDistributionPointUrls({url});
554*6777b538SAndroid Build Coastguard Worker }
555*6777b538SAndroid Build Coastguard Worker 
SetCrlDistributionPointUrls(const std::vector<GURL> & urls)556*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetCrlDistributionPointUrls(const std::vector<GURL>& urls) {
557*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
558*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
559*6777b538SAndroid Build Coastguard Worker   CBB dps, dp, dp_name, dp_fullname;
560*6777b538SAndroid Build Coastguard Worker 
561*6777b538SAndroid Build Coastguard Worker   //    CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
562*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &dps, CBS_ASN1_SEQUENCE));
563*6777b538SAndroid Build Coastguard Worker 
564*6777b538SAndroid Build Coastguard Worker   //    DistributionPoint ::= SEQUENCE {
565*6777b538SAndroid Build Coastguard Worker   //         distributionPoint       [0]     DistributionPointName OPTIONAL,
566*6777b538SAndroid Build Coastguard Worker   //         reasons                 [1]     ReasonFlags OPTIONAL,
567*6777b538SAndroid Build Coastguard Worker   //         cRLIssuer               [2]     bssl::GeneralNames OPTIONAL }
568*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(&dps, &dp, CBS_ASN1_SEQUENCE));
569*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(
570*6777b538SAndroid Build Coastguard Worker       &dp, &dp_name, CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
571*6777b538SAndroid Build Coastguard Worker 
572*6777b538SAndroid Build Coastguard Worker   //    DistributionPointName ::= CHOICE {
573*6777b538SAndroid Build Coastguard Worker   //         fullName                [0]     bssl::GeneralNames,
574*6777b538SAndroid Build Coastguard Worker   //         nameRelativeToCRLIssuer [1]     bssl::RelativeDistinguishedName }
575*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
576*6777b538SAndroid Build Coastguard Worker       CBB_add_asn1(&dp_name, &dp_fullname,
577*6777b538SAndroid Build Coastguard Worker                    CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
578*6777b538SAndroid Build Coastguard Worker 
579*6777b538SAndroid Build Coastguard Worker   //   bssl::GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
580*6777b538SAndroid Build Coastguard Worker   //   GeneralName ::= CHOICE {
581*6777b538SAndroid Build Coastguard Worker   // uniformResourceIdentifier       [6]     IA5String,
582*6777b538SAndroid Build Coastguard Worker   for (const auto& url : urls) {
583*6777b538SAndroid Build Coastguard Worker     CBB dp_url;
584*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
585*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1(&dp_fullname, &dp_url, CBS_ASN1_CONTEXT_SPECIFIC | 6));
586*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBBAddBytes(&dp_url, url.spec()));
587*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_flush(&dp_fullname));
588*6777b538SAndroid Build Coastguard Worker   }
589*6777b538SAndroid Build Coastguard Worker 
590*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kCrlDistributionPointsOid),
591*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()));
592*6777b538SAndroid Build Coastguard Worker }
593*6777b538SAndroid Build Coastguard Worker 
SetIssuerTLV(base::span<const uint8_t> issuer_tlv)594*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetIssuerTLV(base::span<const uint8_t> issuer_tlv) {
595*6777b538SAndroid Build Coastguard Worker   if (issuer_tlv.empty())
596*6777b538SAndroid Build Coastguard Worker     issuer_tlv_ = std::nullopt;
597*6777b538SAndroid Build Coastguard Worker   else
598*6777b538SAndroid Build Coastguard Worker     issuer_tlv_ = std::string(issuer_tlv.begin(), issuer_tlv.end());
599*6777b538SAndroid Build Coastguard Worker   Invalidate();
600*6777b538SAndroid Build Coastguard Worker }
601*6777b538SAndroid Build Coastguard Worker 
SetSubjectCommonName(std::string_view common_name)602*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSubjectCommonName(std::string_view common_name) {
603*6777b538SAndroid Build Coastguard Worker   SetSubjectTLV(
604*6777b538SAndroid Build Coastguard Worker       BuildNameWithCommonNameOfType(common_name, CBS_ASN1_UTF8STRING));
605*6777b538SAndroid Build Coastguard Worker   Invalidate();
606*6777b538SAndroid Build Coastguard Worker }
607*6777b538SAndroid Build Coastguard Worker 
SetSubjectTLV(base::span<const uint8_t> subject_tlv)608*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSubjectTLV(base::span<const uint8_t> subject_tlv) {
609*6777b538SAndroid Build Coastguard Worker   subject_tlv_.assign(subject_tlv.begin(), subject_tlv.end());
610*6777b538SAndroid Build Coastguard Worker   Invalidate();
611*6777b538SAndroid Build Coastguard Worker }
612*6777b538SAndroid Build Coastguard Worker 
SetSubjectAltName(std::string_view dns_name)613*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSubjectAltName(std::string_view dns_name) {
614*6777b538SAndroid Build Coastguard Worker   SetSubjectAltNames({std::string(dns_name)}, {});
615*6777b538SAndroid Build Coastguard Worker }
616*6777b538SAndroid Build Coastguard Worker 
SetSubjectAltNames(const std::vector<std::string> & dns_names,const std::vector<IPAddress> & ip_addresses)617*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSubjectAltNames(
618*6777b538SAndroid Build Coastguard Worker     const std::vector<std::string>& dns_names,
619*6777b538SAndroid Build Coastguard Worker     const std::vector<IPAddress>& ip_addresses) {
620*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
621*6777b538SAndroid Build Coastguard Worker   //
622*6777b538SAndroid Build Coastguard Worker   //   SubjectAltName ::= bssl::GeneralNames
623*6777b538SAndroid Build Coastguard Worker   //
624*6777b538SAndroid Build Coastguard Worker   //   bssl::GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
625*6777b538SAndroid Build Coastguard Worker   //
626*6777b538SAndroid Build Coastguard Worker   //   GeneralName ::= CHOICE {
627*6777b538SAndroid Build Coastguard Worker   //        ...
628*6777b538SAndroid Build Coastguard Worker   //        dNSName                         [2]     IA5String,
629*6777b538SAndroid Build Coastguard Worker   //        ...
630*6777b538SAndroid Build Coastguard Worker   //        iPAddress                       [7]     OCTET STRING,
631*6777b538SAndroid Build Coastguard Worker   //        ... }
632*6777b538SAndroid Build Coastguard Worker   ASSERT_GT(dns_names.size() + ip_addresses.size(), 0U);
633*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
634*6777b538SAndroid Build Coastguard Worker   CBB general_names;
635*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
636*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &general_names, CBS_ASN1_SEQUENCE));
637*6777b538SAndroid Build Coastguard Worker   if (!dns_names.empty()) {
638*6777b538SAndroid Build Coastguard Worker     for (const auto& name : dns_names) {
639*6777b538SAndroid Build Coastguard Worker       CBB general_name;
640*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_add_asn1(&general_names, &general_name,
641*6777b538SAndroid Build Coastguard Worker                                CBS_ASN1_CONTEXT_SPECIFIC | 2));
642*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBBAddBytes(&general_name, name));
643*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_flush(&general_names));
644*6777b538SAndroid Build Coastguard Worker     }
645*6777b538SAndroid Build Coastguard Worker   }
646*6777b538SAndroid Build Coastguard Worker   if (!ip_addresses.empty()) {
647*6777b538SAndroid Build Coastguard Worker     for (const auto& addr : ip_addresses) {
648*6777b538SAndroid Build Coastguard Worker       CBB general_name;
649*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_add_asn1(&general_names, &general_name,
650*6777b538SAndroid Build Coastguard Worker                                CBS_ASN1_CONTEXT_SPECIFIC | 7));
651*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(
652*6777b538SAndroid Build Coastguard Worker           CBB_add_bytes(&general_name, addr.bytes().data(), addr.size()));
653*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_flush(&general_names));
654*6777b538SAndroid Build Coastguard Worker     }
655*6777b538SAndroid Build Coastguard Worker   }
656*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kSubjectAltNameOid),
657*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()));
658*6777b538SAndroid Build Coastguard Worker }
659*6777b538SAndroid Build Coastguard Worker 
SetKeyUsages(const std::vector<bssl::KeyUsageBit> & usages)660*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetKeyUsages(const std::vector<bssl::KeyUsageBit>& usages) {
661*6777b538SAndroid Build Coastguard Worker   ASSERT_GT(usages.size(), 0U);
662*6777b538SAndroid Build Coastguard Worker   int number_of_unused_bits = 0;
663*6777b538SAndroid Build Coastguard Worker   std::vector<uint8_t> bytes;
664*6777b538SAndroid Build Coastguard Worker   for (auto usage : usages) {
665*6777b538SAndroid Build Coastguard Worker     int bit_index = static_cast<int>(usage);
666*6777b538SAndroid Build Coastguard Worker 
667*6777b538SAndroid Build Coastguard Worker     // Index of the byte that contains the bit.
668*6777b538SAndroid Build Coastguard Worker     size_t byte_index = bit_index / 8;
669*6777b538SAndroid Build Coastguard Worker 
670*6777b538SAndroid Build Coastguard Worker     if (byte_index + 1 > bytes.size()) {
671*6777b538SAndroid Build Coastguard Worker       bytes.resize(byte_index + 1);
672*6777b538SAndroid Build Coastguard Worker       number_of_unused_bits = 8;
673*6777b538SAndroid Build Coastguard Worker     }
674*6777b538SAndroid Build Coastguard Worker 
675*6777b538SAndroid Build Coastguard Worker     // Within a byte, bits are ordered from most significant to least
676*6777b538SAndroid Build Coastguard Worker     // significant. Convert |bit_index| to an index within the |byte_index|
677*6777b538SAndroid Build Coastguard Worker     // byte, measured from its least significant bit.
678*6777b538SAndroid Build Coastguard Worker     uint8_t bit_index_in_byte = 7 - (bit_index - byte_index * 8);
679*6777b538SAndroid Build Coastguard Worker 
680*6777b538SAndroid Build Coastguard Worker     if (byte_index + 1 == bytes.size() &&
681*6777b538SAndroid Build Coastguard Worker         bit_index_in_byte < number_of_unused_bits) {
682*6777b538SAndroid Build Coastguard Worker       number_of_unused_bits = bit_index_in_byte;
683*6777b538SAndroid Build Coastguard Worker     }
684*6777b538SAndroid Build Coastguard Worker 
685*6777b538SAndroid Build Coastguard Worker     bytes[byte_index] |= (1 << bit_index_in_byte);
686*6777b538SAndroid Build Coastguard Worker   }
687*6777b538SAndroid Build Coastguard Worker 
688*6777b538SAndroid Build Coastguard Worker   // From RFC 5290:
689*6777b538SAndroid Build Coastguard Worker   //   KeyUsage ::= BIT STRING {...}
690*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
691*6777b538SAndroid Build Coastguard Worker   CBB ku_cbb;
692*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), bytes.size() + 1));
693*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &ku_cbb, CBS_ASN1_BITSTRING));
694*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_u8(&ku_cbb, number_of_unused_bits));
695*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_bytes(&ku_cbb, bytes.data(), bytes.size()));
696*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kKeyUsageOid), FinishCBB(cbb.get()),
697*6777b538SAndroid Build Coastguard Worker                /*critical=*/true);
698*6777b538SAndroid Build Coastguard Worker }
699*6777b538SAndroid Build Coastguard Worker 
SetExtendedKeyUsages(const std::vector<bssl::der::Input> & purpose_oids)700*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetExtendedKeyUsages(
701*6777b538SAndroid Build Coastguard Worker     const std::vector<bssl::der::Input>& purpose_oids) {
702*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
703*6777b538SAndroid Build Coastguard Worker   //   ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
704*6777b538SAndroid Build Coastguard Worker   //   KeyPurposeId ::= OBJECT IDENTIFIER
705*6777b538SAndroid Build Coastguard Worker   ASSERT_GT(purpose_oids.size(), 0U);
706*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
707*6777b538SAndroid Build Coastguard Worker   CBB eku;
708*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
709*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &eku, CBS_ASN1_SEQUENCE));
710*6777b538SAndroid Build Coastguard Worker 
711*6777b538SAndroid Build Coastguard Worker   for (const auto& oid : purpose_oids) {
712*6777b538SAndroid Build Coastguard Worker     CBB purpose_cbb;
713*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1(&eku, &purpose_cbb, CBS_ASN1_OBJECT));
714*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBBAddBytes(&purpose_cbb, oid.AsStringView()));
715*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_flush(&eku));
716*6777b538SAndroid Build Coastguard Worker   }
717*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kExtKeyUsageOid), FinishCBB(cbb.get()));
718*6777b538SAndroid Build Coastguard Worker }
719*6777b538SAndroid Build Coastguard Worker 
SetCertificatePolicies(const std::vector<std::string> & policy_oids)720*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetCertificatePolicies(
721*6777b538SAndroid Build Coastguard Worker     const std::vector<std::string>& policy_oids) {
722*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
723*6777b538SAndroid Build Coastguard Worker   //    certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
724*6777b538SAndroid Build Coastguard Worker   //
725*6777b538SAndroid Build Coastguard Worker   //    PolicyInformation ::= SEQUENCE {
726*6777b538SAndroid Build Coastguard Worker   //         policyIdentifier   CertPolicyId,
727*6777b538SAndroid Build Coastguard Worker   //         policyQualifiers   SEQUENCE SIZE (1..MAX) OF
728*6777b538SAndroid Build Coastguard Worker   //                                 PolicyQualifierInfo OPTIONAL }
729*6777b538SAndroid Build Coastguard Worker   //
730*6777b538SAndroid Build Coastguard Worker   //    CertPolicyId ::= OBJECT IDENTIFIER
731*6777b538SAndroid Build Coastguard Worker   if (policy_oids.empty()) {
732*6777b538SAndroid Build Coastguard Worker     EraseExtension(bssl::der::Input(bssl::kCertificatePoliciesOid));
733*6777b538SAndroid Build Coastguard Worker     return;
734*6777b538SAndroid Build Coastguard Worker   }
735*6777b538SAndroid Build Coastguard Worker 
736*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
737*6777b538SAndroid Build Coastguard Worker   CBB certificate_policies;
738*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
739*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
740*6777b538SAndroid Build Coastguard Worker       CBB_add_asn1(cbb.get(), &certificate_policies, CBS_ASN1_SEQUENCE));
741*6777b538SAndroid Build Coastguard Worker   for (const auto& oid : policy_oids) {
742*6777b538SAndroid Build Coastguard Worker     CBB policy_information, policy_identifier;
743*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1(&certificate_policies, &policy_information,
744*6777b538SAndroid Build Coastguard Worker                              CBS_ASN1_SEQUENCE));
745*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
746*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1(&policy_information, &policy_identifier, CBS_ASN1_OBJECT));
747*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
748*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1_oid_from_text(&policy_identifier, oid.data(), oid.size()));
749*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_flush(&certificate_policies));
750*6777b538SAndroid Build Coastguard Worker   }
751*6777b538SAndroid Build Coastguard Worker 
752*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kCertificatePoliciesOid),
753*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()));
754*6777b538SAndroid Build Coastguard Worker }
755*6777b538SAndroid Build Coastguard Worker 
SetPolicyMappings(const std::vector<std::pair<std::string,std::string>> & policy_mappings)756*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetPolicyMappings(
757*6777b538SAndroid Build Coastguard Worker     const std::vector<std::pair<std::string, std::string>>& policy_mappings) {
758*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
759*6777b538SAndroid Build Coastguard Worker   //   PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
760*6777b538SAndroid Build Coastguard Worker   //        issuerDomainPolicy      CertPolicyId,
761*6777b538SAndroid Build Coastguard Worker   //        subjectDomainPolicy     CertPolicyId }
762*6777b538SAndroid Build Coastguard Worker   if (policy_mappings.empty()) {
763*6777b538SAndroid Build Coastguard Worker     EraseExtension(bssl::der::Input(bssl::kPolicyMappingsOid));
764*6777b538SAndroid Build Coastguard Worker     return;
765*6777b538SAndroid Build Coastguard Worker   }
766*6777b538SAndroid Build Coastguard Worker 
767*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
768*6777b538SAndroid Build Coastguard Worker   CBB mappings_sequence;
769*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
770*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &mappings_sequence, CBS_ASN1_SEQUENCE));
771*6777b538SAndroid Build Coastguard Worker   for (const auto& [issuer_domain_policy, subject_domain_policy] :
772*6777b538SAndroid Build Coastguard Worker        policy_mappings) {
773*6777b538SAndroid Build Coastguard Worker     CBB mapping_sequence;
774*6777b538SAndroid Build Coastguard Worker     CBB issuer_policy_object;
775*6777b538SAndroid Build Coastguard Worker     CBB subject_policy_object;
776*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
777*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1(&mappings_sequence, &mapping_sequence, CBS_ASN1_SEQUENCE));
778*6777b538SAndroid Build Coastguard Worker 
779*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1(&mapping_sequence, &issuer_policy_object,
780*6777b538SAndroid Build Coastguard Worker                              CBS_ASN1_OBJECT));
781*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1_oid_from_text(&issuer_policy_object,
782*6777b538SAndroid Build Coastguard Worker                                            issuer_domain_policy.data(),
783*6777b538SAndroid Build Coastguard Worker                                            issuer_domain_policy.size()));
784*6777b538SAndroid Build Coastguard Worker 
785*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1(&mapping_sequence, &subject_policy_object,
786*6777b538SAndroid Build Coastguard Worker                              CBS_ASN1_OBJECT));
787*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1_oid_from_text(&subject_policy_object,
788*6777b538SAndroid Build Coastguard Worker                                            subject_domain_policy.data(),
789*6777b538SAndroid Build Coastguard Worker                                            subject_domain_policy.size()));
790*6777b538SAndroid Build Coastguard Worker 
791*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_flush(&mappings_sequence));
792*6777b538SAndroid Build Coastguard Worker   }
793*6777b538SAndroid Build Coastguard Worker 
794*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kPolicyMappingsOid), FinishCBB(cbb.get()),
795*6777b538SAndroid Build Coastguard Worker                /*critical=*/true);
796*6777b538SAndroid Build Coastguard Worker }
797*6777b538SAndroid Build Coastguard Worker 
SetPolicyConstraints(std::optional<uint64_t> require_explicit_policy,std::optional<uint64_t> inhibit_policy_mapping)798*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetPolicyConstraints(
799*6777b538SAndroid Build Coastguard Worker     std::optional<uint64_t> require_explicit_policy,
800*6777b538SAndroid Build Coastguard Worker     std::optional<uint64_t> inhibit_policy_mapping) {
801*6777b538SAndroid Build Coastguard Worker   if (!require_explicit_policy.has_value() &&
802*6777b538SAndroid Build Coastguard Worker       !inhibit_policy_mapping.has_value()) {
803*6777b538SAndroid Build Coastguard Worker     EraseExtension(bssl::der::Input(bssl::kPolicyConstraintsOid));
804*6777b538SAndroid Build Coastguard Worker     return;
805*6777b538SAndroid Build Coastguard Worker   }
806*6777b538SAndroid Build Coastguard Worker 
807*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
808*6777b538SAndroid Build Coastguard Worker   //   PolicyConstraints ::= SEQUENCE {
809*6777b538SAndroid Build Coastguard Worker   //        requireExplicitPolicy           [0] SkipCerts OPTIONAL,
810*6777b538SAndroid Build Coastguard Worker   //        inhibitPolicyMapping            [1] SkipCerts OPTIONAL }
811*6777b538SAndroid Build Coastguard Worker   //
812*6777b538SAndroid Build Coastguard Worker   //   SkipCerts ::= INTEGER (0..MAX)
813*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
814*6777b538SAndroid Build Coastguard Worker   CBB policy_constraints;
815*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
816*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &policy_constraints, CBS_ASN1_SEQUENCE));
817*6777b538SAndroid Build Coastguard Worker   if (require_explicit_policy.has_value()) {
818*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1_uint64_with_tag(&policy_constraints,
819*6777b538SAndroid Build Coastguard Worker                                              *require_explicit_policy,
820*6777b538SAndroid Build Coastguard Worker                                              CBS_ASN1_CONTEXT_SPECIFIC | 0));
821*6777b538SAndroid Build Coastguard Worker   }
822*6777b538SAndroid Build Coastguard Worker   if (inhibit_policy_mapping.has_value()) {
823*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_add_asn1_uint64_with_tag(&policy_constraints,
824*6777b538SAndroid Build Coastguard Worker                                              *inhibit_policy_mapping,
825*6777b538SAndroid Build Coastguard Worker                                              CBS_ASN1_CONTEXT_SPECIFIC | 1));
826*6777b538SAndroid Build Coastguard Worker   }
827*6777b538SAndroid Build Coastguard Worker 
828*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kPolicyConstraintsOid),
829*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()),
830*6777b538SAndroid Build Coastguard Worker                /*critical=*/true);
831*6777b538SAndroid Build Coastguard Worker }
832*6777b538SAndroid Build Coastguard Worker 
SetInhibitAnyPolicy(uint64_t skip_certs)833*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetInhibitAnyPolicy(uint64_t skip_certs) {
834*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
835*6777b538SAndroid Build Coastguard Worker   //   id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-ce 54 }
836*6777b538SAndroid Build Coastguard Worker   //
837*6777b538SAndroid Build Coastguard Worker   //   InhibitAnyPolicy ::= SkipCerts
838*6777b538SAndroid Build Coastguard Worker   //
839*6777b538SAndroid Build Coastguard Worker   //   SkipCerts ::= INTEGER (0..MAX)
840*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
841*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
842*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1_uint64(cbb.get(), skip_certs));
843*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kInhibitAnyPolicyOid),
844*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()),
845*6777b538SAndroid Build Coastguard Worker                /*critical=*/true);
846*6777b538SAndroid Build Coastguard Worker }
847*6777b538SAndroid Build Coastguard Worker 
SetValidity(base::Time not_before,base::Time not_after)848*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetValidity(base::Time not_before, base::Time not_after) {
849*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
850*6777b538SAndroid Build Coastguard Worker   //   Validity ::= SEQUENCE {
851*6777b538SAndroid Build Coastguard Worker   //        notBefore      Time,
852*6777b538SAndroid Build Coastguard Worker   //        notAfter       Time }
853*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
854*6777b538SAndroid Build Coastguard Worker   CBB validity;
855*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
856*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &validity, CBS_ASN1_SEQUENCE));
857*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(x509_util::CBBAddTime(&validity, not_before));
858*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(x509_util::CBBAddTime(&validity, not_after));
859*6777b538SAndroid Build Coastguard Worker   validity_tlv_ = FinishCBB(cbb.get());
860*6777b538SAndroid Build Coastguard Worker   Invalidate();
861*6777b538SAndroid Build Coastguard Worker }
862*6777b538SAndroid Build Coastguard Worker 
SetSubjectKeyIdentifier(const std::string & subject_key_identifier)863*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSubjectKeyIdentifier(
864*6777b538SAndroid Build Coastguard Worker     const std::string& subject_key_identifier) {
865*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(subject_key_identifier.empty());
866*6777b538SAndroid Build Coastguard Worker 
867*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
868*6777b538SAndroid Build Coastguard Worker   //   KeyIdentifier ::= OCTET STRING
869*6777b538SAndroid Build Coastguard Worker   //   SubjectKeyIdentifier ::= KeyIdentifier
870*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
871*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 32));
872*6777b538SAndroid Build Coastguard Worker 
873*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1_octet_string(
874*6777b538SAndroid Build Coastguard Worker       cbb.get(),
875*6777b538SAndroid Build Coastguard Worker       reinterpret_cast<const uint8_t*>(subject_key_identifier.data()),
876*6777b538SAndroid Build Coastguard Worker       subject_key_identifier.size()));
877*6777b538SAndroid Build Coastguard Worker 
878*6777b538SAndroid Build Coastguard Worker   // Replace the existing SKI. Note it MUST be non-critical, per RFC 5280.
879*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kSubjectKeyIdentifierOid),
880*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()),
881*6777b538SAndroid Build Coastguard Worker                /*critical=*/false);
882*6777b538SAndroid Build Coastguard Worker }
883*6777b538SAndroid Build Coastguard Worker 
SetAuthorityKeyIdentifier(const std::string & authority_key_identifier)884*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetAuthorityKeyIdentifier(
885*6777b538SAndroid Build Coastguard Worker     const std::string& authority_key_identifier) {
886*6777b538SAndroid Build Coastguard Worker   // If an empty AKI is presented, simply erase the existing one. Creating
887*6777b538SAndroid Build Coastguard Worker   // an empty AKI is technically valid, but there's no use case for this.
888*6777b538SAndroid Build Coastguard Worker   // An empty AKI would an empty (ergo, non-unique) SKI on the issuer,
889*6777b538SAndroid Build Coastguard Worker   // which would violate RFC 5280, so using the empty value as a placeholder
890*6777b538SAndroid Build Coastguard Worker   // unless and until a use case emerges is fine.
891*6777b538SAndroid Build Coastguard Worker   if (authority_key_identifier.empty()) {
892*6777b538SAndroid Build Coastguard Worker     EraseExtension(bssl::der::Input(bssl::kAuthorityKeyIdentifierOid));
893*6777b538SAndroid Build Coastguard Worker     return;
894*6777b538SAndroid Build Coastguard Worker   }
895*6777b538SAndroid Build Coastguard Worker 
896*6777b538SAndroid Build Coastguard Worker   // From RFC 5280:
897*6777b538SAndroid Build Coastguard Worker   //
898*6777b538SAndroid Build Coastguard Worker   //   AuthorityKeyIdentifier ::= SEQUENCE {
899*6777b538SAndroid Build Coastguard Worker   //       keyIdentifier             [0] KeyIdentifier           OPTIONAL,
900*6777b538SAndroid Build Coastguard Worker   //       authorityCertIssuer       [1] bssl::GeneralNames            OPTIONAL,
901*6777b538SAndroid Build Coastguard Worker   //       authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
902*6777b538SAndroid Build Coastguard Worker   //
903*6777b538SAndroid Build Coastguard Worker   //   KeyIdentifier ::= OCTET STRING
904*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
905*6777b538SAndroid Build Coastguard Worker   CBB aki, aki_value;
906*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 32));
907*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &aki, CBS_ASN1_SEQUENCE));
908*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(&aki, &aki_value, CBS_ASN1_CONTEXT_SPECIFIC | 0));
909*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBBAddBytes(&aki_value, authority_key_identifier));
910*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_flush(&aki));
911*6777b538SAndroid Build Coastguard Worker 
912*6777b538SAndroid Build Coastguard Worker   SetExtension(bssl::der::Input(bssl::kAuthorityKeyIdentifierOid),
913*6777b538SAndroid Build Coastguard Worker                FinishCBB(cbb.get()));
914*6777b538SAndroid Build Coastguard Worker }
915*6777b538SAndroid Build Coastguard Worker 
SetSignatureAlgorithm(bssl::SignatureAlgorithm signature_algorithm)916*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSignatureAlgorithm(
917*6777b538SAndroid Build Coastguard Worker     bssl::SignatureAlgorithm signature_algorithm) {
918*6777b538SAndroid Build Coastguard Worker   signature_algorithm_ = signature_algorithm;
919*6777b538SAndroid Build Coastguard Worker   Invalidate();
920*6777b538SAndroid Build Coastguard Worker }
921*6777b538SAndroid Build Coastguard Worker 
SetSignatureAlgorithmTLV(std::string_view signature_algorithm_tlv)922*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSignatureAlgorithmTLV(
923*6777b538SAndroid Build Coastguard Worker     std::string_view signature_algorithm_tlv) {
924*6777b538SAndroid Build Coastguard Worker   SetOuterSignatureAlgorithmTLV(signature_algorithm_tlv);
925*6777b538SAndroid Build Coastguard Worker   SetTBSSignatureAlgorithmTLV(signature_algorithm_tlv);
926*6777b538SAndroid Build Coastguard Worker }
927*6777b538SAndroid Build Coastguard Worker 
SetOuterSignatureAlgorithmTLV(std::string_view signature_algorithm_tlv)928*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetOuterSignatureAlgorithmTLV(
929*6777b538SAndroid Build Coastguard Worker     std::string_view signature_algorithm_tlv) {
930*6777b538SAndroid Build Coastguard Worker   outer_signature_algorithm_tlv_ = std::string(signature_algorithm_tlv);
931*6777b538SAndroid Build Coastguard Worker   Invalidate();
932*6777b538SAndroid Build Coastguard Worker }
933*6777b538SAndroid Build Coastguard Worker 
SetTBSSignatureAlgorithmTLV(std::string_view signature_algorithm_tlv)934*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetTBSSignatureAlgorithmTLV(
935*6777b538SAndroid Build Coastguard Worker     std::string_view signature_algorithm_tlv) {
936*6777b538SAndroid Build Coastguard Worker   tbs_signature_algorithm_tlv_ = std::string(signature_algorithm_tlv);
937*6777b538SAndroid Build Coastguard Worker   Invalidate();
938*6777b538SAndroid Build Coastguard Worker }
939*6777b538SAndroid Build Coastguard Worker 
SetSerialNumber(uint64_t serial_number)940*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSerialNumber(uint64_t serial_number) {
941*6777b538SAndroid Build Coastguard Worker   serial_number_ = serial_number;
942*6777b538SAndroid Build Coastguard Worker   Invalidate();
943*6777b538SAndroid Build Coastguard Worker }
944*6777b538SAndroid Build Coastguard Worker 
SetRandomSerialNumber()945*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetRandomSerialNumber() {
946*6777b538SAndroid Build Coastguard Worker   serial_number_ = base::RandUint64();
947*6777b538SAndroid Build Coastguard Worker   Invalidate();
948*6777b538SAndroid Build Coastguard Worker }
949*6777b538SAndroid Build Coastguard Worker 
SetSctConfig(std::vector<CertBuilder::SctConfig> sct_configs)950*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetSctConfig(
951*6777b538SAndroid Build Coastguard Worker     std::vector<CertBuilder::SctConfig> sct_configs) {
952*6777b538SAndroid Build Coastguard Worker   sct_configs_ = std::move(sct_configs);
953*6777b538SAndroid Build Coastguard Worker   Invalidate();
954*6777b538SAndroid Build Coastguard Worker }
955*6777b538SAndroid Build Coastguard Worker 
GetCertBuffer()956*6777b538SAndroid Build Coastguard Worker CRYPTO_BUFFER* CertBuilder::GetCertBuffer() {
957*6777b538SAndroid Build Coastguard Worker   if (!cert_)
958*6777b538SAndroid Build Coastguard Worker     GenerateCertificate();
959*6777b538SAndroid Build Coastguard Worker   return cert_.get();
960*6777b538SAndroid Build Coastguard Worker }
961*6777b538SAndroid Build Coastguard Worker 
DupCertBuffer()962*6777b538SAndroid Build Coastguard Worker bssl::UniquePtr<CRYPTO_BUFFER> CertBuilder::DupCertBuffer() {
963*6777b538SAndroid Build Coastguard Worker   return bssl::UpRef(GetCertBuffer());
964*6777b538SAndroid Build Coastguard Worker }
965*6777b538SAndroid Build Coastguard Worker 
GetSubject()966*6777b538SAndroid Build Coastguard Worker const std::string& CertBuilder::GetSubject() {
967*6777b538SAndroid Build Coastguard Worker   if (subject_tlv_.empty())
968*6777b538SAndroid Build Coastguard Worker     GenerateSubject();
969*6777b538SAndroid Build Coastguard Worker   return subject_tlv_;
970*6777b538SAndroid Build Coastguard Worker }
971*6777b538SAndroid Build Coastguard Worker 
GetSerialNumber()972*6777b538SAndroid Build Coastguard Worker uint64_t CertBuilder::GetSerialNumber() {
973*6777b538SAndroid Build Coastguard Worker   if (!serial_number_)
974*6777b538SAndroid Build Coastguard Worker     serial_number_ = base::RandUint64();
975*6777b538SAndroid Build Coastguard Worker   return serial_number_;
976*6777b538SAndroid Build Coastguard Worker }
977*6777b538SAndroid Build Coastguard Worker 
GetSubjectKeyIdentifier()978*6777b538SAndroid Build Coastguard Worker std::string CertBuilder::GetSubjectKeyIdentifier() {
979*6777b538SAndroid Build Coastguard Worker   std::string ski_oid =
980*6777b538SAndroid Build Coastguard Worker       bssl::der::Input(bssl::kSubjectKeyIdentifierOid).AsString();
981*6777b538SAndroid Build Coastguard Worker   if (extensions_.find(ski_oid) == extensions_.end()) {
982*6777b538SAndroid Build Coastguard Worker     // If no SKI is present, this means that the certificate was either
983*6777b538SAndroid Build Coastguard Worker     // created by FromStaticCert() and lacked one, or it was explicitly
984*6777b538SAndroid Build Coastguard Worker     // deleted as an extension.
985*6777b538SAndroid Build Coastguard Worker     return std::string();
986*6777b538SAndroid Build Coastguard Worker   }
987*6777b538SAndroid Build Coastguard Worker 
988*6777b538SAndroid Build Coastguard Worker   auto& extension_value = extensions_[ski_oid];
989*6777b538SAndroid Build Coastguard Worker   bssl::der::Input ski_value;
990*6777b538SAndroid Build Coastguard Worker   if (!bssl::ParseSubjectKeyIdentifier(bssl::der::Input(extension_value.value),
991*6777b538SAndroid Build Coastguard Worker                                        &ski_value)) {
992*6777b538SAndroid Build Coastguard Worker     return std::string();
993*6777b538SAndroid Build Coastguard Worker   }
994*6777b538SAndroid Build Coastguard Worker   return ski_value.AsString();
995*6777b538SAndroid Build Coastguard Worker }
996*6777b538SAndroid Build Coastguard Worker 
GetValidity(base::Time * not_before,base::Time * not_after) const997*6777b538SAndroid Build Coastguard Worker bool CertBuilder::GetValidity(base::Time* not_before,
998*6777b538SAndroid Build Coastguard Worker                               base::Time* not_after) const {
999*6777b538SAndroid Build Coastguard Worker   bssl::der::GeneralizedTime not_before_generalized_time;
1000*6777b538SAndroid Build Coastguard Worker   bssl::der::GeneralizedTime not_after_generalized_time;
1001*6777b538SAndroid Build Coastguard Worker   if (!bssl::ParseValidity(bssl::der::Input(validity_tlv_),
1002*6777b538SAndroid Build Coastguard Worker                            &not_before_generalized_time,
1003*6777b538SAndroid Build Coastguard Worker                            &not_after_generalized_time) ||
1004*6777b538SAndroid Build Coastguard Worker       !GeneralizedTimeToTime(not_before_generalized_time, not_before) ||
1005*6777b538SAndroid Build Coastguard Worker       !GeneralizedTimeToTime(not_after_generalized_time, not_after)) {
1006*6777b538SAndroid Build Coastguard Worker     return false;
1007*6777b538SAndroid Build Coastguard Worker   }
1008*6777b538SAndroid Build Coastguard Worker   return true;
1009*6777b538SAndroid Build Coastguard Worker }
1010*6777b538SAndroid Build Coastguard Worker 
GetKey()1011*6777b538SAndroid Build Coastguard Worker EVP_PKEY* CertBuilder::GetKey() {
1012*6777b538SAndroid Build Coastguard Worker   if (!key_) {
1013*6777b538SAndroid Build Coastguard Worker     switch (default_pkey_id_) {
1014*6777b538SAndroid Build Coastguard Worker       case EVP_PKEY_RSA:
1015*6777b538SAndroid Build Coastguard Worker         GenerateRSAKey();
1016*6777b538SAndroid Build Coastguard Worker         break;
1017*6777b538SAndroid Build Coastguard Worker       case EVP_PKEY_EC:
1018*6777b538SAndroid Build Coastguard Worker         GenerateECKey();
1019*6777b538SAndroid Build Coastguard Worker         break;
1020*6777b538SAndroid Build Coastguard Worker     }
1021*6777b538SAndroid Build Coastguard Worker   }
1022*6777b538SAndroid Build Coastguard Worker   return key_.get();
1023*6777b538SAndroid Build Coastguard Worker }
1024*6777b538SAndroid Build Coastguard Worker 
GetX509Certificate()1025*6777b538SAndroid Build Coastguard Worker scoped_refptr<X509Certificate> CertBuilder::GetX509Certificate() {
1026*6777b538SAndroid Build Coastguard Worker   return X509Certificate::CreateFromBuffer(DupCertBuffer(), {});
1027*6777b538SAndroid Build Coastguard Worker }
1028*6777b538SAndroid Build Coastguard Worker 
GetX509CertificateChain()1029*6777b538SAndroid Build Coastguard Worker scoped_refptr<X509Certificate> CertBuilder::GetX509CertificateChain() {
1030*6777b538SAndroid Build Coastguard Worker   std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1031*6777b538SAndroid Build Coastguard Worker   // Add intermediates, not including the self-signed root.
1032*6777b538SAndroid Build Coastguard Worker   for (CertBuilder* cert = issuer_; cert && cert != cert->issuer_;
1033*6777b538SAndroid Build Coastguard Worker        cert = cert->issuer_) {
1034*6777b538SAndroid Build Coastguard Worker     intermediates.push_back(cert->DupCertBuffer());
1035*6777b538SAndroid Build Coastguard Worker   }
1036*6777b538SAndroid Build Coastguard Worker   return X509Certificate::CreateFromBuffer(DupCertBuffer(),
1037*6777b538SAndroid Build Coastguard Worker                                            std::move(intermediates));
1038*6777b538SAndroid Build Coastguard Worker }
1039*6777b538SAndroid Build Coastguard Worker 
GetX509CertificateFullChain()1040*6777b538SAndroid Build Coastguard Worker scoped_refptr<X509Certificate> CertBuilder::GetX509CertificateFullChain() {
1041*6777b538SAndroid Build Coastguard Worker   std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1042*6777b538SAndroid Build Coastguard Worker   // Add intermediates and the self-signed root.
1043*6777b538SAndroid Build Coastguard Worker   for (CertBuilder* cert = issuer_; cert; cert = cert->issuer_) {
1044*6777b538SAndroid Build Coastguard Worker     intermediates.push_back(cert->DupCertBuffer());
1045*6777b538SAndroid Build Coastguard Worker     if (cert == cert->issuer_)
1046*6777b538SAndroid Build Coastguard Worker       break;
1047*6777b538SAndroid Build Coastguard Worker   }
1048*6777b538SAndroid Build Coastguard Worker   return X509Certificate::CreateFromBuffer(DupCertBuffer(),
1049*6777b538SAndroid Build Coastguard Worker                                            std::move(intermediates));
1050*6777b538SAndroid Build Coastguard Worker }
1051*6777b538SAndroid Build Coastguard Worker 
GetDER()1052*6777b538SAndroid Build Coastguard Worker std::string CertBuilder::GetDER() {
1053*6777b538SAndroid Build Coastguard Worker   return std::string(x509_util::CryptoBufferAsStringPiece(GetCertBuffer()));
1054*6777b538SAndroid Build Coastguard Worker }
1055*6777b538SAndroid Build Coastguard Worker 
GetPEM()1056*6777b538SAndroid Build Coastguard Worker std::string CertBuilder::GetPEM() {
1057*6777b538SAndroid Build Coastguard Worker   std::string pem_encoded;
1058*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(X509Certificate::GetPEMEncoded(GetCertBuffer(), &pem_encoded));
1059*6777b538SAndroid Build Coastguard Worker   return pem_encoded;
1060*6777b538SAndroid Build Coastguard Worker }
1061*6777b538SAndroid Build Coastguard Worker 
GetPEMFullChain()1062*6777b538SAndroid Build Coastguard Worker std::string CertBuilder::GetPEMFullChain() {
1063*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> pems;
1064*6777b538SAndroid Build Coastguard Worker   CertBuilder* cert = this;
1065*6777b538SAndroid Build Coastguard Worker   while (cert) {
1066*6777b538SAndroid Build Coastguard Worker     pems.push_back(cert->GetPEM());
1067*6777b538SAndroid Build Coastguard Worker     if (cert == cert->issuer_)
1068*6777b538SAndroid Build Coastguard Worker       break;
1069*6777b538SAndroid Build Coastguard Worker     cert = cert->issuer_;
1070*6777b538SAndroid Build Coastguard Worker   }
1071*6777b538SAndroid Build Coastguard Worker   return base::JoinString(pems, "\n");
1072*6777b538SAndroid Build Coastguard Worker }
1073*6777b538SAndroid Build Coastguard Worker 
GetPrivateKeyPEM()1074*6777b538SAndroid Build Coastguard Worker std::string CertBuilder::GetPrivateKeyPEM() {
1075*6777b538SAndroid Build Coastguard Worker   std::string pem_encoded = key_util::PEMFromPrivateKey(GetKey());
1076*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(pem_encoded.empty());
1077*6777b538SAndroid Build Coastguard Worker   return pem_encoded;
1078*6777b538SAndroid Build Coastguard Worker }
1079*6777b538SAndroid Build Coastguard Worker 
CertBuilder(CRYPTO_BUFFER * orig_cert,CertBuilder * issuer,bool unique_subject_key_identifier)1080*6777b538SAndroid Build Coastguard Worker CertBuilder::CertBuilder(CRYPTO_BUFFER* orig_cert,
1081*6777b538SAndroid Build Coastguard Worker                          CertBuilder* issuer,
1082*6777b538SAndroid Build Coastguard Worker                          bool unique_subject_key_identifier)
1083*6777b538SAndroid Build Coastguard Worker     : issuer_(issuer) {
1084*6777b538SAndroid Build Coastguard Worker   if (!issuer_)
1085*6777b538SAndroid Build Coastguard Worker     issuer_ = this;
1086*6777b538SAndroid Build Coastguard Worker 
1087*6777b538SAndroid Build Coastguard Worker   crypto::EnsureOpenSSLInit();
1088*6777b538SAndroid Build Coastguard Worker   if (orig_cert)
1089*6777b538SAndroid Build Coastguard Worker     InitFromCert(
1090*6777b538SAndroid Build Coastguard Worker         bssl::der::Input(x509_util::CryptoBufferAsStringPiece(orig_cert)));
1091*6777b538SAndroid Build Coastguard Worker 
1092*6777b538SAndroid Build Coastguard Worker   if (unique_subject_key_identifier) {
1093*6777b538SAndroid Build Coastguard Worker     GenerateSubjectKeyIdentifier();
1094*6777b538SAndroid Build Coastguard Worker     SetAuthorityKeyIdentifier(issuer_->GetSubjectKeyIdentifier());
1095*6777b538SAndroid Build Coastguard Worker   }
1096*6777b538SAndroid Build Coastguard Worker }
1097*6777b538SAndroid Build Coastguard Worker 
Invalidate()1098*6777b538SAndroid Build Coastguard Worker void CertBuilder::Invalidate() {
1099*6777b538SAndroid Build Coastguard Worker   cert_.reset();
1100*6777b538SAndroid Build Coastguard Worker }
1101*6777b538SAndroid Build Coastguard Worker 
GenerateECKey()1102*6777b538SAndroid Build Coastguard Worker void CertBuilder::GenerateECKey() {
1103*6777b538SAndroid Build Coastguard Worker   auto private_key = crypto::ECPrivateKey::Create();
1104*6777b538SAndroid Build Coastguard Worker   SetKey(bssl::UpRef(private_key->key()));
1105*6777b538SAndroid Build Coastguard Worker }
1106*6777b538SAndroid Build Coastguard Worker 
GenerateRSAKey()1107*6777b538SAndroid Build Coastguard Worker void CertBuilder::GenerateRSAKey() {
1108*6777b538SAndroid Build Coastguard Worker   auto private_key = crypto::RSAPrivateKey::Create(2048);
1109*6777b538SAndroid Build Coastguard Worker   SetKey(bssl::UpRef(private_key->key()));
1110*6777b538SAndroid Build Coastguard Worker }
1111*6777b538SAndroid Build Coastguard Worker 
UseKeyFromFile(const base::FilePath & key_file)1112*6777b538SAndroid Build Coastguard Worker bool CertBuilder::UseKeyFromFile(const base::FilePath& key_file) {
1113*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> private_key(
1114*6777b538SAndroid Build Coastguard Worker       key_util::LoadEVP_PKEYFromPEM(key_file));
1115*6777b538SAndroid Build Coastguard Worker   if (!private_key)
1116*6777b538SAndroid Build Coastguard Worker     return false;
1117*6777b538SAndroid Build Coastguard Worker   SetKey(std::move(private_key));
1118*6777b538SAndroid Build Coastguard Worker   return true;
1119*6777b538SAndroid Build Coastguard Worker }
1120*6777b538SAndroid Build Coastguard Worker 
SetKey(bssl::UniquePtr<EVP_PKEY> key)1121*6777b538SAndroid Build Coastguard Worker void CertBuilder::SetKey(bssl::UniquePtr<EVP_PKEY> key) {
1122*6777b538SAndroid Build Coastguard Worker   key_ = std::move(key);
1123*6777b538SAndroid Build Coastguard Worker   Invalidate();
1124*6777b538SAndroid Build Coastguard Worker }
1125*6777b538SAndroid Build Coastguard Worker 
GenerateSubjectKeyIdentifier()1126*6777b538SAndroid Build Coastguard Worker void CertBuilder::GenerateSubjectKeyIdentifier() {
1127*6777b538SAndroid Build Coastguard Worker   // 20 bytes are chosen here for no other reason than it's compatible with
1128*6777b538SAndroid Build Coastguard Worker   // systems that assume the SKI is SHA-1(SPKI), which RFC 5280 notes as one
1129*6777b538SAndroid Build Coastguard Worker   // mechanism for generating an SKI, while also noting that random/unique
1130*6777b538SAndroid Build Coastguard Worker   // SKIs are also fine.
1131*6777b538SAndroid Build Coastguard Worker   std::string random_ski = base::RandBytesAsString(20);
1132*6777b538SAndroid Build Coastguard Worker   SetSubjectKeyIdentifier(random_ski);
1133*6777b538SAndroid Build Coastguard Worker }
1134*6777b538SAndroid Build Coastguard Worker 
GenerateSubject()1135*6777b538SAndroid Build Coastguard Worker void CertBuilder::GenerateSubject() {
1136*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(subject_tlv_.empty());
1137*6777b538SAndroid Build Coastguard Worker 
1138*6777b538SAndroid Build Coastguard Worker   // Use a random common name comprised of 12 bytes in hex.
1139*6777b538SAndroid Build Coastguard Worker   std::string common_name = MakeRandomHexString(12);
1140*6777b538SAndroid Build Coastguard Worker 
1141*6777b538SAndroid Build Coastguard Worker   SetSubjectCommonName(common_name);
1142*6777b538SAndroid Build Coastguard Worker }
1143*6777b538SAndroid Build Coastguard Worker 
InitFromCert(const bssl::der::Input & cert)1144*6777b538SAndroid Build Coastguard Worker void CertBuilder::InitFromCert(const bssl::der::Input& cert) {
1145*6777b538SAndroid Build Coastguard Worker   extensions_.clear();
1146*6777b538SAndroid Build Coastguard Worker   Invalidate();
1147*6777b538SAndroid Build Coastguard Worker 
1148*6777b538SAndroid Build Coastguard Worker   // From RFC 5280, section 4.1
1149*6777b538SAndroid Build Coastguard Worker   //    Certificate  ::=  SEQUENCE  {
1150*6777b538SAndroid Build Coastguard Worker   //      tbsCertificate       TBSCertificate,
1151*6777b538SAndroid Build Coastguard Worker   //      signatureAlgorithm   AlgorithmIdentifier,
1152*6777b538SAndroid Build Coastguard Worker   //      signatureValue       BIT STRING  }
1153*6777b538SAndroid Build Coastguard Worker 
1154*6777b538SAndroid Build Coastguard Worker   // TBSCertificate  ::=  SEQUENCE  {
1155*6777b538SAndroid Build Coastguard Worker   //      version         [0]  EXPLICIT Version DEFAULT v1,
1156*6777b538SAndroid Build Coastguard Worker   //      serialNumber         CertificateSerialNumber,
1157*6777b538SAndroid Build Coastguard Worker   //      signature            AlgorithmIdentifier,
1158*6777b538SAndroid Build Coastguard Worker   //      issuer               Name,
1159*6777b538SAndroid Build Coastguard Worker   //      validity             Validity,
1160*6777b538SAndroid Build Coastguard Worker   //      subject              Name,
1161*6777b538SAndroid Build Coastguard Worker   //      subjectPublicKeyInfo SubjectPublicKeyInfo,
1162*6777b538SAndroid Build Coastguard Worker   //      issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
1163*6777b538SAndroid Build Coastguard Worker   //                           -- If present, version MUST be v2 or v3
1164*6777b538SAndroid Build Coastguard Worker   //      subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
1165*6777b538SAndroid Build Coastguard Worker   //                           -- If present, version MUST be v2 or v3
1166*6777b538SAndroid Build Coastguard Worker   //      extensions      [3]  EXPLICIT Extensions OPTIONAL
1167*6777b538SAndroid Build Coastguard Worker   //                           -- If present, version MUST be v3
1168*6777b538SAndroid Build Coastguard Worker   //      }
1169*6777b538SAndroid Build Coastguard Worker   bssl::der::Parser parser(cert);
1170*6777b538SAndroid Build Coastguard Worker   bssl::der::Parser certificate;
1171*6777b538SAndroid Build Coastguard Worker   bssl::der::Parser tbs_certificate;
1172*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(parser.ReadSequence(&certificate));
1173*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(certificate.ReadSequence(&tbs_certificate));
1174*6777b538SAndroid Build Coastguard Worker 
1175*6777b538SAndroid Build Coastguard Worker   // version
1176*6777b538SAndroid Build Coastguard Worker   bool has_version;
1177*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(tbs_certificate.SkipOptionalTag(
1178*6777b538SAndroid Build Coastguard Worker       CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0, &has_version));
1179*6777b538SAndroid Build Coastguard Worker   if (has_version) {
1180*6777b538SAndroid Build Coastguard Worker     // TODO(mattm): could actually parse the version here instead of assuming
1181*6777b538SAndroid Build Coastguard Worker     // V3.
1182*6777b538SAndroid Build Coastguard Worker     version_ = bssl::CertificateVersion::V3;
1183*6777b538SAndroid Build Coastguard Worker   } else {
1184*6777b538SAndroid Build Coastguard Worker     version_ = bssl::CertificateVersion::V1;
1185*6777b538SAndroid Build Coastguard Worker   }
1186*6777b538SAndroid Build Coastguard Worker 
1187*6777b538SAndroid Build Coastguard Worker   // serialNumber
1188*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(tbs_certificate.SkipTag(CBS_ASN1_INTEGER));
1189*6777b538SAndroid Build Coastguard Worker 
1190*6777b538SAndroid Build Coastguard Worker   // signature
1191*6777b538SAndroid Build Coastguard Worker   bssl::der::Input signature_algorithm_tlv;
1192*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(tbs_certificate.ReadRawTLV(&signature_algorithm_tlv));
1193*6777b538SAndroid Build Coastguard Worker   auto signature_algorithm =
1194*6777b538SAndroid Build Coastguard Worker       bssl::ParseSignatureAlgorithm(signature_algorithm_tlv);
1195*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(signature_algorithm);
1196*6777b538SAndroid Build Coastguard Worker   signature_algorithm_ = *signature_algorithm;
1197*6777b538SAndroid Build Coastguard Worker 
1198*6777b538SAndroid Build Coastguard Worker   // issuer
1199*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(tbs_certificate.SkipTag(CBS_ASN1_SEQUENCE));
1200*6777b538SAndroid Build Coastguard Worker 
1201*6777b538SAndroid Build Coastguard Worker   // validity
1202*6777b538SAndroid Build Coastguard Worker   bssl::der::Input validity_tlv;
1203*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(tbs_certificate.ReadRawTLV(&validity_tlv));
1204*6777b538SAndroid Build Coastguard Worker   validity_tlv_ = validity_tlv.AsString();
1205*6777b538SAndroid Build Coastguard Worker 
1206*6777b538SAndroid Build Coastguard Worker   // subject
1207*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(tbs_certificate.SkipTag(CBS_ASN1_SEQUENCE));
1208*6777b538SAndroid Build Coastguard Worker 
1209*6777b538SAndroid Build Coastguard Worker   // subjectPublicKeyInfo
1210*6777b538SAndroid Build Coastguard Worker   bssl::der::Input spki_tlv;
1211*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(tbs_certificate.ReadRawTLV(&spki_tlv));
1212*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> public_key;
1213*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(bssl::ParsePublicKey(spki_tlv, &public_key));
1214*6777b538SAndroid Build Coastguard Worker   default_pkey_id_ = EVP_PKEY_id(public_key.get());
1215*6777b538SAndroid Build Coastguard Worker 
1216*6777b538SAndroid Build Coastguard Worker   // issuerUniqueID
1217*6777b538SAndroid Build Coastguard Worker   bool unused;
1218*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
1219*6777b538SAndroid Build Coastguard Worker       tbs_certificate.SkipOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 1, &unused));
1220*6777b538SAndroid Build Coastguard Worker   // subjectUniqueID
1221*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
1222*6777b538SAndroid Build Coastguard Worker       tbs_certificate.SkipOptionalTag(CBS_ASN1_CONTEXT_SPECIFIC | 2, &unused));
1223*6777b538SAndroid Build Coastguard Worker 
1224*6777b538SAndroid Build Coastguard Worker   // extensions
1225*6777b538SAndroid Build Coastguard Worker   std::optional<bssl::der::Input> extensions_tlv;
1226*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(tbs_certificate.ReadOptionalTag(
1227*6777b538SAndroid Build Coastguard Worker       CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3, &extensions_tlv));
1228*6777b538SAndroid Build Coastguard Worker   if (extensions_tlv) {
1229*6777b538SAndroid Build Coastguard Worker     std::map<bssl::der::Input, bssl::ParsedExtension> parsed_extensions;
1230*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(ParseExtensions(extensions_tlv.value(), &parsed_extensions));
1231*6777b538SAndroid Build Coastguard Worker 
1232*6777b538SAndroid Build Coastguard Worker     for (const auto& parsed_extension : parsed_extensions) {
1233*6777b538SAndroid Build Coastguard Worker       SetExtension(parsed_extension.second.oid,
1234*6777b538SAndroid Build Coastguard Worker                    parsed_extension.second.value.AsString(),
1235*6777b538SAndroid Build Coastguard Worker                    parsed_extension.second.critical);
1236*6777b538SAndroid Build Coastguard Worker     }
1237*6777b538SAndroid Build Coastguard Worker   }
1238*6777b538SAndroid Build Coastguard Worker }
1239*6777b538SAndroid Build Coastguard Worker 
BuildTBSCertificate(std::string_view signature_algorithm_tlv,std::string * out)1240*6777b538SAndroid Build Coastguard Worker void CertBuilder::BuildTBSCertificate(std::string_view signature_algorithm_tlv,
1241*6777b538SAndroid Build Coastguard Worker                                       std::string* out) {
1242*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
1243*6777b538SAndroid Build Coastguard Worker   CBB tbs_cert, version, extensions_context, extensions;
1244*6777b538SAndroid Build Coastguard Worker 
1245*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 64));
1246*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE));
1247*6777b538SAndroid Build Coastguard Worker   if (version_ != bssl::CertificateVersion::V1) {
1248*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
1249*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1(&tbs_cert, &version,
1250*6777b538SAndroid Build Coastguard Worker                      CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0));
1251*6777b538SAndroid Build Coastguard Worker     switch (version_) {
1252*6777b538SAndroid Build Coastguard Worker       case bssl::CertificateVersion::V2:
1253*6777b538SAndroid Build Coastguard Worker         ASSERT_TRUE(CBB_add_asn1_uint64(&version, 1));
1254*6777b538SAndroid Build Coastguard Worker         break;
1255*6777b538SAndroid Build Coastguard Worker       case bssl::CertificateVersion::V3:
1256*6777b538SAndroid Build Coastguard Worker         ASSERT_TRUE(CBB_add_asn1_uint64(&version, 2));
1257*6777b538SAndroid Build Coastguard Worker         break;
1258*6777b538SAndroid Build Coastguard Worker       case bssl::CertificateVersion::V1:
1259*6777b538SAndroid Build Coastguard Worker         NOTREACHED_NORETURN();
1260*6777b538SAndroid Build Coastguard Worker     }
1261*6777b538SAndroid Build Coastguard Worker   }
1262*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1_uint64(&tbs_cert, GetSerialNumber()));
1263*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBBAddBytes(&tbs_cert, signature_algorithm_tlv));
1264*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBBAddBytes(&tbs_cert, issuer_tlv_.has_value()
1265*6777b538SAndroid Build Coastguard Worker                                          ? *issuer_tlv_
1266*6777b538SAndroid Build Coastguard Worker                                          : issuer_->GetSubject()));
1267*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBBAddBytes(&tbs_cert, validity_tlv_));
1268*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBBAddBytes(&tbs_cert, GetSubject()));
1269*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(GetKey());
1270*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_marshal_public_key(&tbs_cert, GetKey()));
1271*6777b538SAndroid Build Coastguard Worker 
1272*6777b538SAndroid Build Coastguard Worker   // Serialize all the extensions.
1273*6777b538SAndroid Build Coastguard Worker   if (!extensions_.empty()) {
1274*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
1275*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1(&tbs_cert, &extensions_context,
1276*6777b538SAndroid Build Coastguard Worker                      CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3));
1277*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
1278*6777b538SAndroid Build Coastguard Worker         CBB_add_asn1(&extensions_context, &extensions, CBS_ASN1_SEQUENCE));
1279*6777b538SAndroid Build Coastguard Worker 
1280*6777b538SAndroid Build Coastguard Worker     //   Extension  ::=  SEQUENCE  {
1281*6777b538SAndroid Build Coastguard Worker     //        extnID      OBJECT IDENTIFIER,
1282*6777b538SAndroid Build Coastguard Worker     //        critical    BOOLEAN DEFAULT FALSE,
1283*6777b538SAndroid Build Coastguard Worker     //        extnValue   OCTET STRING
1284*6777b538SAndroid Build Coastguard Worker     //                    -- contains the DER encoding of an ASN.1 value
1285*6777b538SAndroid Build Coastguard Worker     //                    -- corresponding to the extension type identified
1286*6777b538SAndroid Build Coastguard Worker     //                    -- by extnID
1287*6777b538SAndroid Build Coastguard Worker     //        }
1288*6777b538SAndroid Build Coastguard Worker     for (const auto& extension_it : extensions_) {
1289*6777b538SAndroid Build Coastguard Worker       CBB extension_seq, oid, extn_value;
1290*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_add_asn1(&extensions, &extension_seq, CBS_ASN1_SEQUENCE));
1291*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_add_asn1(&extension_seq, &oid, CBS_ASN1_OBJECT));
1292*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBBAddBytes(&oid, extension_it.first));
1293*6777b538SAndroid Build Coastguard Worker       if (extension_it.second.critical) {
1294*6777b538SAndroid Build Coastguard Worker         ASSERT_TRUE(CBB_add_asn1_bool(&extension_seq, true));
1295*6777b538SAndroid Build Coastguard Worker       }
1296*6777b538SAndroid Build Coastguard Worker 
1297*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(
1298*6777b538SAndroid Build Coastguard Worker           CBB_add_asn1(&extension_seq, &extn_value, CBS_ASN1_OCTETSTRING));
1299*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBBAddBytes(&extn_value, extension_it.second.value));
1300*6777b538SAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_flush(&extensions));
1301*6777b538SAndroid Build Coastguard Worker     }
1302*6777b538SAndroid Build Coastguard Worker   }
1303*6777b538SAndroid Build Coastguard Worker 
1304*6777b538SAndroid Build Coastguard Worker   *out = FinishCBB(cbb.get());
1305*6777b538SAndroid Build Coastguard Worker }
1306*6777b538SAndroid Build Coastguard Worker 
BuildSctListExtension(const std::string & pre_tbs_certificate,std::string * out)1307*6777b538SAndroid Build Coastguard Worker void CertBuilder::BuildSctListExtension(const std::string& pre_tbs_certificate,
1308*6777b538SAndroid Build Coastguard Worker                                         std::string* out) {
1309*6777b538SAndroid Build Coastguard Worker   std::vector<std::string> encoded_scts;
1310*6777b538SAndroid Build Coastguard Worker   for (const SctConfig& sct_config : sct_configs_) {
1311*6777b538SAndroid Build Coastguard Worker     ct::SignedEntryData entry;
1312*6777b538SAndroid Build Coastguard Worker     entry.type = ct::SignedEntryData::LOG_ENTRY_TYPE_PRECERT;
1313*6777b538SAndroid Build Coastguard Worker     bssl::ScopedCBB issuer_spki_cbb;
1314*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_init(issuer_spki_cbb.get(), 32));
1315*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(
1316*6777b538SAndroid Build Coastguard Worker         EVP_marshal_public_key(issuer_spki_cbb.get(), issuer_->GetKey()));
1317*6777b538SAndroid Build Coastguard Worker     crypto::SHA256HashString(FinishCBB(issuer_spki_cbb.get()),
1318*6777b538SAndroid Build Coastguard Worker                              entry.issuer_key_hash.data,
1319*6777b538SAndroid Build Coastguard Worker                              sizeof(entry.issuer_key_hash.data));
1320*6777b538SAndroid Build Coastguard Worker     entry.tbs_certificate = pre_tbs_certificate;
1321*6777b538SAndroid Build Coastguard Worker 
1322*6777b538SAndroid Build Coastguard Worker     std::string serialized_log_entry;
1323*6777b538SAndroid Build Coastguard Worker     std::string serialized_data;
1324*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(ct::EncodeSignedEntry(entry, &serialized_log_entry));
1325*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(ct::EncodeV1SCTSignedData(sct_config.timestamp,
1326*6777b538SAndroid Build Coastguard Worker                                           serialized_log_entry,
1327*6777b538SAndroid Build Coastguard Worker                                           /*extensions=*/"", &serialized_data));
1328*6777b538SAndroid Build Coastguard Worker 
1329*6777b538SAndroid Build Coastguard Worker     scoped_refptr<ct::SignedCertificateTimestamp> sct =
1330*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<ct::SignedCertificateTimestamp>();
1331*6777b538SAndroid Build Coastguard Worker     sct->log_id = sct_config.log_id;
1332*6777b538SAndroid Build Coastguard Worker     sct->timestamp = sct_config.timestamp;
1333*6777b538SAndroid Build Coastguard Worker     sct->signature.hash_algorithm = ct::DigitallySigned::HASH_ALGO_SHA256;
1334*6777b538SAndroid Build Coastguard Worker     sct->signature.signature_algorithm = ct::DigitallySigned::SIG_ALGO_ECDSA;
1335*6777b538SAndroid Build Coastguard Worker 
1336*6777b538SAndroid Build Coastguard Worker     bssl::ScopedCBB sct_signature_cbb;
1337*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(CBB_init(sct_signature_cbb.get(), 0));
1338*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(SignData(bssl::SignatureAlgorithm::kEcdsaSha256,
1339*6777b538SAndroid Build Coastguard Worker                          serialized_data, sct_config.log_key.get(),
1340*6777b538SAndroid Build Coastguard Worker                          sct_signature_cbb.get()));
1341*6777b538SAndroid Build Coastguard Worker     sct->signature.signature_data = FinishCBB(sct_signature_cbb.get());
1342*6777b538SAndroid Build Coastguard Worker 
1343*6777b538SAndroid Build Coastguard Worker     sct->origin = ct::SignedCertificateTimestamp::SCT_EMBEDDED;
1344*6777b538SAndroid Build Coastguard Worker 
1345*6777b538SAndroid Build Coastguard Worker     std::string encoded_sct;
1346*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(ct::EncodeSignedCertificateTimestamp(sct, &encoded_sct));
1347*6777b538SAndroid Build Coastguard Worker     encoded_scts.push_back(std::move(encoded_sct));
1348*6777b538SAndroid Build Coastguard Worker   }
1349*6777b538SAndroid Build Coastguard Worker   std::string encoded_sct_list;
1350*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(ct::EncodeSCTListForTesting(encoded_scts, &encoded_sct_list));
1351*6777b538SAndroid Build Coastguard Worker 
1352*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB sct_extension_cbb;
1353*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(sct_extension_cbb.get(), 32));
1354*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1_octet_string(
1355*6777b538SAndroid Build Coastguard Worker       sct_extension_cbb.get(),
1356*6777b538SAndroid Build Coastguard Worker       reinterpret_cast<const uint8_t*>(encoded_sct_list.data()),
1357*6777b538SAndroid Build Coastguard Worker       encoded_sct_list.size()));
1358*6777b538SAndroid Build Coastguard Worker 
1359*6777b538SAndroid Build Coastguard Worker   *out = FinishCBB(sct_extension_cbb.get());
1360*6777b538SAndroid Build Coastguard Worker }
1361*6777b538SAndroid Build Coastguard Worker 
GenerateCertificate()1362*6777b538SAndroid Build Coastguard Worker void CertBuilder::GenerateCertificate() {
1363*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(cert_);
1364*6777b538SAndroid Build Coastguard Worker 
1365*6777b538SAndroid Build Coastguard Worker   std::optional<bssl::SignatureAlgorithm> signature_algorithm =
1366*6777b538SAndroid Build Coastguard Worker       signature_algorithm_;
1367*6777b538SAndroid Build Coastguard Worker   if (!signature_algorithm)
1368*6777b538SAndroid Build Coastguard Worker     signature_algorithm = DefaultSignatureAlgorithmForKey(issuer_->GetKey());
1369*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(signature_algorithm.has_value());
1370*6777b538SAndroid Build Coastguard Worker 
1371*6777b538SAndroid Build Coastguard Worker   std::string signature_algorithm_tlv =
1372*6777b538SAndroid Build Coastguard Worker       !outer_signature_algorithm_tlv_.empty()
1373*6777b538SAndroid Build Coastguard Worker           ? outer_signature_algorithm_tlv_
1374*6777b538SAndroid Build Coastguard Worker           : SignatureAlgorithmToDer(*signature_algorithm);
1375*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(signature_algorithm_tlv.empty());
1376*6777b538SAndroid Build Coastguard Worker 
1377*6777b538SAndroid Build Coastguard Worker   std::string tbs_signature_algorithm_tlv =
1378*6777b538SAndroid Build Coastguard Worker       !tbs_signature_algorithm_tlv_.empty()
1379*6777b538SAndroid Build Coastguard Worker           ? tbs_signature_algorithm_tlv_
1380*6777b538SAndroid Build Coastguard Worker           : SignatureAlgorithmToDer(*signature_algorithm);
1381*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(tbs_signature_algorithm_tlv.empty());
1382*6777b538SAndroid Build Coastguard Worker 
1383*6777b538SAndroid Build Coastguard Worker   if (!sct_configs_.empty()) {
1384*6777b538SAndroid Build Coastguard Worker     EraseExtension(bssl::der::Input(ct::kEmbeddedSCTOid));
1385*6777b538SAndroid Build Coastguard Worker     std::string pre_tbs_certificate;
1386*6777b538SAndroid Build Coastguard Worker     BuildTBSCertificate(tbs_signature_algorithm_tlv, &pre_tbs_certificate);
1387*6777b538SAndroid Build Coastguard Worker     std::string sct_extension;
1388*6777b538SAndroid Build Coastguard Worker     BuildSctListExtension(pre_tbs_certificate, &sct_extension);
1389*6777b538SAndroid Build Coastguard Worker     SetExtension(bssl::der::Input(ct::kEmbeddedSCTOid), sct_extension,
1390*6777b538SAndroid Build Coastguard Worker                  /*critical=*/false);
1391*6777b538SAndroid Build Coastguard Worker   }
1392*6777b538SAndroid Build Coastguard Worker 
1393*6777b538SAndroid Build Coastguard Worker   std::string tbs_cert;
1394*6777b538SAndroid Build Coastguard Worker   BuildTBSCertificate(tbs_signature_algorithm_tlv, &tbs_cert);
1395*6777b538SAndroid Build Coastguard Worker 
1396*6777b538SAndroid Build Coastguard Worker   // Sign the TBSCertificate and write the entire certificate.
1397*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
1398*6777b538SAndroid Build Coastguard Worker   CBB cert, signature;
1399*6777b538SAndroid Build Coastguard Worker 
1400*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), tbs_cert.size()));
1401*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE));
1402*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBBAddBytes(&cert, tbs_cert));
1403*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBBAddBytes(&cert, signature_algorithm_tlv));
1404*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING));
1405*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_add_u8(&signature, 0 /* no unused bits */));
1406*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(
1407*6777b538SAndroid Build Coastguard Worker       SignData(*signature_algorithm, tbs_cert, issuer_->GetKey(), &signature));
1408*6777b538SAndroid Build Coastguard Worker 
1409*6777b538SAndroid Build Coastguard Worker   auto cert_der = FinishCBB(cbb.get());
1410*6777b538SAndroid Build Coastguard Worker   cert_ = x509_util::CreateCryptoBuffer(base::as_byte_span(cert_der));
1411*6777b538SAndroid Build Coastguard Worker }
1412*6777b538SAndroid Build Coastguard Worker 
1413*6777b538SAndroid Build Coastguard Worker }  // namespace net
1414