1 // Copyright 2023 The BoringSSL Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <optional>
16 #include <string_view>
17 
18 #include <openssl/pki/certificate.h>
19 #include <openssl/pool.h>
20 
21 #include "cert_errors.h"
22 #include "encode_values.h"
23 #include "parsed_certificate.h"
24 #include "pem.h"
25 #include "parse_values.h"
26 
27 BSSL_NAMESPACE_BEGIN
28 
29 namespace {
30 
ParseCertificateFromDer(bssl::Span<const uint8_t> cert,std::string * out_diagnostic)31 std::shared_ptr<const bssl::ParsedCertificate> ParseCertificateFromDer(
32     bssl::Span<const uint8_t>cert, std::string *out_diagnostic) {
33   bssl::ParseCertificateOptions default_options{};
34   // We follow Chromium in setting |allow_invalid_serial_numbers| in order to
35   // not choke on 21-byte serial numbers, which are common.  davidben explains
36   // why:
37   //
38   // The reason for the discrepancy is that unsigned numbers with the high bit
39   // otherwise set get an extra 0 byte in front to keep them positive. So if you
40   // do:
41   //    var num [20]byte
42   //    fillWithRandom(num[:])
43   //    serialNumber := new(big.Int).SetBytes(num[:])
44   //    encodeASN1Integer(serialNumber)
45   //
46   // Then half of your serial numbers will be encoded with 21 bytes. (And
47   // 1/512th will have 19 bytes instead of 20.)
48   default_options.allow_invalid_serial_numbers = true;
49 
50   bssl::UniquePtr<CRYPTO_BUFFER> buffer(
51       CRYPTO_BUFFER_new(cert.data(), cert.size(), nullptr));
52   bssl::CertErrors errors;
53   std::shared_ptr<const bssl::ParsedCertificate> parsed_cert(
54       bssl::ParsedCertificate::Create(std::move(buffer), default_options, &errors));
55   if (!parsed_cert) {
56     *out_diagnostic = errors.ToDebugString();
57     return nullptr;
58   }
59   return parsed_cert;
60 }
61 
62 } // namespace
63 
64 struct CertificateInternals {
65   std::shared_ptr<const bssl::ParsedCertificate> cert;
66 };
67 
Certificate(std::unique_ptr<CertificateInternals> internals)68 Certificate::Certificate(std::unique_ptr<CertificateInternals> internals)
69     : internals_(std::move(internals)) {}
70 Certificate::~Certificate() = default;
71 Certificate::Certificate(Certificate&& other) = default;
72 
FromDER(bssl::Span<const uint8_t> der,std::string * out_diagnostic)73 std::unique_ptr<Certificate> Certificate::FromDER(bssl::Span<const uint8_t> der,
74                                                   std::string *out_diagnostic) {
75   std::shared_ptr<const bssl::ParsedCertificate> result =
76       ParseCertificateFromDer(der, out_diagnostic);
77   if (result == nullptr) {
78     return nullptr;
79   }
80 
81   auto internals = std::make_unique<CertificateInternals>();
82   internals->cert = std::move(result);
83   std::unique_ptr<Certificate> ret(new Certificate(std::move(internals)));
84   return ret;
85 }
86 
FromPEM(std::string_view pem,std::string * out_diagnostic)87 std::unique_ptr<Certificate> Certificate::FromPEM(std::string_view pem,
88                                                   std::string *out_diagnostic) {
89   bssl::PEMTokenizer tokenizer(pem, {"CERTIFICATE"});
90   if (!tokenizer.GetNext()) {
91     return nullptr;
92   }
93   return FromDER(StringAsBytes(tokenizer.data()), out_diagnostic);
94 }
95 
IsSelfIssued() const96 bool Certificate::IsSelfIssued() const {
97   return internals_->cert->normalized_subject() ==
98          internals_->cert->normalized_issuer();
99 }
100 
GetValidity() const101 Certificate::Validity Certificate::GetValidity() const {
102   Certificate::Validity validity;
103 
104   // As this is a previously parsed certificate, we know the not_before
105   // and not after are valid, so these conversions can not fail.
106   (void) GeneralizedTimeToPosixTime(
107       internals_->cert->tbs().validity_not_before, &validity.not_before);
108   (void) GeneralizedTimeToPosixTime(
109       internals_->cert->tbs().validity_not_after, &validity.not_after);
110   return validity;
111 }
112 
GetSerialNumber() const113 bssl::Span<const uint8_t> Certificate::GetSerialNumber() const {
114   return internals_->cert->tbs().serial_number;
115 }
116 
117 BSSL_NAMESPACE_END
118