aboutsummaryrefslogtreecommitdiffstats
path: root/src/cert
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-03-28 21:09:47 +0000
committerlloyd <[email protected]>2012-03-28 21:09:47 +0000
commitd4050e6b838acfd9552b4ab137fbf0717ff1e0ca (patch)
treea811718e0ada95191fd64c353bb2357953be86d3 /src/cert
parent199bc49219175d29076692a3131ac5425d750461 (diff)
parentf1a2b5a7b5f35322927446d1b9a381f05cc677df (diff)
propagate from branch 'net.randombit.botan' (head 0d0f3fba72f3300bc995c79124a75a4fc0b83879)
to branch 'net.randombit.botan.x509-path-validation' (head 48d03e596f032c0c69d691dbf49a2a1415b348c3)
Diffstat (limited to 'src/cert')
-rw-r--r--src/cert/certstore/info.txt6
-rw-r--r--src/cert/pkcs10/info.txt6
-rw-r--r--src/cert/x509/certstor.cpp (renamed from src/cert/certstore/certstor.cpp)22
-rw-r--r--src/cert/x509/certstor.h (renamed from src/cert/certstore/certstor.h)16
-rw-r--r--src/cert/x509/crl_ent.cpp (renamed from src/cert/x509crl/crl_ent.cpp)0
-rw-r--r--src/cert/x509/crl_ent.h (renamed from src/cert/x509crl/crl_ent.h)20
-rw-r--r--src/cert/x509/info.txt (renamed from src/cert/x509cert/info.txt)1
-rw-r--r--src/cert/x509/pkcs10.cpp (renamed from src/cert/pkcs10/pkcs10.cpp)0
-rw-r--r--src/cert/x509/pkcs10.h (renamed from src/cert/pkcs10/pkcs10.h)0
-rw-r--r--src/cert/x509/x509_ca.cpp (renamed from src/cert/x509ca/x509_ca.cpp)0
-rw-r--r--src/cert/x509/x509_ca.h (renamed from src/cert/x509ca/x509_ca.h)0
-rw-r--r--src/cert/x509/x509_crl.cpp (renamed from src/cert/x509crl/x509_crl.cpp)38
-rw-r--r--src/cert/x509/x509_crl.h (renamed from src/cert/x509crl/x509_crl.h)7
-rw-r--r--src/cert/x509/x509_ext.cpp (renamed from src/cert/x509cert/x509_ext.cpp)0
-rw-r--r--src/cert/x509/x509_ext.h (renamed from src/cert/x509cert/x509_ext.h)2
-rw-r--r--src/cert/x509/x509_obj.cpp (renamed from src/cert/x509cert/x509_obj.cpp)5
-rw-r--r--src/cert/x509/x509_obj.h (renamed from src/cert/x509cert/x509_obj.h)0
-rw-r--r--src/cert/x509/x509cert.cpp (renamed from src/cert/x509cert/x509cert.cpp)10
-rw-r--r--src/cert/x509/x509cert.h (renamed from src/cert/x509cert/x509cert.h)10
-rw-r--r--src/cert/x509/x509opt.cpp (renamed from src/cert/x509self/x509opt.cpp)0
-rw-r--r--src/cert/x509/x509path.cpp211
-rw-r--r--src/cert/x509/x509path.h110
-rw-r--r--src/cert/x509/x509self.cpp (renamed from src/cert/x509self/x509self.cpp)0
-rw-r--r--src/cert/x509/x509self.h (renamed from src/cert/x509self/x509self.h)0
-rw-r--r--src/cert/x509ca/info.txt6
-rw-r--r--src/cert/x509crl/info.txt6
-rw-r--r--src/cert/x509self/info.txt6
-rw-r--r--src/cert/x509store/info.txt5
-rw-r--r--src/cert/x509store/x509stor.cpp660
-rw-r--r--src/cert/x509store/x509stor.h131
30 files changed, 424 insertions, 854 deletions
diff --git a/src/cert/certstore/info.txt b/src/cert/certstore/info.txt
deleted file mode 100644
index a5de1baff..000000000
--- a/src/cert/certstore/info.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-define CERTIFICATE_STORE
-
-<requires>
-x509cert
-x509crl
-</requires>
diff --git a/src/cert/pkcs10/info.txt b/src/cert/pkcs10/info.txt
deleted file mode 100644
index bf53a562a..000000000
--- a/src/cert/pkcs10/info.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-define PKCS10_REQUESTS
-
-<requires>
-asn1
-x509cert
-</requires>
diff --git a/src/cert/certstore/certstor.cpp b/src/cert/x509/certstor.cpp
index 3cba2f39e..de27361ed 100644
--- a/src/cert/certstore/certstor.cpp
+++ b/src/cert/x509/certstor.cpp
@@ -9,12 +9,16 @@
namespace Botan {
-Certificate_Store* Certificate_Store_Memory::clone() const
+bool Certificate_Store::certificate_known(const X509_Certificate& cert) const
{
- return new Certificate_Store_Memory(*this);
+ std::vector<X509_Certificate> found =
+ find_cert_by_subject_and_key_id(cert.subject_dn(),
+ cert.subject_key_id());
+
+ return (found.size() > 0);
}
-void Certificate_Store_Memory::add_certificate(const X509_Certificate& cert)
+void Certificate_Store_In_Memory::add_certificate(const X509_Certificate& cert)
{
for(size_t i = 0; i != certs.size(); ++i)
{
@@ -26,7 +30,7 @@ void Certificate_Store_Memory::add_certificate(const X509_Certificate& cert)
}
std::vector<X509_Certificate>
-Certificate_Store_Memory::find_cert_by_subject_and_key_id(
+Certificate_Store_In_Memory::find_cert_by_subject_and_key_id(
const X509_DN& subject_dn,
const MemoryRegion<byte>& key_id) const
{
@@ -50,7 +54,7 @@ Certificate_Store_Memory::find_cert_by_subject_and_key_id(
return result;
}
-void Certificate_Store_Memory::add_crl(const X509_CRL& crl)
+void Certificate_Store_In_Memory::add_crl(const X509_CRL& crl)
{
X509_DN crl_issuer = crl.issuer_dn();
@@ -59,11 +63,9 @@ void Certificate_Store_Memory::add_crl(const X509_CRL& crl)
// Found an update of a previously existing one; replace it
if(crls[i].issuer_dn() == crl_issuer)
{
- if(crls[i].this_update() < crl.this_update())
- {
+ if(crls[i].this_update() <= crl.this_update())
crls[i] = crl;
- return;
- }
+ return;
}
}
@@ -72,7 +74,7 @@ void Certificate_Store_Memory::add_crl(const X509_CRL& crl)
}
std::vector<X509_CRL>
-Certificate_Store_Memory::find_crl_by_subject_and_key_id(
+Certificate_Store_In_Memory::find_crl_by_issuer_and_key_id(
const X509_DN& issuer_dn,
const MemoryRegion<byte>& key_id) const
{
diff --git a/src/cert/certstore/certstor.h b/src/cert/x509/certstor.h
index 374013984..e2727c569 100644
--- a/src/cert/certstore/certstor.h
+++ b/src/cert/x509/certstor.h
@@ -21,8 +21,6 @@ class BOTAN_DLL Certificate_Store
public:
virtual ~Certificate_Store() {}
- virtual Certificate_Store* clone() const = 0;
-
/**
* Add a certificate; this may fail if the store is write-only
*/
@@ -33,6 +31,8 @@ class BOTAN_DLL Certificate_Store
*/
virtual void add_crl(const X509_CRL& crl) = 0;
+ bool certificate_known(const X509_Certificate& cert) const;
+
/**
* Subject DN and (optionally) key identifier
*/
@@ -45,7 +45,7 @@ class BOTAN_DLL Certificate_Store
* Find CRLs by the DN and key id of the issuer
*/
virtual std::vector<X509_CRL>
- find_crl_by_subject_and_key_id(
+ find_crl_by_issuer_and_key_id(
const X509_DN& issuer_dn,
const MemoryRegion<byte>& key_id) const = 0;
};
@@ -53,11 +53,9 @@ class BOTAN_DLL Certificate_Store
/**
* In Memory Certificate Store
*/
-class BOTAN_DLL Certificate_Store_Memory : public Certificate_Store
+class BOTAN_DLL Certificate_Store_In_Memory : public Certificate_Store
{
public:
- Certificate_Store* clone() const;
-
void add_certificate(const X509_Certificate& cert);
void add_crl(const X509_CRL& crl);
@@ -66,13 +64,13 @@ class BOTAN_DLL Certificate_Store_Memory : public Certificate_Store
const X509_DN& subject_dn,
const MemoryRegion<byte>& key_id) const;
- std::vector<X509_CRL> find_crl_by_subject_and_key_id(
+ std::vector<X509_CRL> find_crl_by_issuer_and_key_id(
const X509_DN& issuer_dn,
const MemoryRegion<byte>& key_id) const;
- Certificate_Store_Memory() {}
+ Certificate_Store_In_Memory() {}
private:
- // TODO: Add indexing on the DN and key id to avoid linear search?
+ // TODO: Add indexing on the DN and key id to avoid linear search
std::vector<X509_Certificate> certs;
std::vector<X509_CRL> crls;
};
diff --git a/src/cert/x509crl/crl_ent.cpp b/src/cert/x509/crl_ent.cpp
index d566637f6..d566637f6 100644
--- a/src/cert/x509crl/crl_ent.cpp
+++ b/src/cert/x509/crl_ent.cpp
diff --git a/src/cert/x509crl/crl_ent.h b/src/cert/x509/crl_ent.h
index b3e696a86..ae9535484 100644
--- a/src/cert/x509crl/crl_ent.h
+++ b/src/cert/x509/crl_ent.h
@@ -13,6 +13,26 @@
namespace Botan {
/**
+* X.509v2 CRL Reason Code.
+*/
+enum CRL_Code {
+ UNSPECIFIED = 0,
+ KEY_COMPROMISE = 1,
+ CA_COMPROMISE = 2,
+ AFFILIATION_CHANGED = 3,
+ SUPERSEDED = 4,
+ CESSATION_OF_OPERATION = 5,
+ CERTIFICATE_HOLD = 6,
+ REMOVE_FROM_CRL = 8,
+ PRIVLEDGE_WITHDRAWN = 9,
+ AA_COMPROMISE = 10,
+
+ DELETE_CRL_ENTRY = 0xFF00,
+ OCSP_GOOD = 0xFF01,
+ OCSP_UNKNOWN = 0xFF02
+};
+
+/**
* This class represents CRL entries
*/
class BOTAN_DLL CRL_Entry : public ASN1_Object
diff --git a/src/cert/x509cert/info.txt b/src/cert/x509/info.txt
index 5e3715e7a..c994dab8f 100644
--- a/src/cert/x509cert/info.txt
+++ b/src/cert/x509/info.txt
@@ -1,6 +1,5 @@
define X509_CERTIFICATES
<requires>
-certstore
datastor
</requires>
diff --git a/src/cert/pkcs10/pkcs10.cpp b/src/cert/x509/pkcs10.cpp
index 784318d3d..784318d3d 100644
--- a/src/cert/pkcs10/pkcs10.cpp
+++ b/src/cert/x509/pkcs10.cpp
diff --git a/src/cert/pkcs10/pkcs10.h b/src/cert/x509/pkcs10.h
index bd01fb6b5..bd01fb6b5 100644
--- a/src/cert/pkcs10/pkcs10.h
+++ b/src/cert/x509/pkcs10.h
diff --git a/src/cert/x509ca/x509_ca.cpp b/src/cert/x509/x509_ca.cpp
index 40f2e3b3a..40f2e3b3a 100644
--- a/src/cert/x509ca/x509_ca.cpp
+++ b/src/cert/x509/x509_ca.cpp
diff --git a/src/cert/x509ca/x509_ca.h b/src/cert/x509/x509_ca.h
index 97be6a415..97be6a415 100644
--- a/src/cert/x509ca/x509_ca.h
+++ b/src/cert/x509/x509_ca.h
diff --git a/src/cert/x509crl/x509_crl.cpp b/src/cert/x509/x509_crl.cpp
index 01fce4c52..9c6b891c7 100644
--- a/src/cert/x509crl/x509_crl.cpp
+++ b/src/cert/x509/x509_crl.cpp
@@ -7,6 +7,7 @@
#include <botan/x509_crl.h>
#include <botan/x509_ext.h>
+#include <botan/x509cert.h>
#include <botan/ber_dec.h>
#include <botan/parsing.h>
#include <botan/bigint.h>
@@ -32,6 +33,43 @@ X509_CRL::X509_CRL(const std::string& in, bool touc) :
do_decode();
}
+/**
+* Check if this particular certificate is listed in the CRL
+*/
+bool X509_CRL::is_revoked(const X509_Certificate& cert) const
+ {
+ /*
+ If the cert wasn't issued by the CRL issuer, it's possible the cert
+ is revoked, but not by this CRL. Maybe throw an exception instead?
+ */
+ if(cert.issuer_dn() != issuer_dn())
+ return false;
+
+ MemoryVector<byte> crl_akid = authority_key_id();
+ MemoryVector<byte> cert_akid = cert.authority_key_id();
+
+ if(!crl_akid.empty() && !cert_akid.empty())
+ if(crl_akid != cert_akid)
+ return false;
+
+ MemoryVector<byte> cert_serial = cert.serial_number();
+
+ bool is_revoked = false;
+
+ for(size_t i = 0; i != revoked.size(); ++i)
+ {
+ if(cert_serial == revoked[i].serial_number())
+ {
+ if(revoked[i].reason_code() == REMOVE_FROM_CRL)
+ is_revoked = false;
+ else
+ is_revoked = true;
+ }
+ }
+
+ return is_revoked;
+ }
+
/*
* Decode the TBSCertList data
*/
diff --git a/src/cert/x509crl/x509_crl.h b/src/cert/x509/x509_crl.h
index c2b3c4f5c..55eb8424b 100644
--- a/src/cert/x509crl/x509_crl.h
+++ b/src/cert/x509/x509_crl.h
@@ -14,6 +14,8 @@
namespace Botan {
+class X509_Certificate;
+
/**
* This class represents X.509 Certificate Revocation Lists (CRLs).
*/
@@ -30,6 +32,11 @@ class BOTAN_DLL X509_CRL : public X509_Object
};
/**
+ * Check if this particular certificate is listed in the CRL
+ */
+ bool is_revoked(const X509_Certificate& cert) const;
+
+ /**
* Get the entries of this CRL in the form of a vector.
* @return vector containing the entries of this CRL.
*/
diff --git a/src/cert/x509cert/x509_ext.cpp b/src/cert/x509/x509_ext.cpp
index 6e0befaf3..6e0befaf3 100644
--- a/src/cert/x509cert/x509_ext.cpp
+++ b/src/cert/x509/x509_ext.cpp
diff --git a/src/cert/x509cert/x509_ext.h b/src/cert/x509/x509_ext.h
index 8799c5921..714e29562 100644
--- a/src/cert/x509cert/x509_ext.h
+++ b/src/cert/x509/x509_ext.h
@@ -12,7 +12,7 @@
#include <botan/asn1_oid.h>
#include <botan/asn1_obj.h>
#include <botan/datastor.h>
-#include <botan/pubkey_enums.h>
+#include <botan/crl_ent.h>
namespace Botan {
diff --git a/src/cert/x509cert/x509_obj.cpp b/src/cert/x509/x509_obj.cpp
index 13193f09c..c58081225 100644
--- a/src/cert/x509cert/x509_obj.cpp
+++ b/src/cert/x509/x509_obj.cpp
@@ -16,6 +16,8 @@
#include <algorithm>
#include <memory>
+#include <stdio.h>
+
namespace Botan {
/*
@@ -192,8 +194,9 @@ bool X509_Object::check_signature(Public_Key& pub_key) const
return verifier.verify_message(tbs_data(), signature());
}
- catch(...)
+ catch(std::exception& e)
{
+ printf("Failure during validation %s\n", e.what());
return false;
}
}
diff --git a/src/cert/x509cert/x509_obj.h b/src/cert/x509/x509_obj.h
index 570b00f51..570b00f51 100644
--- a/src/cert/x509cert/x509_obj.h
+++ b/src/cert/x509/x509_obj.h
diff --git a/src/cert/x509cert/x509cert.cpp b/src/cert/x509/x509cert.cpp
index 7d9370f2a..52115a1a8 100644
--- a/src/cert/x509cert/x509cert.cpp
+++ b/src/cert/x509/x509cert.cpp
@@ -206,9 +206,15 @@ bool X509_Certificate::is_CA_cert() const
{
if(!subject.get1_u32bit("X509v3.BasicConstraints.is_ca"))
return false;
- if((constraints() & KEY_CERT_SIGN) || (constraints() == NO_CONSTRAINTS))
+
+ return allowed_usage(KEY_CERT_SIGN);
+ }
+
+bool X509_Certificate::allowed_usage(Key_Constraints restriction) const
+ {
+ if(constraints() == NO_CONSTRAINTS)
return true;
- return false;
+ return (constraints() & restriction);
}
/*
diff --git a/src/cert/x509cert/x509cert.h b/src/cert/x509/x509cert.h
index 8798ef1c2..d25b97694 100644
--- a/src/cert/x509cert/x509cert.h
+++ b/src/cert/x509/x509cert.h
@@ -23,10 +23,10 @@ namespace Botan {
class BOTAN_DLL X509_Certificate : public X509_Object
{
public:
- /**
- * Get the public key associated with this certificate.
- * @return subject public key of this certificate
- */
+ /**
+ * Get the public key associated with this certificate.
+ * @return subject public key of this certificate
+ */
Public_Key* subject_public_key() const;
/**
@@ -111,6 +111,8 @@ class BOTAN_DLL X509_Certificate : public X509_Object
*/
bool is_CA_cert() const;
+ bool allowed_usage(Key_Constraints restriction) const;
+
/**
* Get the path limit as defined in the BasicConstraints extension of
* this certificate.
diff --git a/src/cert/x509self/x509opt.cpp b/src/cert/x509/x509opt.cpp
index 345df1fe0..345df1fe0 100644
--- a/src/cert/x509self/x509opt.cpp
+++ b/src/cert/x509/x509opt.cpp
diff --git a/src/cert/x509/x509path.cpp b/src/cert/x509/x509path.cpp
new file mode 100644
index 000000000..a9b8150ae
--- /dev/null
+++ b/src/cert/x509/x509path.cpp
@@ -0,0 +1,211 @@
+/*
+* X.509 Certificate Path Validation
+* (C) 2010-2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/x509path.h>
+#include <botan/parsing.h>
+#include <botan/pubkey.h>
+#include <botan/oids.h>
+#include <botan/time.h>
+#include <algorithm>
+#include <memory>
+
+namespace Botan {
+
+namespace {
+
+class PKIX_Validation_Failure : public std::exception
+ {
+ public:
+ PKIX_Validation_Failure(X509_Path_Validation_Code code) : m_code(code) {}
+
+ X509_Path_Validation_Code code() const { return m_code; }
+
+ const char* what() { return "PKIX validation failed"; }
+ private:
+ X509_Path_Validation_Code m_code;
+ };
+
+X509_Certificate find_issuing_cert(const X509_Certificate& cert,
+ const std::vector<Certificate_Store*>& certstores)
+ {
+ const X509_DN issuer_dn = cert.issuer_dn();
+ const MemoryVector<byte> auth_key_id = cert.authority_key_id();
+
+ for(size_t i = 0; i != certstores.size(); ++i)
+ {
+ std::vector<X509_Certificate> certs =
+ certstores[i]->find_cert_by_subject_and_key_id(issuer_dn, auth_key_id);
+
+ if(certs.size() == 0)
+ throw PKIX_Validation_Failure(CERT_ISSUER_NOT_FOUND);
+ else if(certs.size() > 1)
+ throw PKIX_Validation_Failure(CERT_MULTIPLE_ISSUERS_FOUND);
+
+ return certs[0];
+ }
+
+ throw PKIX_Validation_Failure(CERT_ISSUER_NOT_FOUND);
+ }
+
+std::vector<X509_CRL> find_crls_from(const X509_Certificate& cert,
+ const std::vector<Certificate_Store*>& certstores)
+ {
+ const X509_DN issuer_dn = cert.subject_dn();
+ const MemoryVector<byte> auth_key_id = cert.subject_key_id();
+
+ for(size_t i = 0; i != certstores.size(); ++i)
+ {
+ std::vector<X509_CRL> crl =
+ certstores[i]->find_crl_by_issuer_and_key_id(issuer_dn, auth_key_id);
+
+ if(!crl.empty())
+ return crl;
+ }
+
+ return std::vector<X509_CRL>();
+ }
+
+}
+
+const X509_Certificate& Path_Validation_Result::trust_root() const
+ {
+ return m_cert_path[m_cert_path.size()-1];
+ }
+
+std::set<std::string> Path_Validation_Result::trusted_hashes() const
+ {
+ std::set<std::string> hashes;
+ for(size_t i = 0; i != m_cert_path.size(); ++i)
+ hashes.insert(m_cert_path[i].hash_used_for_signature());
+ return hashes;
+ }
+
+Path_Validation_Result x509_path_validate(
+ const X509_Certificate& end_cert,
+ const std::vector<Certificate_Store*>& certstores)
+ {
+ std::vector<X509_Certificate> certs;
+ certs.push_back(end_cert);
+ return x509_path_validate(certs, certstores);
+ }
+
+Path_Validation_Result x509_path_validate(
+ const std::vector<X509_Certificate>& end_certs,
+ Certificate_Store& store)
+ {
+ std::vector<Certificate_Store*> certstores;
+ certstores.push_back(&store);
+
+ return x509_path_validate(end_certs, certstores);
+ }
+
+Path_Validation_Result x509_path_validate(
+ const X509_Certificate& end_cert,
+ Certificate_Store& store)
+ {
+ std::vector<X509_Certificate> certs;
+ certs.push_back(end_cert);
+
+ std::vector<Certificate_Store*> certstores;
+ certstores.push_back(&store);
+
+ return x509_path_validate(certs, certstores);
+ }
+
+Path_Validation_Result
+x509_path_validate(const std::vector<X509_Certificate>& end_certs,
+ const std::vector<Certificate_Store*>& certstores)
+ {
+ Path_Validation_Result r;
+
+ r.m_cert_path = end_certs;
+
+ std::vector<X509_Certificate>& cert_path = r.m_cert_path;
+
+ try
+ {
+ // iterate until we reach a root or cannot find the issuer
+ while(!cert_path.back().is_self_signed())
+ {
+ cert_path.push_back(
+ find_issuing_cert(cert_path.back(), certstores)
+ );
+ }
+
+ const bool self_signed_ee_cert = (cert_path.size() == 1);
+
+ X509_Time current_time(system_time());
+
+ for(size_t i = 0; i != cert_path.size(); ++i)
+ {
+ const X509_Certificate& subject = cert_path[i];
+
+ // Check all certs for valid time range
+ if(current_time < X509_Time(subject.start_time()))
+ throw PKIX_Validation_Failure(CERT_NOT_YET_VALID);
+
+ if(current_time > X509_Time(subject.end_time()))
+ throw PKIX_Validation_Failure(CERT_HAS_EXPIRED);
+
+ const bool at_self_signed_root = (i == cert_path.size() - 1);
+
+ const X509_Certificate& issuer =
+ cert_path[at_self_signed_root ? (i) : (i + 1)];
+
+ // Check issuer constraints
+
+ // Don't require CA bit set on self-signed end entity cert
+ if(!issuer.is_CA_cert() && !self_signed_ee_cert)
+ throw PKIX_Validation_Failure(CA_CERT_NOT_FOR_CERT_ISSUER);
+
+ if(issuer.path_limit() < i)
+ throw PKIX_Validation_Failure(CERT_CHAIN_TOO_LONG);
+
+ if(subject.check_signature(issuer.subject_public_key()) == false)
+ throw PKIX_Validation_Failure(SIGNATURE_ERROR);
+ }
+
+ for(size_t i = 1; i != cert_path.size(); ++i)
+ {
+ const X509_Certificate& subject = cert_path[i-1];
+ const X509_Certificate& ca = cert_path[i];
+
+ std::vector<X509_CRL> crls = find_crls_from(ca, certstores);
+
+ if(crls.empty())
+ //throw PKIX_Validation_Failure(CRL_NOT_FOUND);
+ continue;
+
+ const X509_CRL& crl = crls[0];
+
+ if(!ca.allowed_usage(CRL_SIGN))
+ throw PKIX_Validation_Failure(CA_CERT_NOT_FOR_CRL_ISSUER);
+
+ if(current_time < X509_Time(crl.this_update()))
+ throw PKIX_Validation_Failure(CRL_NOT_YET_VALID);
+
+ if(current_time > X509_Time(crl.next_update()))
+ throw PKIX_Validation_Failure(CRL_HAS_EXPIRED);
+
+ if(crl.check_signature(ca.subject_public_key()) == false)
+ throw PKIX_Validation_Failure(SIGNATURE_ERROR);
+
+ if(crl.is_revoked(subject))
+ throw PKIX_Validation_Failure(CERT_IS_REVOKED);
+ }
+
+ r.set_result(self_signed_ee_cert ? CANNOT_ESTABLISH_TRUST : VERIFIED);
+ }
+ catch(PKIX_Validation_Failure& e)
+ {
+ r.set_result(e.code());
+ }
+
+ return r;
+ }
+
+}
diff --git a/src/cert/x509/x509path.h b/src/cert/x509/x509path.h
new file mode 100644
index 000000000..c389431d8
--- /dev/null
+++ b/src/cert/x509/x509path.h
@@ -0,0 +1,110 @@
+/*
+* X.509 Cert Path Validation
+* (C) 2010-2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_X509_CERT_PATH_VALIDATION_H__
+#define BOTAN_X509_CERT_PATH_VALIDATION_H__
+
+#include <botan/x509cert.h>
+#include <botan/certstor.h>
+#include <set>
+
+namespace Botan {
+
+/**
+* X.509 Certificate Validation Result
+*/
+enum X509_Path_Validation_Code {
+ VERIFIED,
+ UNKNOWN_X509_ERROR,
+ CANNOT_ESTABLISH_TRUST,
+ CERT_CHAIN_TOO_LONG,
+ SIGNATURE_ERROR,
+ POLICY_ERROR,
+ INVALID_USAGE,
+
+ CERT_MULTIPLE_ISSUERS_FOUND,
+
+ CERT_FORMAT_ERROR,
+ CERT_ISSUER_NOT_FOUND,
+ CERT_NOT_YET_VALID,
+ CERT_HAS_EXPIRED,
+ CERT_IS_REVOKED,
+
+ CRL_NOT_FOUND,
+ CRL_FORMAT_ERROR,
+ CRL_ISSUER_NOT_FOUND,
+ CRL_NOT_YET_VALID,
+ CRL_HAS_EXPIRED,
+
+ CA_CERT_CANNOT_SIGN,
+ CA_CERT_NOT_FOR_CERT_ISSUER,
+ CA_CERT_NOT_FOR_CRL_ISSUER
+};
+
+enum Usage_Restrictions {
+ NO_RESTRICTIONS = 0x00,
+ TLS_SERVER = 0x01,
+ TLS_CLIENT = 0x02,
+ CODE_SIGNING = 0x04,
+ EMAIL_PROTECTION = 0x08,
+ TIME_STAMPING = 0x10,
+ CRL_SIGNING = 0x20
+};
+
+class BOTAN_DLL Path_Validation_Result
+ {
+ public:
+ Path_Validation_Result() :
+ m_result(UNKNOWN_X509_ERROR),
+ m_usages(NO_RESTRICTIONS)
+ {}
+
+ /**
+ * Returns the set of hash functions you are implicitly
+ * trusting by trusting this result.
+ */
+ std::set<std::string> trusted_hashes() const;
+
+ const X509_Certificate& trust_root() const;
+
+ const std::vector<X509_Certificate>& cert_path() const { return m_cert_path; }
+
+ bool successful_validation() const { return result() == VERIFIED; }
+
+ X509_Path_Validation_Code result() const { return m_result; }
+ private:
+ friend Path_Validation_Result x509_path_validate(
+ const std::vector<X509_Certificate>& end_certs,
+ const std::vector<Certificate_Store*>& certstores);
+
+ void set_result(X509_Path_Validation_Code result) { m_result = result; }
+
+ X509_Path_Validation_Code m_result;
+ Usage_Restrictions m_usages;
+
+ std::vector<X509_Certificate> m_cert_path;
+ };
+
+Path_Validation_Result BOTAN_DLL x509_path_validate(
+ const std::vector<X509_Certificate>& end_certs,
+ const std::vector<Certificate_Store*>& certstores);
+
+Path_Validation_Result BOTAN_DLL x509_path_validate(
+ const X509_Certificate& end_cert,
+ const std::vector<Certificate_Store*>& certstores);
+
+Path_Validation_Result BOTAN_DLL x509_path_validate(
+ const X509_Certificate& end_cert,
+ Certificate_Store& store);
+
+Path_Validation_Result BOTAN_DLL x509_path_validate(
+ const std::vector<X509_Certificate>& end_certs,
+ Certificate_Store& store);
+
+}
+
+#endif
diff --git a/src/cert/x509self/x509self.cpp b/src/cert/x509/x509self.cpp
index a2f89159f..a2f89159f 100644
--- a/src/cert/x509self/x509self.cpp
+++ b/src/cert/x509/x509self.cpp
diff --git a/src/cert/x509self/x509self.h b/src/cert/x509/x509self.h
index 2850096c8..2850096c8 100644
--- a/src/cert/x509self/x509self.h
+++ b/src/cert/x509/x509self.h
diff --git a/src/cert/x509ca/info.txt b/src/cert/x509ca/info.txt
deleted file mode 100644
index d412c3070..000000000
--- a/src/cert/x509ca/info.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-define X509_CA
-
-<requires>
-pkcs10
-x509cert
-</requires>
diff --git a/src/cert/x509crl/info.txt b/src/cert/x509crl/info.txt
deleted file mode 100644
index 77de46074..000000000
--- a/src/cert/x509crl/info.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-define X509_CRL
-
-<requires>
-x509cert
-</requires>
-
diff --git a/src/cert/x509self/info.txt b/src/cert/x509self/info.txt
deleted file mode 100644
index bb02c4f74..000000000
--- a/src/cert/x509self/info.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-define X509_SELF_SIGNED
-
-<requires>
-x509cert
-</requires>
-
diff --git a/src/cert/x509store/info.txt b/src/cert/x509store/info.txt
deleted file mode 100644
index b24b03a02..000000000
--- a/src/cert/x509store/info.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-define X509_STORE
-
-<requires>
-x509cert
-</requires>
diff --git a/src/cert/x509store/x509stor.cpp b/src/cert/x509store/x509stor.cpp
deleted file mode 100644
index 3fe1adf62..000000000
--- a/src/cert/x509store/x509stor.cpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
-* X.509 Certificate Store
-* (C) 1999-2007 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/x509stor.h>
-#include <botan/parsing.h>
-#include <botan/pubkey.h>
-#include <botan/oids.h>
-#include <botan/time.h>
-#include <algorithm>
-#include <memory>
-
-namespace Botan {
-
-namespace {
-
-/*
-* Do a validity check
-*/
-s32bit validity_check(const X509_Time& start, const X509_Time& end,
- u64bit current_time, u32bit slack)
- {
- const s32bit NOT_YET_VALID = -1, VALID_TIME = 0, EXPIRED = 1;
-
- if(start.cmp(current_time + slack) > 0)
- return NOT_YET_VALID;
- if(end.cmp(current_time - slack) < 0)
- return EXPIRED;
- return VALID_TIME;
- }
-
-/*
-* Compare the value of unique ID fields
-*/
-bool compare_ids(const MemoryVector<byte>& id1,
- const MemoryVector<byte>& id2)
- {
- if(!id1.size() || !id2.size())
- return true;
- return (id1 == id2);
- }
-
-/*
-* Check a particular usage restriction
-*/
-bool check_usage(const X509_Certificate& cert, X509_Store::Cert_Usage usage,
- X509_Store::Cert_Usage check_for, Key_Constraints constraints)
- {
- if((usage & check_for) == 0)
- return true;
- if(cert.constraints() == NO_CONSTRAINTS)
- return true;
- if(cert.constraints() & constraints)
- return true;
- return false;
- }
-
-/*
-* Check a particular usage restriction
-*/
-bool check_usage(const X509_Certificate& cert, X509_Store::Cert_Usage usage,
- X509_Store::Cert_Usage check_for,
- const std::string& usage_oid)
- {
- if((usage & check_for) == 0)
- return true;
-
- const std::vector<std::string> constraints = cert.ex_constraints();
-
- if(constraints.empty())
- return true;
-
- return std::binary_search(constraints.begin(), constraints.end(),
- usage_oid);
- }
-
-/*
-* Check the usage restrictions
-*/
-X509_Code usage_check(const X509_Certificate& cert,
- X509_Store::Cert_Usage usage)
- {
- if(usage == X509_Store::ANY)
- return VERIFIED;
-
- if(!check_usage(cert, usage, X509_Store::CRL_SIGNING, CRL_SIGN))
- return CA_CERT_NOT_FOR_CRL_ISSUER;
-
- if(!check_usage(cert, usage, X509_Store::TLS_SERVER, "PKIX.ServerAuth"))
- return INVALID_USAGE;
- if(!check_usage(cert, usage, X509_Store::TLS_CLIENT, "PKIX.ClientAuth"))
- return INVALID_USAGE;
- if(!check_usage(cert, usage, X509_Store::CODE_SIGNING, "PKIX.CodeSigning"))
- return INVALID_USAGE;
- if(!check_usage(cert, usage, X509_Store::EMAIL_PROTECTION,
- "PKIX.EmailProtection"))
- return INVALID_USAGE;
- if(!check_usage(cert, usage, X509_Store::TIME_STAMPING,
- "PKIX.TimeStamping"))
- return INVALID_USAGE;
-
- return VERIFIED;
- }
-
-}
-
-/*
-* Define equality for revocation data
-*/
-bool X509_Store::CRL_Data::operator==(const CRL_Data& other) const
- {
- if(issuer != other.issuer)
- return false;
- if(serial != other.serial)
- return false;
- return compare_ids(auth_key_id, other.auth_key_id);
- }
-
-/*
-* Define inequality for revocation data
-*/
-bool X509_Store::CRL_Data::operator!=(const CRL_Data& other) const
- {
- return !((*this) == other);
- }
-
-/*
-* Define an ordering for revocation data
-*/
-bool X509_Store::CRL_Data::operator<(const X509_Store::CRL_Data& other) const
- {
- if(*this == other)
- return false;
-
- const MemoryVector<byte>& serial1 = serial;
- const MemoryVector<byte>& key_id1 = auth_key_id;
- const MemoryVector<byte>& serial2 = other.serial;
- const MemoryVector<byte>& key_id2 = other.auth_key_id;
-
- if(compare_ids(key_id1, key_id2) == false)
- {
- if(std::lexicographical_compare(key_id1.begin(), key_id1.end(),
- key_id2.begin(), key_id2.end()))
- return true;
-
- if(std::lexicographical_compare(key_id2.begin(), key_id2.end(),
- key_id1.begin(), key_id1.end()))
- return false;
- }
-
- if(compare_ids(serial1, serial2) == false)
- {
- if(std::lexicographical_compare(serial1.begin(), serial1.end(),
- serial2.begin(), serial2.end()))
- return true;
-
- if(std::lexicographical_compare(serial2.begin(), serial2.end(),
- serial1.begin(), serial1.end()))
- return false;
- }
-
- return (issuer < other.issuer);
- }
-
-/*
-* X509_Store Constructor
-*/
-X509_Store::X509_Store(u32bit slack, u32bit cache_timeout)
- {
- revoked_info_valid = true;
-
- validation_cache_timeout = cache_timeout;
- time_slack = slack;
- }
-
-/*
-* X509_Store Copy Constructor
-*/
-X509_Store::X509_Store(const X509_Store& other)
- {
- certs = other.certs;
- revoked = other.revoked;
- revoked_info_valid = other.revoked_info_valid;
- for(size_t j = 0; j != other.stores.size(); ++j)
- stores[j] = other.stores[j]->clone();
- time_slack = other.time_slack;
- }
-
-/*
-* X509_Store Destructor
-*/
-X509_Store::~X509_Store()
- {
- for(size_t j = 0; j != stores.size(); ++j)
- delete stores[j];
- }
-
-/*
-* Verify a certificate's authenticity
-*/
-X509_Code X509_Store::validate_cert(const X509_Certificate& cert,
- Cert_Usage cert_usage)
- {
- recompute_revoked_info();
-
- std::vector<size_t> indexes;
- X509_Code chaining_result = construct_cert_chain(cert, indexes);
- if(chaining_result != VERIFIED)
- return chaining_result;
-
- const u64bit current_time = system_time();
-
- s32bit time_check = validity_check(cert.start_time(), cert.end_time(),
- current_time, time_slack);
- if(time_check < 0) return CERT_NOT_YET_VALID;
- else if(time_check > 0) return CERT_HAS_EXPIRED;
-
- X509_Code sig_check_result = check_sig(cert, certs[indexes[0]]);
- if(sig_check_result != VERIFIED)
- return sig_check_result;
-
- if(is_revoked(cert))
- return CERT_IS_REVOKED;
-
- for(size_t j = 0; j != indexes.size() - 1; ++j)
- {
- const X509_Certificate& current_cert = certs[indexes[j]].cert;
-
- time_check = validity_check(current_cert.start_time(),
- current_cert.end_time(),
- current_time,
- time_slack);
-
- if(time_check < 0) return CERT_NOT_YET_VALID;
- else if(time_check > 0) return CERT_HAS_EXPIRED;
-
- sig_check_result = check_sig(certs[indexes[j]], certs[indexes[j+1]]);
- if(sig_check_result != VERIFIED)
- return sig_check_result;
- }
-
- return usage_check(cert, cert_usage);
- }
-
-/*
-* Find this certificate
-*/
-size_t X509_Store::find_cert(const X509_DN& subject_dn,
- const MemoryRegion<byte>& subject_key_id) const
- {
- for(size_t j = 0; j != certs.size(); ++j)
- {
- const X509_Certificate& this_cert = certs[j].cert;
- if(compare_ids(this_cert.subject_key_id(), subject_key_id) &&
- this_cert.subject_dn() == subject_dn)
- return j;
- }
- return NO_CERT_FOUND;
- }
-
-/*
-* Find the parent of this certificate
-*/
-size_t X509_Store::find_parent_of(const X509_Certificate& cert)
- {
- const X509_DN issuer_dn = cert.issuer_dn();
- const MemoryVector<byte> auth_key_id = cert.authority_key_id();
-
- size_t index = find_cert(issuer_dn, auth_key_id);
-
- if(index != NO_CERT_FOUND)
- return index;
-
- for(size_t j = 0; j != stores.size(); ++j)
- {
- std::vector<X509_Certificate> got =
- stores[j]->find_cert_by_subject_and_key_id(issuer_dn, auth_key_id);
-
- for(size_t k = 0; k != got.size(); ++k)
- add_cert(got[k]);
- }
-
- return find_cert(issuer_dn, auth_key_id);
- }
-
-/*
-* Construct a chain of certificate relationships
-*/
-X509_Code X509_Store::construct_cert_chain(const X509_Certificate& end_cert,
- std::vector<size_t>& indexes,
- bool need_full_chain)
- {
- size_t parent = find_parent_of(end_cert);
-
- while(true)
- {
- if(parent == NO_CERT_FOUND)
- return CERT_ISSUER_NOT_FOUND;
- indexes.push_back(parent);
-
- if(certs[parent].is_verified(validation_cache_timeout))
- if(certs[parent].verify_result() != VERIFIED)
- return certs[parent].verify_result();
-
- const X509_Certificate& parent_cert = certs[parent].cert;
- if(!parent_cert.is_CA_cert())
- return CA_CERT_NOT_FOR_CERT_ISSUER;
-
- if(certs[parent].is_trusted())
- break;
- if(parent_cert.is_self_signed())
- return CANNOT_ESTABLISH_TRUST;
-
- if(parent_cert.path_limit() < indexes.size() - 1)
- return CERT_CHAIN_TOO_LONG;
-
- parent = find_parent_of(parent_cert);
- }
-
- if(need_full_chain)
- return VERIFIED;
-
- while(true)
- {
- if(indexes.size() < 2)
- break;
-
- const size_t cert = indexes.back();
-
- if(certs[cert].is_verified(validation_cache_timeout))
- {
- if(certs[cert].verify_result() != VERIFIED)
- throw Internal_Error("X509_Store::construct_cert_chain");
- indexes.pop_back();
- }
- else
- break;
- }
-
- const size_t last_cert = indexes.back();
- const size_t parent_of_last_cert = find_parent_of(certs[last_cert].cert);
- if(parent_of_last_cert == NO_CERT_FOUND)
- return CERT_ISSUER_NOT_FOUND;
- indexes.push_back(parent_of_last_cert);
-
- return VERIFIED;
- }
-
-/*
-* Check the CAs signature on a certificate
-*/
-X509_Code X509_Store::check_sig(const Cert_Info& cert_info,
- const Cert_Info& ca_cert_info) const
- {
- if(cert_info.is_verified(validation_cache_timeout))
- return cert_info.verify_result();
-
- const X509_Certificate& cert = cert_info.cert;
- const X509_Certificate& ca_cert = ca_cert_info.cert;
-
- X509_Code verify_code = check_sig(cert, ca_cert.subject_public_key());
-
- cert_info.set_result(verify_code);
-
- return verify_code;
- }
-
-/*
-* Check a CA's signature
-*/
-X509_Code X509_Store::check_sig(const X509_Object& object, Public_Key* key)
- {
- std::auto_ptr<Public_Key> pub_key(key);
-
- try {
- std::vector<std::string> sig_info =
- split_on(OIDS::lookup(object.signature_algorithm().oid), '/');
-
- if(sig_info.size() != 2 || sig_info[0] != pub_key->algo_name())
- return SIGNATURE_ERROR;
-
- std::string padding = sig_info[1];
- Signature_Format format;
- if(key->message_parts() >= 2) format = DER_SEQUENCE;
- else format = IEEE_1363;
-
- PK_Verifier verifier(*pub_key.get(), padding, format);
-
- bool valid = verifier.verify_message(object.tbs_data(),
- object.signature());
-
- if(valid)
- return VERIFIED;
- else
- return SIGNATURE_ERROR;
- }
- catch(Lookup_Error) { return CA_CERT_CANNOT_SIGN; }
- catch(Decoding_Error) { return CERT_FORMAT_ERROR; }
- catch(Exception) {}
-
- return UNKNOWN_X509_ERROR;
- }
-
-/*
-* Recompute the revocation status of the certs
-*/
-void X509_Store::recompute_revoked_info() const
- {
- if(revoked_info_valid)
- return;
-
- for(size_t j = 0; j != certs.size(); ++j)
- {
- if((certs[j].is_verified(validation_cache_timeout)) &&
- (certs[j].verify_result() != VERIFIED))
- continue;
-
- if(is_revoked(certs[j].cert))
- certs[j].set_result(CERT_IS_REVOKED);
- }
-
- revoked_info_valid = true;
- }
-
-/*
-* Check if a certificate is revoked
-*/
-bool X509_Store::is_revoked(const X509_Certificate& cert) const
- {
- CRL_Data revoked_info;
- revoked_info.issuer = cert.issuer_dn();
- revoked_info.serial = cert.serial_number();
- revoked_info.auth_key_id = cert.authority_key_id();
-
- if(std::binary_search(revoked.begin(), revoked.end(), revoked_info))
- return true;
- return false;
- }
-
-/*
-* Construct a path back to a root for this cert
-*/
-std::vector<X509_Certificate>
-X509_Store::get_cert_chain(const X509_Certificate& cert)
- {
- std::vector<X509_Certificate> result;
- std::vector<size_t> indexes;
- X509_Code chaining_result = construct_cert_chain(cert, indexes, true);
-
- if(chaining_result != VERIFIED)
- throw Invalid_State("X509_Store::get_cert_chain: Can't construct chain");
-
- for(size_t j = 0; j != indexes.size(); ++j)
- result.push_back(certs[indexes[j]].cert);
- return result;
- }
-
-/*
-* Add a certificate store to the list of stores
-*/
-void X509_Store::add_new_certstore(Certificate_Store* certstore)
- {
- stores.push_back(certstore);
- }
-
-/*
-* Add a certificate to the store
-*/
-void X509_Store::add_cert(const X509_Certificate& cert, bool trusted)
- {
- if(trusted && !cert.is_self_signed())
- throw Invalid_Argument("X509_Store: Trusted certs must be self-signed");
-
- if(find_cert(cert.subject_dn(), cert.subject_key_id()) == NO_CERT_FOUND)
- {
- revoked_info_valid = false;
- Cert_Info info(cert, trusted);
- certs.push_back(info);
- }
- else if(trusted)
- {
- for(size_t j = 0; j != certs.size(); ++j)
- {
- const X509_Certificate& this_cert = certs[j].cert;
- if(this_cert == cert)
- certs[j].trusted = trusted;
- }
- }
- }
-
-/*
-* Add one or more certificates to the store
-*/
-void X509_Store::do_add_certs(DataSource& source, bool trusted)
- {
- while(!source.end_of_data())
- {
- try {
- X509_Certificate cert(source);
- add_cert(cert, trusted);
- }
- catch(Decoding_Error) {}
- catch(Invalid_Argument) {}
- }
- }
-
-/*
-* Add one or more certificates to the store
-*/
-void X509_Store::add_certs(DataSource& source)
- {
- do_add_certs(source, false);
- }
-
-/*
-* Add one or more certificates to the store
-*/
-void X509_Store::add_trusted_certs(DataSource& source)
- {
- do_add_certs(source, true);
- }
-
-/*
-* Add one or more certificates to the store
-*/
-X509_Code X509_Store::add_crl(const X509_CRL& crl)
- {
- s32bit time_check = validity_check(crl.this_update(), crl.next_update(),
- system_time(), time_slack);
-
- if(time_check < 0) return CRL_NOT_YET_VALID;
- else if(time_check > 0) return CRL_HAS_EXPIRED;
-
- size_t cert_index = NO_CERT_FOUND;
-
- for(size_t j = 0; j != certs.size(); ++j)
- {
- const X509_Certificate& this_cert = certs[j].cert;
- if(compare_ids(this_cert.subject_key_id(), crl.authority_key_id()))
- {
- if(this_cert.subject_dn() == crl.issuer_dn())
- cert_index = j;
- }
- }
-
- if(cert_index == NO_CERT_FOUND)
- return CRL_ISSUER_NOT_FOUND;
-
- const X509_Certificate& ca_cert = certs[cert_index].cert;
-
- X509_Code verify_result = validate_cert(ca_cert, CRL_SIGNING);
- if(verify_result != VERIFIED)
- return verify_result;
-
- verify_result = check_sig(crl, ca_cert.subject_public_key());
- if(verify_result != VERIFIED)
- return verify_result;
-
- std::vector<CRL_Entry> revoked_certs = crl.get_revoked();
-
- for(size_t j = 0; j != revoked_certs.size(); ++j)
- {
- CRL_Data revoked_info;
- revoked_info.issuer = crl.issuer_dn();
- revoked_info.serial = revoked_certs[j].serial_number();
- revoked_info.auth_key_id = crl.authority_key_id();
-
- std::vector<CRL_Data>::iterator p =
- std::find(revoked.begin(), revoked.end(), revoked_info);
-
- if(revoked_certs[j].reason_code() == REMOVE_FROM_CRL)
- {
- if(p == revoked.end()) continue;
- revoked.erase(p);
- }
- else
- {
- if(p != revoked.end()) continue;
- revoked.push_back(revoked_info);
- }
- }
-
- std::sort(revoked.begin(), revoked.end());
- revoked_info_valid = false;
-
- return VERIFIED;
- }
-
-/*
-* PEM encode the set of certificates
-*/
-std::string X509_Store::PEM_encode() const
- {
- std::string cert_store;
- for(size_t j = 0; j != certs.size(); ++j)
- cert_store += certs[j].cert.PEM_encode();
- return cert_store;
- }
-
-/*
-* Create a Cert_Info structure
-*/
-X509_Store::Cert_Info::Cert_Info(const X509_Certificate& c,
- bool t) : cert(c), trusted(t)
- {
- checked = false;
- result = UNKNOWN_X509_ERROR;
- last_checked = 0;
- }
-
-/*
-* Return the verification results
-*/
-X509_Code X509_Store::Cert_Info::verify_result() const
- {
- if(!checked)
- throw Invalid_State("Cert_Info::verify_result() called; not checked");
- return result;
- }
-
-/*
-* Set the verification results
-*/
-void X509_Store::Cert_Info::set_result(X509_Code code) const
- {
- result = code;
- last_checked = system_time();
- checked = true;
- }
-
-/*
-* Check if this certificate can be trusted
-*/
-bool X509_Store::Cert_Info::is_trusted() const
- {
- return trusted;
- }
-
-/*
-* Check if this certificate has been verified
-*/
-bool X509_Store::Cert_Info::is_verified(u32bit timeout) const
- {
- if(!checked)
- return false;
- if(result != VERIFIED && result != CERT_NOT_YET_VALID)
- return true;
-
- const u64bit current_time = system_time();
-
- if(current_time > last_checked + timeout)
- checked = false;
-
- return checked;
- }
-
-}
diff --git a/src/cert/x509store/x509stor.h b/src/cert/x509store/x509stor.h
deleted file mode 100644
index b4b50022c..000000000
--- a/src/cert/x509store/x509stor.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
-* X.509 Certificate Store
-* (C) 1999-2007 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#ifndef BOTAN_X509_CERT_STORE_H__
-#define BOTAN_X509_CERT_STORE_H__
-
-#include <botan/x509cert.h>
-#include <botan/x509_crl.h>
-#include <botan/certstor.h>
-
-namespace Botan {
-
-/**
-* X.509 Certificate Validation Result
-*/
-enum X509_Code {
- VERIFIED,
- UNKNOWN_X509_ERROR,
- CANNOT_ESTABLISH_TRUST,
- CERT_CHAIN_TOO_LONG,
- SIGNATURE_ERROR,
- POLICY_ERROR,
- INVALID_USAGE,
-
- CERT_FORMAT_ERROR,
- CERT_ISSUER_NOT_FOUND,
- CERT_NOT_YET_VALID,
- CERT_HAS_EXPIRED,
- CERT_IS_REVOKED,
-
- CRL_FORMAT_ERROR,
- CRL_ISSUER_NOT_FOUND,
- CRL_NOT_YET_VALID,
- CRL_HAS_EXPIRED,
-
- CA_CERT_CANNOT_SIGN,
- CA_CERT_NOT_FOR_CERT_ISSUER,
- CA_CERT_NOT_FOR_CRL_ISSUER
-};
-
-/**
-* X.509 Certificate Store
-*/
-class BOTAN_DLL X509_Store
- {
- public:
- enum Cert_Usage {
- ANY = 0x00,
- TLS_SERVER = 0x01,
- TLS_CLIENT = 0x02,
- CODE_SIGNING = 0x04,
- EMAIL_PROTECTION = 0x08,
- TIME_STAMPING = 0x10,
- CRL_SIGNING = 0x20
- };
-
- X509_Code validate_cert(const X509_Certificate&, Cert_Usage = ANY);
-
- std::vector<X509_Certificate> get_cert_chain(const X509_Certificate&);
- std::string PEM_encode() const;
-
- X509_Code add_crl(const X509_CRL&);
- void add_cert(const X509_Certificate&, bool = false);
- void add_certs(DataSource&);
- void add_trusted_certs(DataSource&);
-
- void add_new_certstore(Certificate_Store*);
-
- X509_Store(u32bit time_slack = 24*60*60,
- u32bit cache_results = 30*60);
-
- X509_Store(const X509_Store&);
- ~X509_Store();
- private:
- X509_Store& operator=(const X509_Store&) { return (*this); }
-
- class BOTAN_DLL CRL_Data
- {
- public:
- X509_DN issuer;
- MemoryVector<byte> serial, auth_key_id;
- bool operator==(const CRL_Data&) const;
- bool operator!=(const CRL_Data&) const;
- bool operator<(const CRL_Data&) const;
- };
-
- class BOTAN_DLL Cert_Info
- {
- public:
- bool is_verified(u32bit timeout) const;
- bool is_trusted() const;
- X509_Code verify_result() const;
- void set_result(X509_Code) const;
- Cert_Info(const X509_Certificate&, bool = false);
-
- X509_Certificate cert;
- bool trusted;
- private:
- mutable bool checked;
- mutable X509_Code result;
- mutable u64bit last_checked;
- };
-
- static X509_Code check_sig(const X509_Object&, Public_Key*);
-
- size_t find_cert(const X509_DN&, const MemoryRegion<byte>&) const;
- X509_Code check_sig(const Cert_Info&, const Cert_Info&) const;
- void recompute_revoked_info() const;
-
- void do_add_certs(DataSource&, bool);
- X509_Code construct_cert_chain(const X509_Certificate&,
- std::vector<size_t>&, bool = false);
-
- size_t find_parent_of(const X509_Certificate&);
- bool is_revoked(const X509_Certificate&) const;
-
- static const size_t NO_CERT_FOUND = 0xFFFFFFFF;
- std::vector<Cert_Info> certs;
- std::vector<CRL_Data> revoked;
- std::vector<Certificate_Store*> stores;
- u32bit time_slack, validation_cache_timeout;
- mutable bool revoked_info_valid;
- };
-
-}
-
-#endif