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>
23struct X509_Certificate_Data
25 std::vector<uint8_t> m_serial;
26 AlgorithmIdentifier m_sig_algo_inner;
29 std::vector<uint8_t> m_issuer_dn_bits;
30 std::vector<uint8_t> m_subject_dn_bits;
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;
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;
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;
48 std::vector<std::string> m_crl_distribution_points;
49 std::string m_ocsp_responder;
50 std::vector<std::string> m_ca_issuers;
52 std::vector<uint8_t> m_issuer_dn_bits_sha256;
53 std::vector<uint8_t> m_subject_dn_bits_sha256;
55 std::string m_fingerprint_sha1;
56 std::string m_fingerprint_sha256;
58 AlternativeName m_subject_alt_name;
59 AlternativeName m_issuer_alt_name;
60 NameConstraints m_name_constraints;
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;
70std::string X509_Certificate::PEM_label()
const
75std::vector<std::string> X509_Certificate::alternate_PEM_labels()
const
77 return {
"X509 CERTIFICATE" };
97#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
107std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(
const X509_Object& obj)
109 auto data = std::make_unique<X509_Certificate_Data>();
112 BER_Object public_key;
113 BER_Object v3_exts_data;
115 BER_Decoder(obj.signed_body())
118 .decode(data->m_sig_algo_inner)
119 .decode(data->m_issuer_dn)
121 .decode(data->m_not_before)
122 .decode(data->m_not_after)
124 .decode(data->m_subject_dn)
125 .get_next(public_key)
128 .get_next(v3_exts_data)
129 .verify_end(
"TBSCertificate has extra data after extensions block");
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");
139 data->m_serial_negative = serial_bn.is_negative();
142 data->m_version += 1;
148 data->m_subject_public_key_bits.assign(public_key.bits(), public_key.bits() + public_key.length());
152 BER_Decoder(data->m_subject_public_key_bits)
153 .decode(data->m_subject_public_key_algid)
159 BER_Decoder(v3_exts_data).decode(data->m_v3_extensions).verify_end();
161 else if(v3_exts_data.is_set())
163 throw BER_Bad_Tag(
"Unknown tag in X.509 cert", v3_exts_data.tagging());
167 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Key_Usage>())
169 data->m_key_constraints = ext->get_constraints();
174 if(data->m_key_constraints.empty())
176 throw Decoding_Error(
"Certificate has invalid encoding for KeyUsage");
180 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Key_ID>())
182 data->m_subject_key_id = ext->get_key_id();
185 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Key_ID>())
187 data->m_authority_key_id = ext->get_key_id();
190 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Name_Constraints>())
192 data->m_name_constraints = ext->get_name_constraints();
195 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Basic_Constraints>())
197 if(ext->get_is_ca() ==
true)
206 if(data->m_key_constraints.empty() ||
209 data->m_is_ca_certificate =
true;
210 data->m_path_len_constraint = ext->get_path_limit();
215 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Issuer_Alternative_Name>())
217 data->m_issuer_alt_name = ext->get_alt_name();
220 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Alternative_Name>())
222 data->m_subject_alt_name = ext->get_alt_name();
225 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Extended_Key_Usage>())
227 data->m_extended_key_usage = ext->object_identifiers();
230 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Certificate_Policies>())
232 data->m_cert_policies = ext->get_policy_oids();
235 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Information_Access>())
237 data->m_ocsp_responder = ext->ocsp_responder();
238 data->m_ca_issuers = ext->ca_issuers();
241 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::CRL_Distribution_Points>())
243 data->m_crl_distribution_points = ext->crl_distribution_urls();
247 if(data->m_subject_dn == data->m_issuer_dn)
249 if(data->m_subject_key_id.empty() ==
false && data->m_authority_key_id.empty() ==
false)
251 data->m_self_signed = (data->m_subject_key_id == data->m_authority_key_id);
260 data->m_self_signed =
true;
264 auto pub_key =
X509::load_key(data->m_subject_public_key_bits_seq);
266 const auto sig_status = obj.verify_signature(*pub_key);
271 data->m_self_signed =
true;
275 data->m_self_signed =
false;
285 const std::vector<uint8_t> full_encoding = obj.BER_encode();
290 sha1->update(data->m_subject_public_key_bitstring);
291 data->m_subject_public_key_bitstring_sha1 = sha1->final_stdvec();
300 sha256->update(data->m_issuer_dn_bits);
301 data->m_issuer_dn_bits_sha256 = sha256->final_stdvec();
303 sha256->update(data->m_subject_dn_bits);
304 data->m_subject_dn_bits_sha256 = sha256->final_stdvec();
317void X509_Certificate::force_decode()
320 m_data = parse_x509_cert_body(*
this);
323const X509_Certificate_Data& X509_Certificate::data()
const
325 if(m_data ==
nullptr)
327 throw Invalid_State(
"X509_Certificate uninitialized");
334 return static_cast<uint32_t
>(data().m_version);
339 return data().m_self_signed;
344 return data().m_not_before;
349 return data().m_not_after;
354 return data().m_subject_public_key_algid;
359 return data().m_v2_issuer_key_id;
364 return data().m_v2_subject_key_id;
369 return data().m_subject_public_key_bits;
374 return data().m_subject_public_key_bits_seq;
379 return data().m_subject_public_key_bitstring;
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");
387 return data().m_subject_public_key_bitstring_sha1;
392 return data().m_authority_key_id;
397 return data().m_subject_key_id;
402 return data().m_serial;
407 return data().m_serial_negative;
413 return data().m_issuer_dn;
418 return data().m_subject_dn;
423 return data().m_issuer_dn_bits;
428 return data().m_subject_dn_bits;
433 if(data().m_version < 3 && data().m_self_signed)
436 return data().m_is_ca_certificate;
441 if(data().m_version < 3 && data().m_self_signed)
444 return static_cast<uint32_t
>(data().m_path_len_constraint);
449 return data().m_key_constraints;
454 return data().m_extended_key_usage;
459 return data().m_cert_policies;
464 return data().m_name_constraints;
469 return data().m_v3_extensions;
496 if(std::find(ex.begin(), ex.end(), usage) != ex.end())
546 return (std::find(ex.begin(), ex.end(), usage) != ex.end());
559 return data().m_ocsp_responder;
564 return data().m_ca_issuers;
570 if(!data().m_crl_distribution_points.empty())
571 return data().m_crl_distribution_points[0];
577 return data().m_subject_alt_name;
582 return data().m_issuer_alt_name;
588std::vector<std::string>
606std::vector<std::string>
627 catch(std::exception& e)
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;
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;
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;
679 if(issued_names.empty())
682 for(
const auto& issued_name : issued_names)
718 return !(cert1 == cert2);
723 std::ostringstream out;
727 out <<
"Issuer: " <<
issuer_dn() <<
"\n";
731 out <<
"Constraints:\n";
733 if(constraints.
empty())
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";
758 if(!policies.empty())
760 out <<
"Policies: " <<
"\n";
761 for(
const auto& oid : policies)
762 out <<
" " << oid.to_string() <<
"\n";
766 if(!ex_constraints.empty())
768 out <<
"Extended Constraints:\n";
769 for(
auto&& oid : ex_constraints)
771 out <<
" " << oid.to_formatted_string() <<
"\n";
779 out <<
"Name Constraints:\n";
786 out <<
" " << st.base();
796 out <<
" " << st.base();
806 if(!ca_issuers.empty())
808 out <<
"CA Issuers:\n";
810 out <<
" URI: " << ca_issuer <<
"\n";
829 out <<
"Public Key [" << pubkey->algo_name() <<
"-" << pubkey->key_length() <<
"]\n\n";
835 out <<
"Failed to decode key with oid " << alg_id.
oid().
to_string() <<
"\n";
std::vector< uint8_t > BER_encode() const
std::string readable_string() const
Returns a human friendly string replesentation of no particular formatting.
std::vector< std::string > get_attribute(std::string_view attr) const
static std::vector< uint8_t > encode(const BigInt &n)
bool critical_extension_set(const OID &oid) const
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
bool includes(Key_Constraints::Bits other) const
const std::vector< GeneralSubtree > & permitted() const
const std::vector< GeneralSubtree > & excluded() const
std::string to_formatted_string() const
std::string to_string() const
static OID from_string(std::string_view str)
const std::vector< OID > & extended_key_usage() const
Key_Constraints constraints() const
bool operator==(const X509_Certificate &other) const
const NameConstraints & name_constraints() const
X509_Certificate()=default
bool is_critical(std::string_view ex_name) const
const std::vector< uint8_t > & serial_number() const
std::string fingerprint(std::string_view hash_name="SHA-1") const
const X509_DN & subject_dn() const
std::vector< uint8_t > raw_subject_dn_sha256() const
uint32_t path_limit() const
const X509_Time & not_after() const
const std::vector< uint8_t > & authority_key_id() const
bool allowed_extended_usage(std::string_view usage) const
const AlternativeName & issuer_alt_name() const
const std::vector< uint8_t > & raw_subject_dn() const
const std::vector< uint8_t > & subject_key_id() const
const std::vector< uint8_t > & subject_public_key_bits() const
bool has_constraints(Key_Constraints constraints) const
const Extensions & v3_extensions() const
bool has_ex_constraint(std::string_view ex_constraint) const
const std::vector< uint8_t > & subject_public_key_bitstring_sha1() const
bool allowed_usage(Key_Constraints usage) const
const X509_DN & issuer_dn() const
const std::vector< uint8_t > & v2_issuer_key_id() const
std::string ocsp_responder() const
bool matches_dns_name(std::string_view name) const
std::vector< std::string > subject_info(std::string_view name) const
uint32_t x509_version() const
std::string crl_distribution_point() const
const std::vector< OID > & certificate_policy_oids() const
std::unique_ptr< Public_Key > load_subject_public_key() const
bool is_self_signed() const
const std::vector< uint8_t > & raw_issuer_dn() const
bool operator<(const X509_Certificate &other) const
const AlgorithmIdentifier & subject_public_key_algo() const
const AlternativeName & subject_alt_name() const
std::vector< std::string > ca_issuers() const
const std::vector< uint8_t > & subject_public_key_info() const
std::vector< uint8_t > raw_issuer_dn_sha256() const
bool is_serial_negative() const
const std::vector< uint8_t > & subject_public_key_bitstring() const
std::unique_ptr< Public_Key > subject_public_key() const
const std::vector< uint8_t > & v2_subject_key_id() const
const X509_Time & not_before() const
std::vector< std::string > issuer_info(std::string_view name) const
std::string to_string() const
std::vector< std::string > get_attribute(std::string_view attr) const
const std::vector< uint8_t > & signed_body() const
const AlgorithmIdentifier & signature_algorithm() const
const std::vector< uint8_t > & signature() const
void load_data(DataSource &src)
std::vector< uint8_t > put_in_sequence(const std::vector< uint8_t > &contents)
std::unique_ptr< Public_Key > load_key(DataSource &source)
std::string PEM_encode(const Public_Key &key)
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
bool host_wildcard_match(std::string_view issued_, std::string_view host_)
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
std::string create_hex_fingerprint(const uint8_t bits[], size_t bits_len, std::string_view hash_name)