8 #include <botan/x509stor.h>     9 #include <botan/parsing.h>    10 #include <botan/pubkey.h>    11 #include <botan/oids.h>    12 #include <botan/time.h>    23 s32bit validity_check(
const X509_Time& start, 
const X509_Time& end,
    26    const s32bit NOT_YET_VALID = -1, VALID_TIME = 0, EXPIRED = 1;
    28    if(start.cmp(current_time + slack) > 0)
    30    if(end.cmp(current_time - slack) < 0)
    38 bool compare_ids(
const MemoryVector<byte>& id1,
    39                  const MemoryVector<byte>& id2)
    41    if(!id1.size() || !id2.size())
    52    if((usage & check_for) == 0)
    56    if(cert.constraints() & constraints)
    66                  const std::string& usage_oid)
    68    if((usage & check_for) == 0)
    71    const std::vector<std::string> constraints = cert.ex_constraints();
    73    if(constraints.empty())
    76    return std::binary_search(constraints.begin(), constraints.end(),
    83 X509_Code usage_check(
const X509_Certificate& cert,
    99                    "PKIX.EmailProtection"))
   102                    "PKIX.TimeStamping"))
   115    if(issuer != other.issuer)
   117    if(serial != other.serial)
   119    return compare_ids(auth_key_id, other.auth_key_id);
   127    return !((*this) == other);
   138    const MemoryVector<byte>& serial1 = serial;
   139    const MemoryVector<byte>& key_id1 = auth_key_id;
   140    const MemoryVector<byte>& serial2 = other.serial;
   141    const MemoryVector<byte>& key_id2 = other.auth_key_id;
   143    if(compare_ids(key_id1, key_id2) == 
false)
   145       if(std::lexicographical_compare(key_id1.begin(), key_id1.end(),
   146                                       key_id2.begin(), key_id2.end()))
   149       if(std::lexicographical_compare(key_id2.begin(), key_id2.end(),
   150                                       key_id1.begin(), key_id1.end()))
   154    if(compare_ids(serial1, serial2) == 
false)
   156       if(std::lexicographical_compare(serial1.begin(), serial1.end(),
   157                                       serial2.begin(), serial2.end()))
   160       if(std::lexicographical_compare(serial2.begin(), serial2.end(),
   161                                       serial1.begin(), serial1.end()))
   165    return (issuer < other.issuer);
   173    revoked_info_valid = 
