summaryrefslogtreecommitdiff
path: root/src/libstrongswan/credentials
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-04-11 22:03:59 +0200
committerYves-Alexis Perez <corsac@debian.org>2015-04-11 22:03:59 +0200
commit83b8aebb19fe6e49e13a05d4e8f5ab9a06177642 (patch)
tree51255545ba43b84aa5d673bd0eb557cbd0155c9e /src/libstrongswan/credentials
parent2b8de74ff4c334c25e89988c4a401b24b5bcf03d (diff)
downloadvyos-strongswan-83b8aebb19fe6e49e13a05d4e8f5ab9a06177642.tar.gz
vyos-strongswan-83b8aebb19fe6e49e13a05d4e8f5ab9a06177642.zip
Imported Upstream version 5.3.0
Diffstat (limited to 'src/libstrongswan/credentials')
-rw-r--r--src/libstrongswan/credentials/auth_cfg.c60
-rw-r--r--src/libstrongswan/credentials/auth_cfg.h4
-rw-r--r--src/libstrongswan/credentials/cred_encoding.h4
-rw-r--r--src/libstrongswan/credentials/credential_manager.c3
-rw-r--r--src/libstrongswan/credentials/keys/public_key.c168
-rw-r--r--src/libstrongswan/credentials/keys/public_key.h41
-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
9 files changed, 292 insertions, 36 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index db08c6b96..0ca45a15b 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2007-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -49,6 +49,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
"RULE_GROUP",
"RULE_RSA_STRENGTH",
"RULE_ECDSA_STRENGTH",
+ "RULE_BLISS_STRENGTH",
"RULE_SIGNATURE_SCHEME",
"RULE_CERT_POLICY",
"HELPER_IM_CERT",
@@ -71,6 +72,7 @@ static inline bool is_multi_value_rule(auth_rule_t type)
case AUTH_RULE_EAP_VENDOR:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_IDENTITY:
case AUTH_RULE_IDENTITY_LOOSE:
case AUTH_RULE_EAP_IDENTITY:
@@ -207,6 +209,7 @@ static void init_entry(entry_t *this, auth_rule_t type, va_list args)
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
/* integer type */
this->value = (void*)(uintptr_t)va_arg(args, u_int);
@@ -255,6 +258,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2)
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
{
return e1->value == e2->value;
@@ -345,6 +349,7 @@ static void destroy_entry_value(entry_t *entry)
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
case AUTH_RULE_MAX:
break;
@@ -376,6 +381,7 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
/* integer type */
entry->value = (void*)(uintptr_t)va_arg(args, u_int);
@@ -450,6 +456,7 @@ METHOD(auth_cfg_t, get, void*,
case AUTH_RULE_EAP_VENDOR:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
return (void*)0;
case AUTH_RULE_SIGNATURE_SCHEME:
return (void*)HASH_UNKNOWN;
@@ -513,6 +520,7 @@ METHOD(auth_cfg_t, complies, bool,
signature_scheme_t scheme = SIGN_UNKNOWN;
u_int strength = 0;
auth_rule_t t1, t2;
+ char *key_type;
void *value;
e1 = constraints->create_enumerator(constraints);
@@ -703,6 +711,7 @@ METHOD(auth_cfg_t, complies, bool,
}
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
{
strength = (uintptr_t)value;
break;
@@ -797,30 +806,39 @@ METHOD(auth_cfg_t, complies, bool,
e2 = create_enumerator(this);
while (e2->enumerate(e2, &t2, &strength))
{
- if (t2 == AUTH_RULE_RSA_STRENGTH ||
- t2 == AUTH_RULE_ECDSA_STRENGTH)
+ switch (t2)
{
- success = FALSE;
- e1 = constraints->create_enumerator(constraints);
- while (e1->enumerate(e1, &t1, &value))
+ default:
+ continue;
+ case AUTH_RULE_RSA_STRENGTH:
+ key_type = "RSA";
+ break;
+ case AUTH_RULE_ECDSA_STRENGTH:
+ key_type = "ECDSA";
+ break;
+ case AUTH_RULE_BLISS_STRENGTH:
+ key_type = "BLISS";
+ break;
+ }
+ success = FALSE;
+ e1 = constraints->create_enumerator(constraints);
+ while (e1->enumerate(e1, &t1, &value))
+ {
+ if (t1 == t2 && (uintptr_t)value <= strength)
{
- if (t1 == t2 && (uintptr_t)value <= strength)
- {
- success = TRUE;
- break;
- }
+ success = TRUE;
+ break;
}
- e1->destroy(e1);
- if (!success)
+ }
+ e1->destroy(e1);
+ if (!success)
+ {
+ if (log_error)
{
- if (log_error)
- {
- DBG1(DBG_CFG, "%s-%d signatures not acceptable",
- t2 == AUTH_RULE_RSA_STRENGTH ? "RSA" : "ECDSA",
- strength);
- }
- break;
+ DBG1(DBG_CFG, "%s-%d signatures not acceptable",
+ key_type, strength);
}
+ break;
}
}
e2->destroy(e2);
@@ -891,6 +909,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
case AUTH_RULE_EAP_VENDOR:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
{
add(this, type, (uintptr_t)value);
@@ -1060,6 +1079,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*,
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
clone->add(clone, type, (uintptr_t)value);
break;
diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h
index 95b36d706..53f1b3805 100644
--- a/src/libstrongswan/credentials/auth_cfg.h
+++ b/src/libstrongswan/credentials/auth_cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2007-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -102,6 +102,8 @@ enum auth_rule_t {
AUTH_RULE_RSA_STRENGTH,
/** required ECDSA public key strength, u_int in bits */
AUTH_RULE_ECDSA_STRENGTH,
+ /** required BLISS public key strength, u_int in bits */
+ AUTH_RULE_BLISS_STRENGTH,
/** required signature scheme, signature_scheme_t */
AUTH_RULE_SIGNATURE_SCHEME,
/** certificatePolicy constraint, numerical OID as char* */
diff --git a/src/libstrongswan/credentials/cred_encoding.h b/src/libstrongswan/credentials/cred_encoding.h
index a6c9c30af..b4d1f4c3c 100644
--- a/src/libstrongswan/credentials/cred_encoding.h
+++ b/src/libstrongswan/credentials/cred_encoding.h
@@ -144,6 +144,10 @@ enum cred_encoding_part_t {
CRED_PART_PKCS10_ASN1_DER,
/** a PGP encoded certificate */
CRED_PART_PGP_CERT,
+ /** a DER encoded BLISS public key */
+ CRED_PART_BLISS_PUB_ASN1_DER,
+ /** a DER encoded BLISS private key */
+ CRED_PART_BLISS_PRIV_ASN1_DER,
CRED_PART_END,
};
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
index b0c8e48ba..371e6404d 100644
--- a/src/libstrongswan/credentials/credential_manager.c
+++ b/src/libstrongswan/credentials/credential_manager.c
@@ -698,6 +698,9 @@ static void get_key_strength(certificate_t *cert, auth_cfg_t *auth)
case KEY_ECDSA:
auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
break;
+ case KEY_BLISS:
+ auth->add(auth, AUTH_RULE_BLISS_STRENGTH, strength);
+ break;
default:
break;
}
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index 37bba77d1..bd5915e60 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -1,6 +1,8 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -17,14 +19,15 @@
#include "public_key.h"
-ENUM(key_type_names, KEY_ANY, KEY_DSA,
+ENUM(key_type_names, KEY_ANY, KEY_BLISS,
"ANY",
"RSA",
"ECDSA",
- "DSA"
+ "DSA",
+ "BLISS"
);
-ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
+ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA512,
"UNKNOWN",
"RSA_EMSA_PKCS1_NULL",
"RSA_EMSA_PKCS1_MD5",
@@ -41,6 +44,9 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
"ECDSA-256",
"ECDSA-384",
"ECDSA-521",
+ "BLISS_WITH_SHA256",
+ "BLISS_WITH_SHA384",
+ "BLISS_WITH_SHA512",
);
ENUM(encryption_scheme_names, ENCRYPT_UNKNOWN, ENCRYPT_RSA_OAEP_SHA512,
@@ -130,8 +136,158 @@ signature_scheme_t signature_scheme_from_oid(int oid)
return SIGN_ECDSA_WITH_SHA384_DER;
case OID_ECDSA_WITH_SHA512:
return SIGN_ECDSA_WITH_SHA512_DER;
- default:
- return SIGN_UNKNOWN;
+ case OID_BLISS_PUBLICKEY:
+ case OID_BLISS_WITH_SHA512:
+ return SIGN_BLISS_WITH_SHA512;
+ case OID_BLISS_WITH_SHA256:
+ return SIGN_BLISS_WITH_SHA256;
+ case OID_BLISS_WITH_SHA384:
+ return SIGN_BLISS_WITH_SHA384;
}
+ return SIGN_UNKNOWN;
}
+/*
+ * Defined in header.
+ */
+int signature_scheme_to_oid(signature_scheme_t scheme)
+{
+ switch (scheme)
+ {
+ case SIGN_UNKNOWN:
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ case SIGN_ECDSA_WITH_NULL:
+ case SIGN_ECDSA_256:
+ case SIGN_ECDSA_384:
+ case SIGN_ECDSA_521:
+ break;
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return OID_MD5_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return OID_SHA1_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA224:
+ return OID_SHA224_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return OID_SHA256_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return OID_SHA384_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return OID_SHA512_WITH_RSA;
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ return OID_ECDSA_WITH_SHA1;
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ return OID_ECDSA_WITH_SHA256;
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ return OID_ECDSA_WITH_SHA384;
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ return OID_ECDSA_WITH_SHA512;
+ case SIGN_BLISS_WITH_SHA256:
+ return OID_BLISS_WITH_SHA256;
+ case SIGN_BLISS_WITH_SHA384:
+ return OID_BLISS_WITH_SHA384;
+ case SIGN_BLISS_WITH_SHA512:
+ return OID_BLISS_WITH_SHA512;
+ }
+ return OID_UNKNOWN;
+}
+
+/**
+ * Map for signature schemes to the key type and maximum key size allowed.
+ * We only cover schemes with hash algorithms supported by IKEv2 signature
+ * authentication.
+ */
+static struct {
+ signature_scheme_t scheme;
+ key_type_t type;
+ int max_keysize;
+} scheme_map[] = {
+ { SIGN_RSA_EMSA_PKCS1_SHA256, KEY_RSA, 3072 },
+ { SIGN_RSA_EMSA_PKCS1_SHA384, KEY_RSA, 7680 },
+ { SIGN_RSA_EMSA_PKCS1_SHA512, KEY_RSA, 0 },
+ { SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, 256 },
+ { SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, 384 },
+ { SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, 0 },
+ { SIGN_BLISS_WITH_SHA256, KEY_BLISS, 128 },
+ { SIGN_BLISS_WITH_SHA384, KEY_BLISS, 192 },
+ { SIGN_BLISS_WITH_SHA512, KEY_BLISS, 0 },
+};
+
+/**
+ * Private data for signature scheme enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ int index;
+ key_type_t type;
+ int size;
+} private_enumerator_t;
+
+METHOD(enumerator_t, signature_schemes_enumerate, bool,
+ private_enumerator_t *this, signature_scheme_t *scheme)
+{
+ while (++this->index < countof(scheme_map))
+ {
+ if (this->type == scheme_map[this->index].type &&
+ (this->size <= scheme_map[this->index].max_keysize ||
+ !scheme_map[this->index].max_keysize))
+ {
+ *scheme = scheme_map[this->index].scheme;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Defined in header.
+ */
+enumerator_t *signature_schemes_for_key(key_type_t type, int size)
+{
+ private_enumerator_t *this;
+
+ INIT(this,
+ .public = {
+ .enumerate = (void*)_signature_schemes_enumerate,
+ .destroy = (void*)free,
+ },
+ .index = -1,
+ .type = type,
+ .size = size,
+ );
+
+ return &this->public;
+}
+
+/*
+ * Defined in header.
+ */
+key_type_t key_type_from_signature_scheme(signature_scheme_t scheme)
+{
+ switch (scheme)
+ {
+ case SIGN_UNKNOWN:
+ break;
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ case SIGN_RSA_EMSA_PKCS1_SHA224:
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return KEY_RSA;
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ case SIGN_ECDSA_WITH_NULL:
+ case SIGN_ECDSA_256:
+ case SIGN_ECDSA_384:
+ case SIGN_ECDSA_521:
+ return KEY_ECDSA;
+ case SIGN_BLISS_WITH_SHA256:
+ case SIGN_BLISS_WITH_SHA384:
+ case SIGN_BLISS_WITH_SHA512:
+ return KEY_BLISS;
+ }
+ return KEY_ANY;
+}
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
index 2afcf8325..66e98b294 100644
--- a/src/libstrongswan/credentials/keys/public_key.h
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -1,6 +1,8 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -42,6 +44,8 @@ enum key_type_t {
KEY_ECDSA = 2,
/** DSA */
KEY_DSA = 3,
+ /** BLISS */
+ KEY_BLISS = 4,
/** ElGamal, ... */
};
@@ -90,6 +94,12 @@ enum signature_scheme_t {
SIGN_ECDSA_384,
/** ECDSA on the P-521 curve with SHA-512 as in RFC 4754 */
SIGN_ECDSA_521,
+ /** BLISS with SHA-256 */
+ SIGN_BLISS_WITH_SHA256,
+ /** BLISS with SHA-384 */
+ SIGN_BLISS_WITH_SHA384,
+ /** BLISS with SHA-512 */
+ SIGN_BLISS_WITH_SHA512,
};
/**
@@ -234,8 +244,35 @@ bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint);
* Conversion of ASN.1 signature or hash OID to signature scheme.
*
* @param oid ASN.1 OID
- * @return signature_scheme, SIGN_UNKNOWN if OID is unsupported
+ * @return signature scheme, SIGN_UNKNOWN if OID is unsupported
*/
signature_scheme_t signature_scheme_from_oid(int oid);
+/**
+ * Conversion of signature scheme to ASN.1 signature OID.
+ *
+ * @param scheme signature scheme
+ * @return ASN.1 OID, OID_UNKNOWN if not supported
+ */
+int signature_scheme_to_oid(signature_scheme_t scheme);
+
+/**
+ * Enumerate signature schemes that are appropriate for a key of the given type
+ * and size|strength.
+ *
+ * @param type type of the key
+ * @param size size or strength of the key
+ * @return enumerator over signature_scheme_t (increasing strength)
+ */
+enumerator_t *signature_schemes_for_key(key_type_t type, int size);
+
+/**
+ * Determine the type of key associated with a given signature scheme.
+ *
+ * @param scheme signature scheme
+ * @return key type (could be KEY_ANY)
+ */
+key_type_t key_type_from_signature_scheme(signature_scheme_t scheme);
+
+
#endif /** PUBLIC_KEY_H_ @}*/
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