aboutsummaryrefslogtreecommitdiffstats
path: root/src/libstrongswan
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-03-01 11:33:47 +0100
committerMartin Willi <martin@revosec.ch>2013-03-01 11:33:47 +0100
commitadf239abca62808cecf9530120091fa69f4f183f (patch)
tree995c04c534c9db1264cc7fd7511b20b80fea3b28 /src/libstrongswan
parentb611d8ba48424747ad1330e6ffbba3de8f5f0555 (diff)
parent295e42a47f9a46366209c076f6542459d65a4a38 (diff)
downloadstrongswan-adf239abca62808cecf9530120091fa69f4f183f.tar.bz2
strongswan-adf239abca62808cecf9530120091fa69f4f183f.tar.xz
Merge branch 'systime'
Add a systime-fix plugin allowing an embedded system to validate certificates if the system time has not been synchronized after boot. Certificates of established tunnels can be re-validated after the system time gets valid.
Diffstat (limited to 'src/libstrongswan')
-rw-r--r--src/libstrongswan/credentials/cert_validator.h17
-rw-r--r--src/libstrongswan/credentials/credential_manager.c62
2 files changed, 69 insertions, 10 deletions
diff --git a/src/libstrongswan/credentials/cert_validator.h b/src/libstrongswan/credentials/cert_validator.h
index 00e30d7a0..325fa0af3 100644
--- a/src/libstrongswan/credentials/cert_validator.h
+++ b/src/libstrongswan/credentials/cert_validator.h
@@ -35,6 +35,22 @@ typedef struct cert_validator_t cert_validator_t;
struct cert_validator_t {
/**
+ * Check the lifetime of a certificate.
+ *
+ * If this function returns SUCCESS or FAILED, the certificate lifetime is
+ * considered definitely (in-)valid, without asking other validators.
+ * If all registered validaters return NEED_MORE, the default
+ * lifetime check is performed.
+ *
+ * @param cert certificate to check lifetime
+ * @param pathlen the current length of the path bottom-up
+ * @param anchor is certificate trusted root anchor?
+ * @param auth container for resulting authentication info
+ * @return SUCCESS, FAILED or NEED_MORE to ask next validator
+ */
+ status_t (*check_lifetime)(cert_validator_t *this, certificate_t *cert,
+ int pathlen, bool anchor, auth_cfg_t *auth);
+ /**
* Validate a subject certificate in relation to its issuer.
*
* @param subject subject certificate to check
@@ -43,6 +59,7 @@ struct cert_validator_t {
* @param pathlen the current length of the path bottom-up
* @param anchor is issuer trusted root anchor
* @param auth container for resulting authentication info
+ * @return TRUE if subject certificate valid
*/
bool (*validate)(cert_validator_t *this, certificate_t *subject,
certificate_t *issuer, bool online, u_int pathlen,
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
index 9e40c5a10..44eaec62c 100644
--- a/src/libstrongswan/credentials/credential_manager.c
+++ b/src/libstrongswan/credentials/credential_manager.c
@@ -515,32 +515,74 @@ static void cache_queue(private_credential_manager_t *this)
}
/**
+ * Use validators to check the lifetime of certificates
+ */
+static bool check_lifetime(private_credential_manager_t *this,
+ certificate_t *cert, char *label,
+ int pathlen, bool trusted, auth_cfg_t *auth)
+{
+ time_t not_before, not_after;
+ cert_validator_t *validator;
+ enumerator_t *enumerator;
+ status_t status = NEED_MORE;
+
+ enumerator = this->validators->create_enumerator(this->validators);
+ while (enumerator->enumerate(enumerator, &validator))
+ {
+ if (!validator->check_lifetime)
+ {
+ continue;
+ }
+ status = validator->check_lifetime(validator, cert,
+ pathlen, trusted, auth);
+ if (status != NEED_MORE)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ switch (status)
+ {
+ case NEED_MORE:
+ if (!cert->get_validity(cert, NULL, &not_before, &not_after))
+ {
+ DBG1(DBG_CFG, "%s certificate invalid (valid from %T to %T)",
+ label, &not_before, FALSE, &not_after, FALSE);
+ return FALSE;
+ }
+ return TRUE;
+ case SUCCESS:
+ return TRUE;
+ case FAILED:
+ default:
+ return FALSE;
+ }
+}
+
+/**
* check a certificate for its lifetime
*/
static bool check_certificate(private_credential_manager_t *this,
certificate_t *subject, certificate_t *issuer, bool online,
int pathlen, bool trusted, auth_cfg_t *auth)
{
- time_t not_before, not_after;
cert_validator_t *validator;
enumerator_t *enumerator;
- if (!subject->get_validity(subject, NULL, &not_before, &not_after))
- {
- DBG1(DBG_CFG, "subject certificate invalid (valid from %T to %T)",
- &not_before, FALSE, &not_after, FALSE);
- return FALSE;
- }
- if (!issuer->get_validity(issuer, NULL, &not_before, &not_after))
+ if (!check_lifetime(this, subject, "subject", pathlen, FALSE, auth) ||
+ !check_lifetime(this, issuer, "issuer", pathlen + 1, trusted, auth))
{
- DBG1(DBG_CFG, "issuer certificate invalid (valid from %T to %T)",
- &not_before, FALSE, &not_after, FALSE);
return FALSE;
}
enumerator = this->validators->create_enumerator(this->validators);
while (enumerator->enumerate(enumerator, &validator))
{
+ if (!validator->validate)
+ {
+ continue;
+ }
if (!validator->validate(validator, subject, issuer,
online, pathlen, trusted, auth))
{