/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_ |