9#include <botan/x509cert.h>
10#include <botan/x509_key.h>
11#include <botan/datastor.h>
12#include <botan/pk_keys.h>
13#include <botan/x509_ext.h>
14#include <botan/ber_dec.h>
15#include <botan/parsing.h>
16#include <botan/bigint.h>
17#include <botan/oids.h>
18#include <botan/hash.h>
20#include <botan/internal/stl_util.h>
26struct X509_Certificate_Data
28 std::vector<uint8_t> m_serial;
29 AlgorithmIdentifier m_sig_algo_inner;
32 std::vector<uint8_t> m_issuer_dn_bits;
33 std::vector<uint8_t> m_subject_dn_bits;
36 std::vector<uint8_t> m_subject_public_key_bits;
37 std::vector<uint8_t> m_subject_public_key_bits_seq;
38 std::vector<uint8_t> m_subject_public_key_bitstring;
39 std::vector<uint8_t> m_subject_public_key_bitstring_sha1;
40 AlgorithmIdentifier m_subject_public_key_algid;
42 std::vector<uint8_t> m_v2_issuer_key_id;
43 std::vector<uint8_t> m_v2_subject_key_id;
44 Extensions m_v3_extensions;
46 std::vector<OID> m_extended_key_usage;
47 std::vector<uint8_t> m_authority_key_id;
48 std::vector<uint8_t> m_subject_key_id;
49 std::vector<OID> m_cert_policies;
51 std::vector<std::string> m_crl_distribution_points;
52 std::string m_ocsp_responder;
53 std::vector<std::string> m_ca_issuers;
55 std::vector<uint8_t> m_issuer_dn_bits_sha256;
56 std::vector<uint8_t> m_subject_dn_bits_sha256;
58 std::string m_fingerprint_sha1;
59 std::string m_fingerprint_sha256;
61 AlternativeName m_subject_alt_name;
62 AlternativeName m_issuer_alt_name;
63 NameConstraints m_name_constraints;
65 Data_Store m_subject_ds;
66 Data_Store m_issuer_ds;
69 size_t m_path_len_constraint = 0;
71 bool m_self_signed =
false;
72 bool m_is_ca_certificate =
false;
73 bool m_serial_negative =
false;
76std::string X509_Certificate::PEM_label()
const
81std::vector<std::string> X509_Certificate::alternate_PEM_labels()
const
83 return {
"X509 CERTIFICATE" };
103#if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM)
113std::unique_ptr<X509_Certificate_Data> parse_x509_cert_body(
const X509_Object& obj)
115 std::unique_ptr<X509_Certificate_Data> data(
new X509_Certificate_Data);
118 BER_Object public_key;
119 BER_Object v3_exts_data;
121 BER_Decoder(obj.signed_body())
124 .decode(data->m_sig_algo_inner)
125 .decode(data->m_issuer_dn)
127 .decode(data->m_not_before)
128 .decode(data->m_not_after)
130 .decode(data->m_subject_dn)
131 .get_next(public_key)
132 .decode_optional_string(data->m_v2_issuer_key_id,
BIT_STRING, 1)
133 .decode_optional_string(data->m_v2_subject_key_id,
BIT_STRING, 2)
134 .get_next(v3_exts_data)
135 .verify_end(
"TBSCertificate has extra data after extensions block");
137 if(data->m_version > 2)
138 throw Decoding_Error(
"Unknown X.509 cert version " + std::to_string(data->m_version));
139 if(obj.signature_algorithm() != data->m_sig_algo_inner)
140 throw Decoding_Error(
"X.509 Certificate had differing algorithm identifers in inner and outer ID fields");
145 data->m_serial_negative = serial_bn.is_negative();
148 data->m_version += 1;
155 AlgorithmIdentifier public_key_alg_id;
156 BER_Decoder(public_key).decode(public_key_alg_id).discard_remaining();
158 const std::vector<std::string> public_key_info =
161 if(!public_key_info.empty() && public_key_info[0] ==
"RSA")
164 if(public_key_info.size() >= 2)
166 if(public_key_info[1] ==
"EMSA4")
182 if(public_key_alg_id != obj.signature_algorithm())
184 throw Decoding_Error(
"Algorithm identifier mismatch");
193 throw Decoding_Error(
"RSA algorithm parameters field MUST contain NULL");
198 data->m_subject_public_key_bits.assign(public_key.bits(), public_key.bits() + public_key.length());
202 BER_Decoder(data->m_subject_public_key_bits)
203 .decode(data->m_subject_public_key_algid)
204 .decode(data->m_subject_public_key_bitstring,
BIT_STRING);
209 BER_Decoder(v3_exts_data).decode(data->m_v3_extensions).verify_end();
211 else if(v3_exts_data.is_set())
213 throw BER_Bad_Tag(
"Unknown tag in X.509 cert", v3_exts_data.tagging());
217 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Key_Usage>())
219 data->m_key_constraints = ext->get_constraints();
226 throw Decoding_Error(
"Certificate has invalid encoding for KeyUsage");
234 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Key_ID>())
236 data->m_subject_key_id = ext->get_key_id();
239 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Key_ID>())
241 data->m_authority_key_id = ext->get_key_id();
244 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Name_Constraints>())
246 data->m_name_constraints = ext->get_name_constraints();
249 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Basic_Constraints>())
251 if(ext->get_is_ca() ==
true)
263 data->m_is_ca_certificate =
true;
264 data->m_path_len_constraint = ext->get_path_limit();
269 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Issuer_Alternative_Name>())
271 data->m_issuer_alt_name = ext->get_alt_name();
274 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Subject_Alternative_Name>())
276 data->m_subject_alt_name = ext->get_alt_name();
279 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Extended_Key_Usage>())
281 data->m_extended_key_usage = ext->get_oids();
284 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Certificate_Policies>())
286 data->m_cert_policies = ext->get_policy_oids();
289 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::Authority_Information_Access>())
291 data->m_ocsp_responder = ext->ocsp_responder();
292 data->m_ca_issuers = ext->ca_issuers();
295 if(
auto ext = data->m_v3_extensions.get_extension_object_as<Cert_Extension::CRL_Distribution_Points>())
297 data->m_crl_distribution_points = ext->crl_distribution_urls();
301 if(data->m_subject_dn == data->m_issuer_dn)
303 if(data->m_subject_key_id.empty() ==
false && data->m_authority_key_id.empty() ==
false)
305 data->m_self_signed = (data->m_subject_key_id == data->m_authority_key_id);
314 data->m_self_signed =
true;
318 std::unique_ptr<Public_Key> pub_key(
X509::load_key(data->m_subject_public_key_bits_seq));
325 data->m_self_signed =
true;
329 data->m_self_signed =
false;
339 const std::vector<uint8_t> full_encoding = obj.BER_encode();
344 sha1->update(data->m_subject_public_key_bitstring);
345 data->m_subject_public_key_bitstring_sha1 = sha1->final_stdvec();
354 sha256->update(data->m_issuer_dn_bits);
355 data->m_issuer_dn_bits_sha256 = sha256->final_stdvec();
357 sha256->update(data->m_subject_dn_bits);
358 data->m_subject_dn_bits_sha256 = sha256->final_stdvec();
363 data->m_subject_ds.add(data->m_subject_dn.contents());
364 data->m_issuer_ds.add(data->m_issuer_dn.contents());
365 data->m_v3_extensions.contents_to(data->m_subject_ds, data->m_issuer_ds);
375void X509_Certificate::force_decode()
379 std::unique_ptr<X509_Certificate_Data> data = parse_x509_cert_body(*
this);
381 m_data.reset(data.release());
384const X509_Certificate_Data& X509_Certificate::data()
const
386 if(m_data ==
nullptr)
388 throw Invalid_State(
"X509_Certificate uninitialized");
390 return *m_data.get();
395 return static_cast<uint32_t
>(data().m_version);
400 return data().m_self_signed;
405 return data().m_not_before;
410 return data().m_not_after;
415 return data().m_subject_public_key_algid;
420 return data().m_v2_issuer_key_id;
425 return data().m_v2_subject_key_id;
430 return data().m_subject_public_key_bits;
435 return data().m_subject_public_key_bits_seq;
440 return data().m_subject_public_key_bitstring;
445 if(data().m_subject_public_key_bitstring_sha1.empty())
446 throw Encoding_Error(
"X509_Certificate::subject_public_key_bitstring_sha1 called but SHA-1 disabled in build");
448 return data().m_subject_public_key_bitstring_sha1;
453 return data().m_authority_key_id;
458 return data().m_subject_key_id;
463 return data().m_serial;
468 return data().m_serial_negative;
474 return data().m_issuer_dn;
479 return data().m_subject_dn;
484 return data().m_issuer_dn_bits;
489 return data().m_subject_dn_bits;
494 if(data().m_version < 3 && data().m_self_signed)
497 return data().m_is_ca_certificate;
502 if(data().m_version < 3 && data().m_self_signed)
505 return static_cast<uint32_t
>(data().m_path_len_constraint);
510 return data().m_key_constraints;
515 return data().m_extended_key_usage;
520 return data().m_cert_policies;
525 return data().m_name_constraints;
530 return data().m_v3_extensions;
551 if(std::find(ex.begin(), ex.end(), usage) != ex.end())
603 return (std::find(ex.begin(), ex.end(), usage) != ex.end());
616 return data().m_ocsp_responder;
621 return data().m_ca_issuers;
627 if(data().m_crl_distribution_points.size() > 0)
628 return data().m_crl_distribution_points[0];
634 return data().m_subject_alt_name;
639 return data().m_issuer_alt_name;
645std::vector<std::string>
658 if(req ==
"X509.Certificate.v2.key_id")
660 if(req ==
"X509v3.SubjectKeyIdentifier")
662 if(req ==
"X509.Certificate.dn_bits")
664 if(req ==
"X509.Certificate.start")
666 if(req ==
"X509.Certificate.end")
669 if(req ==
"X509.Certificate.version")
671 if(req ==
"X509.Certificate.serial")
674 return data().m_subject_ds.get(req);
680std::vector<std::string>
690 if(req ==
"X509.Certificate.v2.key_id")
692 if(req ==
"X509v3.AuthorityKeyIdentifier")
694 if(req ==
"X509.Certificate.dn_bits")
697 return data().m_issuer_ds.get(req);
709 catch(std::exception& e)
711 throw Decoding_Error(
"X509_Certificate::load_subject_public_key", e);
722 if(data().m_issuer_dn_bits_sha256.empty())
723 throw Encoding_Error(
"X509_Certificate::raw_issuer_dn_sha256 called but SHA-256 disabled in build");
724 return data().m_issuer_dn_bits_sha256;
729 if(data().m_subject_dn_bits_sha256.empty())
730 throw Encoding_Error(
"X509_Certificate::raw_subject_dn_sha256 called but SHA-256 disabled in build");
731 return data().m_subject_dn_bits_sha256;
739std::vector<std::string> lookup_oids(
const std::vector<OID>& oids)
741 std::vector<std::string> out;
743 for(
const OID& oid : oids)
745 out.push_back(oid.to_formatted_string());
779 if(hash_name ==
"SHA-256" && data().m_fingerprint_sha256.size() > 0)
780 return data().m_fingerprint_sha256;
781 else if(hash_name ==
"SHA-1" && data().m_fingerprint_sha1.size() > 0)
782 return data().m_fingerprint_sha1;
792 bool is_ipv4 =
false;
800 std::vector<std::string> issued_names;
804 }
else if(is_ipv4 ==
false) {
809 for(
size_t i = 0; i != issued_names.size(); ++i)
813 if(issued_names[i] ==
name)
853 return !(cert1 == cert2);
858 std::ostringstream out;
862 out <<
"Issuer: " <<
issuer_dn() <<
"\n";
866 out <<
"Constraints:\n";
873 out <<
" Digital Signature\n";
875 out <<
" Non-Repudiation\n";
877 out <<
" Key Encipherment\n";
879 out <<
" Data Encipherment\n";
881 out <<
" Key Agreement\n";
883 out <<
" Cert Sign\n";
885 out <<
" CRL Sign\n";
887 out <<
" Encipher Only\n";
889 out <<
" Decipher Only\n";
893 if(!policies.empty())
895 out <<
"Policies: " <<
"\n";
897 out <<
" " << oid.to_string() <<
"\n";
901 if(!ex_constraints.empty())
903 out <<
"Extended Constraints:\n";
906 out <<
" " << oid.to_formatted_string() <<
"\n";
914 out <<
"Name Constraints:\n";
921 out <<
" " << st.base();
931 out <<
" " << st.base();
941 if(!ca_issuers.empty())
943 out <<
"CA Issuers:\n";
944 for(
size_t i = 0; i !=
ca_issuers.size(); i++)
964 out <<
"Public Key [" << pubkey->algo_name() <<
"-" << pubkey->key_length() <<
"]\n\n";
970 out <<
"Failed to decode key with oid " << alg_id.
get_oid().
to_string() <<
"\n";
std::vector< uint8_t > BER_encode() const
std::string to_string() const
Return an internal string representation of the time.
std::string readable_string() const
Returns a human friendly string replesentation of no particular formatting.
const OID & get_oid() const
std::vector< std::string > get_attribute(const std::string &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(const std::string &algo_spec, const std::string &provider="")
const std::vector< GeneralSubtree > & permitted() const
const std::vector< GeneralSubtree > & excluded() const
std::string to_formatted_string() const
static OID from_string(const std::string &str)
std::string to_string() const
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
std::vector< std::string > issuer_info(const std::string &name) const
const std::vector< uint8_t > & serial_number() const
std::vector< std::string > ex_constraints() const
const X509_DN & subject_dn() const
std::vector< uint8_t > raw_subject_dn_sha256() const
bool allowed_extended_usage(const std::string &usage) const
uint32_t path_limit() const
const X509_Time & not_after() const
const std::vector< uint8_t > & authority_key_id() 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
std::vector< std::string > subject_info(const std::string &name) 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 has_ex_constraint(const std::string &ex_constraint) const
uint32_t x509_version() const
std::vector< std::string > policies() 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
Public_Key * subject_public_key() const
const AlgorithmIdentifier & subject_public_key_algo() const
bool matches_dns_name(const std::string &name) 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::string fingerprint(const std::string &hash_name="SHA-1") const
const std::vector< uint8_t > & v2_subject_key_id() const
const X509_Time & not_before() const
std::string to_string() const
bool is_critical(const std::string &ex_name) const
std::vector< std::string > get_attribute(const std::string &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)
BOTAN_UNSTABLE_API std::string oid2str_or_empty(const OID &oid)
Public_Key * load_key(DataSource &source)
std::string PEM_encode(const Public_Key &key)
std::vector< std::string > split_on(const std::string &str, char delim)
uint32_t string_to_ipv4(const std::string &str)
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
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, const std::string &hash_name)
bool host_wildcard_match(const std::string &issued_, const std::string &host_)