Botan 3.4.0
Crypto and TLS for C&
x509cert.cpp
Go to the documentation of this file.
1/*
2* X.509 Certificates
3* (C) 1999-2010,2015,2017 Jack Lloyd
4* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#include <botan/x509cert.h>
10
11#include <botan/ber_dec.h>
12#include <botan/bigint.h>
13#include <botan/hash.h>
14#include <botan/hex.h>
15#include <botan/pk_keys.h>
16#include <botan/x509_ext.h>
17#include <botan/x509_key.h>
18#include <botan/internal/parsing.h>
19#include <algorithm>
20#include <sstream>
21
22namespace Botan {
23
24struct X509_Certificate_Data {
25 std::vector<uint8_t> m_serial;
26 AlgorithmIdentifier m_sig_algo_inner;
27 X509_DN m_issuer_dn;
28 X509_DN m_subject_dn;
29 std::vector<uint8_t> m_issuer_dn_bits;
30 std::vector<uint8_t> m_subject_dn_bits;
31 X509_Time m_not_before;
32 X509_Time m_not_after;
33 std::vector<uint8_t> m_subject_public_key_bits;
34 std::vector<uint8_t> m_subject_public_key_bits_seq;
35 std::vector<uint8_t> m_subject_public_key_bitstring;
36 std::vector<uint8_t> m_subject_public_key_bitstring_sha1;
37 AlgorithmIdentifier m_subject_public_key_algid;
38
39 std::vector<uint8_t> m_v2_issuer_key_id;
40 std::vector<uint8_t> m_v2_subject_key_id;
41 Extensions m_v3_extensions;
42
43 std::vector<OID> m_extended_key_usage;
44 std::vector<uint8_t> m_authority_key_id;
45 std::vector<uint8_t> m_subject_key_id;
46 std::vector<OID> m_cert_policies;
47
48 std::vector<std::string> m_crl_distribution_points;
49 std::string m_ocsp_responder;
50 std::vector<std::string> m_ca_issuers;
51
52 std::vector<uint8_t> m_issuer_dn_bits_sha256;
53 std::vector<uint8_t> m_subject_dn_bits_sha256;
54
55 std::string m_fingerprint_sha1;
56 std::string m_fingerprint_sha256;
57
58 AlternativeName m_subject_alt_name;
59 AlternativeName m_issuer_alt_name;
60 NameConstraints m_name_constraints;
61
62 size_t m_version = 0;
63 size_t m_path_len_constraint = 0;
64 Key_Constraints m_key_constraints;
65 bool m_self_signed = false;
66 bool m_is_ca_certificate = false;
67 bool m_serial_negative = false;
68};
69
70std::string X509_Certificate::PEM_label() const {
71 return "CERTIFICATE";
72}
73
74std::vector<std::string> X509_Certificate::alternate_PEM_labels() const {
75 return {"X509 CERTIFICATE"};
76}
77
81
82X509_Certificate::X509_Certificate(const std::vector<uint8_t>& vec) {
83 DataSource_Memory src(vec.data(), vec.size());
84 load_data(src);
85}
86
87X509_Certificate::X509_Certificate(const uint8_t data[], size_t len) {
88 DataSource_Memory src(data, len);
89 load_data(src);
90}
91
92#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
93X509_Certificate::X509_Certificate(std::string_view fsname) {
94 DataSource_Stream src(fsname, true);
95 load_data(src);
96}
97#endif
98
99namespace {
100
101std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(const X509_Object& obj) {
102 auto data = std::make_unique<X509_Certificate_Data>();
103
104 BigInt serial_bn;
105 BER_Object public_key;
106 BER_Object v3_exts_data;
107
108 BER_Decoder(obj.signed_body())
109 .decode_optional(data->m_version, ASN1_Type(0), ASN1_Class::Constructed | ASN1_Class::ContextSpecific)
110 .decode(serial_bn)
111 .decode(data->m_sig_algo_inner)
112 .decode(data->m_issuer_dn)
113 .start_sequence()
114 .decode(data->m_not_before)
115 .decode(data->m_not_after)
116 .end_cons()
117 .decode(data->m_subject_dn)
118 .get_next(public_key)
119 .decode_optional_string(data->m_v2_issuer_key_id, ASN1_Type::BitString, 1)
120 .decode_optional_string(data->m_v2_subject_key_id, ASN1_Type::BitString, 2)
121 .get_next(v3_exts_data)
122 .verify_end("TBSCertificate has extra data after extensions block");
123
124 if(data->m_version > 2) {
125 throw Decoding_Error("Unknown X.509 cert version " + std::to_string(data->m_version));
126 }
127 if(obj.signature_algorithm() != data->m_sig_algo_inner) {
128 throw Decoding_Error("X.509 Certificate had differing algorithm identifers in inner and outer ID fields");
129 }
130
131 public_key.assert_is_a(ASN1_Type::Sequence, ASN1_Class::Constructed, "X.509 certificate public key");
132
133 // crude method to save the serial's sign; will get lost during decoding, otherwise
134 data->m_serial_negative = serial_bn.is_negative();
135
136 // for general sanity convert wire version (0 based) to standards version (v1 .. v3)
137 data->m_version += 1;
138
139 data->m_serial = BigInt::encode(serial_bn);
140 data->m_subject_dn_bits = ASN1::put_in_sequence(data->m_subject_dn.get_bits());
141 data->m_issuer_dn_bits = ASN1::put_in_sequence(data->m_issuer_dn.get_bits());
142
143 data->m_subject_public_key_bits.assign(public_key.bits(), public_key.bits() + public_key.length());
144
145 data->m_subject_public_key_bits_seq = ASN1::put_in_sequence(data->m_subject_public_key_bits);
146
147 BER_Decoder(data->m_subject_public_key_bits)
148 .decode(data->m_subject_public_key_algid)
149 .decode(data->m_subject_public_key_bitstring, ASN1_Type::BitString);
150
151 if(v3_exts_data.is_a(3, ASN1_Class::Constructed | ASN1_Class::ContextSpecific)) {
152 // Path validation will reject a v1/v2 cert with v3 extensions
153 BER_Decoder(v3_exts_data).decode(data->m_v3_extensions).verify_end();
154 } else if(v3_exts_data.is_set()) {
155 throw BER_Bad_Tag("Unknown tag in X.509 cert", v3_exts_data.tagging());
156 }
157
158 // Now cache some fields from the extensions
159 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Key_Usage>()) {
160 data->m_key_constraints = ext->get_constraints();
161 /*
162 RFC 5280: When the keyUsage extension appears in a certificate,
163 at least one of the bits MUST be set to 1.
164 */
165 if(data->m_key_constraints.empty()) {
166 throw Decoding_Error("Certificate has invalid encoding for KeyUsage");
167 }
168 }
169
170 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Key_ID>()) {
171 data->m_subject_key_id = ext->get_key_id();
172 }
173
174 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Key_ID>()) {
175 data->m_authority_key_id = ext->get_key_id();
176 }
177
178 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Name_Constraints>()) {
179 data->m_name_constraints = ext->get_name_constraints();
180 }
181
182 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Basic_Constraints>()) {
183 if(ext->get_is_ca() == true) {
184 /*
185 * RFC 5280 section 4.2.1.3 requires that CAs include KeyUsage in all
186 * intermediate CA certificates they issue. Currently we accept it being
187 * missing, as do most other implementations. But it may be worth
188 * removing this entirely, or alternately adding a warning level
189 * validation failure for it.
190 */
191 if(data->m_key_constraints.empty() || data->m_key_constraints.includes(Key_Constraints::KeyCertSign)) {
192 data->m_is_ca_certificate = true;
193 data->m_path_len_constraint = ext->get_path_limit();
194 }
195 }
196 }
197
198 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Issuer_Alternative_Name>()) {
199 data->m_issuer_alt_name = ext->get_alt_name();
200 }
201
202 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Alternative_Name>()) {
203 data->m_subject_alt_name = ext->get_alt_name();
204 }
205
206 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Extended_Key_Usage>()) {
207 data->m_extended_key_usage = ext->object_identifiers();
208 }
209
210 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Certificate_Policies>()) {
211 data->m_cert_policies = ext->get_policy_oids();
212 }
213
214 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Information_Access>()) {
215 data->m_ocsp_responder = ext->ocsp_responder();
216 data->m_ca_issuers = ext->ca_issuers();
217 }
218
219 if(auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::CRL_Distribution_Points>()) {
220 data->m_crl_distribution_points = ext->crl_distribution_urls();
221 }
222
223 // Check for self-signed vs self-issued certificates
224 if(data->m_subject_dn == data->m_issuer_dn) {
225 if(data->m_subject_key_id.empty() == false && data->m_authority_key_id.empty() == false) {
226 data->m_self_signed = (data->m_subject_key_id == data->m_authority_key_id);
227 } else {
228 /*
229 If a parse error or unknown algorithm is encountered, default
230 to assuming it is self signed. We have no way of being certain but
231 that is usually the default case (self-issued is rare in practice).
232 */
233 data->m_self_signed = true;
234
235 try {
236 auto pub_key = X509::load_key(data->m_subject_public_key_bits_seq);
237
238 const auto sig_status = obj.verify_signature(*pub_key);
239
240 if(sig_status.first == Certificate_Status_Code::OK ||
242 data->m_self_signed = true;
243 } else {
244 data->m_self_signed = false;
245 }
246 } catch(...) {
247 // ignore errors here to allow parsing to continue
248 }
249 }
250 }
251
252 const std::vector<uint8_t> full_encoding = obj.BER_encode();
253
254 auto sha1 = HashFunction::create("SHA-1");
255 if(sha1) {
256 sha1->update(data->m_subject_public_key_bitstring);
257 data->m_subject_public_key_bitstring_sha1 = sha1->final_stdvec();
258 // otherwise left as empty, and we will throw if subject_public_key_bitstring_sha1 is called
259
260 data->m_fingerprint_sha1 = create_hex_fingerprint(full_encoding, "SHA-1");
261 }
262
263 auto sha256 = HashFunction::create("SHA-256");
264 if(sha256) {
265 sha256->update(data->m_issuer_dn_bits);
266 data->m_issuer_dn_bits_sha256 = sha256->final_stdvec();
267
268 sha256->update(data->m_subject_dn_bits);
269 data->m_subject_dn_bits_sha256 = sha256->final_stdvec();
270
271 data->m_fingerprint_sha256 = create_hex_fingerprint(full_encoding, "SHA-256");
272 }
273
274 return data;
275}
276
277} // namespace
278
279/*
280* Decode the TBSCertificate data
281*/
282void X509_Certificate::force_decode() {
283 m_data.reset();
284 m_data = parse_x509_cert_body(*this);
285}
286
287const X509_Certificate_Data& X509_Certificate::data() const {
288 if(m_data == nullptr) {
289 throw Invalid_State("X509_Certificate uninitialized");
290 }
291 return *m_data;
292}
293
295 return static_cast<uint32_t>(data().m_version);
296}
297
299 return data().m_self_signed;
300}
301
303 return data().m_not_before;
304}
305
307 return data().m_not_after;
308}
309
311 return data().m_subject_public_key_algid;
312}
313
314const std::vector<uint8_t>& X509_Certificate::v2_issuer_key_id() const {
315 return data().m_v2_issuer_key_id;
316}
317
318const std::vector<uint8_t>& X509_Certificate::v2_subject_key_id() const {
319 return data().m_v2_subject_key_id;
320}
321
322const std::vector<uint8_t>& X509_Certificate::subject_public_key_bits() const {
323 return data().m_subject_public_key_bits;
324}
325
326const std::vector<uint8_t>& X509_Certificate::subject_public_key_info() const {
327 return data().m_subject_public_key_bits_seq;
328}
329
330const std::vector<uint8_t>& X509_Certificate::subject_public_key_bitstring() const {
331 return data().m_subject_public_key_bitstring;
332}
333
334const std::vector<uint8_t>& X509_Certificate::subject_public_key_bitstring_sha1() const {
335 if(data().m_subject_public_key_bitstring_sha1.empty()) {
336 throw Encoding_Error("X509_Certificate::subject_public_key_bitstring_sha1 called but SHA-1 disabled in build");
337 }
338
339 return data().m_subject_public_key_bitstring_sha1;
340}
341
342const std::vector<uint8_t>& X509_Certificate::authority_key_id() const {
343 return data().m_authority_key_id;
344}
345
346const std::vector<uint8_t>& X509_Certificate::subject_key_id() const {
347 return data().m_subject_key_id;
348}
349
350const std::vector<uint8_t>& X509_Certificate::serial_number() const {
351 return data().m_serial;
352}
353
355 return data().m_serial_negative;
356}
357
359 return data().m_issuer_dn;
360}
361
363 return data().m_subject_dn;
364}
365
366const std::vector<uint8_t>& X509_Certificate::raw_issuer_dn() const {
367 return data().m_issuer_dn_bits;
368}
369
370const std::vector<uint8_t>& X509_Certificate::raw_subject_dn() const {
371 return data().m_subject_dn_bits;
372}
373
375 if(data().m_version < 3 && data().m_self_signed) {
376 return true;
377 }
378
379 return data().m_is_ca_certificate;
380}
381
383 if(data().m_version < 3 && data().m_self_signed) {
384 return 32; // in theory infinite, but this is more than enough
385 }
386
387 return static_cast<uint32_t>(data().m_path_len_constraint);
388}
389
391 return data().m_key_constraints;
392}
393
394const std::vector<OID>& X509_Certificate::extended_key_usage() const {
395 return data().m_extended_key_usage;
396}
397
398const std::vector<OID>& X509_Certificate::certificate_policy_oids() const {
399 return data().m_cert_policies;
400}
401
403 return data().m_name_constraints;
404}
405
407 return data().m_v3_extensions;
408}
409
411 // Unlike allowed_usage, returns false if constraints was not set
412 return constraints().includes(usage);
413}
414
416 if(constraints().empty()) {
417 return true;
418 }
419 return constraints().includes(usage);
420}
421
422bool X509_Certificate::allowed_extended_usage(std::string_view usage) const {
424}
425
427 const std::vector<OID>& ex = extended_key_usage();
428 if(ex.empty()) {
429 return true;
430 }
431
432 if(std::find(ex.begin(), ex.end(), usage) != ex.end()) {
433 return true;
434 }
435
436 return false;
437}
438
468
469bool X509_Certificate::has_ex_constraint(std::string_view ex_constraint) const {
470 return has_ex_constraint(OID::from_string(ex_constraint));
471}
472
473bool X509_Certificate::has_ex_constraint(const OID& usage) const {
474 const std::vector<OID>& ex = extended_key_usage();
475 return (std::find(ex.begin(), ex.end(), usage) != ex.end());
476}
477
478/*
479* Return if a certificate extension is marked critical
480*/
481bool X509_Certificate::is_critical(std::string_view ex_name) const {
483}
484
486 return data().m_ocsp_responder;
487}
488
489std::vector<std::string> X509_Certificate::ca_issuers() const {
490 return data().m_ca_issuers;
491}
492
494 // just returns the first (arbitrarily)
495 if(!data().m_crl_distribution_points.empty()) {
496 return data().m_crl_distribution_points[0];
497 }
498 return "";
499}
500
502 return data().m_subject_alt_name;
503}
504
506 return data().m_issuer_alt_name;
507}
508
509/*
510* Return information about the subject
511*/
512std::vector<std::string> X509_Certificate::subject_info(std::string_view req) const {
513 if(req == "Email") {
514 return this->subject_info("RFC822");
515 }
516
517 if(subject_dn().has_field(req)) {
518 return subject_dn().get_attribute(req);
519 }
520
521 if(subject_alt_name().has_field(req)) {
522 return subject_alt_name().get_attribute(req);
523 }
524
525 return {};
526}
527
528/*
529* Return information about the issuer
530*/
531std::vector<std::string> X509_Certificate::issuer_info(std::string_view req) const {
532 if(issuer_dn().has_field(req)) {
533 return issuer_dn().get_attribute(req);
534 }
535
536 if(issuer_alt_name().has_field(req)) {
537 return issuer_alt_name().get_attribute(req);
538 }
539
540 return {};
541}
542
543/*
544* Return the public key in this certificate
545*/
546std::unique_ptr<Public_Key> X509_Certificate::subject_public_key() const {
547 try {
548 return std::unique_ptr<Public_Key>(X509::load_key(subject_public_key_info()));
549 } catch(std::exception& e) {
550 throw Decoding_Error("X509_Certificate::subject_public_key", e);
551 }
552}
553
554std::unique_ptr<Public_Key> X509_Certificate::load_subject_public_key() const {
555 return this->subject_public_key();
556}
557
558std::vector<uint8_t> X509_Certificate::raw_issuer_dn_sha256() const {
559 if(data().m_issuer_dn_bits_sha256.empty()) {
560 throw Encoding_Error("X509_Certificate::raw_issuer_dn_sha256 called but SHA-256 disabled in build");
561 }
562 return data().m_issuer_dn_bits_sha256;
563}
564
565std::vector<uint8_t> X509_Certificate::raw_subject_dn_sha256() const {
566 if(data().m_subject_dn_bits_sha256.empty()) {
567 throw Encoding_Error("X509_Certificate::raw_subject_dn_sha256 called but SHA-256 disabled in build");
568 }
569 return data().m_subject_dn_bits_sha256;
570}
571
572std::string X509_Certificate::fingerprint(std::string_view hash_name) const {
573 /*
574 * The SHA-1 and SHA-256 fingerprints are precomputed since these
575 * are the most commonly used. Especially, SHA-256 fingerprints are
576 * used for cycle detection during path construction.
577 *
578 * If SHA-1 or SHA-256 was missing at parsing time the vectors are
579 * left empty in which case we fall back to create_hex_fingerprint
580 * which will throw if the hash is unavailable.
581 */
582 if(hash_name == "SHA-256" && !data().m_fingerprint_sha256.empty()) {
583 return data().m_fingerprint_sha256;
584 } else if(hash_name == "SHA-1" && !data().m_fingerprint_sha1.empty()) {
585 return data().m_fingerprint_sha1;
586 } else {
587 return create_hex_fingerprint(this->BER_encode(), hash_name);
588 }
589}
590
591bool X509_Certificate::matches_dns_name(std::string_view name) const {
592 if(name.empty()) {
593 return false;
594 }
595
596 auto issued_names = subject_info("DNS");
597
598 // Fall back to CN only if no DNS names are set (RFC 6125 sec 6.4.4)
599 if(issued_names.empty()) {
600 issued_names = subject_info("Name");
601 }
602
603 for(const auto& issued_name : issued_names) {
604 if(host_wildcard_match(issued_name, name)) {
605 return true;
606 }
607 }
608
609 return false;
610}
611
612/*
613* Compare two certificates for equality
614*/
616 return (this->signature() == other.signature() && this->signature_algorithm() == other.signature_algorithm() &&
617 this->signed_body() == other.signed_body());
618}
619
621 /* If signature values are not equal, sort by lexicographic ordering of that */
622 if(this->signature() != other.signature()) {
623 return (this->signature() < other.signature());
624 }
625
626 // Then compare the signed contents
627 return this->signed_body() < other.signed_body();
628}
629
630/*
631* X.509 Certificate Comparison
632*/
633bool operator!=(const X509_Certificate& cert1, const X509_Certificate& cert2) {
634 return !(cert1 == cert2);
635}
636
637std::string X509_Certificate::to_string() const {
638 std::ostringstream out;
639
640 out << "Version: " << this->x509_version() << "\n";
641 out << "Subject: " << subject_dn() << "\n";
642 out << "Issuer: " << issuer_dn() << "\n";
643 out << "Issued: " << this->not_before().readable_string() << "\n";
644 out << "Expires: " << this->not_after().readable_string() << "\n";
645
646 out << "Constraints:\n";
648 if(constraints.empty()) {
649 out << " None\n";
650 } else {
652 out << " Digital Signature\n";
653 }
655 out << " Non-Repudiation\n";
656 }
658 out << " Key Encipherment\n";
659 }
661 out << " Data Encipherment\n";
662 }
664 out << " Key Agreement\n";
665 }
667 out << " Cert Sign\n";
668 }
670 out << " CRL Sign\n";
671 }
673 out << " Encipher Only\n";
674 }
676 out << " Decipher Only\n";
677 }
678 }
679
680 const std::vector<OID>& policies = this->certificate_policy_oids();
681 if(!policies.empty()) {
682 out << "Policies: "
683 << "\n";
684 for(const auto& oid : policies) {
685 out << " " << oid.to_string() << "\n";
686 }
687 }
688
689 const std::vector<OID>& ex_constraints = this->extended_key_usage();
690 if(!ex_constraints.empty()) {
691 out << "Extended Constraints:\n";
692 for(auto&& oid : ex_constraints) {
693 out << " " << oid.to_formatted_string() << "\n";
694 }
695 }
696
698
699 if(!name_constraints.permitted().empty() || !name_constraints.excluded().empty()) {
700 out << "Name Constraints:\n";
701
702 if(!name_constraints.permitted().empty()) {
703 out << " Permit";
704 for(const auto& st : name_constraints.permitted()) {
705 out << " " << st.base();
706 }
707 out << "\n";
708 }
709
710 if(!name_constraints.excluded().empty()) {
711 out << " Exclude";
712 for(const auto& st : name_constraints.excluded()) {
713 out << " " << st.base();
714 }
715 out << "\n";
716 }
717 }
718
719 if(!ocsp_responder().empty()) {
720 out << "OCSP responder " << ocsp_responder() << "\n";
721 }
722
723 const std::vector<std::string> ca_issuers = this->ca_issuers();
724 if(!ca_issuers.empty()) {
725 out << "CA Issuers:\n";
726 for(const auto& ca_issuer : ca_issuers) {
727 out << " URI: " << ca_issuer << "\n";
728 }
729 }
730
731 if(!crl_distribution_point().empty()) {
732 out << "CRL " << crl_distribution_point() << "\n";
733 }
734
735 out << "Signature algorithm: " << this->signature_algorithm().oid().to_formatted_string() << "\n";
736
737 out << "Serial number: " << hex_encode(this->serial_number()) << "\n";
738
739 if(!this->authority_key_id().empty()) {
740 out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n";
741 }
742
743 if(!this->subject_key_id().empty()) {
744 out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n";
745 }
746
747 try {
748 auto pubkey = this->subject_public_key();
749 out << "Public Key [" << pubkey->algo_name() << "-" << pubkey->key_length() << "]\n\n";
750 out << X509::PEM_encode(*pubkey);
751 } catch(Decoding_Error&) {
752 const AlgorithmIdentifier& alg_id = this->subject_public_key_algo();
753 out << "Failed to decode key with oid " << alg_id.oid().to_string() << "\n";
754 }
755
756 return out.str();
757}
758
759} // namespace Botan
std::vector< uint8_t > BER_encode() const
Definition asn1_obj.cpp:19
std::string readable_string() const
Returns a human friendly string replesentation of no particular formatting.
Definition asn1_time.cpp:92
const OID & oid() const
Definition asn1_obj.h:455
std::vector< std::string > get_attribute(std::string_view attr) const
static std::vector< uint8_t > encode(const BigInt &n)
Definition bigint.h:750
bool critical_extension_set(const OID &oid) const
Definition x509_ext.cpp:173
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition hash.cpp:107
bool includes(Key_Constraints::Bits other) const
Definition pkix_enums.h:160
Name Constraints.
Definition pkix_types.h:294
const std::vector< GeneralSubtree > & permitted() const
Definition pkix_types.h:313
const std::vector< GeneralSubtree > & excluded() const
Definition pkix_types.h:318
std::string to_formatted_string() const
Definition asn1_oid.cpp:114
std::string to_string() const
Definition asn1_oid.cpp:108
static OID from_string(std::string_view str)
Definition asn1_oid.cpp:74
const std::vector< OID > & extended_key_usage() const
Definition x509cert.cpp:394
bool is_CA_cert() const
Definition x509cert.cpp:374
Key_Constraints constraints() const
Definition x509cert.cpp:390
bool operator==(const X509_Certificate &other) const
Definition x509cert.cpp:615
const NameConstraints & name_constraints() const
Definition x509cert.cpp:402
bool is_critical(std::string_view ex_name) const
Definition x509cert.cpp:481
const std::vector< uint8_t > & serial_number() const
Definition x509cert.cpp:350
std::string fingerprint(std::string_view hash_name="SHA-1") const
Definition x509cert.cpp:572
const X509_DN & subject_dn() const
Definition x509cert.cpp:362
std::vector< uint8_t > raw_subject_dn_sha256() const
Definition x509cert.cpp:565
uint32_t path_limit() const
Definition x509cert.cpp:382
const X509_Time & not_after() const
Definition x509cert.cpp:306
const std::vector< uint8_t > & authority_key_id() const
Definition x509cert.cpp:342
bool allowed_extended_usage(std::string_view usage) const
Definition x509cert.cpp:422
const AlternativeName & issuer_alt_name() const
Definition x509cert.cpp:505
const std::vector< uint8_t > & raw_subject_dn() const
Definition x509cert.cpp:370
const std::vector< uint8_t > & subject_key_id() const
Definition x509cert.cpp:346
const std::vector< uint8_t > & subject_public_key_bits() const
Definition x509cert.cpp:322
bool has_constraints(Key_Constraints constraints) const
Definition x509cert.cpp:410
const Extensions & v3_extensions() const
Definition x509cert.cpp:406
bool has_ex_constraint(std::string_view ex_constraint) const
Definition x509cert.cpp:469
const std::vector< uint8_t > & subject_public_key_bitstring_sha1() const
Definition x509cert.cpp:334
bool allowed_usage(Key_Constraints usage) const
Definition x509cert.cpp:415
const X509_DN & issuer_dn() const
Definition x509cert.cpp:358
const std::vector< uint8_t > & v2_issuer_key_id() const
Definition x509cert.cpp:314
std::string ocsp_responder() const
Definition x509cert.cpp:485
bool matches_dns_name(std::string_view name) const
Definition x509cert.cpp:591
std::vector< std::string > subject_info(std::string_view name) const
Definition x509cert.cpp:512
uint32_t x509_version() const
Definition x509cert.cpp:294
std::string crl_distribution_point() const
Definition x509cert.cpp:493
const std::vector< OID > & certificate_policy_oids() const
Definition x509cert.cpp:398
std::unique_ptr< Public_Key > load_subject_public_key() const
Definition x509cert.cpp:554
bool is_self_signed() const
Definition x509cert.cpp:298
const std::vector< uint8_t > & raw_issuer_dn() const
Definition x509cert.cpp:366
bool operator<(const X509_Certificate &other) const
Definition x509cert.cpp:620
const AlgorithmIdentifier & subject_public_key_algo() const
Definition x509cert.cpp:310
const AlternativeName & subject_alt_name() const
Definition x509cert.cpp:501
std::vector< std::string > ca_issuers() const
Definition x509cert.cpp:489
const std::vector< uint8_t > & subject_public_key_info() const
Definition x509cert.cpp:326
std::vector< uint8_t > raw_issuer_dn_sha256() const
Definition x509cert.cpp:558
bool is_serial_negative() const
Definition x509cert.cpp:354
const std::vector< uint8_t > & subject_public_key_bitstring() const
Definition x509cert.cpp:330
std::unique_ptr< Public_Key > subject_public_key() const
Definition x509cert.cpp:546
const std::vector< uint8_t > & v2_subject_key_id() const
Definition x509cert.cpp:318
const X509_Time & not_before() const
Definition x509cert.cpp:302
std::vector< std::string > issuer_info(std::string_view name) const
Definition x509cert.cpp:531
std::string to_string() const
Definition x509cert.cpp:637
std::vector< std::string > get_attribute(std::string_view attr) const
Definition x509_dn.cpp:172
const std::vector< uint8_t > & signed_body() const
Definition x509_obj.h:42
const AlgorithmIdentifier & signature_algorithm() const
Definition x509_obj.h:47
const std::vector< uint8_t > & signature() const
Definition x509_obj.h:37
void load_data(DataSource &src)
Definition x509_obj.cpp:24
std::string name
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
Definition asn1_obj.cpp:172
std::unique_ptr< Public_Key > load_key(DataSource &source)
Definition x509_key.cpp:28
std::string PEM_encode(const Public_Key &key)
Definition x509_key.cpp:21
ASN1_Time X509_Time
Definition asn1_obj.h:402
ASN1_Type
Definition asn1_obj.h:43
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition alg_id.cpp:69
bool host_wildcard_match(std::string_view issued_, std::string_view host_)
Definition parsing.cpp:207
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition hex.cpp:33
std::string create_hex_fingerprint(const uint8_t bits[], size_t bits_len, std::string_view hash_name)
Definition pk_keys.cpp:30
Usage_Type
Definition x509cert.h:22