summaryrefslogtreecommitdiff
path: root/src/libstrongswan/credentials/sets
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/credentials/sets')
-rw-r--r--src/libstrongswan/credentials/sets/cert_cache.c17
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.c19
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.h12
3 files changed, 41 insertions, 7 deletions
diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c
index 563f4bdd5..60720dc57 100644
--- a/src/libstrongswan/credentials/sets/cert_cache.c
+++ b/src/libstrongswan/credentials/sets/cert_cache.c
@@ -143,6 +143,7 @@ METHOD(cert_cache_t, issued_by, bool,
private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer,
signature_scheme_t *schemep)
{
+ certificate_t *cached_issuer = NULL;
relation_t *found = NULL, *current;
signature_scheme_t scheme;
int i;
@@ -154,39 +155,41 @@ METHOD(cert_cache_t, issued_by, bool,
current->lock->read_lock(current->lock);
if (current->subject)
{
- /* check for equal issuer */
if (issuer->equals(issuer, current->issuer))
{
- /* reuse issuer instance in cache() */
- issuer = current->issuer;
if (subject->equals(subject, current->subject))
{
- /* write hit counter is not locked, but not critical */
current->hits++;
- found = current;;
+ found = current;
if (schemep)
{
*schemep = current->scheme;
}
}
+ else if (!cached_issuer)
+ {
+ cached_issuer = current->issuer->get_ref(current->issuer);
+ }
}
}
current->lock->unlock(current->lock);
if (found)
{
+ DESTROY_IF(cached_issuer);
return TRUE;
}
}
- /* no cache hit, check and cache signature */
if (subject->issued_by(subject, issuer, &scheme))
{
- cache(this, subject, issuer, scheme);
+ cache(this, subject, cached_issuer ?: issuer, scheme);
if (schemep)
{
*schemep = scheme;
}
+ DESTROY_IF(cached_issuer);
return TRUE;
}
+ DESTROY_IF(cached_issuer);
return FALSE;
}
diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c
index d8f568d36..7ad011b5e 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.c
+++ b/src/libstrongswan/credentials/sets/mem_cred.c
@@ -192,6 +192,24 @@ METHOD(mem_cred_t, add_cert_ref, certificate_t*,
return add_cert_internal(this, trusted, cert);
}
+METHOD(mem_cred_t, get_cert_ref, certificate_t*,
+ private_mem_cred_t *this, certificate_t *cert)
+{
+ certificate_t *cached;
+
+ this->lock->write_lock(this->lock);
+ if (this->untrusted->find_first(this->untrusted,
+ (linked_list_match_t)certificate_equals,
+ (void**)&cached, cert) == SUCCESS)
+ {
+ cert->destroy(cert);
+ cert = cached->get_ref(cached);
+ }
+ this->lock->unlock(this->lock);
+
+ return cert;
+}
+
METHOD(mem_cred_t, add_crl, bool,
private_mem_cred_t *this, crl_t *crl)
{
@@ -736,6 +754,7 @@ mem_cred_t *mem_cred_create()
},
.add_cert = _add_cert,
.add_cert_ref = _add_cert_ref,
+ .get_cert_ref = _get_cert_ref,
.add_crl = _add_crl,
.add_key = _add_key,
.add_shared = _add_shared,
diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h
index d0dd51da1..3ce815abc 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.h
+++ b/src/libstrongswan/credentials/sets/mem_cred.h
@@ -59,6 +59,18 @@ struct mem_cred_t {
certificate_t *cert);
/**
+ * Get an existing reference to the same certificate.
+ *
+ * Searches for the same certficate in the set, and returns a reference
+ * to it, destroying the passed certificate. If the passed certificate
+ * is not found, it is just returned.
+ *
+ * @param cert certificate to look up
+ * @return the same certificate, potentially different instance
+ */
+ certificate_t* (*get_cert_ref)(mem_cred_t *this, certificate_t *cert);
+
+ /**
* Add an X.509 CRL to the credential set.
*
* @param crl CRL, gets owned by set