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