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/lookup.h>
16 #include <botan/oids.h>
17 #include <botan/pem.h>
18 #include <botan/hex.h>
31 std::vector<std::string> lookup_oids(
const std::vector<std::string>& in)
33 std::vector<std::string> out;
35 for(
auto i = in.begin(); i != in.end(); ++i)
55 X509_Certificate::X509_Certificate(
const std::string& in) :
65 X509_Certificate::X509_Certificate(
const std::vector<byte>& in) :
75 void X509_Certificate::force_decode()
85 tbs_cert.decode_optional(version,
ASN1_Tag(0),
88 .decode(sig_algo_inner)
102 self_signed = (dn_subject == dn_issuer);
110 BER_Object public_key = tbs_cert.get_next_object();
112 throw BER_Bad_Tag(
"X509_Certificate: Unexpected tag for public key",
115 std::vector<byte> v2_issuer_key_id, v2_subject_key_id;
117 tbs_cert.decode_optional_string(v2_issuer_key_id,
BIT_STRING, 1);
118 tbs_cert.decode_optional_string(v2_subject_key_id,
BIT_STRING, 2);
120 BER_Object v3_exts_data = tbs_cert.get_next_object();
131 throw BER_Bad_Tag(
"Unknown tag in X.509 cert",
134 if(tbs_cert.more_items())
135 throw Decoding_Error(
"TBSCertificate has more items that expected");
137 subject.
add(
"X509.Certificate.version", version);
142 issuer.
add(
"X509.Certificate.v2.key_id", v2_issuer_key_id);
143 subject.
add(
"X509.Certificate.v2.key_id", v2_subject_key_id);
145 subject.
add(
"X509.Certificate.public_key",
148 if(self_signed && version == 0)
150 subject.
add(
"X509v3.BasicConstraints.is_ca", 1);
151 subject.
add(
"X509v3.BasicConstraints.path_constraint", Cert_Extension::NO_CERT_PATH_LIMIT);
155 !subject.
has_value(
"X509v3.BasicConstraints.path_constraint"))
158 Cert_Extension::NO_CERT_PATH_LIMIT : 0;
160 subject.
add(
"X509v3.BasicConstraints.path_constraint", limit);
169 return (subject.
get1_u32bit(
"X509.Certificate.version") + 1);
177 return subject.
get1(
"X509.Certificate.start");
185 return subject.
get1(
"X509.Certificate.end");
191 std::vector<std::string>
200 std::vector<std::string>
225 if(!subject.
get1_u32bit(
"X509v3.BasicConstraints.is_ca"))
241 if(constraint == usage)
252 return subject.
get1_u32bit(
"X509v3.BasicConstraints.path_constraint", 0);
269 return lookup_oids(subject.
get(
"X509v3.ExtendedKeyUsage"));
277 return lookup_oids(subject.
get(
"X509v3.CertificatePolicies"));
282 return subject.
get1(
"OCSP.responder",
"");
287 return subject.
get1(
"CRL.DistributionPoint",
"");
295 return issuer.
get1_memvec(
"X509v3.AuthorityKeyIdentifier");
303 return subject.
get1_memvec(
"X509v3.SubjectKeyIdentifier");
311 return subject.
get1_memvec(
"X509.Certificate.serial");
324 return issuer.
get1_memvec(
"X509.Certificate.dn_bits");
337 return subject.
get1_memvec(
"X509.Certificate.dn_bits");
342 bool cert_subject_dns_match(
const std::string& name,
343 const std::vector<std::string>& cert_names)
345 for(
size_t i = 0; i != cert_names.size(); ++i)
347 const std::string cn = cert_names[i];
356 if(cn.size() > 2 && cn[0] ==
'*' && cn[1] ==
'.' && name.size() > cn.size())
358 const std::string
base = cn.substr(1, std::string::npos);
360 if(name.compare(name.size() - base.size(), base.size(),
base) == 0)
372 std::unique_ptr<HashFunction> hash(
get_hash(hash_name));
374 const auto hex_print =
hex_encode(hash->final());
376 std::string formatted_print;
378 for(
size_t i = 0; i != hex_print.size(); i += 2)
380 formatted_print.push_back(hex_print[i]);
381 formatted_print.push_back(hex_print[i+1]);
383 if(i != hex_print.size() - 2)
384 formatted_print.push_back(
':');
387 return formatted_print;
409 return (
sig == other.
sig &&
411 self_signed == other.self_signed &&
412 issuer == other.issuer &&
413 subject == other.subject);
435 return !(cert1 == cert2);
440 const char* dn_fields[] = {
"Name",
443 "Organizational Unit",
453 std::ostringstream out;
455 for(
size_t i = 0; dn_fields[i]; ++i)
457 const std::vector<std::string> vals = this->
subject_info(dn_fields[i]);
462 out <<
"Subject " << dn_fields[i] <<
":";
463 for(
size_t j = 0; j != vals.size(); ++j)
464 out <<
" " << vals[j];
468 for(
size_t i = 0; dn_fields[i]; ++i)
470 const std::vector<std::string> vals = this->
issuer_info(dn_fields[i]);
475 out <<
"Issuer " << dn_fields[i] <<
":";
476 for(
size_t j = 0; j != vals.size(); ++j)
477 out <<
" " << vals[j];
483 out <<
"Not valid before: " << this->
start_time() <<
"\n";
484 out <<
"Not valid after: " << this->
end_time() <<
"\n";
486 out <<
"Constraints:\n";
493 out <<
" Digital Signature\n";
495 out <<
" Non-Repuidation\n";
497 out <<
" Key Encipherment\n";
499 out <<
" Data Encipherment\n";
501 out <<
" Key Agreement\n";
503 out <<
" Cert Sign\n";
505 out <<
" CRL Sign\n";
509 if(!policies.empty())
511 out <<
"Policies: " <<
"\n";
512 for(
size_t i = 0; i != policies.size(); i++)
513 out <<
" " << policies[i] <<
"\n";
517 if(!ex_constraints.empty())
519 out <<
"Extended Constraints:\n";
520 for(
size_t i = 0; i != ex_constraints.size(); i++)
521 out <<
" " << ex_constraints[i] <<
"\n";
524 out <<
"Signature algorithm: " <<
547 [](
const std::string& key,
const std::string&)
549 return (key.find(
"X520.") != std::string::npos);
554 for(
auto i = names.begin(); i != names.end(); ++i)
566 [](
const std::string& key,
const std::string&)
568 return (key ==
"RFC822" ||
576 for(
auto i = names.begin(); i != names.end(); ++i)