8 #include <botan/x509cert.h>
9 #include <botan/x509_ext.h>
10 #include <botan/der_enc.h>
11 #include <botan/ber_dec.h>
12 #include <botan/internal/stl_util.h>
13 #include <botan/parsing.h>
14 #include <botan/bigint.h>
15 #include <botan/oids.h>
16 #include <botan/pem.h>
17 #include <botan/hex.h>
29 std::vector<std::string> lookup_oids(
const std::vector<std::string>& in)
31 std::vector<std::string> out;
33 std::vector<std::string>::const_iterator i = in.begin();
57 X509_Certificate::X509_Certificate(
const std::string& in) :
67 void X509_Certificate::force_decode()
77 tbs_cert.decode_optional(version,
ASN1_Tag(0),
80 .decode(sig_algo_inner)
94 self_signed = (dn_subject == dn_issuer);
99 BER_Object public_key = tbs_cert.get_next_object();
101 throw BER_Bad_Tag(
"X509_Certificate: Unexpected tag for public key",
106 tbs_cert.decode_optional_string(v2_issuer_key_id,
BIT_STRING, 1);
107 tbs_cert.decode_optional_string(v2_subject_key_id,
BIT_STRING, 2);
109 BER_Object v3_exts_data = tbs_cert.get_next_object();
120 throw BER_Bad_Tag(
"Unknown tag in X.509 cert",
123 if(tbs_cert.more_items())
124 throw Decoding_Error(
"TBSCertificate has more items that expected");
126 subject.
add(
"X509.Certificate.version", version);
131 issuer.
add(
"X509.Certificate.v2.key_id", v2_issuer_key_id);
132 subject.
add(
"X509.Certificate.v2.key_id", v2_subject_key_id);
134 subject.
add(
"X509.Certificate.public_key",
142 !subject.
has_value(
"X509v3.BasicConstraints.path_constraint"))
145 Cert_Extension::NO_CERT_PATH_LIMIT : 0;
147 subject.
add(
"X509v3.BasicConstraints.path_constraint", limit);
156 return (subject.
get1_u32bit(
"X509.Certificate.version") + 1);
164 return subject.
get1(
"X509.Certificate.start");
172 return subject.
get1(
"X509.Certificate.end");
178 std::vector<std::string>
187 std::vector<std::string>
207 if(!subject.
get1_u32bit(
"X509v3.BasicConstraints.is_ca"))
219 return subject.
get1_u32bit(
"X509v3.BasicConstraints.path_constraint", 0);
236 return lookup_oids(subject.
get(
"X509v3.ExtendedKeyUsage"));
244 return lookup_oids(subject.
get(
"X509v3.CertificatePolicies"));
252 return issuer.
get1_memvec(
"X509v3.AuthorityKeyIdentifier");
260 return subject.
get1_memvec(
"X509v3.SubjectKeyIdentifier");
268 return subject.
get1_memvec(
"X509.Certificate.serial");
292 return (
sig == other.
sig &&
294 self_signed == other.self_signed &&
295 issuer == other.issuer &&
296 subject == other.subject);
304 return !(cert1 == cert2);
309 const char* dn_fields[] = {
"Name",
312 "Organizational Unit",
322 std::ostringstream out;
324 for(
size_t i = 0; dn_fields[i]; ++i)
326 const std::vector<std::string> vals = this->
subject_info(dn_fields[i]);
331 out <<
"Subject " << dn_fields[i] <<
":";
332 for(
size_t j = 0; j != vals.size(); ++j)
333 out <<
" " << vals[j];
337 for(
size_t i = 0; dn_fields[i]; ++i)
339 const std::vector<std::string> vals = this->
issuer_info(dn_fields[i]);
344 out <<
"Issuer " << dn_fields[i] <<
":";
345 for(
size_t j = 0; j != vals.size(); ++j)
346 out <<
" " << vals[j];
352 out <<
"Not valid before: " << this->
start_time() <<
"\n";
353 out <<
"Not valid after: " << this->
end_time() <<
"\n";
355 out <<
"Constraints:\n";
362 out <<
" Digital Signature\n";
364 out <<
" Non-Repuidation\n";
366 out <<
" Key Encipherment\n";
368 out <<
" Data Encipherment\n";
370 out <<
" Key Agreement\n";
372 out <<
" Cert Sign\n";
374 out <<
" CRL Sign\n";
380 out <<
"Policies: " <<
"\n";
381 for(
size_t i = 0; i != policies.size(); i++)
382 out <<
" " << policies[i] <<
"\n";
386 if(ex_constraints.size())
388 out <<
"Extended Constraints:\n";
389 for(
size_t i = 0; i != ex_constraints.size(); i++)
390 out <<
" " << ex_constraints[i] <<
"\n";
393 out <<
"Signature algorithm: " <<
419 bool operator()(
const std::string& key,
const std::string&)
const
421 if(key.find(
"X520.") != std::string::npos)
427 std::multimap<std::string, std::string> names =
432 std::multimap<std::string, std::string>::iterator i;
433 for(i = names.begin(); i != names.end(); ++i)
447 bool operator()(
const std::string& key,
const std::string&)
const
449 for(
size_t i = 0; i !=
matches.size(); ++i)
450 if(key.compare(
matches[i]) == 0)
455 AltName_Matcher(
const std::string& match_any_of)
460 std::vector<std::string>
matches;
463 std::multimap<std::string, std::string> names =
464 info.
search_with(AltName_Matcher(
"RFC822/DNS/URI/IP"));
468 std::multimap<std::string, std::string>::iterator i;
469 for(i = names.begin(); i != names.end(); ++i)
void add_attribute(const std::string &, const std::string &)
bool operator!=(const OctetString &s1, const OctetString &s2)
MemoryVector< byte > tbs_bits
bool operator==(const X509_Certificate &other) const
BER_Decoder & decode(bool &)
Public_Key * load_key(DataSource &source)
std::vector< std::string > split_on(const std::string &str, char delim)
Key_Constraints constraints() const
void add_attribute(const std::string &, const std::string &)
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
void contents_to(Data_Store &, Data_Store &) const
u32bit path_limit() const
MemoryVector< byte > authority_key_id() const
std::string get1(const std::string &) const
AlgorithmIdentifier sig_algo
X509_DN create_dn(const Data_Store &info)
std::string end_time() const
AlternativeName create_alt_name(const Data_Store &info)
std::string to_string() const
std::string lookup(const OID &oid)
std::string start_time() const
std::string PEM_encode(const Public_Key &key)
SecureVector< byte > value
MemoryVector< byte > serial_number() const
bool matches(DataSource &source, const std::string &extra, size_t search_range)
std::multimap< std::string, std::string > search_with(const Matcher &) const
std::vector< std::string > policies() const
MemoryVector< byte > subject_key_id() const
SecureVector< byte > put_in_sequence(const MemoryRegion< byte > &contents)
std::string encode(const byte der[], size_t length, const std::string &label, size_t width)
MemoryVector< byte > get1_memvec(const std::string &) const
u32bit get1_u32bit(const std::string &, u32bit=0) const
bool has_value(const std::string &) const
BER_Decoder & verify_end()
X509_DN issuer_dn() const
std::vector< std::string > subject_info(const std::string &name) const
std::vector< std::string > ex_constraints() const
static std::string deref_info_field(const std::string &)
std::string to_string(u64bit n, size_t min_len)
std::string readable_string() const
std::vector< std::string > issuer_info(const std::string &name) const
Public_Key * subject_public_key() const
std::multimap< std::string, std::string > contents() const
X509_DN subject_dn() const
u32bit x509_version() const
std::vector< std::string > get(const std::string &) const
AlgorithmIdentifier signature_algorithm() const
void add(const std::multimap< std::string, std::string > &)
void hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)