diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-11-28 11:42:20 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2010-11-28 11:42:20 +0000 |
commit | f73fba54dc8b30c6482e1e8abf15bbf455592fcd (patch) | |
tree | a449515607c5e51a5c703d7a9b1149c9e4a11560 /src/libstrongswan/credentials | |
parent | b8064f4099997a9e2179f3ad4ace605f5ccac3a1 (diff) | |
download | vyos-strongswan-f73fba54dc8b30c6482e1e8abf15bbf455592fcd.tar.gz vyos-strongswan-f73fba54dc8b30c6482e1e8abf15bbf455592fcd.zip |
[svn-upgrade] new version strongswan (4.5.0)
Diffstat (limited to 'src/libstrongswan/credentials')
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.c | 65 | ||||
-rw-r--r-- | src/libstrongswan/credentials/auth_cfg.h | 32 | ||||
-rw-r--r-- | src/libstrongswan/credentials/builder.c | 6 | ||||
-rw-r--r-- | src/libstrongswan/credentials/builder.h | 18 | ||||
-rw-r--r-- | src/libstrongswan/credentials/credential_factory.c | 76 | ||||
-rw-r--r-- | src/libstrongswan/credentials/credential_factory.h | 18 | ||||
-rw-r--r-- | src/libstrongswan/credentials/credential_manager.c | 43 | ||||
-rw-r--r-- | src/libstrongswan/credentials/keys/private_key.h | 10 | ||||
-rw-r--r-- | src/libstrongswan/credentials/keys/public_key.c | 10 | ||||
-rw-r--r-- | src/libstrongswan/credentials/keys/public_key.h | 36 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/callback_cred.c | 144 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/callback_cred.h | 67 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/mem_cred.c | 433 | ||||
-rw-r--r-- | src/libstrongswan/credentials/sets/mem_cred.h | 77 |
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, ¤t)) + { + 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_ @}*/ |