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