aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/cert/x509/x509path.cpp34
-rw-r--r--src/lib/cert/x509/x509path.h13
-rw-r--r--src/tests/test_x509_path.cpp6
3 files changed, 34 insertions, 19 deletions
diff --git a/src/lib/cert/x509/x509path.cpp b/src/lib/cert/x509/x509path.cpp
index a0cae2c93..f0b07e5fc 100644
--- a/src/lib/cert/x509/x509path.cpp
+++ b/src/lib/cert/x509/x509path.cpp
@@ -77,13 +77,14 @@ std::shared_ptr<const X509_CRL> find_crls_for(const X509_Certificate& cert,
std::vector<std::set<Certificate_Status_Code>>
check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path,
const Path_Validation_Restrictions& restrictions,
- const std::vector<Certificate_Store*>& certstores)
+ const std::vector<Certificate_Store*>& certstores,
+ std::chrono::system_clock::time_point ref_time)
{
const std::set<std::string>& trusted_hashes = restrictions.trusted_hashes();
const bool self_signed_ee_cert = (cert_path.size() == 1);
- X509_Time current_time(std::chrono::system_clock::now());
+ X509_Time validation_time(ref_time);
std::vector<std::future<OCSP::Response>> ocsp_responses;
@@ -109,10 +110,10 @@ check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_pat
}
// Check all certs for valid time range
- if(current_time < X509_Time(subject->start_time(), ASN1_Tag::UTC_OR_GENERALIZED_TIME))
+ if(validation_time < X509_Time(subject->start_time(), ASN1_Tag::UTC_OR_GENERALIZED_TIME))
status.insert(Certificate_Status_Code::CERT_NOT_YET_VALID);
- if(current_time > X509_Time(subject->end_time(), ASN1_Tag::UTC_OR_GENERALIZED_TIME))
+ if(validation_time > X509_Time(subject->end_time(), ASN1_Tag::UTC_OR_GENERALIZED_TIME))
status.insert(Certificate_Status_Code::CERT_HAS_EXPIRED);
// Check issuer constraints
@@ -198,10 +199,10 @@ check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_pat
if(!ca->allowed_usage(CRL_SIGN))
status.insert(Certificate_Status_Code::CA_CERT_NOT_FOR_CRL_ISSUER);
- if(current_time < X509_Time(crl.this_update()))
+ if(validation_time < X509_Time(crl.this_update()))
status.insert(Certificate_Status_Code::CRL_NOT_YET_VALID);
- if(current_time > X509_Time(crl.next_update()))
+ if(validation_time > X509_Time(crl.next_update()))
status.insert(Certificate_Status_Code::CRL_HAS_EXPIRED);
if(crl.check_signature(ca->subject_public_key()) == false)
@@ -224,7 +225,8 @@ Path_Validation_Result x509_path_validate(
const Path_Validation_Restrictions& restrictions,
const std::vector<Certificate_Store*>& certstores,
const std::string& hostname,
- Usage_Type usage)
+ Usage_Type usage,
+ std::chrono::system_clock::time_point validation_time)
{
if(end_certs.empty())
throw Invalid_Argument("x509_path_validate called with no subjects");
@@ -259,7 +261,8 @@ Path_Validation_Result x509_path_validate(
cert_path.push_back(cert);
}
- std::vector<std::set<Certificate_Status_Code>> res = check_chain(cert_path, restrictions, certstores);
+ std::vector<std::set<Certificate_Status_Code>> res =
+ check_chain(cert_path, restrictions, certstores, validation_time);
if(!hostname.empty() && !cert_path[0]->matches_dns_name(hostname))
res[0].insert(Certificate_Status_Code::CERT_NAME_NOMATCH);
@@ -275,11 +278,12 @@ Path_Validation_Result x509_path_validate(
const Path_Validation_Restrictions& restrictions,
const std::vector<Certificate_Store*>& certstores,
const std::string& hostname,
- Usage_Type usage)
+ Usage_Type usage,
+ std::chrono::system_clock::time_point when)
{
std::vector<X509_Certificate> certs;
certs.push_back(end_cert);
- return x509_path_validate(certs, restrictions, certstores, hostname, usage);
+ return x509_path_validate(certs, restrictions, certstores, hostname, usage, when);
}
Path_Validation_Result x509_path_validate(
@@ -287,12 +291,13 @@ Path_Validation_Result x509_path_validate(
const Path_Validation_Restrictions& restrictions,
const Certificate_Store& store,
const std::string& hostname,
- Usage_Type usage)
+ Usage_Type usage,
+ std::chrono::system_clock::time_point when)
{
std::vector<Certificate_Store*> certstores;
certstores.push_back(const_cast<Certificate_Store*>(&store));
- return x509_path_validate(end_certs, restrictions, certstores, hostname, usage);
+ return x509_path_validate(end_certs, restrictions, certstores, hostname, usage, when);
}
Path_Validation_Result x509_path_validate(
@@ -300,7 +305,8 @@ Path_Validation_Result x509_path_validate(
const Path_Validation_Restrictions& restrictions,
const Certificate_Store& store,
const std::string& hostname,
- Usage_Type usage)
+ Usage_Type usage,
+ std::chrono::system_clock::time_point when)
{
std::vector<X509_Certificate> certs;
certs.push_back(end_cert);
@@ -308,7 +314,7 @@ Path_Validation_Result x509_path_validate(
std::vector<Certificate_Store*> certstores;
certstores.push_back(const_cast<Certificate_Store*>(&store));
- return x509_path_validate(certs, restrictions, certstores, hostname, usage);
+ return x509_path_validate(certs, restrictions, certstores, hostname, usage, when);
}
Path_Validation_Restrictions::Path_Validation_Restrictions(bool require_rev,
diff --git a/src/lib/cert/x509/x509path.h b/src/lib/cert/x509/x509path.h
index 362f65852..b33069f72 100644
--- a/src/lib/cert/x509/x509path.h
+++ b/src/lib/cert/x509/x509path.h
@@ -12,6 +12,7 @@
#include <botan/x509cert.h>
#include <botan/certstor.h>
#include <set>
+#include <chrono>
namespace Botan {
@@ -175,7 +176,8 @@ Path_Validation_Result BOTAN_DLL x509_path_validate(
const Path_Validation_Restrictions& restrictions,
const std::vector<Certificate_Store*>& certstores,
const std::string& hostname = "",
- Usage_Type usage = Usage_Type::UNSPECIFIED);
+ Usage_Type usage = Usage_Type::UNSPECIFIED,
+ std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now());
/**
* PKIX Path Validation
@@ -191,7 +193,8 @@ Path_Validation_Result BOTAN_DLL x509_path_validate(
const Path_Validation_Restrictions& restrictions,
const std::vector<Certificate_Store*>& certstores,
const std::string& hostname = "",
- Usage_Type usage = Usage_Type::UNSPECIFIED);
+ Usage_Type usage = Usage_Type::UNSPECIFIED,
+ std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now());
/**
* PKIX Path Validation
@@ -207,7 +210,8 @@ Path_Validation_Result BOTAN_DLL x509_path_validate(
const Path_Validation_Restrictions& restrictions,
const Certificate_Store& store,
const std::string& hostname = "",
- Usage_Type usage = Usage_Type::UNSPECIFIED);
+ Usage_Type usage = Usage_Type::UNSPECIFIED,
+ std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now());
/**
* PKIX Path Validation
@@ -223,7 +227,8 @@ Path_Validation_Result BOTAN_DLL x509_path_validate(
const Path_Validation_Restrictions& restrictions,
const Certificate_Store& store,
const std::string& hostname = "",
- Usage_Type usage = Usage_Type::UNSPECIFIED);
+ Usage_Type usage = Usage_Type::UNSPECIFIED,
+ std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now());
}
diff --git a/src/tests/test_x509_path.cpp b/src/tests/test_x509_path.cpp
index 96cc7a190..ae52de541 100644
--- a/src/tests/test_x509_path.cpp
+++ b/src/tests/test_x509_path.cpp
@@ -8,6 +8,7 @@
#if defined(BOTAN_HAS_X509_CERTIFICATES)
#include <botan/x509path.h>
+ #include <botan/calendar.h>
#include <botan/internal/filesystem.h>
#endif
@@ -70,6 +71,8 @@ class X509test_Path_Validation_Tests : public Test
Botan::Certificate_Store_In_Memory trusted;
trusted.add_certificate(root);
+ auto validation_time = Botan::calendar_point(2016,10,21,4,20,0).to_std_timepoint();
+
for(auto i = expected.begin(); i != expected.end(); ++i)
{
Test::Result result("X509test path validation");
@@ -84,7 +87,8 @@ class X509test_Path_Validation_Tests : public Test
Botan::Path_Validation_Result path_result = Botan::x509_path_validate(
certs, default_restrictions, trusted,
- "www.tls.test", Botan::Usage_Type::TLS_SERVER_AUTH);
+ "www.tls.test", Botan::Usage_Type::TLS_SERVER_AUTH,
+ validation_time);
if(path_result.successful_validation() && path_result.trust_root() != root)
path_result = Botan::Path_Validation_Result(Botan::Certificate_Status_Code::CANNOT_ESTABLISH_TRUST);