aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/x509
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/x509')
-rw-r--r--src/lib/x509/cert_status.cpp2
-rw-r--r--src/lib/x509/cert_status.h1
-rw-r--r--src/lib/x509/ocsp.cpp26
-rw-r--r--src/lib/x509/ocsp.h6
-rw-r--r--src/lib/x509/x509path.cpp5
-rw-r--r--src/lib/x509/x509path.h3
6 files changed, 29 insertions, 14 deletions
diff --git a/src/lib/x509/cert_status.cpp b/src/lib/x509/cert_status.cpp
index 79bcd1b07..4efd49edf 100644
--- a/src/lib/x509/cert_status.cpp
+++ b/src/lib/x509/cert_status.cpp
@@ -46,6 +46,8 @@ const char* to_string(Certificate_Status_Code code)
return "OCSP is not yet valid";
case Certificate_Status_Code::OCSP_HAS_EXPIRED:
return "OCSP response has expired";
+ case Certificate_Status_Code::OCSP_IS_TOO_OLD:
+ return "OCSP response is too old";
case Certificate_Status_Code::CRL_NOT_YET_VALID:
return "CRL response is not yet valid";
case Certificate_Status_Code::CRL_HAS_EXPIRED:
diff --git a/src/lib/x509/cert_status.h b/src/lib/x509/cert_status.h
index fc1174df3..b682746f8 100644
--- a/src/lib/x509/cert_status.h
+++ b/src/lib/x509/cert_status.h
@@ -48,6 +48,7 @@ enum class Certificate_Status_Code {
OCSP_HAS_EXPIRED = 2003,
CRL_NOT_YET_VALID = 2004,
CRL_HAS_EXPIRED = 2005,
+ OCSP_IS_TOO_OLD = 2006,
// Chain generation problems
CERT_ISSUER_NOT_FOUND = 3000,
diff --git a/src/lib/x509/ocsp.cpp b/src/lib/x509/ocsp.cpp
index de229d412..7907d08e2 100644
--- a/src/lib/x509/ocsp.cpp
+++ b/src/lib/x509/ocsp.cpp
@@ -269,11 +269,12 @@ Certificate_Status_Code Response::check_signature(const std::vector<Certificate_
}
Certificate_Status_Code Response::status_for(const X509_Certificate& issuer,
- const X509_Certificate& subject,
- std::chrono::system_clock::time_point ref_time) const
+ const X509_Certificate& subject,
+ std::chrono::system_clock::time_point ref_time,
+ std::chrono::seconds max_age) const
{
- if (m_responses.empty())
- return m_dummy_response_status;
+ if(m_responses.empty())
+ { return m_dummy_response_status; }
for(const auto& response : m_responses)
{
@@ -282,18 +283,23 @@ Certificate_Status_Code Response::status_for(const X509_Certificate& issuer,
X509_Time x509_ref_time(ref_time);
if(response.cert_status() == 1)
- return Certificate_Status_Code::CERT_IS_REVOKED;
+ { return Certificate_Status_Code::CERT_IS_REVOKED; }
if(response.this_update() > x509_ref_time)
- return Certificate_Status_Code::OCSP_NOT_YET_VALID;
+ { return Certificate_Status_Code::OCSP_NOT_YET_VALID; }
- if(response.next_update().time_is_set() && x509_ref_time > response.next_update())
- return Certificate_Status_Code::OCSP_HAS_EXPIRED;
+ if(response.next_update().time_is_set())
+ {
+ if(x509_ref_time > response.next_update())
+ { return Certificate_Status_Code::OCSP_HAS_EXPIRED; }
+ }
+ else if(max_age > std::chrono::seconds::zero() && ref_time - response.this_update().to_std_timepoint() > max_age)
+ { return Certificate_Status_Code::OCSP_IS_TOO_OLD; }
if(response.cert_status() == 0)
- return Certificate_Status_Code::OCSP_RESPONSE_GOOD;
+ { return Certificate_Status_Code::OCSP_RESPONSE_GOOD; }
else
- return Certificate_Status_Code::OCSP_BAD_STATUS;
+ { return Certificate_Status_Code::OCSP_BAD_STATUS; }
}
}
diff --git a/src/lib/x509/ocsp.h b/src/lib/x509/ocsp.h
index 884b1c5b3..e9d09850f 100644
--- a/src/lib/x509/ocsp.h
+++ b/src/lib/x509/ocsp.h
@@ -139,17 +139,21 @@ class BOTAN_PUBLIC_API(2,0) Response final
* @param issuer issuer certificate
* @param subject subject certificate
* @param ref_time the reference time
+ * @param max_age the maximum age the response should be considered valid
+ * if next_update is not set
* @return OCSP status code, possible values:
* CERT_IS_REVOKED,
* OCSP_NOT_YET_VALID,
* OCSP_HAS_EXPIRED,
+ * OCSP_IS_TOO_OLD,
* OCSP_RESPONSE_GOOD,
* OCSP_BAD_STATUS,
* OCSP_CERT_NOT_LISTED
*/
Certificate_Status_Code status_for(const X509_Certificate& issuer,
const X509_Certificate& subject,
- std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now()) const;
+ std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now(),
+ std::chrono::seconds max_age = std::chrono::seconds::zero()) const;
/**
* @return the certificate chain, if provided in response
diff --git a/src/lib/x509/x509path.cpp b/src/lib/x509/x509path.cpp
index 9d886ca7a..a889aa4d4 100644
--- a/src/lib/x509/x509path.cpp
+++ b/src/lib/x509/x509path.cpp
@@ -204,7 +204,8 @@ CertificatePathStatusCodes
PKIX::check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path,
const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses,
const std::vector<Certificate_Store*>& trusted_certstores,
- std::chrono::system_clock::time_point ref_time)
+ std::chrono::system_clock::time_point ref_time,
+ std::chrono::seconds max_age)
{
if(cert_path.empty())
throw Invalid_Argument("PKIX::check_ocsp cert_path empty");
@@ -227,7 +228,7 @@ PKIX::check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cer
if(ocsp_signature_status == Certificate_Status_Code::OCSP_SIGNATURE_OK)
{
// Signature ok, so check the claimed status
- Certificate_Status_Code ocsp_status = ocsp_responses.at(i)->status_for(*ca, *subject, ref_time);
+ Certificate_Status_Code ocsp_status = ocsp_responses.at(i)->status_for(*ca, *subject, ref_time, max_age);
status.insert(ocsp_status);
}
else
diff --git a/src/lib/x509/x509path.h b/src/lib/x509/x509path.h
index 841f1a8ef..3e457b970 100644
--- a/src/lib/x509/x509path.h
+++ b/src/lib/x509/x509path.h
@@ -352,7 +352,8 @@ CertificatePathStatusCodes
BOTAN_PUBLIC_API(2,0) check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path,
const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses,
const std::vector<Certificate_Store*>& certstores,
- std::chrono::system_clock::time_point ref_time);
+ std::chrono::system_clock::time_point ref_time,
+ std::chrono::seconds max_age = std::chrono::seconds::zero());
/**
* Check CRLs for revocation information