diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2008-03-18 10:36:08 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2008-03-18 10:36:08 +0000 |
commit | 8d49b51f8b7334f399fb36ae24fa959eaedb4b83 (patch) | |
tree | 050eeef2c541dc5614e6a615706794bde433fe3e | |
parent | 50045c3b1415bcfebd32e3d95b63c3ca96a6d5d3 (diff) | |
download | strongswan-8d49b51f8b7334f399fb36ae24fa959eaedb4b83.tar.bz2 strongswan-8d49b51f8b7334f399fb36ae24fa959eaedb4b83.tar.xz |
made is_newer() a certificate_t method
-rw-r--r-- | src/charon/credentials/credential_manager.c | 197 | ||||
-rwxr-xr-x | src/charon/plugins/stroke/stroke.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/credentials/certificates/certificate.h | 7 | ||||
-rw-r--r-- | src/libstrongswan/credentials/certificates/crl.h | 7 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_cert.c | 26 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_crl.c | 74 | ||||
-rw-r--r-- | src/libstrongswan/plugins/x509/x509_ocsp_response.c | 50 |
7 files changed, 226 insertions, 137 deletions
diff --git a/src/charon/credentials/credential_manager.c b/src/charon/credentials/credential_manager.c index f69455685..387c5ad9b 100644 --- a/src/charon/credentials/credential_manager.c +++ b/src/charon/credentials/credential_manager.c @@ -414,8 +414,8 @@ static ocsp_wrapper_t *ocsp_wrapper_create(ocsp_response_t *response) /** * Do an OCSP request */ -static ocsp_response_t *fetch_ocsp(private_credential_manager_t *this, char *url, - certificate_t *subject, certificate_t *issuer) +static certificate_t *fetch_ocsp(private_credential_manager_t *this, char *url, + certificate_t *subject, certificate_t *issuer) { certificate_t *request, *response, *issuer_cert; chunk_t send, receive; @@ -430,7 +430,7 @@ static ocsp_response_t *fetch_ocsp(private_credential_manager_t *this, char *url BUILD_CERT, subject->get_ref(subject), BUILD_END); if (!request) { - DBG1(DBG_CFG, "generating OCSP request failed"); + DBG1(DBG_CFG, " generating ocsp request failed"); return NULL; } @@ -441,7 +441,7 @@ static ocsp_response_t *fetch_ocsp(private_credential_manager_t *this, char *url FETCH_REQUEST_TYPE, "application/ocsp-request", FETCH_END) != SUCCESS) { - DBG1(DBG_CFG, "OCSP request to %s failed", url); + DBG1(DBG_CFG, " ocsp request to %s failed", url); chunk_free(&send); return NULL; } @@ -452,7 +452,7 @@ static ocsp_response_t *fetch_ocsp(private_credential_manager_t *this, char *url BUILD_BLOB_ASN1_DER, receive, BUILD_END); if (!response) { - DBG1(DBG_CFG, "parsing OCSP response from %s failed", url); + DBG1(DBG_CFG, " parsing ocsp response failed"); return NULL; } @@ -466,14 +466,13 @@ static ocsp_response_t *fetch_ocsp(private_credential_manager_t *this, char *url auth->destroy(auth); if (!issuer_cert) { - DBG1(DBG_CFG, "verifying OCSP response failed, no trusted " - "certificate found"); + DBG1(DBG_CFG, " ocsp response untrusted: no signer certificate found"); response->destroy(response); return NULL; } if (!response->issued_by(response, issuer_cert, TRUE)) { - DBG1(DBG_CFG, "verifying OCSP response signature failed"); + DBG1(DBG_CFG, " ocsp response untrusted: bad signature"); response->destroy(response); issuer_cert->destroy(issuer_cert); return NULL; @@ -481,8 +480,7 @@ static ocsp_response_t *fetch_ocsp(private_credential_manager_t *this, char *url issuer_cert->destroy(issuer_cert); /* TODO: cache response? */ - - return (ocsp_response_t*)response; + return response; } /** @@ -492,99 +490,155 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this, x509_t *subject, x509_t *issuer, auth_info_t *auth) { - public_key_t *public; - enumerator_t *enumerator; - ocsp_response_t *response = NULL; - certificate_t *cert, *sub = (certificate_t*)subject; + certificate_t *sub = (certificate_t*)subject; + certificate_t *best_cert = NULL; cert_validation_t valid = VALIDATION_SKIPPED; identification_t *keyid = NULL; - char *url; + bool stale = TRUE; - cert = &issuer->interface; - public = cert->get_public_key(cert); - if (public) + /* derive the authorityKeyIdentifier from the issuer's public key */ { - keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1); + certificate_t *cert = &issuer->interface; + public_key_t *public = cert->get_public_key(cert); + + if (public) + { + keyid = public->get_id(public, ID_PUBKEY_SHA1); + public->destroy(public); + } } - - /* find a OCSP response by Authority key identifier (cache) */ + + /* find a cached ocsp response by authorityKeyIdentifier */ if (keyid) { - time_t update, best_update = 0; + enumerator_t *enumerator = create_cert_enumerator(this, + CERT_X509_OCSP_RESPONSE, + KEY_ANY, keyid, TRUE); + certificate_t *cert; - enumerator = create_cert_enumerator(this, CERT_X509_OCSP_RESPONSE, - KEY_ANY, keyid, TRUE); while (enumerator->enumerate(enumerator, &cert)) - { /* get newest valid response */ - if (cert->has_subject(cert, sub->get_subject(sub)) && - cert->get_validity(cert, NULL, &update, NULL) && - update > best_update) + { + if (cert->has_subject(cert, sub->get_subject(sub))) { - best_update = update; - DESTROY_IF(&response->certificate); - response = (ocsp_response_t*)cert; - valid = VALIDATION_FAILED; + /* select most recent ocsp response */ + if (best_cert == NULL || cert->is_newer(cert, best_cert)) + { + DESTROY_IF(best_cert); + best_cert = cert->get_ref(cert); + } } } enumerator->destroy(enumerator); } + + /* check the validity of the cached ocsp response if one was found */ + if (best_cert) + { + stale = !best_cert->get_validity(best_cert, NULL, NULL, NULL); + DBG1(DBG_CFG, "cached ocsp response is %s", stale? "stale":"valid"); + } + /* fallback to URL fetching from CDPs */ - if (!response && keyid) + if (stale && keyid) { - enumerator = create_cdp_enumerator(this, CERT_X509_OCSP_RESPONSE, keyid); - while (enumerator->enumerate(enumerator, &url)) + enumerator_t *enumerator = create_cdp_enumerator(this, + CERT_X509_OCSP_RESPONSE, keyid); + char *uri; + + while (enumerator->enumerate(enumerator, &uri)) { + certificate_t* cert = fetch_ocsp(this, uri, &subject->interface, + &issuer->interface); + + /* redefine default since we have at least one uri */ valid = VALIDATION_FAILED; - response = fetch_ocsp(this, url, &subject->interface, &issuer->interface); - if (response) + + if (cert) { - break; + /* select most recent ocsp response until valid one is found */ + if (best_cert == NULL || cert->is_newer(cert, best_cert)) + { + DESTROY_IF(best_cert); + best_cert = cert; + stale = !best_cert->get_validity(best_cert, NULL, NULL, NULL); + DBG1(DBG_CFG, "ocsp response is %s", stale? "stale":"valid"); + if (!stale) + { + break; + } + } + else + { + cert->destroy(cert); + } } } enumerator->destroy(enumerator); } + /* fallback to URL fetching from subject certificate's URIs */ - if (!response) + if (stale) { - enumerator = subject->create_ocsp_uri_enumerator(subject); - while (enumerator->enumerate(enumerator, &url)) + enumerator_t *enumerator = subject->create_ocsp_uri_enumerator(subject); + char *uri; + + while (enumerator->enumerate(enumerator, &uri)) { + certificate_t* cert = fetch_ocsp(this, uri, &subject->interface, + &issuer->interface); + + /* redefine default since we have at least one uri */ valid = VALIDATION_FAILED; - response = fetch_ocsp(this, url, &subject->interface, &issuer->interface); - if (response) + + if (cert) { - break; + /* select most recent ocsp response until valid one is found */ + if (best_cert == NULL || cert->is_newer(cert, best_cert)) + { + DESTROY_IF(best_cert); + best_cert = cert; + stale = !best_cert->get_validity(best_cert, NULL, NULL, NULL); + DBG1(DBG_CFG, "ocsp response is %s", stale? "stale":"valid"); + if (!stale) + { + break; + } + } + else + { + cert->destroy(cert); + } } } enumerator->destroy(enumerator); } - /* look for subject in response */ - if (response) + + /* if we have an ocsp response, check the revocation status */ + if (best_cert) { time_t revocation, this_update, next_update; crl_reason_t reason; + ocsp_response_t *response = (ocsp_response_t*)best_cert; valid = response->get_status(response, subject, issuer, &revocation, &reason, &this_update, &next_update); switch (valid) { case VALIDATION_FAILED: - DBG1(DBG_CFG, "subject not found in OCSP response"); + DBG1(DBG_CFG, "subject not found in ocsp response"); break; case VALIDATION_REVOKED: - DBG1(DBG_CFG, "certificate %D revoked by OCSP at %T: %N", - cert->get_subject(cert), &revocation, - crl_reason_names, reason); + DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N", + &revocation, crl_reason_names, reason); break; case VALIDATION_GOOD: - break; + case VALIDATION_UNKNOWN: default: break; } - cert = (certificate_t*)response; - cert->destroy(cert); + best_cert->destroy(best_cert); } - DESTROY_IF(public); + if (auth) { auth->add_item(auth, AUTHZ_OCSP_VALIDATION, &valid); @@ -668,7 +722,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this, } } - /* find a local crl by authorityKeyIdentifier */ + /* find a cached crl by authorityKeyIdentifier */ if (keyid) { enumerator_t *enumerator = create_cert_enumerator(this, CERT_X509_CRL, @@ -677,11 +731,8 @@ static cert_validation_t check_crl(private_credential_manager_t *this, while (enumerator->enumerate(enumerator, &cert)) { - crl_t *crl = (crl_t*)cert; - crl_t *best_crl = (crl_t*)best_cert; - /* select most recent crl */ - if (best_cert == NULL || crl->is_newer(crl, best_crl)) + if (best_cert == NULL || cert->is_newer(cert, best_cert)) { DESTROY_IF(best_cert); best_cert = cert->get_ref(cert); @@ -690,15 +741,11 @@ static cert_validation_t check_crl(private_credential_manager_t *this, enumerator->destroy(enumerator); } - /* check the validity of the local crl if one was found */ + /* check the validity of the cached crl if one was found */ if (best_cert) { stale = !best_cert->get_validity(best_cert, NULL, NULL, NULL); - DBG1(DBG_CFG, "locally-stored crl is %s", stale? "stale":"valid"); - } - else - { - DBG1(DBG_CFG, "no locally-stored crl found"); + DBG1(DBG_CFG, "cached crl is %s", stale? "stale":"valid"); } /* fallback to fetching crls from cdps defined in ca info sections */ @@ -717,11 +764,8 @@ static cert_validation_t check_crl(private_credential_manager_t *this, if (cert) { - crl_t *crl = (crl_t*)cert; - crl_t *best_crl = (crl_t*)best_cert; - - /* select most recent crl */ - if (best_cert == NULL || crl->is_newer(crl, best_crl)) + /* select most recent crl until valid one is found */ + if (best_cert == NULL || cert->is_newer(cert, best_cert)) { DESTROY_IF(best_cert); best_cert = cert; @@ -756,11 +800,8 @@ static cert_validation_t check_crl(private_credential_manager_t *this, if (cert) { - crl_t *crl = (crl_t*)cert; - crl_t *best_crl = (crl_t*)best_cert; - - /* select most recent crl */ - if (best_cert == NULL || crl->is_newer(crl, best_crl)) + /* select most recent crl until valid one is found */ + if (best_cert == NULL || cert->is_newer(cert, best_cert)) { DESTROY_IF(best_cert); best_cert = cert; @@ -783,6 +824,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this, /* if we have a crl, check the revocation status */ if (best_cert) { + chunk_t subject_serial = subject->get_serial(subject); chunk_t serial; time_t revocation; crl_reason_t reason; @@ -794,7 +836,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this, while (enumerator->enumerate(enumerator, &serial, &revocation, &reason)) { - if (chunk_equals(serial, subject->get_serial(subject))) + if (chunk_equals(serial, subject_serial)) { DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N", &revocation, crl_reason_names, reason); @@ -842,10 +884,11 @@ static bool check_certificate(private_credential_manager_t *this, switch (check_ocsp(this, (x509_t*)subject, (x509_t*)issuer, auth)) { case VALIDATION_GOOD: - DBG1(DBG_CFG, "certificate %D validated by OCSP", + DBG1(DBG_CFG, "certificate status is good", subject->get_subject(subject)); return TRUE; case VALIDATION_REVOKED: + /* has already been logged */ return FALSE; case VALIDATION_SKIPPED: DBG2(DBG_CFG, "OCSP check skipped, no OCSP URI found"); diff --git a/src/charon/plugins/stroke/stroke.c b/src/charon/plugins/stroke/stroke.c index cfea9187d..c3ee3305d 100755 --- a/src/charon/plugins/stroke/stroke.c +++ b/src/charon/plugins/stroke/stroke.c @@ -853,7 +853,7 @@ static void add_crl(private_stroke_t *this, crl_t* crl) } if (found) { - new = crl->is_newer(crl, crl_c); + new = cert->is_newer(cert, current); if (new) { this->creds.certs->remove_at(this->creds.certs, enumerator); diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h index 94f19a068..cc3f73a0d 100644 --- a/src/libstrongswan/credentials/certificates/certificate.h +++ b/src/libstrongswan/credentials/certificates/certificate.h @@ -160,6 +160,13 @@ struct certificate_t { time_t *not_before, time_t *not_after); /** + * Is this newer than that? + * + * @return TRUE if newer, FALSE otherwise + */ + bool (*is_newer)(certificate_t *this, certificate_t *that); + + /** * Get the certificate in an encoded form. * * @return allocated chunk of encoded cert diff --git a/src/libstrongswan/credentials/certificates/crl.h b/src/libstrongswan/credentials/certificates/crl.h index 752293ffb..16d9e2470 100644 --- a/src/libstrongswan/credentials/certificates/crl.h +++ b/src/libstrongswan/credentials/certificates/crl.h @@ -58,13 +58,6 @@ struct crl_t { certificate_t certificate; /** - * Is that newer than this? - * - * @return TRUE if newer, FALSE otherwise - */ - bool (*is_newer)(crl_t *this, crl_t *that); - - /** * Get the CRL serial number. * * @return chunk pointing to internal crlNumber diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index e85076d48..a1d410982 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -1035,16 +1035,33 @@ static bool get_validity(private_x509_cert_t *this, time_t *when, { t = time(NULL); } - if (not_after) - { - *not_after = this->notAfter; - } if (not_before) { *not_before = this->notBefore; } + if (not_after) + { + *not_after = this->notAfter; + } return (t >= this->notBefore && t <= this->notAfter); } + +/** + * Implementation of certificate_t.is_newer. + */ +static bool is_newer(certificate_t *this, certificate_t *that) +{ + time_t this_update, that_update, now = time(NULL); + bool new; + + this->get_validity(this, &now, &this_update, NULL); + that->get_validity(that, &now, &that_update, NULL); + new = this_update > that_update; + DBG1(" certificate from %#T is %s - existing certificate from %#T %s", + &this_update, FALSE, new ? "newer":"not newer", + &that_update, FALSE, new ? "replaced":"retained"); + return new; +} /** * Implementation of certificate_t.get_encoding. @@ -1155,6 +1172,7 @@ static private_x509_cert_t *load(chunk_t chunk) this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by; this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key; this->public.interface.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity; + this->public.interface.interface.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer; this->public.interface.interface.get_encoding = (chunk_t (*)(certificate_t*))get_encoding; this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals; this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref; diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c index 3c1a5625d..1748edb9c 100644 --- a/src/libstrongswan/plugins/x509/x509_crl.c +++ b/src/libstrongswan/plugins/x509/x509_crl.c @@ -326,39 +326,6 @@ static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2, } /** - * Implementation of crl_t.is_newer. - */ -static bool is_newer(private_x509_crl_t *this, crl_t *that) -{ - chunk_t that_crlNumber = that->get_serial(that); - bool new; - - /* compare crlNumbers if available - otherwise use thisUpdate */ - if (this->crlNumber.ptr != NULL && that_crlNumber.ptr != NULL) - { - new = chunk_compare(this->crlNumber, that_crlNumber) > 0; - DBG1(" crl #%#B is %s - existing crl #%#B %s", - &this->crlNumber, new ? "newer":"not newer", - &that_crlNumber, new ? "replaced":"retained"); - } - else - { - certificate_t *this_cert = &this->public.crl.certificate; - certificate_t *that_cert = &that->certificate; - - time_t this_update, that_update, now = time(NULL); - - this_cert->get_validity(this_cert, &now, &this_update, NULL); - that_cert->get_validity(that_cert, &now, &that_update, NULL); - new = this_update > that_update; - DBG1(" crl from %#T is %s - existing crl from %#T %s", - &this_update, FALSE, new ? "newer":"not newer", - &that_update, FALSE, new ? "replaced":"retained"); - } - return new; -} - -/** * Implementation of crl_t.get_serial. */ static chunk_t get_serial(private_x509_crl_t *this) @@ -550,15 +517,48 @@ static bool get_validity(private_x509_crl_t *this, time_t *when, { t = time(NULL); } + if (not_before) + { + *not_before = this->thisUpdate; + } if (not_after) { *not_after = this->nextUpdate; } - if (not_before) + return (t <= this->nextUpdate); +} + +/** + * Implementation of certificate_t.is_newer. + */ +static bool is_newer(private_x509_crl_t *this, crl_t *that) +{ + chunk_t that_crlNumber = that->get_serial(that); + bool new; + + /* compare crlNumbers if available - otherwise use thisUpdate */ + if (this->crlNumber.ptr != NULL && that_crlNumber.ptr != NULL) { - *not_before = this->thisUpdate; + new = chunk_compare(this->crlNumber, that_crlNumber) > 0; + DBG1(" crl #%#B is %s - existing crl #%#B %s", + &this->crlNumber, new ? "newer":"not newer", + &that_crlNumber, new ? "replaced":"retained"); } - return (t <= this->nextUpdate); + else + { + certificate_t *this_cert = &this->public.crl.certificate; + certificate_t *that_cert = &that->certificate; + + time_t this_update, that_update, now = time(NULL); + + this_cert->get_validity(this_cert, &now, &this_update, NULL); + that_cert->get_validity(that_cert, &now, &that_update, NULL); + new = this_update > that_update; + DBG1(" crl from %#T is %s - existing crl from %#T %s", + &this_update, FALSE, new ? "newer":"not newer", + &that_update, FALSE, new ? "replaced":"retained"); + } + return new; } /** @@ -609,7 +609,6 @@ static x509_crl_t *load(chunk_t chunk) { private_x509_crl_t *this = malloc_thing(private_x509_crl_t); - this->public.crl.is_newer = (bool (*)(crl_t*,crl_t*))is_newer; this->public.crl.get_serial = (chunk_t (*)(crl_t*))get_serial; this->public.crl.get_authKeyIdentifier = (identification_t* (*)(crl_t*))get_authKeyIdentifier; this->public.crl.create_enumerator = (enumerator_t* (*)(crl_t*))create_enumerator; @@ -621,6 +620,7 @@ static x509_crl_t *load(chunk_t chunk) this->public.crl.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by; this->public.crl.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key; this->public.crl.certificate.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity; + this->public.crl.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer; this->public.crl.certificate.get_encoding = (chunk_t (*)(certificate_t*))get_encoding; this->public.crl.certificate.equals = (bool (*)(certificate_t*, certificate_t *other))equals; this->public.crl.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref; diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index 4ea2871d2..87971f218 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -58,7 +58,10 @@ struct private_x509_ocsp_response_t { int signatureAlgorithm; /** - * signature value + * signature enumerator = this->responses->create_enumerator(this->responses); + while (enumerator->enumerate(enumerator, &response)) + { + value */ chunk_t signature; @@ -420,7 +423,7 @@ static bool parse_singleResponse(private_x509_ocsp_response_t *this, } break; case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN: - response->status = VALIDATION_FAILED; + response->status = VALIDATION_UNKNOWN; break; case SINGLE_RESPONSE_THIS_UPDATE: response->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME); @@ -725,13 +728,25 @@ static public_key_t* get_public_key(private_x509_ocsp_response_t *this) } /** - * Implementation of x509_cert_t.get_validity. + * Implementation of certificate_t.get_validity. */ static bool get_validity(private_x509_ocsp_response_t *this, time_t *when, time_t *not_before, time_t *not_after) { + enumerator_t *enumerator; + single_response_t *response; + time_t thisUpdate = this->producedAt; + time_t nextUpdate = 0; time_t t; + enumerator = this->responses->create_enumerator(this->responses); + if (enumerator->enumerate(enumerator, &response)) + { + thisUpdate = response->thisUpdate; + nextUpdate = response->nextUpdate; + } + enumerator->destroy(enumerator); + if (when == NULL) { t = time(NULL); @@ -742,18 +757,30 @@ static bool get_validity(private_x509_ocsp_response_t *this, time_t *when, } if (not_before) { - *not_before = this->producedAt; + *not_before = thisUpdate; } if (not_after) { - *not_after = ~0; + *not_after = nextUpdate; } - /* valid from produceAt up to infinity */ - if (t >= this->producedAt) - { - return TRUE; - } - return FALSE; + return (t < nextUpdate); +} + +/** + * Implementation of certificate_t.is_newer. + */ +static bool is_newer(certificate_t *this, certificate_t *that) +{ + time_t this_update, that_update, now = time(NULL); + bool new; + + this->get_validity(this, &now, &this_update, NULL); + that->get_validity(that, &now, &that_update, NULL); + new = this_update > that_update; + DBG1(" ocsp response from %#T is %s - existing ocsp response from %#T %s", + &this_update, FALSE, new ? "newer":"not newer", + &that_update, FALSE, new ? "replaced":"retained"); + return new; } /** @@ -828,6 +855,7 @@ static x509_ocsp_response_t *load(chunk_t data) this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer,bool))issued_by; this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key; this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity; + this->public.interface.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer; this->public.interface.certificate.get_encoding = (chunk_t(*)(certificate_t*))get_encoding; this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals; this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref; |