• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cert/x509_util.h"
6 
7 #include <string.h>
8 
9 #include <map>
10 #include <memory>
11 #include <string_view>
12 
13 #include "base/logging.h"
14 #include "base/memory/raw_ptr.h"
15 #include "base/notreached.h"
16 #include "base/strings/string_split.h"
17 #include "base/strings/string_util.h"
18 #include "base/time/time.h"
19 #include "build/build_config.h"
20 #include "crypto/openssl_util.h"
21 #include "crypto/rsa_private_key.h"
22 #include "crypto/sha2.h"
23 #include "net/base/hash_value.h"
24 #include "net/cert/asn1_util.h"
25 #include "net/cert/time_conversions.h"
26 #include "net/cert/x509_certificate.h"
27 #include "third_party/boringssl/src/include/openssl/bytestring.h"
28 #include "third_party/boringssl/src/include/openssl/digest.h"
29 #include "third_party/boringssl/src/include/openssl/ec.h"
30 #include "third_party/boringssl/src/include/openssl/ec_key.h"
31 #include "third_party/boringssl/src/include/openssl/evp.h"
32 #include "third_party/boringssl/src/include/openssl/mem.h"
33 #include "third_party/boringssl/src/include/openssl/pkcs7.h"
34 #include "third_party/boringssl/src/include/openssl/pool.h"
35 #include "third_party/boringssl/src/include/openssl/stack.h"
36 #include "third_party/boringssl/src/pki/cert_errors.h"
37 #include "third_party/boringssl/src/pki/input.h"
38 #include "third_party/boringssl/src/pki/name_constraints.h"
39 #include "third_party/boringssl/src/pki/parse_certificate.h"
40 #include "third_party/boringssl/src/pki/parse_name.h"
41 #include "third_party/boringssl/src/pki/parse_values.h"
42 #include "third_party/boringssl/src/pki/signature_algorithm.h"
43 
44 namespace net::x509_util {
45 
46 namespace {
47 
AddSignatureAlgorithm(CBB * cbb,base::span<const uint8_t> oid_bytes,bool null_param)48 bool AddSignatureAlgorithm(CBB* cbb,
49                            base::span<const uint8_t> oid_bytes,
50                            bool null_param) {
51   // An AlgorithmIdentifier is described in RFC 5280, 4.1.1.2.
52   CBB sequence, oid, params;
53   if (!CBB_add_asn1(cbb, &sequence, CBS_ASN1_SEQUENCE) ||
54       !CBB_add_asn1(&sequence, &oid, CBS_ASN1_OBJECT) ||
55       !CBB_add_bytes(&oid, oid_bytes.data(), oid_bytes.size()) ||
56       (null_param && !CBB_add_asn1(&sequence, &params, CBS_ASN1_NULL)) ||
57       !CBB_flush(cbb)) {
58     return false;
59   }
60   return true;
61 }
62 
AddSignatureAlgorithm(CBB * cbb,const EVP_PKEY * pkey,DigestAlgorithm digest_alg)63 bool AddSignatureAlgorithm(CBB* cbb,
64                            const EVP_PKEY* pkey,
65                            DigestAlgorithm digest_alg) {
66   if (digest_alg != DIGEST_SHA256) {
67     return false;
68   }
69 
70   if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
71     // See RFC 4055.
72     static const uint8_t kSHA256WithRSAEncryption[] = {
73         0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b};
74     // RSA always has null parameters.
75     return AddSignatureAlgorithm(cbb, kSHA256WithRSAEncryption,
76                                  /*null_param=*/true);
77   } else if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
78     // 1.2.840.10045.4.3.2
79     static const uint8_t kECDSAWithSHA256[] = {0x2a, 0x86, 0x48, 0xce,
80                                                0x3d, 0x04, 0x03, 0x02};
81     return AddSignatureAlgorithm(cbb, kECDSAWithSHA256,
82                                  /*null_param=*/false);
83   }
84   return false;
85 }
86 
ToEVP(DigestAlgorithm alg)87 const EVP_MD* ToEVP(DigestAlgorithm alg) {
88   switch (alg) {
89     case DIGEST_SHA256:
90       return EVP_sha256();
91   }
92   return nullptr;
93 }
94 
95 }  // namespace
96 
97 // Adds an X.509 Name with the specified distinguished name to |cbb|.
AddName(CBB * cbb,std::string_view name)98 bool AddName(CBB* cbb, std::string_view name) {
99   // See RFC 4519.
100   static const uint8_t kCommonName[] = {0x55, 0x04, 0x03};
101   static const uint8_t kCountryName[] = {0x55, 0x04, 0x06};
102   static const uint8_t kOrganizationName[] = {0x55, 0x04, 0x0a};
103   static const uint8_t kOrganizationalUnitName[] = {0x55, 0x04, 0x0b};
104 
105   std::vector<std::string> attributes = SplitString(
106       name, /*separators=*/",", base::WhitespaceHandling::TRIM_WHITESPACE,
107       base::SplitResult::SPLIT_WANT_NONEMPTY);
108 
109   if (attributes.size() == 0) {
110     LOG(ERROR) << "Missing DN or wrong format";
111     return false;
112   }
113 
114   // See RFC 5280, section 4.1.2.4.
115   CBB rdns;
116   if (!CBB_add_asn1(cbb, &rdns, CBS_ASN1_SEQUENCE)) {
117     return false;
118   }
119 
120   for (const std::string& attribute : attributes) {
121     std::vector<std::string> parts =
122         SplitString(attribute, /*separators=*/"=",
123                     base::WhitespaceHandling::KEEP_WHITESPACE,
124                     base::SplitResult::SPLIT_WANT_ALL);
125     if (parts.size() != 2) {
126       LOG(ERROR) << "Wrong DN format at " + attribute;
127       return false;
128     }
129 
130     const std::string& type_string = parts[0];
131     const std::string& value_string = parts[1];
132     base::span<const uint8_t> type_bytes;
133     if (type_string == "CN") {
134       type_bytes = kCommonName;
135     } else if (type_string == "C") {
136       type_bytes = kCountryName;
137     } else if (type_string == "O") {
138       type_bytes = kOrganizationName;
139     } else if (type_string == "OU") {
140       type_bytes = kOrganizationalUnitName;
141     } else {
142       LOG(ERROR) << "Unrecognized type " + type_string;
143       return false;
144     }
145 
146     CBB rdn, attr, type, value;
147     if (!CBB_add_asn1(&rdns, &rdn, CBS_ASN1_SET) ||
148         !CBB_add_asn1(&rdn, &attr, CBS_ASN1_SEQUENCE) ||
149         !CBB_add_asn1(&attr, &type, CBS_ASN1_OBJECT) ||
150         !CBB_add_bytes(&type, type_bytes.data(), type_bytes.size()) ||
151         !CBB_add_asn1(&attr, &value, type_string == "C" ?
152                           CBS_ASN1_PRINTABLESTRING : CBS_ASN1_UTF8STRING) ||
153         !CBB_add_bytes(&value,
154                        reinterpret_cast<const uint8_t*>(value_string.data()),
155                        value_string.size()) ||
156         !CBB_flush(&rdns)) {
157       return false;
158     }
159   }
160   if (!CBB_flush(cbb)) {
161     return false;
162   }
163   return true;
164 }
165 
ConvertToX509CertificatesIgnoreErrors(const std::vector<std::vector<uint8_t>> & certs_bytes)166 NET_EXPORT net::CertificateList ConvertToX509CertificatesIgnoreErrors(
167     const std::vector<std::vector<uint8_t>>& certs_bytes) {
168   net::CertificateList x509_certs;
169   for (const auto& cert_uint8 : certs_bytes) {
170     scoped_refptr<net::X509Certificate> x509_cert =
171         net::X509Certificate::CreateFromBytes(base::as_byte_span(cert_uint8));
172     if (x509_cert) {
173       x509_certs.push_back(std::move(x509_cert));
174     }
175   }
176   return x509_certs;
177 }
178 
ParseAllValidCerts(const CertificateList & x509_certs)179 bssl::ParsedCertificateList ParseAllValidCerts(
180     const CertificateList& x509_certs) {
181   bssl::ParsedCertificateList parsed_certs;
182   for (const auto& x509_cert : x509_certs) {
183     std::shared_ptr<const bssl::ParsedCertificate> cert =
184         bssl::ParsedCertificate::Create(
185             bssl::UpRef(x509_cert->cert_buffer()),
186             net::x509_util::DefaultParseCertificateOptions(), nullptr);
187     if (cert) {
188       parsed_certs.push_back(std::move(cert));
189     }
190   }
191 
192   return parsed_certs;
193 }
194 
CBBAddTime(CBB * cbb,base::Time time)195 bool CBBAddTime(CBB* cbb, base::Time time) {
196   bssl::der::GeneralizedTime generalized_time;
197   if (!EncodeTimeAsGeneralizedTime(time, &generalized_time)) {
198     return false;
199   }
200 
201   // Per RFC 5280, 4.1.2.5, times which fit in UTCTime must be encoded as
202   // UTCTime rather than GeneralizedTime.
203   CBB child;
204   uint8_t* out;
205   if (generalized_time.InUTCTimeRange()) {
206     return CBB_add_asn1(cbb, &child, CBS_ASN1_UTCTIME) &&
207            CBB_add_space(&child, &out, bssl::der::kUTCTimeLength) &&
208            bssl::der::EncodeUTCTime(generalized_time, out) && CBB_flush(cbb);
209   }
210 
211   return CBB_add_asn1(cbb, &child, CBS_ASN1_GENERALIZEDTIME) &&
212          CBB_add_space(&child, &out, bssl::der::kGeneralizedTimeLength) &&
213          bssl::der::EncodeGeneralizedTime(generalized_time, out) &&
214          CBB_flush(cbb);
215 }
216 
GetTLSServerEndPointChannelBinding(const X509Certificate & certificate,std::string * token)217 bool GetTLSServerEndPointChannelBinding(const X509Certificate& certificate,
218                                         std::string* token) {
219   static const char kChannelBindingPrefix[] = "tls-server-end-point:";
220 
221   std::string_view der_encoded_certificate =
222       x509_util::CryptoBufferAsStringPiece(certificate.cert_buffer());
223 
224   bssl::der::Input tbs_certificate_tlv;
225   bssl::der::Input signature_algorithm_tlv;
226   bssl::der::BitString signature_value;
227   if (!bssl::ParseCertificate(bssl::der::Input(der_encoded_certificate),
228                               &tbs_certificate_tlv, &signature_algorithm_tlv,
229                               &signature_value, nullptr)) {
230     return false;
231   }
232   std::optional<bssl::SignatureAlgorithm> signature_algorithm =
233       bssl::ParseSignatureAlgorithm(signature_algorithm_tlv);
234   if (!signature_algorithm) {
235     return false;
236   }
237 
238   std::optional<bssl::DigestAlgorithm> binding_digest =
239       bssl::GetTlsServerEndpointDigestAlgorithm(*signature_algorithm);
240   if (!binding_digest) {
241     return false;
242   }
243   const EVP_MD* digest_evp_md = nullptr;
244   switch (binding_digest.value()) {
245     case bssl::DigestAlgorithm::Md2:
246     case bssl::DigestAlgorithm::Md4:
247     case bssl::DigestAlgorithm::Md5:
248     case bssl::DigestAlgorithm::Sha1:
249       // Legacy digests are not supported, and
250       // `GetTlsServerEndpointDigestAlgorithm` internally maps MD5 and SHA-1 to
251       // SHA-256.
252       NOTREACHED();
253 
254     case bssl::DigestAlgorithm::Sha256:
255       digest_evp_md = EVP_sha256();
256       break;
257 
258     case bssl::DigestAlgorithm::Sha384:
259       digest_evp_md = EVP_sha384();
260       break;
261 
262     case bssl::DigestAlgorithm::Sha512:
263       digest_evp_md = EVP_sha512();
264       break;
265   }
266   if (!digest_evp_md)
267     return false;
268 
269   std::array<uint8_t, EVP_MAX_MD_SIZE> digest;
270   unsigned int out_size;
271   if (!EVP_Digest(der_encoded_certificate.data(),
272                   der_encoded_certificate.size(), digest.data(), &out_size,
273                   digest_evp_md, nullptr)) {
274     return false;
275   }
276 
277   token->assign(kChannelBindingPrefix);
278   token->append(base::as_string_view(digest).substr(0, out_size));
279   return true;
280 }
281 
282 // RSA keys created by CreateKeyAndSelfSignedCert will be of this length.
283 static const uint16_t kRSAKeyLength = 1024;
284 
285 // Certificates made by CreateKeyAndSelfSignedCert will be signed using this
286 // digest algorithm.
287 static const DigestAlgorithm kSignatureDigestAlgorithm = DIGEST_SHA256;
288 
CreateKeyAndSelfSignedCert(std::string_view subject,uint32_t serial_number,base::Time not_valid_before,base::Time not_valid_after,std::unique_ptr<crypto::RSAPrivateKey> * key,std::string * der_cert)289 bool CreateKeyAndSelfSignedCert(std::string_view subject,
290                                 uint32_t serial_number,
291                                 base::Time not_valid_before,
292                                 base::Time not_valid_after,
293                                 std::unique_ptr<crypto::RSAPrivateKey>* key,
294                                 std::string* der_cert) {
295   std::unique_ptr<crypto::RSAPrivateKey> new_key(
296       crypto::RSAPrivateKey::Create(kRSAKeyLength));
297   if (!new_key)
298     return false;
299 
300   bool success = CreateSelfSignedCert(new_key->key(), kSignatureDigestAlgorithm,
301                                       subject, serial_number, not_valid_before,
302                                       not_valid_after, {}, der_cert);
303   if (success)
304     *key = std::move(new_key);
305 
306   return success;
307 }
308 
Extension(base::span<const uint8_t> in_oid,bool in_critical,base::span<const uint8_t> in_contents)309 Extension::Extension(base::span<const uint8_t> in_oid,
310                      bool in_critical,
311                      base::span<const uint8_t> in_contents)
312     : oid(in_oid), critical(in_critical), contents(in_contents) {}
313 Extension::~Extension() = default;
314 Extension::Extension(const Extension&) = default;
315 
CreateCert(EVP_PKEY * subject_key,DigestAlgorithm digest_alg,std::string_view subject,uint32_t serial_number,base::Time not_valid_before,base::Time not_valid_after,const std::vector<Extension> & extension_specs,std::string_view issuer,EVP_PKEY * issuer_key,std::string * der_encoded)316 bool CreateCert(EVP_PKEY* subject_key,
317                 DigestAlgorithm digest_alg,
318                 std::string_view subject,
319                 uint32_t serial_number,
320                 base::Time not_valid_before,
321                 base::Time not_valid_after,
322                 const std::vector<Extension>& extension_specs,
323                 std::string_view issuer,
324                 EVP_PKEY* issuer_key,
325                 std::string* der_encoded) {
326   crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
327 
328   // See RFC 5280, section 4.1. First, construct the TBSCertificate.
329   bssl::ScopedCBB cbb;
330   CBB tbs_cert, version, validity;
331   uint8_t* tbs_cert_bytes;
332   size_t tbs_cert_len;
333   if (!CBB_init(cbb.get(), 64) ||
334       !CBB_add_asn1(cbb.get(), &tbs_cert, CBS_ASN1_SEQUENCE) ||
335       !CBB_add_asn1(&tbs_cert, &version,
336                     CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
337       !CBB_add_asn1_uint64(&version, 2) ||
338       !CBB_add_asn1_uint64(&tbs_cert, serial_number) ||
339       !AddSignatureAlgorithm(&tbs_cert, issuer_key, digest_alg) ||  // signature
340       !AddName(&tbs_cert, issuer) ||
341       !CBB_add_asn1(&tbs_cert, &validity, CBS_ASN1_SEQUENCE) ||
342       !CBBAddTime(&validity, not_valid_before) ||
343       !CBBAddTime(&validity, not_valid_after) ||
344       !AddName(&tbs_cert, subject) ||  // subject
345       !EVP_marshal_public_key(&tbs_cert,
346                               subject_key)) {  // subjectPublicKeyInfo
347     return false;
348   }
349 
350   if (!extension_specs.empty()) {
351     CBB outer_extensions, extensions;
352     if (!CBB_add_asn1(&tbs_cert, &outer_extensions,
353                       3 | CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED) ||
354         !CBB_add_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
355       return false;
356     }
357 
358     for (const auto& extension_spec : extension_specs) {
359       CBB extension, oid, value;
360       if (!CBB_add_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) ||
361           !CBB_add_asn1(&extension, &oid, CBS_ASN1_OBJECT) ||
362           !CBB_add_bytes(&oid, extension_spec.oid.data(),
363                          extension_spec.oid.size()) ||
364           (extension_spec.critical && !CBB_add_asn1_bool(&extension, 1)) ||
365           !CBB_add_asn1(&extension, &value, CBS_ASN1_OCTETSTRING) ||
366           !CBB_add_bytes(&value, extension_spec.contents.data(),
367                          extension_spec.contents.size()) ||
368           !CBB_flush(&extensions)) {
369         return false;
370       }
371     }
372 
373     if (!CBB_flush(&tbs_cert)) {
374       return false;
375     }
376   }
377 
378   if (!CBB_finish(cbb.get(), &tbs_cert_bytes, &tbs_cert_len))
379     return false;
380   bssl::UniquePtr<uint8_t> delete_tbs_cert_bytes(tbs_cert_bytes);
381 
382   // Sign the TBSCertificate and write the entire certificate.
383   CBB cert, signature;
384   bssl::ScopedEVP_MD_CTX ctx;
385   uint8_t* sig_out;
386   size_t sig_len;
387   uint8_t* cert_bytes;
388   size_t cert_len;
389   if (!CBB_init(cbb.get(), tbs_cert_len) ||
390       !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE) ||
391       !CBB_add_bytes(&cert, tbs_cert_bytes, tbs_cert_len) ||
392       !AddSignatureAlgorithm(&cert, issuer_key, digest_alg) ||
393       !CBB_add_asn1(&cert, &signature, CBS_ASN1_BITSTRING) ||
394       !CBB_add_u8(&signature, 0 /* no unused bits */) ||
395       !EVP_DigestSignInit(ctx.get(), nullptr, ToEVP(digest_alg), nullptr,
396                           issuer_key) ||
397       // Compute the maximum signature length.
398       !EVP_DigestSign(ctx.get(), nullptr, &sig_len, tbs_cert_bytes,
399                       tbs_cert_len) ||
400       !CBB_reserve(&signature, &sig_out, sig_len) ||
401       // Actually sign the TBSCertificate.
402       !EVP_DigestSign(ctx.get(), sig_out, &sig_len, tbs_cert_bytes,
403                       tbs_cert_len) ||
404       !CBB_did_write(&signature, sig_len) ||
405       !CBB_finish(cbb.get(), &cert_bytes, &cert_len)) {
406     return false;
407   }
408   bssl::UniquePtr<uint8_t> delete_cert_bytes(cert_bytes);
409   der_encoded->assign(reinterpret_cast<char*>(cert_bytes), cert_len);
410   return true;
411 }
412 
CreateSelfSignedCert(EVP_PKEY * key,DigestAlgorithm digest_alg,std::string_view subject,uint32_t serial_number,base::Time not_valid_before,base::Time not_valid_after,const std::vector<Extension> & extension_specs,std::string * der_encoded)413 bool CreateSelfSignedCert(EVP_PKEY* key,
414                           DigestAlgorithm digest_alg,
415                           std::string_view subject,
416                           uint32_t serial_number,
417                           base::Time not_valid_before,
418                           base::Time not_valid_after,
419                           const std::vector<Extension>& extension_specs,
420                           std::string* der_encoded) {
421   return CreateCert(/*subject_key=*/key, digest_alg, subject, serial_number,
422                     not_valid_before, not_valid_after, extension_specs,
423                     /*issuer=*/subject, /*issuer_key=*/key, der_encoded);
424 }
425 
GetBufferPool()426 CRYPTO_BUFFER_POOL* GetBufferPool() {
427   static CRYPTO_BUFFER_POOL* const kSharedPool = CRYPTO_BUFFER_POOL_new();
428   return kSharedPool;
429 }
430 
CreateCryptoBuffer(base::span<const uint8_t> data)431 bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(
432     base::span<const uint8_t> data) {
433   return bssl::UniquePtr<CRYPTO_BUFFER>(
434       CRYPTO_BUFFER_new(data.data(), data.size(), GetBufferPool()));
435 }
436 
CreateCryptoBuffer(std::string_view data)437 bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBuffer(std::string_view data) {
438   return CreateCryptoBuffer(base::as_byte_span(data));
439 }
440 
CreateCryptoBufferFromStaticDataUnsafe(base::span<const uint8_t> data)441 bssl::UniquePtr<CRYPTO_BUFFER> CreateCryptoBufferFromStaticDataUnsafe(
442     base::span<const uint8_t> data) {
443   return bssl::UniquePtr<CRYPTO_BUFFER>(
444       CRYPTO_BUFFER_new_from_static_data_unsafe(data.data(), data.size(),
445                                                 GetBufferPool()));
446 }
447 
CryptoBufferEqual(const CRYPTO_BUFFER * a,const CRYPTO_BUFFER * b)448 bool CryptoBufferEqual(const CRYPTO_BUFFER* a, const CRYPTO_BUFFER* b) {
449   DCHECK(a && b);
450   if (a == b)
451     return true;
452   return CryptoBufferAsSpan(a) == CryptoBufferAsSpan(b);
453 }
454 
CryptoBufferAsStringPiece(const CRYPTO_BUFFER * buffer)455 std::string_view CryptoBufferAsStringPiece(const CRYPTO_BUFFER* buffer) {
456   return base::as_string_view(CryptoBufferAsSpan(buffer));
457 }
458 
CryptoBufferAsSpan(const CRYPTO_BUFFER * buffer)459 base::span<const uint8_t> CryptoBufferAsSpan(const CRYPTO_BUFFER* buffer) {
460   // SAFETY: CRYPTO_BUFFER_data(buffer) returns a pointer to data that is
461   // CRYPTO_BUFFER_len(buffer) bytes in length.
462   return UNSAFE_BUFFERS(
463       base::span(CRYPTO_BUFFER_data(buffer), CRYPTO_BUFFER_len(buffer)));
464 }
465 
CreateX509CertificateFromBuffers(const STACK_OF (CRYPTO_BUFFER)* buffers)466 scoped_refptr<X509Certificate> CreateX509CertificateFromBuffers(
467     const STACK_OF(CRYPTO_BUFFER) * buffers) {
468   if (sk_CRYPTO_BUFFER_num(buffers) == 0) {
469     NOTREACHED();
470   }
471 
472   std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediate_chain;
473   for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(buffers); ++i) {
474     intermediate_chain.push_back(
475         bssl::UpRef(sk_CRYPTO_BUFFER_value(buffers, i)));
476   }
477   return X509Certificate::CreateFromBuffer(
478       bssl::UpRef(sk_CRYPTO_BUFFER_value(buffers, 0)),
479       std::move(intermediate_chain));
480 }
481 
CreateCertBuffersFromPKCS7Bytes(base::span<const uint8_t> data,std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> * handles)482 bool CreateCertBuffersFromPKCS7Bytes(
483     base::span<const uint8_t> data,
484     std::vector<bssl::UniquePtr<CRYPTO_BUFFER>>* handles) {
485   crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE);
486 
487   CBS der_data;
488   CBS_init(&der_data, data.data(), data.size());
489   STACK_OF(CRYPTO_BUFFER)* certs = sk_CRYPTO_BUFFER_new_null();
490   bool success =
491       PKCS7_get_raw_certificates(certs, &der_data, x509_util::GetBufferPool());
492   if (success) {
493     for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(certs); ++i) {
494       handles->push_back(
495           bssl::UniquePtr<CRYPTO_BUFFER>(sk_CRYPTO_BUFFER_value(certs, i)));
496     }
497   }
498   // |handles| took ownership of the individual buffers, so only free the list
499   // itself.
500   sk_CRYPTO_BUFFER_free(certs);
501 
502   return success;
503 }
504 
DefaultParseCertificateOptions()505 bssl::ParseCertificateOptions DefaultParseCertificateOptions() {
506   bssl::ParseCertificateOptions options;
507   options.allow_invalid_serial_numbers = true;
508   return options;
509 }
510 
CalculateSha256SpkiHash(const CRYPTO_BUFFER * buffer,HashValue * hash)511 bool CalculateSha256SpkiHash(const CRYPTO_BUFFER* buffer, HashValue* hash) {
512   std::string_view spki;
513   if (!asn1::ExtractSPKIFromDERCert(CryptoBufferAsStringPiece(buffer), &spki)) {
514     return false;
515   }
516   *hash = HashValue(HASH_VALUE_SHA256);
517   crypto::SHA256HashString(spki, hash->data(), hash->size());
518   return true;
519 }
520 
SignatureVerifierInitWithCertificate(crypto::SignatureVerifier * verifier,crypto::SignatureVerifier::SignatureAlgorithm signature_algorithm,base::span<const uint8_t> signature,const CRYPTO_BUFFER * certificate)521 bool SignatureVerifierInitWithCertificate(
522     crypto::SignatureVerifier* verifier,
523     crypto::SignatureVerifier::SignatureAlgorithm signature_algorithm,
524     base::span<const uint8_t> signature,
525     const CRYPTO_BUFFER* certificate) {
526   std::string_view cert_der = x509_util::CryptoBufferAsStringPiece(certificate);
527 
528   bssl::der::Input tbs_certificate_tlv;
529   bssl::der::Input signature_algorithm_tlv;
530   bssl::der::BitString signature_value;
531   bssl::ParsedTbsCertificate tbs;
532   if (!bssl::ParseCertificate(bssl::der::Input(cert_der), &tbs_certificate_tlv,
533                               &signature_algorithm_tlv, &signature_value,
534                               nullptr) ||
535       !ParseTbsCertificate(tbs_certificate_tlv,
536                            DefaultParseCertificateOptions(), &tbs, nullptr)) {
537     return false;
538   }
539 
540   // The key usage extension, if present, must assert the digitalSignature bit.
541   if (tbs.extensions_tlv) {
542     std::map<bssl::der::Input, bssl::ParsedExtension> extensions;
543     if (!ParseExtensions(tbs.extensions_tlv.value(), &extensions)) {
544       return false;
545     }
546     bssl::ParsedExtension key_usage_ext;
547     if (ConsumeExtension(bssl::der::Input(bssl::kKeyUsageOid), &extensions,
548                          &key_usage_ext)) {
549       bssl::der::BitString key_usage;
550       if (!bssl::ParseKeyUsage(key_usage_ext.value, &key_usage) ||
551           !key_usage.AssertsBit(bssl::KEY_USAGE_BIT_DIGITAL_SIGNATURE)) {
552         return false;
553       }
554     }
555   }
556 
557   return verifier->VerifyInit(signature_algorithm, signature, tbs.spki_tlv);
558 }
559 
HasRsaPkcs1Sha1Signature(const CRYPTO_BUFFER * cert_buffer)560 bool HasRsaPkcs1Sha1Signature(const CRYPTO_BUFFER* cert_buffer) {
561   bssl::der::Input tbs_certificate_tlv;
562   bssl::der::Input signature_algorithm_tlv;
563   bssl::der::BitString signature_value;
564   if (!bssl::ParseCertificate(bssl::der::Input(CryptoBufferAsSpan(cert_buffer)),
565                               &tbs_certificate_tlv, &signature_algorithm_tlv,
566                               &signature_value, /*out_errors=*/nullptr)) {
567     return false;
568   }
569 
570   std::optional<bssl::SignatureAlgorithm> signature_algorithm =
571       bssl::ParseSignatureAlgorithm(signature_algorithm_tlv);
572 
573   return signature_algorithm &&
574          *signature_algorithm == bssl::SignatureAlgorithm::kRsaPkcs1Sha1;
575 }
576 
577 }  // namespace net::x509_util
578