true;
   175    validation_cache_timeout = cache_timeout;
   185    revoked = other.revoked;
   186    revoked_info_valid = other.revoked_info_valid;
   187    for(
size_t j = 0; j != other.stores.size(); ++j)
   188       stores[j] = other.stores[j]->clone();
   189    time_slack = other.time_slack;
   190    validation_cache_timeout = other.validation_cache_timeout;
   198    for(
size_t j = 0; j != stores.size(); ++j)
   208    recompute_revoked_info();
   210    std::vector<size_t> indexes;
   211    X509_Code chaining_result = construct_cert_chain(cert, indexes);
   213       return chaining_result;
   218                                       current_time, time_slack);
   222    X509_Code sig_check_result = check_sig(cert, certs[indexes[0]]);
   224       return sig_check_result;
   229    for(
size_t j = 0; j != indexes.size() - 1; ++j)
   233       time_check = validity_check(current_cert.
start_time(),
   241       sig_check_result = check_sig(certs[indexes[j]], certs[indexes[j+1]]);
   243          return sig_check_result;
   246    return usage_check(cert, cert_usage);
   252 size_t X509_Store::find_cert(
const X509_DN& subject_dn,
   255    for(
size_t j = 0; j != certs.size(); ++j)
   262    return NO_CERT_FOUND;
   273    size_t index = find_cert(issuer_dn, auth_key_id);
   275    if(index != NO_CERT_FOUND)
   278    for(
size_t j = 0; j != stores.size(); ++j)
   280       std::vector<X509_Certificate> got =
   281          stores[j]->find_cert_by_subject_and_key_id(issuer_dn, auth_key_id);
   283       for(
size_t k = 0; k != got.size(); ++k)
   287    return find_cert(issuer_dn, auth_key_id);
   294                                            std::vector<size_t>& indexes,
   295                                            bool need_full_chain)
   297    size_t parent = find_parent_of(end_cert);
   301       if(parent == NO_CERT_FOUND)
   303       indexes.push_back(parent);
   305       if(certs[parent].is_verified(validation_cache_timeout))
   306          if(certs[parent].verify_result() != 
VERIFIED)
   307             return certs[parent].verify_result();
   313       if(certs[parent].is_trusted())
   318       if(parent_cert.
path_limit() < indexes.size() - 1)
   321       parent = find_parent_of(parent_cert);
   329       if(indexes.size() < 2)
   332       const size_t cert = indexes.back();
   334       if(certs[cert].is_verified(validation_cache_timeout))
   336          if(certs[cert].verify_result() != 
VERIFIED)
   344    const size_t last_cert = indexes.back();
   345    const size_t parent_of_last_cert = find_parent_of(certs[last_cert].cert);
   346    if(parent_of_last_cert == NO_CERT_FOUND)
   348    indexes.push_back(parent_of_last_cert);
   356 X509_Code X509_Store::check_sig(
const Cert_Info& cert_info,
   357                                 const Cert_Info& ca_cert_info)
 const   359    if(cert_info.is_verified(validation_cache_timeout))
   360       return cert_info.verify_result();
   367    cert_info.set_result(verify_code);
   377    std::auto_ptr<Public_Key> pub_key(key);
   380       std::vector<std::string> sig_info =
   383       if(sig_info.size() != 2 || sig_info[0] != pub_key->algo_name())
   386       std::string padding = sig_info[1];
   391       PK_Verifier verifier(*pub_key.get(), padding, format);
   393       bool valid = verifier.verify_message(
object.tbs_data(),
   411 void X509_Store::recompute_revoked_info()
 const   413    if(revoked_info_valid)
   416    for(
size_t j = 0; j != certs.size(); ++j)
   418       if((certs[j].is_verified(validation_cache_timeout)) &&
   419          (certs[j].verify_result() != 
VERIFIED))
   422       if(is_revoked(certs[j].cert))
   426    revoked_info_valid = 
true;
   434    CRL_Data revoked_info;
   439    if(std::binary_search(revoked.begin(), revoked.end(), revoked_info))
   447 std::vector<X509_Certificate>
   450    std::vector<X509_Certificate> result;
   451    std::vector<size_t> indexes;
   452    X509_Code chaining_result = construct_cert_chain(cert, indexes, 
true);
   455       throw Invalid_State(
"X509_Store::get_cert_chain: Can't construct chain");
   457    for(
size_t j = 0; j != indexes.size(); ++j)
   458       result.push_back(certs[indexes[j]].cert);
   467    stores.push_back(certstore);
   480       revoked_info_valid = 
false;
   481       Cert_Info info(cert, trusted);
   482       certs.push_back(info);
   486       for(
size_t j = 0; j != certs.size(); ++j)
   489          if(this_cert == cert)
   490             certs[j].trusted = trusted;
   498 void X509_Store::do_add_certs(
DataSource& source, 
bool trusted)
   516    do_add_certs(source, 
false);
   524    do_add_certs(source, 
true);
   538    size_t cert_index = NO_CERT_FOUND;
   540    for(
size_t j = 0; j != certs.size(); ++j)
   550    if(cert_index == NO_CERT_FOUND)
   557       return verify_result;
   561       return verify_result;
   563    std::vector<CRL_Entry> revoked_certs = crl.
get_revoked();
   565    for(
size_t j = 0; j != revoked_certs.size(); ++j)
   567       CRL_Data revoked_info;
   569       revoked_info.serial = revoked_certs[j].serial_number();
   572       std::vector<CRL_Data>::iterator p =
   573          std::find(revoked.begin(), revoked.end(), revoked_info);
   577          if(p == revoked.end()) 
continue;
   582          if(p != revoked.end()) 
continue;
   583          revoked.push_back(revoked_info);
   587    std::sort(revoked.begin(), revoked.end());
   588    revoked_info_valid = 
false;
   598    std::string cert_store;
   599    for(
size_t j = 0; j != certs.size(); ++j)
   608                                  bool t) : cert(c), trusted(t)
   618 X509_Code X509_Store::Cert_Info::verify_result()
 const   621       throw Invalid_State(
"Cert_Info::verify_result() called; not checked");
   628 void X509_Store::Cert_Info::set_result(
X509_Code code)
 const   638 bool X509_Store::Cert_Info::is_trusted()
 const   646 bool X509_Store::Cert_Info::is_verified(
u32bit timeout)
 const   655    if(current_time > last_checked + timeout)
 X509_DN issuer_dn() const
X509_DN subject_dn() const
MemoryVector< byte > subject_key_id() const
u32bit path_limit() const
bool is_self_signed() const
bool operator!=(const OctetString &s1, const OctetString &s2)
X509_Code add_crl(const X509_CRL &)
X509_Time this_update() const
void add_new_certstore(Certificate_Store *)
std::vector< X509_Certificate > get_cert_chain(const X509_Certificate &)
bool operator==(const OctetString &s1, const OctetString &s2)
std::vector< std::string > split_on(const std::string &str, char delim)
std::string end_time() const
std::invalid_argument Invalid_Argument
void add_trusted_certs(DataSource &)
X509_DN issuer_dn() const
unsigned long long u64bit
std::string PEM_encode() const
std::string lookup(const OID &oid)
std::vector< CRL_Entry > get_revoked() const
virtual bool end_of_data() const =0
MemoryVector< byte > authority_key_id() const
std::string start_time() const
std::runtime_error Exception
X509_Code validate_cert(const X509_Certificate &, Cert_Usage=ANY)
void add_certs(DataSource &)
MemoryVector< byte > serial_number() const
Public_Key * subject_public_key() const
X509_Time next_update() const
bool BOTAN_DLL operator<(const X509_Time &, const X509_Time &)
MemoryVector< byte > authority_key_id() const
std::string PEM_encode() const
void add_cert(const X509_Certificate &, bool=false)
virtual size_t message_parts() const
X509_Store(u32bit time_slack=24 *60 *60, u32bit cache_results=30 *60)