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>
29std::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();
67void 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();
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");
178std::vector<std::string>
187std::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";
377 std::vector<std::string>
policies = this->policies();
380 out <<
"Policies: " <<
"\n";
381 for(
size_t i = 0; i !=
policies.size(); i++)
388 out <<
"Extended Constraints:\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)
457 matches =
split_on(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 &)
BER_Decoder(DataSource &)
SecureVector< byte > value
static SecureVector< byte > encode(const BigInt &n, Base base=Binary)
void add(const std::multimap< std::string, std::string > &)
std::multimap< std::string, std::string > search_with(const Matcher &) const
bool has_value(const std::string &) const
void contents_to(Data_Store &, Data_Store &) const
OID(const std::string &str="")
Key_Constraints constraints() const
bool operator==(const X509_Certificate &other) const
std::vector< std::string > issuer_info(const std::string &name) const
std::vector< std::string > ex_constraints() const
u32bit x509_version() const
X509_DN subject_dn() const
MemoryVector< byte > serial_number() const
std::string end_time() const
MemoryVector< byte > authority_key_id() const
std::vector< std::string > subject_info(const std::string &name) const
u32bit path_limit() const
std::vector< std::string > policies() const
std::string start_time() const
X509_Certificate(DataSource &source)
Public_Key * subject_public_key() const
X509_DN issuer_dn() const
std::string to_string() const
MemoryVector< byte > subject_key_id() const
static std::string deref_info_field(const std::string &)
std::multimap< std::string, std::string > contents() const
void add_attribute(const std::string &, const std::string &)
X509_Object(DataSource &src, const std::string &pem_labels)
AlgorithmIdentifier signature_algorithm() const
AlgorithmIdentifier sig_algo
MemoryVector< byte > tbs_bits
std::string readable_string() const
SecureVector< byte > put_in_sequence(const MemoryRegion< byte > &contents)
std::string lookup(const OID &oid)
std::string encode(const byte der[], size_t length, const std::string &label, size_t width)
std::string PEM_encode(const Public_Key &key)
Public_Key * load_key(DataSource &source)
void hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)
std::string to_string(u64bit n, size_t min_len)
bool operator!=(const OctetString &s1, const OctetString &s2)
std::vector< std::string > split_on(const std::string &str, char delim)
Public_Key X509_PublicKey
X509_DN create_dn(const Data_Store &info)
AlternativeName create_alt_name(const Data_Store &info)
BER_Bad_Tag(const std::string &msg, ASN1_Tag tag)
Decoding_Error(const std::string &name)