Coverage Report

Created: 2025-09-05 06:13

/src/boringssl/pki/parsed_certificate.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2016 The Chromium 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
#ifndef BSSL_PKI_PARSED_CERTIFICATE_H_
16
#define BSSL_PKI_PARSED_CERTIFICATE_H_
17
18
#include <map>
19
#include <memory>
20
#include <optional>
21
#include <vector>
22
23
#include <openssl/base.h>
24
#include <openssl/span.h>
25
26
#include "certificate_policies.h"
27
#include "input.h"
28
#include "parse_certificate.h"
29
#include "signature_algorithm.h"
30
31
BSSL_NAMESPACE_BEGIN
32
33
struct GeneralNames;
34
class NameConstraints;
35
class ParsedCertificate;
36
class CertErrors;
37
38
using ParsedCertificateList =
39
    std::vector<std::shared_ptr<const ParsedCertificate>>;
40
41
// Represents an X.509 certificate, including Certificate, TBSCertificate, and
42
// standard extensions.
43
// Creating a ParsedCertificate does not completely parse and validate the
44
// certificate data. Presence of a member in this class implies the DER was
45
// parsed successfully to that level, but does not imply the contents of that
46
// member are valid, unless otherwise specified. See the documentation for each
47
// member or the documentation of the type it returns.
48
class OPENSSL_EXPORT ParsedCertificate {
49
 private:
50
  // Used to make constructors private while still being compatible with
51
  // |std::make_shared|.
52
  class PrivateConstructor {
53
   private:
54
    friend ParsedCertificate;
55
    PrivateConstructor() = default;
56
  };
57
58
 public:
59
  ~ParsedCertificate();
60
  // Map from OID to ParsedExtension.
61
  using ExtensionsMap = std::map<der::Input, ParsedExtension>;
62
63
  // Creates a ParsedCertificate given a DER-encoded Certificate. Returns
64
  // nullptr on failure. Failure will occur if the standard certificate fields
65
  // and supported extensions cannot be parsed.
66
  // On either success or failure, if |errors| is non-null it may have error
67
  // information added to it.
68
  static std::shared_ptr<const ParsedCertificate> Create(
69
      bssl::UniquePtr<CRYPTO_BUFFER> cert_data,
70
      const ParseCertificateOptions &options, CertErrors *errors);
71
72
  // Creates a ParsedCertificate by copying the provided |data|, and appends it
73
  // to |chain|. Returns true if the certificate was successfully parsed and
74
  // added. If false is return, |chain| is unmodified.
75
  //
76
  // On either success or failure, if |errors| is non-null it may have error
77
  // information added to it.
78
  static bool CreateAndAddToVector(
79
      bssl::UniquePtr<CRYPTO_BUFFER> cert_data,
80
      const ParseCertificateOptions &options,
81
      std::vector<std::shared_ptr<const bssl::ParsedCertificate>> *chain,
82
      CertErrors *errors);
83
84
  explicit ParsedCertificate(PrivateConstructor);
85
86
  ParsedCertificate(const ParsedCertificate &) = delete;
87
  ParsedCertificate &operator=(const ParsedCertificate &) = delete;
88
89
  // Returns the DER-encoded certificate data for this cert.
90
0
  der::Input der_cert() const { return cert_; }
91
92
  // Returns the CRYPTO_BUFFER backing this object.
93
0
  CRYPTO_BUFFER *cert_buffer() const { return cert_data_.get(); }
94
95
  // Accessors for raw fields of the Certificate.
96
0
  der::Input tbs_certificate_tlv() const { return tbs_certificate_tlv_; }
97
98
0
  der::Input signature_algorithm_tlv() const {
99
0
    return signature_algorithm_tlv_;
100
0
  }
101
102
0
  const der::BitString &signature_value() const { return signature_value_; }
103
104
  // Accessor for struct containing raw fields of the TbsCertificate.
105
0
  const ParsedTbsCertificate &tbs() const { return tbs_; }
106
107
  // Returns the signatureAlgorithm of the Certificate (not the tbsCertificate).
108
  // If the signature algorithm is unknown/unsupported, this returns nullopt.
109
0
  std::optional<SignatureAlgorithm> signature_algorithm() const {
110
0
    return signature_algorithm_;
111
0
  }
112
113
  // Returns the DER-encoded raw subject value (including the outer sequence
114
  // tag). This is guaranteed to be valid DER, though the contents of unhandled
115
  // string types are treated as raw bytes.
116
0
  der::Input subject_tlv() const { return tbs_.subject_tlv; }
117
  // Returns the DER-encoded normalized subject value (not including outer
118
  // Sequence tag). This is guaranteed to be valid DER, though the contents of
119
  // unhandled string types are treated as raw bytes.
120
0
  der::Input normalized_subject() const {
121
0
    return StringAsBytes(normalized_subject_);
122
0
  }
123
  // Returns the DER-encoded raw issuer value (including the outer sequence
124
  // tag). This is guaranteed to be valid DER, though the contents of unhandled
125
  // string types are treated as raw bytes.
126
0
  der::Input issuer_tlv() const { return tbs_.issuer_tlv; }
127
  // Returns the DER-encoded normalized issuer value (not including outer
128
  // Sequence tag). This is guaranteed to be valid DER, though the contents of
129
  // unhandled string types are treated as raw bytes.
130
0
  der::Input normalized_issuer() const {
131
0
    return StringAsBytes(normalized_issuer_);
132
0
  }
133
134
  // Returns true if the certificate has a BasicConstraints extension.
135
0
  bool has_basic_constraints() const { return has_basic_constraints_; }
136
137
  // Returns the ParsedBasicConstraints struct. Caller must check
138
  // has_basic_constraints() before accessing this.
139
0
  const ParsedBasicConstraints &basic_constraints() const {
140
0
    BSSL_CHECK(has_basic_constraints_);
141
0
    return basic_constraints_;
142
0
  }
Unexecuted instantiation: bssl::ParsedCertificate::basic_constraints() const
Unexecuted instantiation: bssl::ParsedCertificate::basic_constraints() const
143
144
  // Returns true if the certificate has a KeyUsage extension.
145
0
  bool has_key_usage() const { return has_key_usage_; }
146
147
  // Returns the KeyUsage BitString. Caller must check
148
  // has_key_usage() before accessing this.
149
0
  const der::BitString &key_usage() const {
150
0
    BSSL_CHECK(has_key_usage_);
151
0
    return key_usage_;
152
0
  }
Unexecuted instantiation: bssl::ParsedCertificate::key_usage() const
Unexecuted instantiation: bssl::ParsedCertificate::key_usage() const
153
154
  // Returns true if the certificate has a ExtendedKeyUsage extension.
155
0
  bool has_extended_key_usage() const { return has_extended_key_usage_; }
156
157
  // Returns the ExtendedKeyUsage key purpose OIDs. Caller must check
158
  // has_extended_key_usage() before accessing this.
159
0
  const std::vector<der::Input> &extended_key_usage() const {
160
0
    BSSL_CHECK(has_extended_key_usage_);
161
0
    return extended_key_usage_;
162
0
  }
Unexecuted instantiation: bssl::ParsedCertificate::extended_key_usage() const
Unexecuted instantiation: bssl::ParsedCertificate::extended_key_usage() const
163
164
  // Returns true if the certificate has a SubjectAltName extension.
165
0
  bool has_subject_alt_names() const { return subject_alt_names_ != nullptr; }
166
167
  // Returns the ParsedExtension struct for the SubjectAltName extension.
168
  // If the cert did not have a SubjectAltName extension, this will be a
169
  // default-initialized ParsedExtension struct.
170
0
  const ParsedExtension &subject_alt_names_extension() const {
171
0
    return subject_alt_names_extension_;
172
0
  }
173
174
  // Returns the GeneralNames class parsed from SubjectAltName extension, or
175
  // nullptr if no SubjectAltName extension was present.
176
0
  const GeneralNames *subject_alt_names() const {
177
0
    return subject_alt_names_.get();
178
0
  }
179
180
  // Returns true if the certificate has a NameConstraints extension.
181
0
  bool has_name_constraints() const { return name_constraints_ != nullptr; }
182
183
  // Returns the parsed NameConstraints extension. Must not be called if
184
  // has_name_constraints() is false.
185
0
  const NameConstraints &name_constraints() const {
186
0
    BSSL_CHECK(name_constraints_);
187
0
    return *name_constraints_;
188
0
  }
189
190
  // Returns true if the certificate has an AuthorityInfoAccess extension.
191
0
  bool has_authority_info_access() const { return has_authority_info_access_; }
192
193
  // Returns the ParsedExtension struct for the AuthorityInfoAccess extension.
194
0
  const ParsedExtension &authority_info_access_extension() const {
195
0
    return authority_info_access_extension_;
196
0
  }
197
198
  // Returns any caIssuers URIs from the AuthorityInfoAccess extension.
199
0
  const std::vector<std::string_view> &ca_issuers_uris() const {
200
0
    return ca_issuers_uris_;
201
0
  }
202
203
  // Returns any OCSP URIs from the AuthorityInfoAccess extension.
204
0
  const std::vector<std::string_view> &ocsp_uris() const { return ocsp_uris_; }
205
206
  // Returns true if the certificate has a Policies extension.
207
0
  bool has_policy_oids() const { return has_policy_oids_; }
208
209
  // Returns the policy OIDs. Caller must check has_policy_oids() before
210
  // accessing this.
211
0
  const std::vector<der::Input> &policy_oids() const {
212
0
    BSSL_CHECK(has_policy_oids());
213
0
    return policy_oids_;
214
0
  }
215
216
  // Returns true if the certificate has a PolicyConstraints extension.
217
0
  bool has_policy_constraints() const { return has_policy_constraints_; }
218
219
  // Returns the ParsedPolicyConstraints struct. Caller must check
220
  // has_policy_constraints() before accessing this.
221
0
  const ParsedPolicyConstraints &policy_constraints() const {
222
0
    BSSL_CHECK(has_policy_constraints_);
223
0
    return policy_constraints_;
224
0
  }
225
226
  // Returns true if the certificate has a PolicyMappings extension.
227
0
  bool has_policy_mappings() const { return has_policy_mappings_; }
228
229
  // Returns the PolicyMappings extension. Caller must check
230
  // has_policy_mappings() before accessing this.
231
0
  const std::vector<ParsedPolicyMapping> &policy_mappings() const {
232
0
    BSSL_CHECK(has_policy_mappings_);
233
0
    return policy_mappings_;
234
0
  }
235
236
  // Returns the Inhibit Any Policy extension.
237
0
  const std::optional<uint8_t> &inhibit_any_policy() const {
238
0
    return inhibit_any_policy_;
239
0
  }
240
241
  // Returns the AuthorityKeyIdentifier extension, or nullopt if there wasn't
242
  // one.
243
  const std::optional<ParsedAuthorityKeyIdentifier> &authority_key_identifier()
244
0
      const {
245
0
    return authority_key_identifier_;
246
0
  }
247
248
  // Returns the SubjectKeyIdentifier extension, or nullopt if there wasn't
249
  // one.
250
0
  const std::optional<der::Input> &subject_key_identifier() const {
251
0
    return subject_key_identifier_;
252
0
  }
253
254
  // Returns a map of all the extensions in the certificate.
255
0
  const ExtensionsMap &extensions() const { return extensions_; }
256
257
  // Gets the value for extension matching |extension_oid|. Returns false if the
258
  // extension is not present.
259
  bool GetExtension(der::Input extension_oid,
260
                    ParsedExtension *parsed_extension) const;
261
262
 private:
263
  // The backing store for the certificate data.
264
  bssl::UniquePtr<CRYPTO_BUFFER> cert_data_;
265
266
  // Points to the raw certificate DER.
267
  der::Input cert_;
268
269
  der::Input tbs_certificate_tlv_;
270
  der::Input signature_algorithm_tlv_;
271
  der::BitString signature_value_;
272
  ParsedTbsCertificate tbs_;
273
274
  // The signatureAlgorithm from the Certificate.
275
  std::optional<SignatureAlgorithm> signature_algorithm_;
276
277
  // Normalized DER-encoded Subject (not including outer Sequence tag).
278
  std::string normalized_subject_;
279
  // Normalized DER-encoded Issuer (not including outer Sequence tag).
280
  std::string normalized_issuer_;
281
282
  // BasicConstraints extension.
283
  bool has_basic_constraints_ = false;
284
  ParsedBasicConstraints basic_constraints_;
285
286
  // KeyUsage extension.
287
  bool has_key_usage_ = false;
288
  der::BitString key_usage_;
289
290
  // ExtendedKeyUsage extension.
291
  bool has_extended_key_usage_ = false;
292
  std::vector<der::Input> extended_key_usage_;
293
294
  // Raw SubjectAltName extension.
295
  ParsedExtension subject_alt_names_extension_;
296
  // Parsed SubjectAltName extension.
297
  std::unique_ptr<GeneralNames> subject_alt_names_;
298
299
  // NameConstraints extension.
300
  std::unique_ptr<NameConstraints> name_constraints_;
301
302
  // AuthorityInfoAccess extension.
303
  bool has_authority_info_access_ = false;
304
  ParsedExtension authority_info_access_extension_;
305
  // CaIssuers and Ocsp URIs parsed from the AuthorityInfoAccess extension. Note
306
  // that the AuthorityInfoAccess may have contained other AccessDescriptions
307
  // which are not represented here.
308
  std::vector<std::string_view> ca_issuers_uris_;
309
  std::vector<std::string_view> ocsp_uris_;
310
311
  // Policies extension. This list will already have been checked for
312
  // duplicates.
313
  bool has_policy_oids_ = false;
314
  std::vector<der::Input> policy_oids_;
315
316
  // Policy constraints extension.
317
  bool has_policy_constraints_ = false;
318
  ParsedPolicyConstraints policy_constraints_;
319
320
  // Policy mappings extension.
321
  bool has_policy_mappings_ = false;
322
  std::vector<ParsedPolicyMapping> policy_mappings_;
323
324
  // Inhibit Any Policy extension.
325
  std::optional<uint8_t> inhibit_any_policy_;
326
327
  // AuthorityKeyIdentifier extension.
328
  std::optional<ParsedAuthorityKeyIdentifier> authority_key_identifier_;
329
330
  // SubjectKeyIdentifier extension.
331
  std::optional<der::Input> subject_key_identifier_;
332
333
  // All of the extensions.
334
  ExtensionsMap extensions_;
335
};
336
337
BSSL_NAMESPACE_END
338
339
#endif  // BSSL_PKI_PARSED_CERTIFICATE_H_