summaryrefslogtreecommitdiff
path: root/src/libstrongswan/credentials
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/credentials')
-rw-r--r--src/libstrongswan/credentials/auth_cfg.c65
-rw-r--r--src/libstrongswan/credentials/auth_cfg.h32
-rw-r--r--src/libstrongswan/credentials/builder.c6
-rw-r--r--src/libstrongswan/credentials/builder.h18
-rw-r--r--src/libstrongswan/credentials/credential_factory.c76
-rw-r--r--src/libstrongswan/credentials/credential_factory.h18
-rw-r--r--src/libstrongswan/credentials/credential_manager.c43
-rw-r--r--src/libstrongswan/credentials/keys/private_key.h10
-rw-r--r--src/libstrongswan/credentials/keys/public_key.c10
-rw-r--r--src/libstrongswan/credentials/keys/public_key.h36
-rw-r--r--src/libstrongswan/credentials/sets/callback_cred.c144
-rw-r--r--src/libstrongswan/credentials/sets/callback_cred.h67
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.c433
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.h77
14 files changed, 884 insertions, 151 deletions
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index 2573d0327..ce718b9cb 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -20,6 +20,7 @@
#include <debug.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
+#include <eap/eap.h>
#include <credentials/certificates/certificate.h>
ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP,
@@ -29,62 +30,6 @@ ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP,
"EAP",
);
-ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_GTC,
- "EAP_IDENTITY",
- "EAP_NOTIFICATION",
- "EAP_NAK",
- "EAP_MD5",
- "EAP_OTP",
- "EAP_GTC");
-ENUM_NEXT(eap_type_names, EAP_SIM, EAP_SIM, EAP_GTC,
- "EAP_SIM");
-ENUM_NEXT(eap_type_names, EAP_AKA, EAP_AKA, EAP_SIM,
- "EAP_AKA");
-ENUM_NEXT(eap_type_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
- "EAP_MSCHAPV2");
-ENUM_NEXT(eap_type_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
- "EAP_RADIUS",
- "EAP_EXPANDED",
- "EAP_EXPERIMENTAL");
-ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
-
-ENUM_BEGIN(eap_type_short_names, EAP_IDENTITY, EAP_GTC,
- "ID",
- "NTF",
- "NAK",
- "MD5",
- "OTP",
- "GTC");
-ENUM_NEXT(eap_type_short_names, EAP_SIM, EAP_SIM, EAP_GTC,
- "SIM");
-ENUM_NEXT(eap_type_short_names, EAP_AKA, EAP_AKA, EAP_SIM,
- "AKA");
-ENUM_NEXT(eap_type_short_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
- "MSCHAPV2");
-ENUM_NEXT(eap_type_short_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
- "RAD",
- "EXP",
- "XP");
-ENUM_END(eap_type_short_names, EAP_EXPERIMENTAL);
-
-ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
- "RULE_IDENTITY",
- "RULE_AUTH_CLASS",
- "RULE_EAP_IDENTITY",
- "RULE_EAP_TYPE",
- "RULE_EAP_VENDOR",
- "RULE_CA_CERT",
- "RULE_IM_CERT",
- "RULE_SUBJECT_CERT",
- "RULE_CRL_VALIDATION",
- "RULE_OCSP_VALIDATION",
- "RULE_GROUP",
- "HELPER_IM_CERT",
- "HELPER_SUBJECT_CERT",
- "HELPER_IM_HASH_URL",
- "HELPER_SUBJECT_HASH_URL",
-);
-
typedef struct private_auth_cfg_t private_auth_cfg_t;
/**
@@ -174,6 +119,7 @@ static void destroy_entry_value(entry_t *entry)
{
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
case AUTH_RULE_GROUP:
{
identification_t *id = (identification_t*)entry->value;
@@ -231,6 +177,7 @@ static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
break;
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
case AUTH_RULE_GROUP:
case AUTH_RULE_CA_CERT:
case AUTH_RULE_IM_CERT:
@@ -296,6 +243,7 @@ static void* get(private_auth_cfg_t *this, auth_rule_t type)
return (void*)VALIDATION_FAILED;
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
case AUTH_RULE_GROUP:
case AUTH_RULE_CA_CERT:
case AUTH_RULE_IM_CERT:
@@ -331,6 +279,7 @@ static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
break;
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
case AUTH_RULE_GROUP:
case AUTH_RULE_CA_CERT:
case AUTH_RULE_IM_CERT:
@@ -445,6 +394,7 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
}
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
{
identification_t *id1, *id2;
@@ -590,6 +540,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
}
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
case AUTH_RULE_GROUP:
{
identification_t *id = (identification_t*)value;
@@ -677,6 +628,7 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
}
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
case AUTH_RULE_GROUP:
{
identification_t *id1, *id2;
@@ -761,6 +713,7 @@ static auth_cfg_t* clone_(private_auth_cfg_t *this)
{
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
case AUTH_RULE_GROUP:
{
identification_t *id = (identification_t*)entry->value;
diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h
index 713e16372..19624a2fe 100644
--- a/src/libstrongswan/credentials/auth_cfg.h
+++ b/src/libstrongswan/credentials/auth_cfg.h
@@ -27,7 +27,6 @@
typedef struct auth_cfg_t auth_cfg_t;
typedef enum auth_rule_t auth_rule_t;
typedef enum auth_class_t auth_class_t;
-typedef enum eap_type_t eap_type_t;
/**
* Class of authentication to use. This is different to auth_method_t in that
@@ -51,35 +50,6 @@ enum auth_class_t {
extern enum_name_t *auth_class_names;
/**
- * EAP types, defines the EAP method implementation
- */
-enum eap_type_t {
- EAP_IDENTITY = 1,
- EAP_NOTIFICATION = 2,
- EAP_NAK = 3,
- EAP_MD5 = 4,
- EAP_OTP = 5,
- EAP_GTC = 6,
- EAP_SIM = 18,
- EAP_AKA = 23,
- EAP_MSCHAPV2 = 26,
- /** not a method, but an implementation providing different methods */
- EAP_RADIUS = 253,
- EAP_EXPANDED = 254,
- EAP_EXPERIMENTAL = 255,
-};
-
-/**
- * enum names for eap_type_t.
- */
-extern enum_name_t *eap_type_names;
-
-/**
- * short string enum names for eap_type_t.
- */
-extern enum_name_t *eap_type_short_names;
-
-/**
* Authentication config to use during authentication process.
*
* Each authentication config contains a set of rules. These rule-sets are used
@@ -98,6 +68,8 @@ enum auth_rule_t {
AUTH_RULE_IDENTITY,
/** authentication class, auth_class_t */
AUTH_RULE_AUTH_CLASS,
+ /** AAA-backend identity for EAP methods supporting it, identification_t* */
+ AUTH_RULE_AAA_IDENTITY,
/** EAP identity to use within EAP-Identity exchange, identification_t* */
AUTH_RULE_EAP_IDENTITY,
/** EAP type to propose for peer authentication, eap_type_t */
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
index cfb708e33..c43e5fd5d 100644
--- a/src/libstrongswan/credentials/builder.c
+++ b/src/libstrongswan/credentials/builder.c
@@ -45,8 +45,10 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_PATHLEN",
"BUILD_X509_FLAG",
"BUILD_REVOKED_ENUMERATOR",
- "BUILD_SMARTCARD_KEYID",
- "BUILD_SMARTCARD_PIN",
+ "BUILD_CHALLENGE_PWD",
+ "BUILD_PKCS11_MODULE",
+ "BUILD_PKCS11_SLOT",
+ "BUILD_PKCS11_KEYID",
"BUILD_RSA_MODULUS",
"BUILD_RSA_PUB_EXP",
"BUILD_RSA_PRIV_EXP",
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
index ffb09f72a..dc87da2a4 100644
--- a/src/libstrongswan/credentials/builder.h
+++ b/src/libstrongswan/credentials/builder.h
@@ -57,12 +57,6 @@ enum builder_part_t {
BUILD_BLOB_PGP,
/** DNS public key blob (RFC 4034, RSA specifc RFC 3110), chunk_t */
BUILD_BLOB_DNSKEY,
- /** passphrase for e.g. PEM decryption, chunk_t */
- BUILD_PASSPHRASE,
- /** passphrase callback, chunk_t(*fn)(void *user, int try), void *user.
- * The callback is invoked until the returned passphrase is accepted, or
- * a zero-length passphrase is returned. Try starts at 1. */
- BUILD_PASSPHRASE_CALLBACK,
/** key size in bits, as used for key generation, u_int */
BUILD_KEY_SIZE,
/** private key to use for signing, private_key_t* */
@@ -103,10 +97,14 @@ enum builder_part_t {
BUILD_X509_FLAG,
/** enumerator_t over (chunk_t serial, time_t date, crl_reason_t reason) */
BUILD_REVOKED_ENUMERATOR,
- /** key ID of a key on a smartcard, null terminated char* ([slot:]keyid) */
- BUILD_SMARTCARD_KEYID,
- /** pin to access a key on a smartcard, null terminated char* */
- BUILD_SMARTCARD_PIN,
+ /** PKCS#10 challenge password */
+ BUILD_CHALLENGE_PWD,
+ /** friendly name of a PKCS#11 module, null terminated char* */
+ BUILD_PKCS11_MODULE,
+ /** slot specifier for a token in a PKCS#11 module, int */
+ BUILD_PKCS11_SLOT,
+ /** key ID of a key on a token, chunk_t */
+ BUILD_PKCS11_KEYID,
/** modulus (n) of a RSA key, chunk_t */
BUILD_RSA_MODULUS,
/** public exponent (e) of a RSA key, chunk_t */
diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c
index 7cc7dbe0e..ff621012f 100644
--- a/src/libstrongswan/credentials/credential_factory.c
+++ b/src/libstrongswan/credentials/credential_factory.c
@@ -64,32 +64,29 @@ struct entry_t {
credential_type_t type;
/** subtype of credential, e.g. certificate_type_t */
int subtype;
+ /** registered with final flag? */
+ bool final;
/** builder function */
builder_function_t constructor;
};
-/**
- * Implementation of credential_factory_t.add_builder_constructor.
- */
-static void add_builder(private_credential_factory_t *this,
- credential_type_t type, int subtype,
- builder_function_t constructor)
+METHOD(credential_factory_t, add_builder, void,
+ private_credential_factory_t *this, credential_type_t type, int subtype,
+ bool final, builder_function_t constructor)
{
entry_t *entry = malloc_thing(entry_t);
entry->type = type;
entry->subtype = subtype;
+ entry->final = final;
entry->constructor = constructor;
this->lock->write_lock(this->lock);
this->constructors->insert_last(this->constructors, entry);
this->lock->unlock(this->lock);
}
-/**
- * Implementation of credential_factory_t.remove_builder.
- */
-static void remove_builder(private_credential_factory_t *this,
- builder_function_t constructor)
+METHOD(credential_factory_t, remove_builder, void,
+ private_credential_factory_t *this, builder_function_t constructor)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -108,11 +105,8 @@ static void remove_builder(private_credential_factory_t *this,
this->lock->unlock(this->lock);
}
-/**
- * Implementation of credential_factory_t.create.
- */
-static void* create(private_credential_factory_t *this, credential_type_t type,
- int subtype, ...)
+METHOD(credential_factory_t, create, void*,
+ private_credential_factory_t *this, credential_type_t type, int subtype, ...)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -159,9 +153,31 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
}
/**
- * Implementation of credential_factory_t.destroy
+ * Filter function for builder enumerator
*/
-static void destroy(private_credential_factory_t *this)
+static bool builder_filter(void *null, entry_t **entry, credential_type_t *type,
+ void *dummy1, int *subtype)
+{
+ if ((*entry)->final)
+ {
+ *type = (*entry)->type;
+ *subtype = (*entry)->subtype;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(credential_factory_t, create_builder_enumerator, enumerator_t*,
+ private_credential_factory_t *this)
+{
+ this->lock->read_lock(this->lock);
+ return enumerator_create_filter(
+ this->constructors->create_enumerator(this->constructors),
+ (void*)builder_filter, this->lock, (void*)this->lock->unlock);
+}
+
+METHOD(credential_factory_t, destroy, void,
+ private_credential_factory_t *this)
{
this->constructors->destroy_function(this->constructors, free);
this->recursive->destroy(this->recursive);
@@ -174,16 +190,20 @@ static void destroy(private_credential_factory_t *this)
*/
credential_factory_t *credential_factory_create()
{
- private_credential_factory_t *this = malloc_thing(private_credential_factory_t);
-
- this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create;
- this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_function_t constructor))add_builder;
- this->public.remove_builder = (void(*)(credential_factory_t*,builder_function_t constructor))remove_builder;
- this->public.destroy = (void(*)(credential_factory_t*))destroy;
-
- this->constructors = linked_list_create();
- this->recursive = thread_value_create(NULL);
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+ private_credential_factory_t *this;
+
+ INIT(this,
+ .public = {
+ .create = _create,
+ .create_builder_enumerator = _create_builder_enumerator,
+ .add_builder = _add_builder,
+ .remove_builder = _remove_builder,
+ .destroy = _destroy,
+ },
+ .constructors = linked_list_create(),
+ .recursive = thread_value_create(NULL),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
return &this->public;
}
diff --git a/src/libstrongswan/credentials/credential_factory.h b/src/libstrongswan/credentials/credential_factory.h
index e8ffb6b9d..709dc916a 100644
--- a/src/libstrongswan/credentials/credential_factory.h
+++ b/src/libstrongswan/credentials/credential_factory.h
@@ -68,11 +68,17 @@ struct credential_factory_t {
/**
* Register a credential builder function.
*
+ * The final flag indicates if the registered builder can build such
+ * a credential itself the most common encoding, without the need
+ * for an additional builder.
+ *
* @param type type of credential the builder creates
+ * @param subtype subtype of the credential, type specific
+ * @param final TRUE if this build does not invoke other builders
* @param constructor builder constructor function to register
*/
void (*add_builder)(credential_factory_t *this,
- credential_type_t type, int subtype,
+ credential_type_t type, int subtype, bool final,
builder_function_t constructor);
/**
* Unregister a credential builder function.
@@ -83,6 +89,16 @@ struct credential_factory_t {
builder_function_t constructor);
/**
+ * Create an enumerator over registered builder types.
+ *
+ * The enumerator returns only builder types registered with the final
+ * flag set.
+ *
+ * @return enumerator (credential_type_t, int subtype)
+ */
+ enumerator_t* (*create_builder_enumerator)(credential_factory_t *this);
+
+ /**
* Destroy a credential_factory instance.
*/
void (*destroy)(credential_factory_t *this);
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
index 46c36c941..97e8d8887 100644
--- a/src/libstrongswan/credentials/credential_manager.c
+++ b/src/libstrongswan/credentials/credential_manager.c
@@ -157,8 +157,10 @@ static enumerator_t *create_sets_enumerator(private_credential_manager_t *this)
linked_list_t *local;
INIT(enumerator,
- .public.enumerate = (void*)_sets_enumerate,
- .public.destroy = _sets_destroy,
+ .public = {
+ .enumerate = (void*)_sets_enumerate,
+ .destroy = _sets_destroy,
+ },
.global = this->sets->create_enumerator(this->sets),
);
local = this->local_sets->get(this->local_sets);
@@ -822,7 +824,7 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*,
}
/**
- * Check if a certificate's keyid is contained in the auth helper
+ * Check if an helper contains a certificate as trust anchor
*/
static bool auth_contains_cacert(auth_cfg_t *auth, certificate_t *cert)
{
@@ -854,17 +856,10 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
certificate_t *issuer, *current;
auth_cfg_t *trustchain;
int pathlen = 0;
+ bool has_anchor;
trustchain = auth_cfg_create();
-
- current = auth->get(auth, AUTH_RULE_CA_CERT);
- if (!current)
- {
- /* no trust anchor specified, return this cert only */
- trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT,
- subject->get_ref(subject));
- return trustchain;
- }
+ has_anchor = auth->get(auth, AUTH_RULE_CA_CERT) != NULL;
current = subject->get_ref(subject);
while (TRUE)
{
@@ -879,17 +874,33 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
}
else
{
+ if (!has_anchor &&
+ this->cache->issued_by(this->cache, current, current))
+ { /* If no trust anchor specified, accept any CA */
+ trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
+ return trustchain;
+ }
trustchain->add(trustchain, AUTH_RULE_IM_CERT, current);
}
+ if (pathlen++ > MAX_TRUST_PATH_LEN)
+ {
+ break;
+ }
issuer = get_issuer_cert(this, current, FALSE);
- if (!issuer || issuer->equals(issuer, current) ||
- pathlen > MAX_TRUST_PATH_LEN)
+ if (!issuer)
{
- DESTROY_IF(issuer);
+ if (!has_anchor)
+ { /* If no trust anchor specified, accept incomplete chains */
+ return trustchain;
+ }
+ break;
+ }
+ if (has_anchor && issuer->equals(issuer, current))
+ {
+ issuer->destroy(issuer);
break;
}
current = issuer;
- pathlen++;
}
trustchain->destroy(trustchain);
return NULL;
diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h
index 27f4ab098..e57d3f5a5 100644
--- a/src/libstrongswan/credentials/keys/private_key.h
+++ b/src/libstrongswan/credentials/keys/private_key.h
@@ -51,18 +51,20 @@ struct private_key_t {
/**
* Decrypt a chunk of data.
*
+ * @param scheme expected encryption scheme used
* @param crypto chunk containing encrypted data
* @param plain where to allocate decrypted data
* @return TRUE if data decrypted and plaintext allocated
*/
- bool (*decrypt)(private_key_t *this, chunk_t crypto, chunk_t *plain);
+ bool (*decrypt)(private_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain);
/**
- * Get the strength of the key in bytes.
+ * Get the strength of the key in bits.
*
- * @return strength of the key in bytes
+ * @return strength of the key in bits
*/
- size_t (*get_keysize) (private_key_t *this);
+ int (*get_keysize) (private_key_t *this);
/**
* Get the public part from the private key.
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index ce342de33..22df5dd1b 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -42,6 +42,16 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
"ECDSA-521",
);
+ENUM(encryption_scheme_names, ENCRYPT_UNKNOWN, ENCRYPT_RSA_OAEP_SHA512,
+ "ENCRYPT_UNKNOWN",
+ "ENCRYPT_RSA_PKCS1",
+ "ENCRYPT_RSA_OAEP_SHA1",
+ "ENCRYPT_RSA_OAEP_SHA224",
+ "ENCRYPT_RSA_OAEP_SHA256",
+ "ENCRYPT_RSA_OAEP_SHA384",
+ "ENCRYPT_RSA_OAEP_SHA512",
+);
+
/**
* See header.
*/
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
index ff827a189..d20d2736b 100644
--- a/src/libstrongswan/credentials/keys/public_key.h
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -24,6 +24,7 @@
typedef struct public_key_t public_key_t;
typedef enum key_type_t key_type_t;
typedef enum signature_scheme_t signature_scheme_t;
+typedef enum encryption_scheme_t encryption_scheme_t;
#include <library.h>
#include <utils/identification.h>
@@ -97,6 +98,31 @@ enum signature_scheme_t {
extern enum_name_t *signature_scheme_names;
/**
+ * Encryption scheme for public key data encryption.
+ */
+enum encryption_scheme_t {
+ /** Unknown encryption scheme */
+ ENCRYPT_UNKNOWN,
+ /** RSAES-PKCS1-v1_5 as in PKCS#1 */
+ ENCRYPT_RSA_PKCS1,
+ /** RSAES-OAEP as in PKCS#1, using SHA1 as hash, no label */
+ ENCRYPT_RSA_OAEP_SHA1,
+ /** RSAES-OAEP as in PKCS#1, using SHA-224 as hash, no label */
+ ENCRYPT_RSA_OAEP_SHA224,
+ /** RSAES-OAEP as in PKCS#1, using SHA-256 as hash, no label */
+ ENCRYPT_RSA_OAEP_SHA256,
+ /** RSAES-OAEP as in PKCS#1, using SHA-384 as hash, no label */
+ ENCRYPT_RSA_OAEP_SHA384,
+ /** RSAES-OAEP as in PKCS#1, using SHA-512 as hash, no label */
+ ENCRYPT_RSA_OAEP_SHA512,
+};
+
+/**
+ * Enum names for encryption_scheme_t
+ */
+extern enum_name_t *encryption_scheme_names;
+
+/**
* Abstract interface of a public key.
*/
struct public_key_t {
@@ -122,11 +148,13 @@ struct public_key_t {
/**
* Encrypt a chunk of data.
*
+ * @param scheme encryption scheme to use
* @param plain chunk containing plaintext data
* @param crypto where to allocate encrypted data
* @return TRUE if data successfully encrypted
*/
- bool (*encrypt)(public_key_t *this, chunk_t plain, chunk_t *crypto);
+ bool (*encrypt)(public_key_t *this, encryption_scheme_t scheme,
+ chunk_t plain, chunk_t *crypto);
/**
* Check if two public keys are equal.
@@ -137,11 +165,11 @@ struct public_key_t {
bool (*equals)(public_key_t *this, public_key_t *other);
/**
- * Get the strength of the key in bytes.
+ * Get the strength of the key in bits.
*
- * @return strength of the key in bytes
+ * @return strength of the key in bits
*/
- size_t (*get_keysize) (public_key_t *this);
+ int (*get_keysize) (public_key_t *this);
/**
* Get the fingerprint of the key.
diff --git a/src/libstrongswan/credentials/sets/callback_cred.c b/src/libstrongswan/credentials/sets/callback_cred.c
new file mode 100644
index 000000000..bff33f029
--- /dev/null
+++ b/src/libstrongswan/credentials/sets/callback_cred.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "callback_cred.h"
+
+typedef struct private_callback_cred_t private_callback_cred_t;
+
+/**
+ * Private data of an callback_cred_t object.
+ */
+struct private_callback_cred_t {
+
+ /**
+ * Public callback_cred_t interface.
+ */
+ callback_cred_t public;
+
+ /**
+ * Callback of this set, for all types, and generic
+ */
+ union {
+ void *generic;
+ callback_cred_shared_cb_t shared;
+ } cb;
+
+ /**
+ * Data to pass to callback
+ */
+ void *data;
+};
+
+/**
+ * Shared key enumerator on callbacks
+ */
+typedef struct {
+ /* implements enumerator_t */
+ enumerator_t public;
+ /* backref to this */
+ private_callback_cred_t *this;
+ /* type if requested key */
+ shared_key_type_t type;
+ /* own identity to match */
+ identification_t *me;
+ /* other identity to match */
+ identification_t *other;
+ /* current shared key */
+ shared_key_t *current;
+} shared_enumerator_t;
+
+METHOD(enumerator_t, shared_enumerate, bool,
+ shared_enumerator_t *this, shared_key_t **out,
+ id_match_t *match_me, id_match_t *match_other)
+{
+ DESTROY_IF(this->current);
+ this->current = this->this->cb.shared(this->this->data, this->type,
+ this->me, this->other, match_me, match_other);
+ if (this->current)
+ {
+ *out = this->current;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(enumerator_t, shared_destroy, void,
+ shared_enumerator_t *this)
+{
+ DESTROY_IF(this->current);
+ free(this);
+}
+
+METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
+ private_callback_cred_t *this, shared_key_type_t type,
+ identification_t *me, identification_t *other)
+{
+ shared_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_shared_enumerate,
+ .destroy = _shared_destroy,
+ },
+ .this = this,
+ .type = type,
+ .me = me,
+ .other = other,
+ );
+ return &enumerator->public;
+}
+
+METHOD(callback_cred_t, destroy, void,
+ private_callback_cred_t *this)
+{
+ free(this);
+}
+
+/**
+ * Create a generic callback credential set
+ */
+static private_callback_cred_t* create_generic(void *cb, void *data)
+{
+ private_callback_cred_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_shared_enumerator = (void*)return_null,
+ .create_private_enumerator = (void*)return_null,
+ .create_cert_enumerator = (void*)return_null,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .cb.generic = cb,
+ .data = data,
+ );
+ return this;
+}
+
+/**
+ * See header
+ */
+callback_cred_t *callback_cred_create_shared(callback_cred_shared_cb_t cb,
+ void *data)
+{
+ private_callback_cred_t *this = create_generic(cb, data);
+
+ this->public.set.create_shared_enumerator = _create_shared_enumerator;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/credentials/sets/callback_cred.h b/src/libstrongswan/credentials/sets/callback_cred.h
new file mode 100644
index 000000000..efc4c7fa5
--- /dev/null
+++ b/src/libstrongswan/credentials/sets/callback_cred.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup callback_cred callback_cred
+ * @{ @ingroup sets
+ */
+
+#ifndef CALLBACK_CRED_H_
+#define CALLBACK_CRED_H_
+
+typedef struct callback_cred_t callback_cred_t;
+
+#include <credentials/credential_set.h>
+
+/**
+ * Callback function to get shared keys.
+ *
+ * @param type type of requested shared key
+ * @param me own identity
+ * @param other other identity
+ * @param match_me match result of own identity
+ * @param match_other match result of other identity
+ */
+typedef shared_key_t* (*callback_cred_shared_cb_t)(
+ void *data, shared_key_type_t type,
+ identification_t *me, identification_t *other,
+ id_match_t *match_me, id_match_t *match_other);
+
+/**
+ * Generic callbcack using user specified callback functions.
+ */
+struct callback_cred_t {
+
+ /**
+ * Implements credential_set_t.
+ */
+ credential_set_t set;
+
+ /**
+ * Destroy a callback_cred_t.
+ */
+ void (*destroy)(callback_cred_t *this);
+};
+
+/**
+ * Create a callback_cred instance, for a shared key.
+ *
+ * @param cb callback function
+ * @param data data to pass to callback
+ */
+callback_cred_t *callback_cred_create_shared(callback_cred_shared_cb_t cb,
+ void *data);
+
+#endif /** CALLBACK_CRED_H_ @}*/
diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c
new file mode 100644
index 000000000..c29a99f1f
--- /dev/null
+++ b/src/libstrongswan/credentials/sets/mem_cred.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "mem_cred.h"
+
+#include <threading/rwlock.h>
+#include <utils/linked_list.h>
+
+typedef struct private_mem_cred_t private_mem_cred_t;
+
+/**
+ * Private data of an mem_cred_t object.
+ */
+struct private_mem_cred_t {
+
+ /**
+ * Public mem_cred_t interface.
+ */
+ mem_cred_t public;
+
+ /**
+ * Lock for this set
+ */
+ rwlock_t *lock;
+
+ /**
+ * List of trusted certificates, certificate_t
+ */
+ linked_list_t *trusted;
+
+ /**
+ * List of trusted and untrusted certificates, certificate_t
+ */
+ linked_list_t *untrusted;
+
+ /**
+ * List of private keys, private_key_t
+ */
+ linked_list_t *keys;
+
+ /**
+ * List of shared keys, as shared_entry_t
+ */
+ linked_list_t *shared;
+};
+
+/**
+ * Data for the certificate enumerator
+ */
+typedef struct {
+ rwlock_t *lock;
+ certificate_type_t cert;
+ key_type_t key;
+ identification_t *id;
+} cert_data_t;
+
+/**
+ * destroy cert_data
+ */
+static void cert_data_destroy(cert_data_t *data)
+{
+ data->lock->unlock(data->lock);
+ free(data);
+}
+
+/**
+ * filter function for certs enumerator
+ */
+static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t **out)
+{
+ public_key_t *public;
+ certificate_t *cert = *in;
+
+ if (data->cert == CERT_ANY || data->cert == cert->get_type(cert))
+ {
+ public = cert->get_public_key(cert);
+ if (public)
+ {
+ if (data->key == KEY_ANY || data->key == public->get_type(public))
+ {
+ if (data->id && public->has_fingerprint(public,
+ data->id->get_encoding(data->id)))
+ {
+ public->destroy(public);
+ *out = *in;
+ return TRUE;
+ }
+ }
+ public->destroy(public);
+ }
+ else if (data->key != KEY_ANY)
+ {
+ return FALSE;
+ }
+ if (data->id == NULL || cert->has_subject(cert, data->id))
+ {
+ *out = *in;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+ private_mem_cred_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
+{
+ cert_data_t *data;
+ enumerator_t *enumerator;
+
+ INIT(data,
+ .lock = this->lock,
+ .cert = cert,
+ .key = key,
+ .id = id,
+ );
+ this->lock->read_lock(this->lock);
+ if (trusted)
+ {
+ enumerator = this->trusted->create_enumerator(this->trusted);
+ }
+ else
+ {
+ enumerator = this->untrusted->create_enumerator(this->untrusted);
+ }
+ return enumerator_create_filter(enumerator, (void*)certs_filter, data,
+ (void*)cert_data_destroy);
+}
+
+static bool certificate_equals(certificate_t *item, certificate_t *cert)
+{
+ return item->equals(item, cert);
+}
+
+METHOD(mem_cred_t, add_cert, void,
+ private_mem_cred_t *this, bool trusted, certificate_t *cert)
+{
+ this->lock->write_lock(this->lock);
+ if (this->untrusted->find_last(this->untrusted,
+ (linked_list_match_t)certificate_equals, NULL, cert) != SUCCESS)
+ {
+ if (trusted)
+ {
+ this->trusted->insert_last(this->trusted, cert->get_ref(cert));
+ }
+ this->untrusted->insert_last(this->untrusted, cert->get_ref(cert));
+ }
+ cert->destroy(cert);
+ this->lock->unlock(this->lock);
+}
+
+/**
+ * Data for key enumerator
+ */
+typedef struct {
+ rwlock_t *lock;
+ key_type_t type;
+ identification_t *id;
+} key_data_t;
+
+/**
+ * Destroy key enumerator data
+ */
+static void key_data_destroy(key_data_t *data)
+{
+ data->lock->unlock(data->lock);
+ free(data);
+}
+
+/**
+ * filter function for private key enumerator
+ */
+static bool key_filter(key_data_t *data, private_key_t **in, private_key_t **out)
+{
+ private_key_t *key;
+
+ key = *in;
+ if (data->type == KEY_ANY || data->type == key->get_type(key))
+ {
+ if (data->id == NULL ||
+ key->has_fingerprint(key, data->id->get_encoding(data->id)))
+ {
+ *out = key;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
+ private_mem_cred_t *this, key_type_t type, identification_t *id)
+{
+ key_data_t *data;
+
+ INIT(data,
+ .lock = this->lock,
+ .type = type,
+ .id = id,
+ );
+ this->lock->read_lock(this->lock);
+ return enumerator_create_filter(this->keys->create_enumerator(this->keys),
+ (void*)key_filter, data, (void*)key_data_destroy);
+}
+
+METHOD(mem_cred_t, add_key, void,
+ private_mem_cred_t *this, private_key_t *key)
+{
+ this->lock->write_lock(this->lock);
+ this->keys->insert_last(this->keys, key);
+ this->lock->unlock(this->lock);
+}
+
+/**
+ * Shared key entry
+ */
+typedef struct {
+ /* shared key */
+ shared_key_t *shared;
+ /* list of owners, identification_t */
+ linked_list_t *owners;
+} shared_entry_t;
+
+/**
+ * Clean up a shared entry
+ */
+static void shared_entry_destroy(shared_entry_t *entry)
+{
+ entry->owners->destroy_offset(entry->owners,
+ offsetof(identification_t, destroy));
+ entry->shared->destroy(entry->shared);
+ free(entry);
+}
+
+/**
+ * Data for the shared_key enumerator
+ */
+typedef struct {
+ rwlock_t *lock;
+ identification_t *me;
+ identification_t *other;
+ shared_key_type_t type;
+} shared_data_t;
+
+/**
+ * free shared key enumerator data and unlock list
+ */
+static void shared_data_destroy(shared_data_t *data)
+{
+ data->lock->unlock(data->lock);
+ free(data);
+}
+
+/**
+ * Get the best match of an owner in an entry.
+ */
+static id_match_t has_owner(shared_entry_t *entry, identification_t *owner)
+{
+ enumerator_t *enumerator;
+ id_match_t match, best = ID_MATCH_NONE;
+ identification_t *current;
+
+ enumerator = entry->owners->create_enumerator(entry->owners);
+ while (enumerator->enumerate(enumerator, &current))
+ {
+ match = owner->matches(owner, current);
+ if (match > best)
+ {
+ best = match;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return best;
+}
+
+/**
+ * enumerator filter function for shared entries
+ */
+static bool shared_filter(shared_data_t *data,
+ shared_entry_t **in, shared_key_t **out,
+ void **unused1, id_match_t *me,
+ void **unused2, id_match_t *other)
+{
+ id_match_t my_match = ID_MATCH_NONE, other_match = ID_MATCH_NONE;
+ shared_entry_t *entry = *in;
+
+ if (data->type != SHARED_ANY &&
+ entry->shared->get_type(entry->shared) != data->type)
+ {
+ return FALSE;
+ }
+ if (data->me)
+ {
+ my_match = has_owner(entry, data->me);
+ }
+ if (data->other)
+ {
+ other_match = has_owner(entry, data->other);
+ }
+ if ((data->me || data->other) && (!my_match && !other_match))
+ {
+ return FALSE;
+ }
+ *out = entry->shared;
+ if (me)
+ {
+ *me = my_match;
+ }
+ if (other)
+ {
+ *other = other_match;
+ }
+ return TRUE;
+}
+
+METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
+ private_mem_cred_t *this, shared_key_type_t type,
+ identification_t *me, identification_t *other)
+{
+ shared_data_t *data;
+
+ INIT(data,
+ .lock = this->lock,
+ .me = me,
+ .other = other,
+ .type = type,
+ );
+ data->lock->read_lock(data->lock);
+ return enumerator_create_filter(
+ this->shared->create_enumerator(this->shared),
+ (void*)shared_filter, data, (void*)shared_data_destroy);
+}
+
+METHOD(mem_cred_t, add_shared, void,
+ private_mem_cred_t *this, shared_key_t *shared, ...)
+{
+ shared_entry_t *entry;
+ identification_t *id;
+ va_list args;
+
+ INIT(entry,
+ .shared = shared,
+ .owners = linked_list_create(),
+ );
+
+ va_start(args, shared);
+ do
+ {
+ id = va_arg(args, identification_t*);
+ if (id)
+ {
+ entry->owners->insert_last(entry->owners, id);
+ }
+ }
+ while (id);
+ va_end(args);
+
+ this->lock->write_lock(this->lock);
+ this->shared->insert_last(this->shared, entry);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(mem_cred_t, clear_, void,
+ private_mem_cred_t *this)
+{
+ this->lock->write_lock(this->lock);
+ this->trusted->destroy_offset(this->trusted,
+ offsetof(certificate_t, destroy));
+ this->untrusted->destroy_offset(this->untrusted,
+ offsetof(certificate_t, destroy));
+ this->keys->destroy_offset(this->keys, offsetof(private_key_t, destroy));
+ this->shared->destroy_function(this->shared, (void*)shared_entry_destroy);
+ this->trusted = linked_list_create();
+ this->untrusted = linked_list_create();
+ this->keys = linked_list_create();
+ this->shared = linked_list_create();
+ this->lock->unlock(this->lock);
+}
+
+METHOD(mem_cred_t, destroy, void,
+ private_mem_cred_t *this)
+{
+ clear_(this);
+ this->trusted->destroy(this->trusted);
+ this->untrusted->destroy(this->untrusted);
+ this->keys->destroy(this->keys);
+ this->shared->destroy(this->shared);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/**
+ * See header
+ */
+mem_cred_t *mem_cred_create()
+{
+ private_mem_cred_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_shared_enumerator = _create_shared_enumerator,
+ .create_private_enumerator = _create_private_enumerator,
+ .create_cert_enumerator = _create_cert_enumerator,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .add_cert = _add_cert,
+ .add_key = _add_key,
+ .add_shared = _add_shared,
+ .clear = _clear_,
+ .destroy = _destroy,
+ },
+ .trusted = linked_list_create(),
+ .untrusted = linked_list_create(),
+ .keys = linked_list_create(),
+ .shared = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h
new file mode 100644
index 000000000..b26e43d6c
--- /dev/null
+++ b/src/libstrongswan/credentials/sets/mem_cred.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * 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
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup mem_cred mem_cred
+ * @{ @ingroup sets
+ */
+
+#ifndef MEM_CRED_H_
+#define MEM_CRED_H_
+
+typedef struct mem_cred_t mem_cred_t;
+
+#include <credentials/credential_set.h>
+
+/**
+ * Generic in-memory credential set.
+ */
+struct mem_cred_t {
+
+ /**
+ * Implements credential_set_t.
+ */
+ credential_set_t set;
+
+ /**
+ * Add a certificate to the credential set.
+ *
+ * @param trusted TRUE to serve certificate as trusted
+ * @param cert certificate, reference gets owned by set
+ */
+ void (*add_cert)(mem_cred_t *this, bool trusted, certificate_t *cert);
+
+ /**
+ * Add a private key to the credential set.
+ *
+ * @param key key, reference gets owned by set
+ */
+ void (*add_key)(mem_cred_t *this, private_key_t *key);
+
+ /**
+ * Add a shared key to the credential set.
+ *
+ * @param shared shared key to add, gets owned by set
+ * @param ... NULL terminated list of owners identification_t*
+ */
+ void (*add_shared)(mem_cred_t *this, shared_key_t *shared, ...);
+
+ /**
+ * Clear all credentials from the credential set.
+ */
+ void (*clear)(mem_cred_t *this);
+
+ /**
+ * Destroy a mem_cred_t.
+ */
+ void (*destroy)(mem_cred_t *this);
+};
+
+/**
+ * Create a mem_cred instance.
+ */
+mem_cred_t *mem_cred_create();
+
+#endif /** MEM_CRED_H_ @}*/