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