diff options
author | Yves-Alexis Perez <corsac@corsac.net> | 2012-06-28 21:16:07 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@corsac.net> | 2012-06-28 21:16:07 +0200 |
commit | b34738ed08c2227300d554b139e2495ca5da97d6 (patch) | |
tree | 62f33b52820f2e49f0e53c0f8c636312037c8054 /src/libstrongswan/plugins | |
parent | 0a9d51a49042a68daa15b0c74a2b7f152f52606b (diff) | |
download | vyos-strongswan-b34738ed08c2227300d554b139e2495ca5da97d6.tar.gz vyos-strongswan-b34738ed08c2227300d554b139e2495ca5da97d6.zip |
Imported Upstream version 4.6.4
Diffstat (limited to 'src/libstrongswan/plugins')
148 files changed, 8071 insertions, 1947 deletions
diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in index c93f84ca7..53eecbe8d 100644 --- a/src/libstrongswan/plugins/aes/Makefile.in +++ b/src/libstrongswan/plugins/aes/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/aes/aes_plugin.c b/src/libstrongswan/plugins/aes/aes_plugin.c index d17355d1d..1e84a7c86 100644 --- a/src/libstrongswan/plugins/aes/aes_plugin.c +++ b/src/libstrongswan/plugins/aes/aes_plugin.c @@ -37,11 +37,22 @@ METHOD(plugin_t, get_name, char*, return "aes"; } +METHOD(plugin_t, get_features, int, + private_aes_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(CRYPTER, aes_crypter_create), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_aes_plugin_t *this) { - lib->crypto->remove_crypter(lib->crypto, - (crypter_constructor_t)aes_crypter_create); free(this); } @@ -56,15 +67,12 @@ plugin_t *aes_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, get_name(this), - (crypter_constructor_t)aes_crypter_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in index 00b54b026..679e883e1 100644 --- a/src/libstrongswan/plugins/af_alg/Makefile.in +++ b/src/libstrongswan/plugins/af_alg/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/af_alg/af_alg_crypter.c b/src/libstrongswan/plugins/af_alg/af_alg_crypter.c index 7b3c062aa..9c547140d 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_crypter.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_crypter.c @@ -61,7 +61,7 @@ static struct { /* size of the keying material (key + nonce for ctr mode) */ size_t keymat_size; size_t iv_size; -} algs[] = { +} algs[AF_ALG_CRYPTER] = { {ENCR_DES, "cbc(des)", 8, 8, 8, 8, }, {ENCR_DES_ECB, "ecb(des)", 8, 8, 8, 0, }, {ENCR_3DES, "cbc(des3_ede)", 8, 24, 24, 8, }, @@ -92,25 +92,20 @@ static struct { /** * See header. */ -void af_alg_crypter_probe(char *plugin) +void af_alg_crypter_probe(plugin_feature_t *features, int *pos) { - encryption_algorithm_t prev = -1; af_alg_ops_t *ops; int i; for (i = 0; i < countof(algs); i++) { - if (prev != algs[i].id) + ops = af_alg_ops_create("skcipher", algs[i].name); + if (ops) { - ops = af_alg_ops_create("skcipher", algs[i].name); - if (ops) - { - ops->destroy(ops); - lib->crypto->add_crypter(lib->crypto, algs[i].id, plugin, - (crypter_constructor_t)af_alg_crypter_create); - } + ops->destroy(ops); + features[(*pos)++] = PLUGIN_PROVIDE(CRYPTER, + algs[i].id, algs[i].key_size); } - prev = algs[i].id; } } diff --git a/src/libstrongswan/plugins/af_alg/af_alg_crypter.h b/src/libstrongswan/plugins/af_alg/af_alg_crypter.h index ed7799cc8..ad2d42a97 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_crypter.h +++ b/src/libstrongswan/plugins/af_alg/af_alg_crypter.h @@ -23,8 +23,12 @@ typedef struct af_alg_crypter_t af_alg_crypter_t; +#include <plugins/plugin.h> #include <crypto/crypters/crypter.h> +/** Number of crypters */ +#define AF_ALG_CRYPTER 25 + /** * Implementation of signers using AF_ALG. */ @@ -47,10 +51,11 @@ af_alg_crypter_t *af_alg_crypter_create(encryption_algorithm_t algo, size_t key_size); /** - * Probe algorithms and register af_alg_crypter_create(). + * Probe algorithms and return plugin features. * - * @param plugin plugin name to register algorithms for + * @param features plugin features to create + * @param pos current position in features */ -void af_alg_crypter_probe(char *plugin); +void af_alg_crypter_probe(plugin_feature_t *features, int *pos); #endif /** AF_ALG_CRYPTER_H_ @}*/ diff --git a/src/libstrongswan/plugins/af_alg/af_alg_hasher.c b/src/libstrongswan/plugins/af_alg/af_alg_hasher.c index 11074c4bd..ef2350497 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_hasher.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_hasher.c @@ -46,7 +46,7 @@ static struct { hash_algorithm_t id; char *name; size_t size; -} algs[] = { +} algs[AF_ALG_HASHER] = { {HASH_SHA1, "sha1", HASH_SIZE_SHA1 }, {HASH_MD5, "md5", HASH_SIZE_MD5 }, {HASH_SHA224, "sha224", HASH_SIZE_SHA224 }, @@ -59,7 +59,7 @@ static struct { /** * See header. */ -void af_alg_hasher_probe(char *plugin) +void af_alg_hasher_probe(plugin_feature_t *features, int *pos) { af_alg_ops_t *ops; int i; @@ -70,8 +70,7 @@ void af_alg_hasher_probe(char *plugin) if (ops) { ops->destroy(ops); - lib->crypto->add_hasher(lib->crypto, algs[i].id, plugin, - (hasher_constructor_t)af_alg_hasher_create); + features[(*pos)++] = PLUGIN_PROVIDE(HASHER, algs[i].id); } } } diff --git a/src/libstrongswan/plugins/af_alg/af_alg_hasher.h b/src/libstrongswan/plugins/af_alg/af_alg_hasher.h index f44ba2938..5b540875a 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_hasher.h +++ b/src/libstrongswan/plugins/af_alg/af_alg_hasher.h @@ -23,8 +23,12 @@ typedef struct af_alg_hasher_t af_alg_hasher_t; +#include <plugins/plugin.h> #include <crypto/hashers/hasher.h> +/** Number of hashers */ +#define AF_ALG_HASHER 7 + /** * Implementation of hashers using AF_ALG. */ @@ -45,10 +49,11 @@ struct af_alg_hasher_t { af_alg_hasher_t *af_alg_hasher_create(hash_algorithm_t algo); /** - * Probe algorithms and register af_alg_hasher_create(). + * Probe algorithms and return plugin features. * - * @param plugin plugin name to register algorithms for + * @param features plugin features to create + * @param pos current position in deps */ -void af_alg_hasher_probe(char *plugin); +void af_alg_hasher_probe(plugin_feature_t *features, int *pos); #endif /** af_alg_HASHER_H_ @}*/ diff --git a/src/libstrongswan/plugins/af_alg/af_alg_ops.c b/src/libstrongswan/plugins/af_alg/af_alg_ops.c index 82a227d97..a7b5de264 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_ops.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_ops.c @@ -122,7 +122,7 @@ METHOD(af_alg_ops_t, crypt, void, cmsg->cmsg_level = SOL_ALG; cmsg->cmsg_type = ALG_SET_OP; cmsg->cmsg_len = CMSG_LEN(sizeof(type)); - *(u_int32_t*)CMSG_DATA(cmsg) = type; + memcpy(CMSG_DATA(cmsg), &type, sizeof(type)); cmsg = CMSG_NXTHDR(&msg, cmsg); cmsg->cmsg_level = SOL_ALG; diff --git a/src/libstrongswan/plugins/af_alg/af_alg_plugin.c b/src/libstrongswan/plugins/af_alg/af_alg_plugin.c index 280ea4e98..445667507 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_plugin.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_plugin.c @@ -41,18 +41,31 @@ METHOD(plugin_t, get_name, char*, return "af-alg"; } +METHOD(plugin_t, get_features, int, + private_af_alg_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[AF_ALG_HASHER + AF_ALG_SIGNER + + AF_ALG_PRF + AF_ALG_CRYPTER + 4] = {}; + static int count = 0; + + if (!count) + { /* initialize only once */ + f[count++] = PLUGIN_REGISTER(HASHER, af_alg_hasher_create); + af_alg_hasher_probe(f, &count); + f[count++] = PLUGIN_REGISTER(SIGNER, af_alg_signer_create); + af_alg_signer_probe(f, &count); + f[count++] = PLUGIN_REGISTER(PRF, af_alg_prf_create); + af_alg_prf_probe(f, &count); + f[count++] = PLUGIN_REGISTER(CRYPTER, af_alg_crypter_create); + af_alg_crypter_probe(f, &count); + } + *features = f; + return count; +} + METHOD(plugin_t, destroy, void, private_af_alg_plugin_t *this) { - lib->crypto->remove_hasher(lib->crypto, - (hasher_constructor_t)af_alg_hasher_create); - lib->crypto->remove_signer(lib->crypto, - (signer_constructor_t)af_alg_signer_create); - lib->crypto->remove_prf(lib->crypto, - (prf_constructor_t)af_alg_prf_create); - lib->crypto->remove_crypter(lib->crypto, - (crypter_constructor_t)af_alg_crypter_create); - free(this); } @@ -67,16 +80,11 @@ plugin_t *af_alg_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - af_alg_hasher_probe(get_name(this)); - af_alg_signer_probe(get_name(this)); - af_alg_prf_probe(get_name(this)); - af_alg_crypter_probe(get_name(this)); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/af_alg/af_alg_prf.c b/src/libstrongswan/plugins/af_alg/af_alg_prf.c index 1c1174abb..a7912291f 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_prf.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_prf.c @@ -57,7 +57,7 @@ static struct { char *name; size_t block_size; bool xcbc; -} algs[] = { +} algs[AF_ALG_PRF] = { {PRF_HMAC_SHA1, "hmac(sha1)", 20, FALSE, }, {PRF_HMAC_SHA2_256, "hmac(sha256)", 32, FALSE, }, {PRF_HMAC_MD5, "hmac(md5)", 16, FALSE, }, @@ -70,7 +70,7 @@ static struct { /** * See header. */ -void af_alg_prf_probe(char *plugin) +void af_alg_prf_probe(plugin_feature_t *features, int *pos) { af_alg_ops_t *ops; int i; @@ -81,8 +81,7 @@ void af_alg_prf_probe(char *plugin) if (ops) { ops->destroy(ops); - lib->crypto->add_prf(lib->crypto, algs[i].id, plugin, - (prf_constructor_t)af_alg_prf_create); + features[(*pos)++] = PLUGIN_PROVIDE(PRF, algs[i].id); } } } @@ -90,7 +89,7 @@ void af_alg_prf_probe(char *plugin) /** * Get the kernel algorithm string and block size for our identifier */ -static size_t lookup_alg(integrity_algorithm_t algo, char **name, bool *xcbc) +static size_t lookup_alg(pseudo_random_function_t algo, char **name, bool *xcbc) { int i; diff --git a/src/libstrongswan/plugins/af_alg/af_alg_prf.h b/src/libstrongswan/plugins/af_alg/af_alg_prf.h index d3275e7be..2f6cf0cf1 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_prf.h +++ b/src/libstrongswan/plugins/af_alg/af_alg_prf.h @@ -23,8 +23,12 @@ typedef struct af_alg_prf_t af_alg_prf_t; +#include <plugins/plugin.h> #include <crypto/prfs/prf.h> +/** Number of PRFs */ +#define AF_ALG_PRF 7 + /** * Implementation of PRFs using AF_ALG. */ @@ -45,10 +49,11 @@ struct af_alg_prf_t { af_alg_prf_t *af_alg_prf_create(pseudo_random_function_t algo); /** - * Probe algorithms and register af_alg_prf_create(). + * Probe algorithms and return plugin features. * - * @param plugin plugin name to register algorithms for + * @param features plugin features to create + * @param pos current position in features */ -void af_alg_prf_probe(char *plugin); +void af_alg_prf_probe(plugin_feature_t *features, int *pos); #endif /** AF_ALG_PRF_H_ @}*/ diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.c b/src/libstrongswan/plugins/af_alg/af_alg_signer.c index 34534a06b..6cd79f8f2 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_signer.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.c @@ -52,7 +52,7 @@ static struct { char *name; size_t block_size; size_t key_size; -} algs[] = { +} algs[AF_ALG_SIGNER] = { {AUTH_HMAC_SHA1_96, "hmac(sha1)", 12, 20, }, {AUTH_HMAC_SHA1_128, "hmac(sha1)", 16, 20, }, {AUTH_HMAC_SHA1_160, "hmac(sha1)", 20, 20, }, @@ -71,7 +71,7 @@ static struct { /** * See header. */ -void af_alg_signer_probe(char *plugin) +void af_alg_signer_probe(plugin_feature_t *features, int *pos) { af_alg_ops_t *ops; int i; @@ -82,8 +82,7 @@ void af_alg_signer_probe(char *plugin) if (ops) { ops->destroy(ops); - lib->crypto->add_signer(lib->crypto, algs[i].id, plugin, - (signer_constructor_t)af_alg_signer_create); + features[(*pos)++] = PLUGIN_PROVIDE(SIGNER, algs[i].id); } } } diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.h b/src/libstrongswan/plugins/af_alg/af_alg_signer.h index 21487a118..deced7110 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_signer.h +++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.h @@ -23,8 +23,12 @@ typedef struct af_alg_signer_t af_alg_signer_t; +#include <plugins/plugin.h> #include <crypto/signers/signer.h> +/** Number of signers */ +#define AF_ALG_SIGNER 13 + /** * Implementation of signers using AF_ALG. */ @@ -45,10 +49,11 @@ struct af_alg_signer_t { af_alg_signer_t *af_alg_signer_create(integrity_algorithm_t algo); /** - * Probe algorithms and register af_alg_signer_create(). + * Probe algorithms and return plugin features. * - * @param plugin plugin name to register algorithms for + * @param features plugin features to create + * @param pos current position in features */ -void af_alg_signer_probe(char *plugin); +void af_alg_signer_probe(plugin_feature_t *features, int *pos); #endif /** AF_ALG_SIGNER_H_ @}*/ diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in index ce333660d..452233b85 100644 --- a/src/libstrongswan/plugins/agent/Makefile.in +++ b/src/libstrongswan/plugins/agent/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/agent/agent_plugin.c b/src/libstrongswan/plugins/agent/agent_plugin.c index 79c13b7c1..980a140b9 100644 --- a/src/libstrongswan/plugins/agent/agent_plugin.c +++ b/src/libstrongswan/plugins/agent/agent_plugin.c @@ -37,11 +37,20 @@ METHOD(plugin_t, get_name, char*, return "agent"; } +METHOD(plugin_t, get_features, int, + private_agent_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRIVKEY, agent_private_key_open, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_agent_plugin_t *this) { - lib->creds->remove_builder(lib->creds, - (builder_function_t)agent_private_key_open); free(this); } @@ -56,14 +65,12 @@ plugin_t *agent_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE, - (builder_function_t)agent_private_key_open); return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/agent/agent_private_key.c b/src/libstrongswan/plugins/agent/agent_private_key.c index 0864f4118..60b57ad2d 100644 --- a/src/libstrongswan/plugins/agent/agent_private_key.c +++ b/src/libstrongswan/plugins/agent/agent_private_key.c @@ -161,7 +161,7 @@ static int open_connection(char *path) */ static bool read_key(private_agent_private_key_t *this, public_key_t *pubkey) { - int len, count; + int len; char buf[2048]; chunk_t blob, key, type, n; @@ -184,7 +184,7 @@ static bool read_key(private_agent_private_key_t *this, public_key_t *pubkey) DBG1(DBG_LIB, "received invalid ssh-agent identity response"); return FALSE; } - count = read_uint32(&blob); + read_uint32(&blob); while (blob.len) { @@ -398,7 +398,7 @@ agent_private_key_t *agent_private_key_open(key_type_t type, va_list args) } if (!path) { - return FALSE; + return NULL; } INIT(this, diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in index be8ba72ee..52f5fa98a 100644 --- a/src/libstrongswan/plugins/blowfish/Makefile.in +++ b/src/libstrongswan/plugins/blowfish/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in index b2bc4a51f..2ffe6194b 100644 --- a/src/libstrongswan/plugins/ccm/Makefile.in +++ b/src/libstrongswan/plugins/ccm/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/ccm/ccm_aead.c b/src/libstrongswan/plugins/ccm/ccm_aead.c index 7fee2b3c4..0d2a56a49 100644 --- a/src/libstrongswan/plugins/ccm/ccm_aead.c +++ b/src/libstrongswan/plugins/ccm/ccm_aead.c @@ -67,7 +67,7 @@ typedef struct __attribute__((packed)) { u_char salt[SALT_SIZE]; u_char iv[IV_SIZE]; } nonce; - /* lenght of plain text, q */ + /* length of plain text, q */ u_char q[Q_SIZE]; } b0_t; diff --git a/src/libstrongswan/plugins/ccm/ccm_plugin.c b/src/libstrongswan/plugins/ccm/ccm_plugin.c index 2865c2ae4..549f0a736 100644 --- a/src/libstrongswan/plugins/ccm/ccm_plugin.c +++ b/src/libstrongswan/plugins/ccm/ccm_plugin.c @@ -5,11 +5,11 @@ * 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>. + * 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 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ @@ -38,12 +38,55 @@ METHOD(plugin_t, get_name, char*, return "ccm"; } +METHOD(plugin_t, get_features, int, + private_ccm_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(AEAD, ccm_aead_create), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV8, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV8, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV8, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 32), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV12, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV12, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV12, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 32), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV16, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV16, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV16, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 32), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_ccm_plugin_t *this) { - lib->crypto->remove_aead(lib->crypto, - (aead_constructor_t)ccm_aead_create); - free(this); } @@ -53,40 +96,16 @@ METHOD(plugin_t, destroy, void, plugin_t *ccm_plugin_create() { private_ccm_plugin_t *this; - crypter_t *crypter; INIT(this, .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 0); - if (crypter) - { - crypter->destroy(crypter); - lib->crypto->add_aead(lib->crypto, ENCR_AES_CCM_ICV8, get_name(this), - (aead_constructor_t)ccm_aead_create); - lib->crypto->add_aead(lib->crypto, ENCR_AES_CCM_ICV12, get_name(this), - (aead_constructor_t)ccm_aead_create); - lib->crypto->add_aead(lib->crypto, ENCR_AES_CCM_ICV16, get_name(this), - (aead_constructor_t)ccm_aead_create); - } - crypter = lib->crypto->create_crypter(lib->crypto, ENCR_CAMELLIA_CBC, 0); - if (crypter) - { - crypter->destroy(crypter); - lib->crypto->add_aead(lib->crypto, ENCR_CAMELLIA_CCM_ICV8, get_name(this), - (aead_constructor_t)ccm_aead_create); - lib->crypto->add_aead(lib->crypto, ENCR_CAMELLIA_CCM_ICV12, get_name(this), - (aead_constructor_t)ccm_aead_create); - lib->crypto->add_aead(lib->crypto, ENCR_CAMELLIA_CCM_ICV16, get_name(this), - (aead_constructor_t)ccm_aead_create); - } - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/cmac/Makefile.am b/src/libstrongswan/plugins/cmac/Makefile.am new file mode 100644 index 000000000..ce0104f11 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-cmac.la +else +plugin_LTLIBRARIES = libstrongswan-cmac.la +endif + +libstrongswan_cmac_la_SOURCES = \ + cmac_plugin.h cmac_plugin.c cmac.h cmac.c \ + cmac_prf.h cmac_prf.c cmac_signer.h cmac_signer.c + +libstrongswan_cmac_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in new file mode 100644 index 000000000..093e63f32 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/Makefile.in @@ -0,0 +1,613 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libstrongswan/plugins/cmac +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +libstrongswan_cmac_la_LIBADD = +am_libstrongswan_cmac_la_OBJECTS = cmac_plugin.lo cmac.lo cmac_prf.lo \ + cmac_signer.lo +libstrongswan_cmac_la_OBJECTS = $(am_libstrongswan_cmac_la_OBJECTS) +libstrongswan_cmac_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_cmac_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_cmac_la_rpath = -rpath $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_cmac_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstrongswan_cmac_la_SOURCES) +DIST_SOURCES = $(libstrongswan_cmac_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +default_pkcs11 = @default_pkcs11@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +oldincludedir = @oldincludedir@ +openac_plugins = @openac_plugins@ +p_plugins = @p_plugins@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pluto_plugins = @pluto_plugins@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +INCLUDES = -I$(top_srcdir)/src/libstrongswan +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-cmac.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-cmac.la +libstrongswan_cmac_la_SOURCES = \ + cmac_plugin.h cmac_plugin.c cmac.h cmac.c \ + cmac_prf.h cmac_prf.c cmac_signer.h cmac_signer.c + +libstrongswan_cmac_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/cmac/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/cmac/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libstrongswan-cmac.la: $(libstrongswan_cmac_la_OBJECTS) $(libstrongswan_cmac_la_DEPENDENCIES) + $(libstrongswan_cmac_la_LINK) $(am_libstrongswan_cmac_la_rpath) $(libstrongswan_cmac_la_OBJECTS) $(libstrongswan_cmac_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_prf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_signer.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libstrongswan/plugins/cmac/cmac.c b/src/libstrongswan/plugins/cmac/cmac.c new file mode 100644 index 000000000..5ec7073c7 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/cmac.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 <string.h> + +#include "cmac.h" + +#include <debug.h> + +typedef struct private_cmac_t private_cmac_t; + +/** + * Private data of a cmac_t object. + * + * The variable names are the same as in the RFC. + */ +struct private_cmac_t { + + /** + * Public interface. + */ + cmac_t public; + + /** + * Block size, in bytes + */ + u_int8_t b; + + /** + * Crypter with key K + */ + crypter_t *k; + + /** + * K1 + */ + u_int8_t *k1; + + /** + * K2 + */ + u_int8_t *k2; + + /** + * T + */ + u_int8_t *t; + + /** + * remaining, unprocessed bytes in append mode + */ + u_int8_t *remaining; + + /** + * number of bytes in remaining + */ + int remaining_bytes; +}; + +/** + * process supplied data, but do not run final operation + */ +static void update(private_cmac_t *this, chunk_t data) +{ + chunk_t iv; + + if (this->remaining_bytes + data.len <= this->b) + { /* no complete block (or last block), just copy into remaining */ + memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len); + this->remaining_bytes += data.len; + return; + } + + iv = chunk_alloca(this->b); + memset(iv.ptr, 0, iv.len); + + /* T := 0x00000000000000000000000000000000 (initially) + * for each block M_i (except the last) + * X := T XOR M_i; + * T := AES-128(K, X); + */ + + /* append data to remaining bytes, process block M_1 */ + memcpy(this->remaining + this->remaining_bytes, data.ptr, + this->b - this->remaining_bytes); + data = chunk_skip(data, this->b - this->remaining_bytes); + memxor(this->t, this->remaining, this->b); + this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); + + /* process blocks M_2 ... M_n-1 */ + while (data.len > this->b) + { + memcpy(this->remaining, data.ptr, this->b); + data = chunk_skip(data, this->b); + memxor(this->t, this->remaining, this->b); + this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); + } + + /* store remaining bytes of block M_n */ + memcpy(this->remaining, data.ptr, data.len); + this->remaining_bytes = data.len; +} + +/** + * process last block M_last + */ +static void final(private_cmac_t *this, u_int8_t *out) +{ + chunk_t iv; + + iv = chunk_alloca(this->b); + memset(iv.ptr, 0, iv.len); + + /* if last block is complete + * M_last := M_n XOR K1; + * else + * M_last := padding(M_n) XOR K2; + */ + if (this->remaining_bytes == this->b) + { + memxor(this->remaining, this->k1, this->b); + } + else + { + /* padding(x) = x || 10^i where i is 128-8*r-1 + * That is, padding(x) is the concatenation of x and a single '1', + * followed by the minimum number of '0's, so that the total length is + * equal to 128 bits. + */ + if (this->remaining_bytes < this->b) + { + this->remaining[this->remaining_bytes] = 0x80; + while (++this->remaining_bytes < this->b) + { + this->remaining[this->remaining_bytes] = 0x00; + } + } + memxor(this->remaining, this->k2, this->b); + } + /* T := M_last XOR T; + * T := AES-128(K,T); + */ + memxor(this->t, this->remaining, this->b); + this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL); + + memcpy(out, this->t, this->b); + + /* reset state */ + memset(this->t, 0, this->b); + this->remaining_bytes = 0; +} + +METHOD(cmac_t, get_mac, void, + private_cmac_t *this, chunk_t data, u_int8_t *out) +{ + /* update T, do not process last block */ + update(this, data); + + if (out) + { /* if not in append mode, process last block and output result */ + final(this, out); + } +} + +METHOD(cmac_t, get_block_size, size_t, + private_cmac_t *this) +{ + return this->b; +} + +/** + * Left-shift the given chunk by one bit. + */ +static void bit_shift(chunk_t chunk) +{ + size_t i; + + for (i = 0; i < chunk.len; i++) + { + chunk.ptr[i] <<= 1; + if (i < chunk.len - 1 && chunk.ptr[i + 1] & 0x80) + { + chunk.ptr[i] |= 0x01; + } + } +} + +/** + * Apply the following key derivation (in-place): + * if MSB(C) == 0 + * C := C << 1 + * else + * C := (C << 1) XOR 0x00000000000000000000000000000087 + */ +static void derive_key(chunk_t chunk) +{ + if (chunk.ptr[0] & 0x80) + { + chunk_t rb; + + rb = chunk_alloca(chunk.len); + memset(rb.ptr, 0, rb.len); + rb.ptr[rb.len - 1] = 0x87; + bit_shift(chunk); + memxor(chunk.ptr, rb.ptr, chunk.len); + } + else + { + bit_shift(chunk); + } +} + +METHOD(cmac_t, set_key, void, + private_cmac_t *this, chunk_t key) +{ + chunk_t resized, iv, l; + + /* we support variable keys as defined in RFC 4615 */ + if (key.len == this->b) + { + resized = key; + } + else + { /* use cmac recursively to resize longer or shorter keys */ + resized = chunk_alloca(this->b); + memset(resized.ptr, 0, resized.len); + set_key(this, resized); + get_mac(this, key, resized.ptr); + } + + /* + * Rb = 0x00000000000000000000000000000087 + * L = 0x00000000000000000000000000000000 encrypted with K + * if MSB(L) == 0 + * K1 = L << 1 + * else + * K1 = (L << 1) XOR Rb + * if MSB(K1) == 0 + * K2 = K1 << 1 + * else + * K2 = (K1 << 1) XOR Rb + */ + iv = chunk_alloca(this->b); + memset(iv.ptr, 0, iv.len); + l = chunk_alloca(this->b); + memset(l.ptr, 0, l.len); + this->k->set_key(this->k, resized); + this->k->encrypt(this->k, l, iv, NULL); + derive_key(l); + memcpy(this->k1, l.ptr, l.len); + derive_key(l); + memcpy(this->k2, l.ptr, l.len); + memwipe(l.ptr, l.len); +} + +METHOD(cmac_t, destroy, void, + private_cmac_t *this) +{ + this->k->destroy(this->k); + memwipe(this->k1, this->b); + free(this->k1); + memwipe(this->k2, this->b); + free(this->k2); + free(this->t); + free(this->remaining); + free(this); +} + +/* + * Described in header + */ +cmac_t *cmac_create(encryption_algorithm_t algo, size_t key_size) +{ + private_cmac_t *this; + crypter_t *crypter; + u_int8_t b; + + crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size); + if (!crypter) + { + return NULL; + } + b = crypter->get_block_size(crypter); + /* input and output of crypter must be equal for cmac */ + if (b != key_size) + { + crypter->destroy(crypter); + return NULL; + } + + INIT(this, + .public = { + .get_mac = _get_mac, + .get_block_size = _get_block_size, + .set_key = _set_key, + .destroy = _destroy, + }, + .b = b, + .k = crypter, + .k1 = malloc(b), + .k2 = malloc(b), + .t = malloc(b), + .remaining = malloc(b), + ); + memset(this->t, 0, b); + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/cmac/cmac.h b/src/libstrongswan/plugins/cmac/cmac.h new file mode 100644 index 000000000..061609127 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/cmac.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 cmac cmac + * @{ @ingroup cmac_p + */ + +#ifndef CMAC_H_ +#define CMAC_H_ + +#include <crypto/crypters/crypter.h> + +typedef struct cmac_t cmac_t; + +/** + * Cipher-based Message Authentication Code (CMAC). + * + * This class implements the message authentication algorithm + * described in RFC 4493. + */ +struct cmac_t { + + /** + * Generate message authentication code. + * + * If buffer is NULL, no result is given back. A next call will + * append the data to already supplied data. If buffer is not NULL, + * the mac of all apended data is calculated, returned and the internal + * state is reset. + * + * @param data chunk of data to authenticate + * @param buffer pointer where the generated bytes will be written + */ + void (*get_mac) (cmac_t *this, chunk_t data, u_int8_t *buffer); + + /** + * Get the block size of this cmac_t object. + * + * @return block size in bytes + */ + size_t (*get_block_size) (cmac_t *this); + + /** + * Set the key for this cmac_t object. + * + * @param key key to set + */ + void (*set_key) (cmac_t *this, chunk_t key); + + /** + * Destroys a cmac_t object. + */ + void (*destroy) (cmac_t *this); +}; + +/** + * Creates a new cmac_t object. + * + * @param algo underlying crypto algorithm + * @param key_size key size to use, if required for algorithm + * @return cmac_t object, NULL if not supported + */ +cmac_t *cmac_create(encryption_algorithm_t algo, size_t key_size); + +#endif /** CMAC_H_ @}*/ diff --git a/src/libstrongswan/plugins/cmac/cmac_plugin.c b/src/libstrongswan/plugins/cmac/cmac_plugin.c new file mode 100644 index 000000000..5b42c5002 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/cmac_plugin.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 "cmac_plugin.h" + +#include <library.h> +#include "cmac_prf.h" +#include "cmac_signer.h" + +typedef struct private_cmac_plugin_t private_cmac_plugin_t; + +/** + * private data of cmac_plugin + */ +struct private_cmac_plugin_t { + + /** + * public functions + */ + cmac_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_cmac_plugin_t *this) +{ + return "cmac"; +} + +METHOD(plugin_t, get_features, int, + private_cmac_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRF, cmac_prf_create), + PLUGIN_PROVIDE(PRF, PRF_AES128_CMAC), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_REGISTER(SIGNER, cmac_signer_create), + PLUGIN_PROVIDE(SIGNER, AUTH_AES_CMAC_96), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_cmac_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *cmac_plugin_create() +{ + private_cmac_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} + diff --git a/src/libstrongswan/plugins/cmac/cmac_plugin.h b/src/libstrongswan/plugins/cmac/cmac_plugin.h new file mode 100644 index 000000000..a31e1077d --- /dev/null +++ b/src/libstrongswan/plugins/cmac/cmac_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 cmac_p cmac + * @ingroup plugins + * + * @defgroup cmac_plugin cmac_plugin + * @{ @ingroup cmac_p + */ + +#ifndef CMAC_PLUGIN_H_ +#define CMAC_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct cmac_plugin_t cmac_plugin_t; + +/** + * Plugin implementing CMAC algorithm to provide crypter based PRF and signer. + */ +struct cmac_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** CMAC_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/cmac/cmac_prf.c b/src/libstrongswan/plugins/cmac/cmac_prf.c new file mode 100644 index 000000000..17affe439 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/cmac_prf.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 "cmac_prf.h" + +#include "cmac.h" + +typedef struct private_cmac_prf_t private_cmac_prf_t; + +/** + * Private data of a cmac_prf_t object. + */ +struct private_cmac_prf_t { + + /** + * Public cmac_prf_t interface. + */ + cmac_prf_t public; + + /** + * cmac to use for generation. + */ + cmac_t *cmac; +}; + +METHOD(prf_t, get_bytes, void, + private_cmac_prf_t *this, chunk_t seed, u_int8_t *buffer) +{ + this->cmac->get_mac(this->cmac, seed, buffer); +} + +METHOD(prf_t, allocate_bytes, void, + private_cmac_prf_t *this, chunk_t seed, chunk_t *chunk) +{ + if (chunk) + { + *chunk = chunk_alloc(this->cmac->get_block_size(this->cmac)); + get_bytes(this, seed, chunk->ptr); + } + else + { + get_bytes(this, seed, NULL); + } +} + +METHOD(prf_t, get_block_size, size_t, + private_cmac_prf_t *this) +{ + return this->cmac->get_block_size(this->cmac); +} + +METHOD(prf_t, get_key_size, size_t, + private_cmac_prf_t *this) +{ + /* in cmac, block and key size are always equal */ + return this->cmac->get_block_size(this->cmac); +} + +METHOD(prf_t, set_key, void, + private_cmac_prf_t *this, chunk_t key) +{ + this->cmac->set_key(this->cmac, key); +} + +METHOD(prf_t, destroy, void, + private_cmac_prf_t *this) +{ + this->cmac->destroy(this->cmac); + free(this); +} + +/* + * Described in header. + */ +cmac_prf_t *cmac_prf_create(pseudo_random_function_t algo) +{ + private_cmac_prf_t *this; + cmac_t *cmac; + + switch (algo) + { + case PRF_AES128_CMAC: + cmac = cmac_create(ENCR_AES_CBC, 16); + break; + default: + return NULL; + } + if (!cmac) + { + return NULL; + } + + INIT(this, + .public = { + .prf = { + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .get_block_size = _get_block_size, + .get_key_size = _get_key_size, + .set_key = _set_key, + .destroy = _destroy, + }, + }, + .cmac = cmac, + ); + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/cmac/cmac_prf.h b/src/libstrongswan/plugins/cmac/cmac_prf.h new file mode 100644 index 000000000..a53cc5947 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/cmac_prf.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 cmac_prf cmac_prf + * @{ @ingroup cmac_p + */ + +#ifndef PRF_CMAC_H_ +#define PRF_CMAC_H_ + +typedef struct cmac_prf_t cmac_prf_t; + +#include <crypto/prfs/prf.h> + +/** + * Implementation of prf_t on CBC block cipher using CMAC, RFC 4493 / RFC 4615. + * + * This simply wraps a cmac_t in a prf_t. More a question of + * interface matching. + */ +struct cmac_prf_t { + + /** + * Implements prf_t interface. + */ + prf_t prf; +}; + +/** + * Creates a new cmac_prf_t object. + * + * @param algo algorithm to implement + * @return cmac_prf_t object, NULL if hash not supported + */ +cmac_prf_t *cmac_prf_create(pseudo_random_function_t algo); + +#endif /** PRF_CMAC_H_ @}*/ diff --git a/src/libstrongswan/plugins/cmac/cmac_signer.c b/src/libstrongswan/plugins/cmac/cmac_signer.c new file mode 100644 index 000000000..82e8885d6 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/cmac_signer.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 <string.h> + +#include "cmac_signer.h" +#include "cmac.h" + +typedef struct private_cmac_signer_t private_cmac_signer_t; + +/** + * Private data structure with signing context. + */ +struct private_cmac_signer_t { + + /** + * Public interface. + */ + cmac_signer_t public; + + /** + * Assigned cmac function. + */ + cmac_t *cmac; + + /** + * Block size (truncation of CMAC MAC) + */ + size_t block_size; +}; + +METHOD(signer_t, get_signature, void, + private_cmac_signer_t *this, chunk_t data, u_int8_t *buffer) +{ + if (buffer == NULL) + { /* append mode */ + this->cmac->get_mac(this->cmac, data, NULL); + } + else + { + u_int8_t mac[this->cmac->get_block_size(this->cmac)]; + + this->cmac->get_mac(this->cmac, data, mac); + memcpy(buffer, mac, this->block_size); + } +} + +METHOD(signer_t, allocate_signature, void, + private_cmac_signer_t *this, chunk_t data, chunk_t *chunk) +{ + if (chunk == NULL) + { /* append mode */ + this->cmac->get_mac(this->cmac, data, NULL); + } + else + { + u_int8_t mac[this->cmac->get_block_size(this->cmac)]; + + this->cmac->get_mac(this->cmac, data, mac); + + chunk->ptr = malloc(this->block_size); + chunk->len = this->block_size; + + memcpy(chunk->ptr, mac, this->block_size); + } +} + +METHOD(signer_t, verify_signature, bool, + private_cmac_signer_t *this, chunk_t data, chunk_t signature) +{ + u_int8_t mac[this->cmac->get_block_size(this->cmac)]; + + if (signature.len != this->block_size) + { + return FALSE; + } + + this->cmac->get_mac(this->cmac, data, mac); + return memeq(signature.ptr, mac, this->block_size); +} + +METHOD(signer_t, get_key_size, size_t, + private_cmac_signer_t *this) +{ + return this->cmac->get_block_size(this->cmac); +} + +METHOD(signer_t, get_block_size, size_t, + private_cmac_signer_t *this) +{ + return this->block_size; +} + +METHOD(signer_t, set_key, void, + private_cmac_signer_t *this, chunk_t key) +{ + this->cmac->set_key(this->cmac, key); +} + +METHOD(signer_t, destroy, void, + private_cmac_signer_t *this) +{ + this->cmac->destroy(this->cmac); + free(this); +} + +/* + * Described in header + */ +cmac_signer_t *cmac_signer_create(integrity_algorithm_t algo) +{ + private_cmac_signer_t *this; + size_t truncation; + cmac_t *cmac; + + switch (algo) + { + case AUTH_AES_CMAC_96: + cmac = cmac_create(ENCR_AES_CBC, 16); + truncation = 12; + break; + default: + return NULL; + } + if (cmac == NULL) + { + return NULL; + } + + INIT(this, + .public = { + .signer = { + .get_signature = _get_signature, + .allocate_signature = _allocate_signature, + .verify_signature = _verify_signature, + .get_key_size = _get_key_size, + .get_block_size = _get_block_size, + .set_key = _set_key, + .destroy = _destroy, + }, + }, + .cmac = cmac, + .block_size = min(truncation, cmac->get_block_size(cmac)), + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/cmac/cmac_signer.h b/src/libstrongswan/plugins/cmac/cmac_signer.h new file mode 100644 index 000000000..2e3724471 --- /dev/null +++ b/src/libstrongswan/plugins/cmac/cmac_signer.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 cmac_signer cmac_signer + * @{ @ingroup cmac_p + */ + +#ifndef CMAC_SIGNER_H_ +#define CMAC_SIGNER_H_ + +typedef struct cmac_signer_t cmac_signer_t; + +#include <crypto/signers/signer.h> + +/** + * Implementation of signer_t on CBC symmetric cipher using CMAC, RFC 4494. + */ +struct cmac_signer_t { + + /** + * Implements signer_t interface. + */ + signer_t signer; +}; + +/** + * Creates a new cmac_signer_t. + * + * @param algo algorithm to implement + * @return cmac_signer_t, NULL if not supported + */ +cmac_signer_t *cmac_signer_create(integrity_algorithm_t algo); + +#endif /** CMAC_SIGNER_H_ @}*/ diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in index 8be502a9c..06b66db60 100644 --- a/src/libstrongswan/plugins/constraints/Makefile.in +++ b/src/libstrongswan/plugins/constraints/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in index 0db640829..853625a19 100644 --- a/src/libstrongswan/plugins/ctr/Makefile.in +++ b/src/libstrongswan/plugins/ctr/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/ctr/ctr_plugin.c b/src/libstrongswan/plugins/ctr/ctr_plugin.c index 6850cacf0..c01308a52 100644 --- a/src/libstrongswan/plugins/ctr/ctr_plugin.c +++ b/src/libstrongswan/plugins/ctr/ctr_plugin.c @@ -38,12 +38,31 @@ METHOD(plugin_t, get_name, char*, return "ctr"; } +METHOD(plugin_t, get_features, int, + private_ctr_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(CRYPTER, ctr_ipsec_crypter_create), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 32), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_ctr_plugin_t *this) { - lib->crypto->remove_crypter(lib->crypto, - (crypter_constructor_t)ctr_ipsec_crypter_create); - free(this); } @@ -53,31 +72,16 @@ METHOD(plugin_t, destroy, void, plugin_t *ctr_plugin_create() { private_ctr_plugin_t *this; - crypter_t *crypter; INIT(this, .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 16); - if (crypter) - { - crypter->destroy(crypter); - lib->crypto->add_crypter(lib->crypto, ENCR_AES_CTR, get_name(this), - (crypter_constructor_t)ctr_ipsec_crypter_create); - } - crypter = lib->crypto->create_crypter(lib->crypto, ENCR_CAMELLIA_CBC, 16); - if (crypter) - { - crypter->destroy(crypter); - lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CTR, get_name(this), - (crypter_constructor_t)ctr_ipsec_crypter_create); - } return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in index cdfb2b801..5b83c60f8 100644 --- a/src/libstrongswan/plugins/curl/Makefile.in +++ b/src/libstrongswan/plugins/curl/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/curl/curl_plugin.c b/src/libstrongswan/plugins/curl/curl_plugin.c index d0e532055..8628c4bb5 100644 --- a/src/libstrongswan/plugins/curl/curl_plugin.c +++ b/src/libstrongswan/plugins/curl/curl_plugin.c @@ -40,11 +40,23 @@ METHOD(plugin_t, get_name, char*, return "curl"; } +METHOD(plugin_t, get_features, int, + private_curl_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(FETCHER, curl_fetcher_create), + PLUGIN_PROVIDE(FETCHER, "file://"), + PLUGIN_PROVIDE(FETCHER, "http://"), + PLUGIN_PROVIDE(FETCHER, "https://"), + PLUGIN_PROVIDE(FETCHER, "ftp://"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_curl_plugin_t *this) { - lib->fetcher->remove_fetcher(lib->fetcher, - (fetcher_constructor_t)curl_fetcher_create); curl_global_cleanup(); free(this); } @@ -61,28 +73,19 @@ plugin_t *curl_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); res = curl_global_init(CURL_GLOBAL_NOTHING); - if (res == CURLE_OK) - { - lib->fetcher->add_fetcher(lib->fetcher, - (fetcher_constructor_t)curl_fetcher_create, "file://"); - lib->fetcher->add_fetcher(lib->fetcher, - (fetcher_constructor_t)curl_fetcher_create, "http://"); - lib->fetcher->add_fetcher(lib->fetcher, - (fetcher_constructor_t)curl_fetcher_create, "https://"); - lib->fetcher->add_fetcher(lib->fetcher, - (fetcher_constructor_t)curl_fetcher_create, "ftp://"); - } - else + if (res != CURLE_OK) { - DBG1(DBG_LIB, "global libcurl initializing failed: %s, curl disabled", + DBG1(DBG_LIB, "global libcurl initializing failed: %s", curl_easy_strerror(res)); + destroy(this); + return NULL; } return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in index d24ac40f8..f4056951a 100644 --- a/src/libstrongswan/plugins/des/Makefile.in +++ b/src/libstrongswan/plugins/des/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/des/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c index 695e7e4c4..bc399ef8a 100644 --- a/src/libstrongswan/plugins/des/des_crypter.c +++ b/src/libstrongswan/plugins/des/des_crypter.c @@ -80,7 +80,7 @@ struct private_des_crypter_t { des_crypter_t public; /** - * Key size, depends on algoritm... + * Key size, depends on algorithm... */ size_t key_size; @@ -127,7 +127,7 @@ YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! #endif /* Unroll the inner loop, this sometimes helps, sometimes hinders. - * Very mucy CPU dependant */ + * Very much CPU dependent */ #ifndef DES_UNROLL #define DES_UNROLL #endif @@ -316,7 +316,7 @@ YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! * bytes, probably an issue of accessing non-word aligned objects :-( */ #ifdef DES_PTR -/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there +/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there * is no reason to not xor all the sub items together. This potentially * saves a register since things can be xored directly into L */ diff --git a/src/libstrongswan/plugins/des/des_plugin.c b/src/libstrongswan/plugins/des/des_plugin.c index 78b73347d..be2587679 100644 --- a/src/libstrongswan/plugins/des/des_plugin.c +++ b/src/libstrongswan/plugins/des/des_plugin.c @@ -37,11 +37,22 @@ METHOD(plugin_t, get_name, char*, return "des"; } +METHOD(plugin_t, get_features, int, + private_des_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(CRYPTER, des_crypter_create), + PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8), + PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_des_plugin_t *this) { - lib->crypto->remove_crypter(lib->crypto, - (crypter_constructor_t)des_crypter_create); free(this); } @@ -56,19 +67,12 @@ plugin_t *des_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->crypto->add_crypter(lib->crypto, ENCR_3DES, get_name(this), - (crypter_constructor_t)des_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_DES, get_name(this), - (crypter_constructor_t)des_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB, get_name(this), - (crypter_constructor_t)des_crypter_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in index 62c52498c..dabddd6d0 100644 --- a/src/libstrongswan/plugins/dnskey/Makefile.in +++ b/src/libstrongswan/plugins/dnskey/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/dnskey/dnskey_plugin.c b/src/libstrongswan/plugins/dnskey/dnskey_plugin.c index 4e08746f8..b6863e8e3 100644 --- a/src/libstrongswan/plugins/dnskey/dnskey_plugin.c +++ b/src/libstrongswan/plugins/dnskey/dnskey_plugin.c @@ -37,11 +37,22 @@ METHOD(plugin_t, get_name, char*, return "dnskey"; } +METHOD(plugin_t, get_features, int, + private_dnskey_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PUBKEY, dnskey_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + PLUGIN_REGISTER(PUBKEY, dnskey_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_dnskey_plugin_t *this) { - lib->creds->remove_builder(lib->creds, - (builder_function_t)dnskey_public_key_load); free(this); } @@ -56,15 +67,11 @@ plugin_t *dnskey_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE, - (builder_function_t)dnskey_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, FALSE, - (builder_function_t)dnskey_public_key_load); return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in index e88a102b8..cbe9ef303 100644 --- a/src/libstrongswan/plugins/fips_prf/Makefile.in +++ b/src/libstrongswan/plugins/fips_prf/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c index ee71f6efd..c0666367a 100644 --- a/src/libstrongswan/plugins/fips_prf/fips_prf.c +++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c @@ -127,14 +127,14 @@ METHOD(prf_t, get_bytes, void, { /* a. XVAL = (XKEY + XSEED j) mod 2^b */ add_mod(this->b, xkey, xseed, xval); - DBG3(DBG_LIB, "XVAL %b", xval, this->b); + DBG3(DBG_LIB, "XVAL %b", xval, (u_int)this->b); /* b. wi = G(t, XVAL ) */ this->g(this, chunk_create(xval, this->b), &w[i * this->b]); - DBG3(DBG_LIB, "w[%d] %b", i, &w[i * this->b], this->b); + DBG3(DBG_LIB, "w[%d] %b", i, &w[i * this->b], (u_int)this->b); /* c. XKEY = (1 + XKEY + wi) mod 2b */ add_mod(this->b, xkey, &w[i * this->b], sum); add_mod(this->b, sum, one, xkey); - DBG3(DBG_LIB, "XKEY %b", xkey, this->b); + DBG3(DBG_LIB, "XKEY %b", xkey, (u_int)this->b); } /* 3.3 done already, mod q not used */ diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c index 7038da146..68b6bacb2 100644 --- a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c +++ b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c @@ -37,11 +37,21 @@ METHOD(plugin_t, get_name, char*, return "fips-prf"; } +METHOD(plugin_t, get_features, int, + private_fips_prf_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRF, fips_prf_create), + PLUGIN_PROVIDE(PRF, PRF_FIPS_SHA1_160), + PLUGIN_DEPENDS(PRF, PRF_KEYED_SHA1), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_fips_prf_plugin_t *this) { - lib->crypto->remove_prf(lib->crypto, - (prf_constructor_t)fips_prf_create); free(this); } @@ -51,25 +61,16 @@ METHOD(plugin_t, destroy, void, plugin_t *fips_prf_plugin_create() { private_fips_prf_plugin_t *this; - prf_t *prf; INIT(this, .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1); - if (prf) - { - prf->destroy(prf); - lib->crypto->add_prf(lib->crypto, PRF_FIPS_SHA1_160, get_name(this), - (prf_constructor_t)fips_prf_create); - } - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in index 202849eb6..8285b5aeb 100644 --- a/src/libstrongswan/plugins/gcm/Makefile.in +++ b/src/libstrongswan/plugins/gcm/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/gcm/gcm_plugin.c b/src/libstrongswan/plugins/gcm/gcm_plugin.c index 4b46f0ee4..abfa4f007 100644 --- a/src/libstrongswan/plugins/gcm/gcm_plugin.c +++ b/src/libstrongswan/plugins/gcm/gcm_plugin.c @@ -38,12 +38,37 @@ METHOD(plugin_t, get_name, char*, return "gcm"; } +METHOD(plugin_t, get_features, int, + private_gcm_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(AEAD, gcm_aead_create), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 16), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_gcm_plugin_t *this) { - lib->crypto->remove_aead(lib->crypto, - (aead_constructor_t)gcm_aead_create); - free(this); } @@ -53,29 +78,16 @@ METHOD(plugin_t, destroy, void, plugin_t *gcm_plugin_create() { private_gcm_plugin_t *this; - crypter_t *crypter; INIT(this, .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 0); - if (crypter) - { - crypter->destroy(crypter); - lib->crypto->add_aead(lib->crypto, ENCR_AES_GCM_ICV8, get_name(this), - (aead_constructor_t)gcm_aead_create); - lib->crypto->add_aead(lib->crypto, ENCR_AES_GCM_ICV12, get_name(this), - (aead_constructor_t)gcm_aead_create); - lib->crypto->add_aead(lib->crypto, ENCR_AES_GCM_ICV16, get_name(this), - (aead_constructor_t)gcm_aead_create); - } - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in index bedb918b9..4dc72fed0 100644 --- a/src/libstrongswan/plugins/gcrypt/Makefile.in +++ b/src/libstrongswan/plugins/gcrypt/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c index e26277b0b..a48d4a133 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c @@ -99,25 +99,81 @@ METHOD(plugin_t, get_name, char*, return "gcrypt"; } +METHOD(plugin_t, get_features, int, + private_gcrypt_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + /* crypters */ + PLUGIN_REGISTER(CRYPTER, gcrypt_crypter_create), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 32), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32), + /* gcrypt only supports 128 bit blowfish */ + PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 16), +#ifdef HAVE_GCRY_CIPHER_CAMELLIA + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 32), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32), +#endif + PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0), + PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8), + PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8), + PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 32), + PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 32), + /* hashers */ + PLUGIN_REGISTER(HASHER, gcrypt_hasher_create), + PLUGIN_PROVIDE(HASHER, HASH_MD4), + PLUGIN_PROVIDE(HASHER, HASH_MD5), + PLUGIN_PROVIDE(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(HASHER, HASH_SHA224), + PLUGIN_PROVIDE(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(HASHER, HASH_SHA512), + /* MODP DH groups */ + PLUGIN_REGISTER(DH, gcrypt_dh_create), + PLUGIN_PROVIDE(DH, MODP_2048_BIT), + PLUGIN_PROVIDE(DH, MODP_2048_224), + PLUGIN_PROVIDE(DH, MODP_2048_256), + PLUGIN_PROVIDE(DH, MODP_1536_BIT), + PLUGIN_PROVIDE(DH, MODP_3072_BIT), + PLUGIN_PROVIDE(DH, MODP_4096_BIT), + PLUGIN_PROVIDE(DH, MODP_6144_BIT), + PLUGIN_PROVIDE(DH, MODP_8192_BIT), + PLUGIN_PROVIDE(DH, MODP_1024_BIT), + PLUGIN_PROVIDE(DH, MODP_1024_160), + PLUGIN_PROVIDE(DH, MODP_768_BIT), + PLUGIN_REGISTER(DH, gcrypt_dh_create_custom), + PLUGIN_PROVIDE(DH, MODP_CUSTOM), + /* RSA private/public key loading */ + PLUGIN_REGISTER(PUBKEY, gcrypt_rsa_public_key_load, TRUE), + PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + PLUGIN_REGISTER(PRIVKEY, gcrypt_rsa_private_key_load, TRUE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), + PLUGIN_REGISTER(PRIVKEY_GEN, gcrypt_rsa_private_key_gen, FALSE), + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA), + /* random numbers */ + PLUGIN_REGISTER(RNG, gcrypt_rng_create), + PLUGIN_PROVIDE(RNG, RNG_WEAK), + PLUGIN_PROVIDE(RNG, RNG_STRONG), + PLUGIN_PROVIDE(RNG, RNG_TRUE), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_gcrypt_plugin_t *this) { - lib->crypto->remove_hasher(lib->crypto, - (hasher_constructor_t)gcrypt_hasher_create); - lib->crypto->remove_crypter(lib->crypto, - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->remove_rng(lib->crypto, - (rng_constructor_t)gcrypt_rng_create); - lib->crypto->remove_dh(lib->crypto, - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->remove_dh(lib->crypto, - (dh_constructor_t)gcrypt_dh_create_custom); - lib->creds->remove_builder(lib->creds, - (builder_function_t)gcrypt_rsa_private_key_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)gcrypt_rsa_private_key_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)gcrypt_rsa_public_key_load); free(this); } @@ -149,96 +205,12 @@ plugin_t *gcrypt_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - /* hashers */ - lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this), - (hasher_constructor_t)gcrypt_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_MD4, get_name(this), - (hasher_constructor_t)gcrypt_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_MD5, get_name(this), - (hasher_constructor_t)gcrypt_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA224, get_name(this), - (hasher_constructor_t)gcrypt_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA256, get_name(this), - (hasher_constructor_t)gcrypt_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA384, get_name(this), - (hasher_constructor_t)gcrypt_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA512, get_name(this), - (hasher_constructor_t)gcrypt_hasher_create); - - /* crypters */ - lib->crypto->add_crypter(lib->crypto, ENCR_3DES, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_CAST, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_DES, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_AES_CTR, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); -#ifdef HAVE_GCRY_CIPHER_CAMELLIA - lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CBC, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CTR, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); -#endif /* HAVE_GCRY_CIPHER_CAMELLIA */ - lib->crypto->add_crypter(lib->crypto, ENCR_SERPENT_CBC, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_TWOFISH_CBC, get_name(this), - (crypter_constructor_t)gcrypt_crypter_create); - - /* random numbers */ - lib->crypto->add_rng(lib->crypto, RNG_WEAK, get_name(this), - (rng_constructor_t)gcrypt_rng_create); - lib->crypto->add_rng(lib->crypto, RNG_STRONG, get_name(this), - (rng_constructor_t)gcrypt_rng_create); - lib->crypto->add_rng(lib->crypto, RNG_TRUE, get_name(this), - (rng_constructor_t)gcrypt_rng_create); - - /* diffie hellman groups, using modp */ - lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_2048_224, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_2048_256, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_1024_BIT, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_1024_160, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_768_BIT, get_name(this), - (dh_constructor_t)gcrypt_dh_create); - lib->crypto->add_dh(lib->crypto, MODP_CUSTOM, get_name(this), - (dh_constructor_t)gcrypt_dh_create_custom); - - /* RSA */ - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE, - (builder_function_t)gcrypt_rsa_private_key_gen); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, TRUE, - (builder_function_t)gcrypt_rsa_private_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE, - (builder_function_t)gcrypt_rsa_public_key_load); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c index 38ce2cd6c..eb38eea3b 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c @@ -68,7 +68,7 @@ chunk_t gcrypt_rsa_find_token(gcry_sexp_t sexp, char *name, gcry_sexp_t key) if (key) { /* gcrypt might return more bytes than necessary. Truncate - * to key lenght if key given, or prepend zeros if needed */ + * to key length if key given, or prepend zeros if needed */ len = gcry_pk_get_nbits(key); len = len / 8 + (len % 8 ? 1 : 0); if (len > data.len) @@ -504,7 +504,7 @@ gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_load(key_type_t type, va_list args) { private_gcrypt_rsa_private_key_t *this; - chunk_t n, e, d, p, q, exp, u; + chunk_t n, e, d, p, q, u; gcry_error_t err; n = e = d = p = q = u = chunk_empty; @@ -531,7 +531,7 @@ gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_load(key_type_t type, case BUILD_RSA_EXP1: case BUILD_RSA_EXP2: /* not required for gcrypt */ - exp = va_arg(args, chunk_t); + va_arg(args, chunk_t); continue; case BUILD_RSA_COEFF: u = va_arg(args, chunk_t); diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in index 18592ab4a..34a23312b 100644 --- a/src/libstrongswan/plugins/gmp/Makefile.in +++ b/src/libstrongswan/plugins/gmp/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c index 55ccd4a4f..d93aa14a1 100644 --- a/src/libstrongswan/plugins/gmp/gmp_plugin.c +++ b/src/libstrongswan/plugins/gmp/gmp_plugin.c @@ -39,19 +39,85 @@ METHOD(plugin_t, get_name, char*, return "gmp"; } +METHOD(plugin_t, get_features, int, + private_gmp_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + /* DH groups */ + PLUGIN_REGISTER(DH, gmp_diffie_hellman_create), + PLUGIN_PROVIDE(DH, MODP_2048_BIT), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_2048_224), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_2048_256), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_1536_BIT), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_3072_BIT), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_4096_BIT), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_6144_BIT), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_8192_BIT), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_1024_BIT), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_1024_160), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_PROVIDE(DH, MODP_768_BIT), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + PLUGIN_REGISTER(DH, gmp_diffie_hellman_create_custom), + PLUGIN_PROVIDE(DH, MODP_CUSTOM), + PLUGIN_DEPENDS(RNG, RNG_STRONG), + /* private/public keys */ + PLUGIN_REGISTER(PRIVKEY, gmp_rsa_private_key_load, TRUE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), + PLUGIN_REGISTER(PRIVKEY_GEN, gmp_rsa_private_key_gen, FALSE), + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA), + PLUGIN_DEPENDS(RNG, RNG_TRUE), + PLUGIN_REGISTER(PUBKEY, gmp_rsa_public_key_load, TRUE), + PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + /* signature schemes, private */ + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA224), + PLUGIN_DEPENDS(HASHER, HASH_SHA224), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA256), + PLUGIN_DEPENDS(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA384), + PLUGIN_DEPENDS(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA512), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + /* signature verification schemes */ + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA224), + PLUGIN_DEPENDS(HASHER, HASH_SHA224), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA256), + PLUGIN_DEPENDS(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA384), + PLUGIN_DEPENDS(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA512), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + /* en-/decryption schemes */ + PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1), + PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_gmp_plugin_t *this) { - lib->crypto->remove_dh(lib->crypto, - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->remove_dh(lib->crypto, - (dh_constructor_t)gmp_diffie_hellman_create_custom); - lib->creds->remove_builder(lib->creds, - (builder_function_t)gmp_rsa_private_key_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)gmp_rsa_private_key_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)gmp_rsa_public_key_load); free(this); } @@ -66,45 +132,12 @@ plugin_t *gmp_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_2048_224, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_2048_256, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_1024_BIT, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_1024_160, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_768_BIT, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create); - - lib->crypto->add_dh(lib->crypto, MODP_CUSTOM, get_name(this), - (dh_constructor_t)gmp_diffie_hellman_create_custom); - - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE, - (builder_function_t)gmp_rsa_private_key_gen); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, TRUE, - (builder_function_t)gmp_rsa_private_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE, - (builder_function_t)gmp_rsa_public_key_load); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c index a7ba80138..898892f5b 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c @@ -137,7 +137,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this, if (signature.len == 0 || signature.len > this->k) { - return INVALID_ARG; + return FALSE; } /* unpack signature */ diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in index b9e2cd817..5242764d4 100644 --- a/src/libstrongswan/plugins/hmac/Makefile.in +++ b/src/libstrongswan/plugins/hmac/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c index 397a1ea11..91294305e 100644 --- a/src/libstrongswan/plugins/hmac/hmac.c +++ b/src/libstrongswan/plugins/hmac/hmac.c @@ -4,13 +4,13 @@ * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General hmac License as published by the + * 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 hmac License + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ diff --git a/src/libstrongswan/plugins/hmac/hmac.h b/src/libstrongswan/plugins/hmac/hmac.h index be1bce66d..1ed041596 100644 --- a/src/libstrongswan/plugins/hmac/hmac.h +++ b/src/libstrongswan/plugins/hmac/hmac.h @@ -29,8 +29,8 @@ typedef struct hmac_t hmac_t; /** * Message authentication using hash functions. * - * This class implements the message authenticaion algorithm - * described in RFC2104. It uses a hash function, wich must + * This class implements the message authentication algorithm + * described in RFC2104. It uses a hash function, which must * be implemented as a hasher_t class. */ struct hmac_t { diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.c b/src/libstrongswan/plugins/hmac/hmac_plugin.c index 47d6d3cde..7d9ff3c67 100644 --- a/src/libstrongswan/plugins/hmac/hmac_plugin.c +++ b/src/libstrongswan/plugins/hmac/hmac_plugin.c @@ -38,13 +38,50 @@ METHOD(plugin_t, get_name, char*, return "hmac"; } +METHOD(plugin_t, get_features, int, + private_hmac_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRF, hmac_prf_create), + PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256), + PLUGIN_DEPENDS(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384), + PLUGIN_DEPENDS(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + PLUGIN_REGISTER(SIGNER, hmac_signer_create), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_96), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_128), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_160), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_96), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_128), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_128), + PLUGIN_DEPENDS(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_256), + PLUGIN_DEPENDS(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_192), + PLUGIN_DEPENDS(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_384), + PLUGIN_DEPENDS(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_hmac_plugin_t *this) { - lib->crypto->remove_prf(lib->crypto, - (prf_constructor_t)hmac_prf_create); - lib->crypto->remove_signer(lib->crypto, - (signer_constructor_t)hmac_signer_create); free(this); } @@ -54,75 +91,17 @@ METHOD(plugin_t, destroy, void, plugin_t *hmac_plugin_create() { private_hmac_plugin_t *this; - hasher_t *hasher; INIT(this, .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (hasher) - { - hasher->destroy(hasher); - lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA1, get_name(this), - (prf_constructor_t)hmac_prf_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_96, get_name(this), - (signer_constructor_t)hmac_signer_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_128, get_name(this), - (signer_constructor_t)hmac_signer_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_160, get_name(this), - (signer_constructor_t)hmac_signer_create); - } - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA256); - if (hasher) - { - hasher->destroy(hasher); - lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_256, get_name(this), - (prf_constructor_t)hmac_prf_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_256_128, get_name(this), - (signer_constructor_t)hmac_signer_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_256_256, get_name(this), - (signer_constructor_t)hmac_signer_create); - - } - hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5); - if (hasher) - { - hasher->destroy(hasher); - lib->crypto->add_prf(lib->crypto, PRF_HMAC_MD5, get_name(this), - (prf_constructor_t)hmac_prf_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_96, get_name(this), - (signer_constructor_t)hmac_signer_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_128, get_name(this), - (signer_constructor_t)hmac_signer_create); - } - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA384); - if (hasher) - { - hasher->destroy(hasher); - lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_384, get_name(this), - (prf_constructor_t)hmac_prf_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_384_192, get_name(this), - (signer_constructor_t)hmac_signer_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_384_384, get_name(this), - (signer_constructor_t)hmac_signer_create); - } - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512); - if (hasher) - { - hasher->destroy(hasher); - lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_512, get_name(this), - (prf_constructor_t)hmac_prf_create); - lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_512_256, get_name(this), - (signer_constructor_t)hmac_signer_create); - } - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in index b496ace28..851df5667 100644 --- a/src/libstrongswan/plugins/ldap/Makefile.in +++ b/src/libstrongswan/plugins/ldap/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.c b/src/libstrongswan/plugins/ldap/ldap_plugin.c index 08d9748ce..210d33a93 100644 --- a/src/libstrongswan/plugins/ldap/ldap_plugin.c +++ b/src/libstrongswan/plugins/ldap/ldap_plugin.c @@ -37,11 +37,21 @@ METHOD(plugin_t, get_name, char*, return "ldap"; } +METHOD(plugin_t, get_features, int, + private_ldap_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(FETCHER, ldap_fetcher_create), + PLUGIN_PROVIDE(FETCHER, "ldap://"), + PLUGIN_PROVIDE(FETCHER, "ldaps://"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_ldap_plugin_t *this) { - lib->fetcher->remove_fetcher(lib->fetcher, - (fetcher_constructor_t)ldap_fetcher_create); free(this); } @@ -56,17 +66,12 @@ plugin_t *ldap_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->fetcher->add_fetcher(lib->fetcher, - (fetcher_constructor_t)ldap_fetcher_create, "ldap://"); - lib->fetcher->add_fetcher(lib->fetcher, - (fetcher_constructor_t)ldap_fetcher_create, "ldaps://"); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in index 82781054b..f5b06a0df 100644 --- a/src/libstrongswan/plugins/md4/Makefile.in +++ b/src/libstrongswan/plugins/md4/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/md4/md4_hasher.c b/src/libstrongswan/plugins/md4/md4_hasher.c index 366d37328..6a31017c2 100644 --- a/src/libstrongswan/plugins/md4/md4_hasher.c +++ b/src/libstrongswan/plugins/md4/md4_hasher.c @@ -268,10 +268,8 @@ static void MD4Final (private_md4_hasher_t *this, u_int8_t digest[16]) -/** - * Implementation of hasher_t.get_hash. - */ -static void get_hash(private_md4_hasher_t *this, chunk_t chunk, u_int8_t *buffer) +METHOD(hasher_t, get_hash, void, + private_md4_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { MD4Update(this, chunk.ptr, chunk.len); if (buffer != NULL) @@ -281,11 +279,8 @@ static void get_hash(private_md4_hasher_t *this, chunk_t chunk, u_int8_t *buffer } } - -/** - * Implementation of hasher_t.allocate_hash. - */ -static void allocate_hash(private_md4_hasher_t *this, chunk_t chunk, chunk_t *hash) +METHOD(hasher_t, allocate_hash, void, + private_md4_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -302,18 +297,14 @@ static void allocate_hash(private_md4_hasher_t *this, chunk_t chunk, chunk_t *ha } } -/** - * Implementation of hasher_t.get_hash_size. - */ -static size_t get_hash_size(private_md4_hasher_t *this) +METHOD(hasher_t, get_hash_size, size_t, + private_md4_hasher_t *this) { return HASH_SIZE_MD4; } -/** - * Implementation of hasher_t.reset. - */ -static void reset(private_md4_hasher_t *this) +METHOD(hasher_t, reset, void, + private_md4_hasher_t *this) { this->state[0] = 0x67452301; this->state[1] = 0xefcdab89; @@ -323,10 +314,8 @@ static void reset(private_md4_hasher_t *this) this->count[1] = 0; } -/** - * Implementation of hasher_t.destroy. - */ -static void destroy(private_md4_hasher_t *this) +METHOD(hasher_t, destroy, void, + private_md4_hasher_t *this) { free(this); } @@ -342,13 +331,18 @@ md4_hasher_t *md4_hasher_create(hash_algorithm_t algo) { return NULL; } - this = malloc_thing(private_md4_hasher_t); - this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash; - this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash; - this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size; - this->public.hasher_interface.reset = (void (*) (hasher_t*))reset; - this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy; + INIT(this, + .public = { + .hasher_interface = { + .get_hash = _get_hash, + .allocate_hash = _allocate_hash, + .get_hash_size = _get_hash_size, + .reset = _reset, + .destroy = _destroy, + }, + }, + ); /* initialize */ reset(this); diff --git a/src/libstrongswan/plugins/md4/md4_plugin.c b/src/libstrongswan/plugins/md4/md4_plugin.c index 371bba280..baa44b7f5 100644 --- a/src/libstrongswan/plugins/md4/md4_plugin.c +++ b/src/libstrongswan/plugins/md4/md4_plugin.c @@ -37,11 +37,20 @@ METHOD(plugin_t, get_name, char*, return "md4"; } +METHOD(plugin_t, get_features, int, + private_md4_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(HASHER, md4_hasher_create), + PLUGIN_PROVIDE(HASHER, HASH_MD4), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_md4_plugin_t *this) { - lib->crypto->remove_hasher(lib->crypto, - (hasher_constructor_t)md4_hasher_create); free(this); } @@ -56,15 +65,12 @@ plugin_t *md4_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->crypto->add_hasher(lib->crypto, HASH_MD4, get_name(this), - (hasher_constructor_t)md4_hasher_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in index 0e3c37e7e..f7762c37e 100644 --- a/src/libstrongswan/plugins/md5/Makefile.in +++ b/src/libstrongswan/plugins/md5/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/md5/md5_hasher.c b/src/libstrongswan/plugins/md5/md5_hasher.c index a97ad5cae..45c2391ef 100644 --- a/src/libstrongswan/plugins/md5/md5_hasher.c +++ b/src/libstrongswan/plugins/md5/md5_hasher.c @@ -299,12 +299,8 @@ static void MD5Final (private_md5_hasher_t *this, u_int8_t digest[16]) } } - - -/** - * Implementation of hasher_t.get_hash. - */ -static void get_hash(private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer) +METHOD(hasher_t, get_hash, void, + private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { MD5Update(this, chunk.ptr, chunk.len); if (buffer != NULL) @@ -314,11 +310,8 @@ static void get_hash(private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer } } - -/** - * Implementation of hasher_t.allocate_hash. - */ -static void allocate_hash(private_md5_hasher_t *this, chunk_t chunk, chunk_t *hash) +METHOD(hasher_t, allocate_hash, void, + private_md5_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -335,18 +328,14 @@ static void allocate_hash(private_md5_hasher_t *this, chunk_t chunk, chunk_t *ha } } -/** - * Implementation of hasher_t.get_hash_size. - */ -static size_t get_hash_size(private_md5_hasher_t *this) +METHOD(hasher_t, get_hash_size, size_t, + private_md5_hasher_t *this) { return HASH_SIZE_MD5; } -/** - * Implementation of hasher_t.reset. - */ -static void reset(private_md5_hasher_t *this) +METHOD(hasher_t, reset, void, + private_md5_hasher_t *this) { this->state[0] = 0x67452301; this->state[1] = 0xefcdab89; @@ -356,10 +345,8 @@ static void reset(private_md5_hasher_t *this) this->count[1] = 0; } -/** - * Implementation of hasher_t.destroy. - */ -static void destroy(private_md5_hasher_t *this) +METHOD(hasher_t, destroy, void, + private_md5_hasher_t *this) { free(this); } @@ -375,13 +362,18 @@ md5_hasher_t *md5_hasher_create(hash_algorithm_t algo) { return NULL; } - this = malloc_thing(private_md5_hasher_t); - this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash; - this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash; - this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size; - this->public.hasher_interface.reset = (void (*) (hasher_t*))reset; - this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy; + INIT(this, + .public = { + .hasher_interface = { + .get_hash = _get_hash, + .allocate_hash = _allocate_hash, + .get_hash_size = _get_hash_size, + .reset = _reset, + .destroy = _destroy, + }, + }, + ); /* initialize */ reset(this); diff --git a/src/libstrongswan/plugins/md5/md5_plugin.c b/src/libstrongswan/plugins/md5/md5_plugin.c index c72284193..a3ad7b305 100644 --- a/src/libstrongswan/plugins/md5/md5_plugin.c +++ b/src/libstrongswan/plugins/md5/md5_plugin.c @@ -37,6 +37,17 @@ METHOD(plugin_t, get_name, char*, return "md5"; } +METHOD(plugin_t, get_features, int, + private_md5_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(HASHER, md5_hasher_create), + PLUGIN_PROVIDE(HASHER, HASH_MD5), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_md5_plugin_t *this) { @@ -56,15 +67,12 @@ plugin_t *md5_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->crypto->add_hasher(lib->crypto, HASH_MD5, get_name(this), - (hasher_constructor_t)md5_hasher_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in index 32067d5b4..5025a0eb8 100644 --- a/src/libstrongswan/plugins/mysql/Makefile.in +++ b/src/libstrongswan/plugins/mysql/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c index 5fbfa0f28..25ea42a4f 100644 --- a/src/libstrongswan/plugins/mysql/mysql_database.c +++ b/src/libstrongswan/plugins/mysql/mysql_database.c @@ -20,6 +20,7 @@ #include "mysql_database.h" #include <debug.h> +#include <chunk.h> #include <threading/thread_value.h> #include <threading/mutex.h> #include <utils/linked_list.h> diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.c b/src/libstrongswan/plugins/mysql/mysql_plugin.c index 579df4d50..dd8b32761 100644 --- a/src/libstrongswan/plugins/mysql/mysql_plugin.c +++ b/src/libstrongswan/plugins/mysql/mysql_plugin.c @@ -38,11 +38,20 @@ METHOD(plugin_t, get_name, char*, return "mysql"; } +METHOD(plugin_t, get_features, int, + private_mysql_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(DATABASE, mysql_database_create), + PLUGIN_PROVIDE(DATABASE, DB_MYSQL), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_mysql_plugin_t *this) { - lib->db->remove_database(lib->db, - (database_constructor_t)mysql_database_create); mysql_database_deinit(); free(this); } @@ -64,15 +73,12 @@ plugin_t *mysql_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->db->add_database(lib->db, - (database_constructor_t)mysql_database_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in index d1c8fce81..8994ff1b4 100644 --- a/src/libstrongswan/plugins/openssl/Makefile.in +++ b/src/libstrongswan/plugins/openssl/Makefile.in @@ -198,6 +198,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -206,6 +209,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -222,11 +226,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -270,6 +276,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c index 58401faa5..9a9efb2b6 100644 --- a/src/libstrongswan/plugins/openssl/openssl_crl.c +++ b/src/libstrongswan/plugins/openssl/openssl_crl.c @@ -185,7 +185,7 @@ METHOD(crl_t, create_enumerator, enumerator_t*, free(enumerator); return enumerator_create_empty(); } - enumerator->num = sk_X509_EXTENSION_num(enumerator->stack); + enumerator->num = sk_X509_REVOKED_num(enumerator->stack); return &enumerator->public; } diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c index 78ed2811a..9e4067589 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c @@ -219,7 +219,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void, return; } - chunk_free(&this->shared_secret); + chunk_clear(&this->shared_secret); if (!compute_shared_key(this, &this->shared_secret)) { DBG1(DBG_LIB, "ECDH shared secret computation failed"); diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c index f4c4759bf..950504573 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c @@ -1,6 +1,6 @@ /* + * Copyright (C) 2008-2012 Tobias Brunner * Copyright (C) 2009 Martin Willi - * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -371,14 +371,17 @@ openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type, va_list args) { private_openssl_ec_private_key_t *this; - chunk_t blob = chunk_empty; + chunk_t par = chunk_empty, key = chunk_empty; while (TRUE) { switch (va_arg(args, builder_part_t)) { + case BUILD_BLOB_ALGID_PARAMS: + par = va_arg(args, chunk_t); + continue; case BUILD_BLOB_ASN1_DER: - blob = va_arg(args, chunk_t); + key = va_arg(args, chunk_t); continue; case BUILD_END: break; @@ -389,18 +392,36 @@ openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type, } this = create_empty(); - this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len); - if (!this->ec) + + if (par.ptr) { - destroy(this); - return NULL; + this->ec = d2i_ECParameters(NULL, (const u_char**)&par.ptr, par.len); + if (!this->ec) + { + goto error; + } + if (!d2i_ECPrivateKey(&this->ec, (const u_char**)&key.ptr, key.len)) + { + goto error; + } + } + else + { + this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&key.ptr, key.len); + if (!this->ec) + { + goto error; + } } if (!EC_KEY_check_key(this->ec)) { - destroy(this); - return NULL; + goto error; } return &this->public; + +error: + destroy(this); + return NULL; } #endif /* OPENSSL_NO_EC */ diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c index 96aa38bb6..c93ceacc9 100644 --- a/src/libstrongswan/plugins/openssl/openssl_plugin.c +++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c @@ -199,40 +199,175 @@ METHOD(plugin_t, get_name, char*, return "openssl"; } +METHOD(plugin_t, get_features, int, + private_openssl_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + /* crypters */ + PLUGIN_REGISTER(CRYPTER, openssl_crypter_create), +#ifndef OPENSSL_NO_AES + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32), +#endif +#ifndef OPENSSL_NO_CAMELLIA + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32), +#endif +#ifndef OPENSSL_NO_RC5 + PLUGIN_PROVIDE(CRYPTER, ENCR_RC5, 0), +#endif +#ifndef OPENSSL_NO_CAST + PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0), +#endif +#ifndef OPENSSL_NO_BLOWFISH + PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 0), +#endif +#ifndef OPENSSL_NO_IDEA + PLUGIN_PROVIDE(CRYPTER, ENCR_IDEA, 16), +#endif +#ifndef OPENSSL_NO_DES + PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24), + PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8), + PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8), +#endif + PLUGIN_PROVIDE(CRYPTER, ENCR_NULL, 0), + /* hashers */ + PLUGIN_REGISTER(HASHER, openssl_hasher_create), +#ifndef OPENSSL_NO_SHA1 + PLUGIN_PROVIDE(HASHER, HASH_SHA1), +#endif +#ifndef OPENSSL_NO_MD2 + PLUGIN_PROVIDE(HASHER, HASH_MD2), +#endif +#ifndef OPENSSL_NO_MD4 + PLUGIN_PROVIDE(HASHER, HASH_MD4), +#endif +#ifndef OPENSSL_NO_MD5 + PLUGIN_PROVIDE(HASHER, HASH_MD5), +#endif +#ifndef OPENSSL_NO_SHA256 + PLUGIN_PROVIDE(HASHER, HASH_SHA224), + PLUGIN_PROVIDE(HASHER, HASH_SHA256), +#endif +#ifndef OPENSSL_NO_SHA512 + PLUGIN_PROVIDE(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(HASHER, HASH_SHA512), +#endif +#ifndef OPENSSL_NO_SHA1 + /* keyed sha1 hasher (aka prf) */ + PLUGIN_REGISTER(PRF, openssl_sha1_prf_create), + PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1), +#endif +#ifndef OPENSSL_NO_DH + /* MODP DH groups */ + PLUGIN_REGISTER(DH, openssl_diffie_hellman_create), + PLUGIN_PROVIDE(DH, MODP_2048_BIT), + PLUGIN_PROVIDE(DH, MODP_2048_224), + PLUGIN_PROVIDE(DH, MODP_2048_256), + PLUGIN_PROVIDE(DH, MODP_1536_BIT), + PLUGIN_PROVIDE(DH, MODP_3072_BIT), + PLUGIN_PROVIDE(DH, MODP_4096_BIT), + PLUGIN_PROVIDE(DH, MODP_6144_BIT), + PLUGIN_PROVIDE(DH, MODP_8192_BIT), + PLUGIN_PROVIDE(DH, MODP_1024_BIT), + PLUGIN_PROVIDE(DH, MODP_1024_160), + PLUGIN_PROVIDE(DH, MODP_768_BIT), + PLUGIN_PROVIDE(DH, MODP_CUSTOM), +#endif +#ifndef OPENSSL_NO_RSA + /* RSA private/public key loading */ + PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_load, TRUE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), + PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_connect, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), + PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE), + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA), + PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE), + PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + /* signature/encryption schemes */ + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL), +#ifndef OPENSSL_NO_SHA1 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1), +#endif +#ifndef OPENSSL_NO_SHA256 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA224), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA256), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA224), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA256), +#endif +#ifndef OPENSSL_NO_SHA512 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA384), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA512), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA384), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA512), +#endif +#ifndef OPENSSL_NO_MD5 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5), +#endif + PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1), + PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1), +#endif /* OPENSSL_NO_RSA */ + /* certificate/CRL loading */ + PLUGIN_REGISTER(CERT_DECODE, openssl_x509_load, TRUE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), + PLUGIN_REGISTER(CERT_DECODE, openssl_crl_load, TRUE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL), +#ifndef OPENSSL_NO_ECDH + /* EC DH groups */ + PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create), + PLUGIN_PROVIDE(DH, ECP_256_BIT), + PLUGIN_PROVIDE(DH, ECP_384_BIT), + PLUGIN_PROVIDE(DH, ECP_521_BIT), + PLUGIN_PROVIDE(DH, ECP_224_BIT), + PLUGIN_PROVIDE(DH, ECP_192_BIT), +#endif +#ifndef OPENSSL_NO_ECDSA + /* EC private/public key loading */ + PLUGIN_REGISTER(PRIVKEY, openssl_ec_private_key_load, TRUE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA), + PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ec_private_key_gen, FALSE), + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA), + PLUGIN_REGISTER(PUBKEY, openssl_ec_public_key_load, TRUE), + PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA), + /* signature encryption schemes */ + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL), +#ifndef OPENSSL_NO_SHA1 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA1_DER), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA1_DER), +#endif +#ifndef OPENSSL_NO_SHA256 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA256_DER), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA256_DER), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_256), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_256), +#endif +#ifndef OPENSSL_NO_SHA512 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA384_DER), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA512_DER), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA384_DER), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA512_DER), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_384), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_521), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_384), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521), +#endif +#endif /* OPENSSL_NO_ECDSA */ + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_openssl_plugin_t *this) { - lib->crypto->remove_crypter(lib->crypto, - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->remove_hasher(lib->crypto, - (hasher_constructor_t)openssl_hasher_create); - lib->crypto->remove_prf(lib->crypto, - (prf_constructor_t)openssl_sha1_prf_create); - lib->crypto->remove_dh(lib->crypto, - (dh_constructor_t)openssl_diffie_hellman_create); - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_rsa_private_key_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_rsa_private_key_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_rsa_private_key_connect); - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_rsa_public_key_load); -#ifndef OPENSSL_NO_EC - lib->crypto->remove_dh(lib->crypto, - (dh_constructor_t)openssl_ec_diffie_hellman_create); - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_ec_private_key_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_ec_private_key_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_ec_public_key_load); -#endif /* OPENSSL_NO_EC */ - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_x509_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)openssl_crl_load); - #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif /* OPENSSL_NO_ENGINE */ @@ -255,7 +390,7 @@ plugin_t *openssl_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, @@ -279,116 +414,6 @@ plugin_t *openssl_plugin_create() return NULL; } - /* crypter */ - lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CBC, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_3DES, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_RC5, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_IDEA, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_CAST, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_DES, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - lib->crypto->add_crypter(lib->crypto, ENCR_NULL, get_name(this), - (crypter_constructor_t)openssl_crypter_create); - - /* hasher */ - lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this), - (hasher_constructor_t)openssl_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_MD2, get_name(this), - (hasher_constructor_t)openssl_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_MD4, get_name(this), - (hasher_constructor_t)openssl_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_MD5, get_name(this), - (hasher_constructor_t)openssl_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA224, get_name(this), - (hasher_constructor_t)openssl_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA256, get_name(this), - (hasher_constructor_t)openssl_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA384, get_name(this), - (hasher_constructor_t)openssl_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA512, get_name(this), - (hasher_constructor_t)openssl_hasher_create); - - /* prf */ - lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1, get_name(this), - (prf_constructor_t)openssl_sha1_prf_create); - - /* (ec) diffie hellman */ - lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_2048_224, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_2048_256, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); -#ifndef OPENSSL_NO_EC - lib->crypto->add_dh(lib->crypto, ECP_256_BIT, get_name(this), - (dh_constructor_t)openssl_ec_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, ECP_384_BIT, get_name(this), - (dh_constructor_t)openssl_ec_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, ECP_521_BIT, get_name(this), - (dh_constructor_t)openssl_ec_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, ECP_224_BIT, get_name(this), - (dh_constructor_t)openssl_ec_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, ECP_192_BIT, get_name(this), - (dh_constructor_t)openssl_ec_diffie_hellman_create); -#endif /* OPENSSL_NO_EC */ - lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_1024_BIT, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_1024_160, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_768_BIT, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - lib->crypto->add_dh(lib->crypto, MODP_CUSTOM, get_name(this), - (dh_constructor_t)openssl_diffie_hellman_create); - - /* rsa */ - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, TRUE, - (builder_function_t)openssl_rsa_private_key_load); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE, - (builder_function_t)openssl_rsa_private_key_gen); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE, - (builder_function_t)openssl_rsa_private_key_connect); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE, - (builder_function_t)openssl_rsa_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE, - (builder_function_t)openssl_rsa_public_key_load); - -#ifndef OPENSSL_NO_EC - /* ecdsa */ - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, TRUE, - (builder_function_t)openssl_ec_private_key_load); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, FALSE, - (builder_function_t)openssl_ec_private_key_gen); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, TRUE, - (builder_function_t)openssl_ec_public_key_load); -#endif /* OPENSSL_NO_EC */ - - /* X509 certificates */ - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, TRUE, - (builder_function_t)openssl_x509_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, TRUE, - (builder_function_t)openssl_crl_load); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index 422e31521..a24bae5d6 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -44,6 +44,8 @@ struct private_openssl_rsa_public_key_t { refcount_t ref; }; + + /** * Verification of an EMPSA PKCS1 signature described in PKCS#1 */ @@ -386,4 +388,3 @@ openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type, destroy(this); return NULL; } - diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c index 99dca3631..1eb1c6723 100644 --- a/src/libstrongswan/plugins/openssl/openssl_util.c +++ b/src/libstrongswan/plugins/openssl/openssl_util.c @@ -130,7 +130,7 @@ chunk_t openssl_asn1_obj2chunk(ASN1_OBJECT *asn1) { if (asn1) { - return chunk_create(asn1->data, asn1->length); + return chunk_create((u_char*)asn1->data, asn1->length); } return chunk_empty; } diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c index f7495b2ae..5caf5182c 100644 --- a/src/libstrongswan/plugins/openssl/openssl_x509.c +++ b/src/libstrongswan/plugins/openssl/openssl_x509.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -597,7 +600,7 @@ static bool parse_basicConstraints_ext(private_openssl_x509_t *this, } if (constraints->pathlen) { - + pathlen = ASN1_INTEGER_get(constraints->pathlen); this->pathlen = (pathlen >= 0 && pathlen < 128) ? pathlen : X509_NO_CONSTRAINT; @@ -609,6 +612,41 @@ static bool parse_basicConstraints_ext(private_openssl_x509_t *this, } /** + * parse key usage + */ +static bool parse_keyUsage_ext(private_openssl_x509_t *this, + X509_EXTENSION *ext) +{ + ASN1_BIT_STRING *usage; + + usage = X509V3_EXT_d2i(ext); + if (usage) + { + if (usage->length > 0) + { + int flags = usage->data[0]; + if (usage->length > 1) + { + flags |= usage->data[1] << 8; + } + switch (flags) + { + case X509v3_KU_CRL_SIGN: + this->flags |= X509_CRL_SIGN; + break; + case X509v3_KU_KEY_CERT_SIGN: + /* we use the caBasicContraint, MUST be set */ + default: + break; + } + } + ASN1_BIT_STRING_free(usage); + return TRUE; + } + return FALSE; +} + +/** * Parse CRL distribution points */ static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this, @@ -713,7 +751,7 @@ static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this, { if (asprintf(&uri, "%Y", id) > 0) { - this->ocsp_uris->insert_first(this->ocsp_uris, uri); + this->ocsp_uris->insert_last(this->ocsp_uris, uri); } id->destroy(id); } @@ -804,6 +842,9 @@ static bool parse_extensions(private_openssl_x509_t *this) case NID_basic_constraints: ok = parse_basicConstraints_ext(this, ext); break; + case NID_key_usage: + ok = parse_keyUsage_ext(this, ext); + break; case NID_crl_distribution_points: ok = parse_crlDistributionPoints_ext(this, ext); break; diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in index 7bc342995..6ff607456 100644 --- a/src/libstrongswan/plugins/padlock/Makefile.in +++ b/src/libstrongswan/plugins/padlock/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in index 92c7fa2fe..98c196ef4 100644 --- a/src/libstrongswan/plugins/pem/Makefile.in +++ b/src/libstrongswan/plugins/pem/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c index b760adda9..c5d96be47 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.c +++ b/src/libstrongswan/plugins/pem/pem_builder.c @@ -73,7 +73,7 @@ static bool find_boundary(char* tag, chunk_t *line) { if (present("-----", line)) { - DBG2(DBG_LIB, " -----%s %.*s-----", tag, (int)name.len, name.ptr); + DBG2(DBG_ASN, " -----%s %.*s-----", tag, (int)name.len, name.ptr); return TRUE; } line->ptr++; line->len--; name.len++; @@ -99,7 +99,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5); if (hasher == NULL) { - DBG1(DBG_LIB, " MD5 hash algorithm not available"); + DBG1(DBG_ASN, " MD5 hash algorithm not available"); return NOT_SUPPORTED; } hash.len = hasher->get_hash_size(hasher); @@ -121,7 +121,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size); if (crypter == NULL) { - DBG1(DBG_LIB, " %N encryption algorithm not available", + DBG1(DBG_ASN, " %N encryption algorithm not available", encryption_algorithm_names, alg); return NOT_SUPPORTED; } @@ -131,7 +131,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, blob->len % crypter->get_block_size(crypter)) { crypter->destroy(crypter); - DBG1(DBG_LIB, " data size is not multiple of block size"); + DBG1(DBG_ASN, " data size is not multiple of block size"); return PARSE_ERROR; } crypter->decrypt(crypter, *blob, iv, &decrypted); @@ -155,7 +155,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, { if (*last_padding_pos != padding) { - DBG1(DBG_LIB, " invalid passphrase"); + DBG1(DBG_ASN, " invalid passphrase"); return INVALID_ARG; } } @@ -234,7 +234,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp) } /* we are looking for a parameter: value pair */ - DBG2(DBG_LIB, " %.*s", (int)line.len, line.ptr); + DBG2(DBG_ASN, " %.*s", (int)line.len, line.ptr); ugh = extract_parameter_value(&name, &value, &line); if (ugh != NULL) { @@ -274,7 +274,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp) } else { - DBG1(DBG_LIB, " encryption algorithm '%.*s'" + DBG1(DBG_ASN, " encryption algorithm '%.*s'" " not supported", dek.len, dek.ptr); return NOT_SUPPORTED; } @@ -298,7 +298,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp) *pgp = TRUE; data.ptr++; data.len--; - DBG2(DBG_LIB, " armor checksum: %.*s", (int)data.len, + DBG2(DBG_ASN, " armor checksum: %.*s", (int)data.len, data.ptr); continue; } @@ -355,7 +355,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp) * load the credential from a blob */ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype, - x509_flag_t flags) + identification_t *subject, x509_flag_t flags) { void *cred = NULL; bool pgp = FALSE; @@ -381,10 +381,19 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype, { subtype = pgp ? CERT_GPG : CERT_X509; } - cred = lib->creds->create(lib->creds, type, subtype, + if (type == CRED_CERTIFICATE && subtype == CERT_TRUSTED_PUBKEY && subject) + { + cred = lib->creds->create(lib->creds, type, subtype, + BUILD_BLOB_ASN1_DER, blob, BUILD_SUBJECT, subject, + BUILD_END); + } + else + { + cred = lib->creds->create(lib->creds, type, subtype, pgp ? BUILD_BLOB_PGP : BUILD_BLOB_ASN1_DER, blob, flags ? BUILD_X509_FLAG : BUILD_END, flags, BUILD_END); + } chunk_clear(&blob); return cred; } @@ -393,7 +402,7 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype, * load the credential from a file */ static void *load_from_file(char *file, credential_type_t type, int subtype, - x509_flag_t flags) + identification_t *subject, x509_flag_t flags) { void *cred = NULL; struct stat sb; @@ -423,7 +432,8 @@ static void *load_from_file(char *file, credential_type_t type, int subtype, return NULL; } - cred = load_from_blob(chunk_create(addr, sb.st_size), type, subtype, flags); + cred = load_from_blob(chunk_create(addr, sb.st_size), type, subtype, + subject, flags); munmap(addr, sb.st_size); close(fd); @@ -434,7 +444,7 @@ static void *load_from_file(char *file, credential_type_t type, int subtype, * load the credential from a file descriptor */ static void *load_from_fd(int fd, credential_type_t type, int subtype, - x509_flag_t flags) + identification_t *subject, x509_flag_t flags) { char buf[8096]; char *pos = buf; @@ -460,7 +470,8 @@ static void *load_from_fd(int fd, credential_type_t type, int subtype, return NULL; } } - return load_from_blob(chunk_create(buf, total), type, subtype, flags); + return load_from_blob(chunk_create(buf, total), type, subtype, + subject, flags); } /** @@ -471,6 +482,7 @@ static void *pem_load(credential_type_t type, int subtype, va_list args) char *file = NULL; int fd = -1; chunk_t pem = chunk_empty; + identification_t *subject = NULL; int flags = 0; while (TRUE) @@ -486,6 +498,9 @@ static void *pem_load(credential_type_t type, int subtype, va_list args) case BUILD_BLOB_PEM: pem = va_arg(args, chunk_t); continue; + case BUILD_SUBJECT: + subject = va_arg(args, identification_t*); + continue; case BUILD_X509_FLAG: flags = va_arg(args, int); continue; @@ -499,15 +514,15 @@ static void *pem_load(credential_type_t type, int subtype, va_list args) if (pem.len) { - return load_from_blob(pem, type, subtype, flags); + return load_from_blob(pem, type, subtype, subject, flags); } if (file) { - return load_from_file(file, type, subtype, flags); + return load_from_file(file, type, subtype, subject, flags); } if (fd != -1) { - return load_from_fd(fd, type, subtype, flags); + return load_from_fd(fd, type, subtype, subject, flags); } return NULL; } diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c index c81605ae5..fca717a10 100644 --- a/src/libstrongswan/plugins/pem/pem_plugin.c +++ b/src/libstrongswan/plugins/pem/pem_plugin.c @@ -39,15 +39,69 @@ METHOD(plugin_t, get_name, char*, return "pem"; } +METHOD(plugin_t, get_features, int, + private_pem_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + /* private key PEM decoding */ + PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_DSA), + PLUGIN_DEPENDS(HASHER, HASH_MD5), + + /* public key PEM decoding */ + PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA), + PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_DSA), + + /* certificate PEM decoding */ + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_ANY), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_OCSP_REQUEST), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_OCSP_RESPONSE), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_AC), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_PKCS10_REQUEST), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_TRUSTED_PUBKEY), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_GPG), + + /* pluto specific certificate formats */ + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_PLUTO_CERT), + PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_PLUTO_CRL), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_pem_plugin_t *this) { - lib->creds->remove_builder(lib->creds, - (builder_function_t)pem_private_key_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)pem_public_key_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)pem_certificate_load); + lib->encoding->remove_encoder(lib->encoding, pem_encoder_encode); + free(this); } @@ -62,58 +116,12 @@ plugin_t *pem_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - /* register private key PEM decoding builders */ - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE, - (builder_function_t)pem_private_key_load); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE, - (builder_function_t)pem_private_key_load); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, FALSE, - (builder_function_t)pem_private_key_load); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_DSA, FALSE, - (builder_function_t)pem_private_key_load); - - /* register public key PEM decoding builders */ - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE, - (builder_function_t)pem_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, FALSE, - (builder_function_t)pem_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, FALSE, - (builder_function_t)pem_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_DSA, FALSE, - (builder_function_t)pem_public_key_load); - - /* register certificate PEM decoding builders */ - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_ANY, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_GPG, FALSE, - (builder_function_t)pem_certificate_load); - - /* register pluto specific certificate formats */ - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT, FALSE, - (builder_function_t)pem_certificate_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL, FALSE, - (builder_function_t)pem_certificate_load); - /* register PEM encoder */ lib->encoding->add_encoder(lib->encoding, pem_encoder_encode); diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in index 6be915f29..946424eee 100644 --- a/src/libstrongswan/plugins/pgp/Makefile.in +++ b/src/libstrongswan/plugins/pgp/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/pgp/pgp_builder.c b/src/libstrongswan/plugins/pgp/pgp_builder.c index 440e70a18..361157742 100644 --- a/src/libstrongswan/plugins/pgp/pgp_builder.c +++ b/src/libstrongswan/plugins/pgp/pgp_builder.c @@ -152,7 +152,7 @@ static private_key_t *parse_private_key(chunk_t blob) } if (!pgp_read_scalar(&packet, 1, &version)) { - return FALSE; + return NULL; } switch (version) { @@ -166,7 +166,7 @@ static private_key_t *parse_private_key(chunk_t blob) break; default: DBG1(DBG_LIB, "PGP packet version V%d not supported", version); - return FALSE; + return NULL; } if (!pgp_read_scalar(&packet, 4, &created)) { diff --git a/src/libstrongswan/plugins/pgp/pgp_cert.c b/src/libstrongswan/plugins/pgp/pgp_cert.c index 5b21b46d4..70a236855 100644 --- a/src/libstrongswan/plugins/pgp/pgp_cert.c +++ b/src/libstrongswan/plugins/pgp/pgp_cert.c @@ -74,35 +74,26 @@ struct private_pgp_cert_t { }; -/** - * Implementation of certificate_t.get_type - */ -static certificate_type_t get_type(private_pgp_cert_t *this) +METHOD(certificate_t, get_type, certificate_type_t, + private_pgp_cert_t *this) { return CERT_GPG; } -/** - * Implementation of certificate_t.get_subject - */ -static identification_t* get_subject(private_pgp_cert_t *this) +METHOD(certificate_t, get_subject,identification_t*, + private_pgp_cert_t *this) { return this->user_id; } -/** - * Implementation of certificate_t.get_issuer - */ -static identification_t* get_issuer(private_pgp_cert_t *this) +METHOD(certificate_t, get_issuer, identification_t*, + private_pgp_cert_t *this) { return this->user_id; } -/** - * Implementation of certificate_t.has_subject. - */ -static id_match_t has_subject(private_pgp_cert_t *this, - identification_t *subject) +METHOD(certificate_t, has_subject, id_match_t, + private_pgp_cert_t *this, identification_t *subject) { id_match_t match_user_id; @@ -116,46 +107,36 @@ static id_match_t has_subject(private_pgp_cert_t *this, return match_user_id; } -/** - * Implementation of certificate_t.has_subject. - */ -static id_match_t has_issuer(private_pgp_cert_t *this, identification_t *issuer) +METHOD(certificate_t, has_issuer, id_match_t, + private_pgp_cert_t *this, identification_t *issuer) { return ID_MATCH_NONE; } -/** - * Implementation of certificate_t.issued_by - */ -static bool issued_by(private_pgp_cert_t *this, certificate_t *issuer) +METHOD(certificate_t, issued_by,bool, + private_pgp_cert_t *this, certificate_t *issuer) { /* TODO: check signature blobs for a valid signature */ return FALSE; } -/** - * Implementation of certificate_t.get_public_key - */ -static public_key_t* get_public_key(private_pgp_cert_t *this) +METHOD(certificate_t, get_public_key, public_key_t*, + private_pgp_cert_t *this) { this->key->get_ref(this->key); return this->key; } -/** - * Implementation of certificate_t.get_ref - */ -static private_pgp_cert_t* get_ref(private_pgp_cert_t *this) +METHOD(certificate_t, get_ref, certificate_t*, + private_pgp_cert_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface.interface; } -/** - * Implementation of certificate_t.get_validity. - */ -static bool get_validity(private_pgp_cert_t *this, time_t *when, - time_t *not_before, time_t *not_after) +METHOD(certificate_t, get_validity, bool, + private_pgp_cert_t *this, time_t *when, time_t *not_before, + time_t *not_after) { time_t t, until; @@ -187,11 +168,8 @@ static bool get_validity(private_pgp_cert_t *this, time_t *when, return (t >= this->valid && t <= until); } -/** - * Implementation of certificate_t.get_encoding. - */ -static bool get_encoding(private_pgp_cert_t *this, cred_encoding_type_t type, - chunk_t *encoding) +METHOD(certificate_t, get_encoding, bool, + private_pgp_cert_t *this, cred_encoding_type_t type, chunk_t *encoding) { if (type == CERT_PGP_PKT) { @@ -202,10 +180,8 @@ static bool get_encoding(private_pgp_cert_t *this, cred_encoding_type_t type, CRED_PART_PGP_CERT, this->encoding, CRED_PART_END); } -/** - * Implementation of certificate_t.equals. - */ -static bool equals(private_pgp_cert_t *this, certificate_t *other) +METHOD(certificate_t, equals, bool, + private_pgp_cert_t *this, certificate_t *other) { chunk_t encoding; bool equal; @@ -231,10 +207,8 @@ static bool equals(private_pgp_cert_t *this, certificate_t *other) return equal; } -/** - * Implementation of pgp_cert_t.destroy. - */ -static void destroy(private_pgp_cert_t *this) +METHOD(certificate_t, destroy, void, + private_pgp_cert_t *this) { if (ref_put(&this->ref)) { @@ -246,10 +220,8 @@ static void destroy(private_pgp_cert_t *this) } } -/** - * Implementation of pgp_certificate_t.get_fingerprint. - */ -static chunk_t get_fingerprint(private_pgp_cert_t *this) +METHOD(pgp_certificate_t, get_fingerprint, chunk_t, + private_pgp_cert_t *this) { return this->fingerprint; } @@ -259,30 +231,30 @@ static chunk_t get_fingerprint(private_pgp_cert_t *this) */ private_pgp_cert_t *create_empty() { - private_pgp_cert_t *this = malloc_thing(private_pgp_cert_t); - - this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type; - this->public.interface.interface.get_subject = (identification_t* (*) (certificate_t*))get_subject; - this->public.interface.interface.get_issuer = (identification_t* (*) (certificate_t*))get_issuer; - this->public.interface.interface.has_subject = (id_match_t (*) (certificate_t*, identification_t*))has_subject; - this->public.interface.interface.has_issuer = (id_match_t (*) (certificate_t*, identification_t*))has_issuer; - this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by; - this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key; - this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity; - this->public.interface.interface.get_encoding = (bool (*) (certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding; - this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals; - this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref; - this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy; - this->public.interface.get_fingerprint = (chunk_t (*)(pgp_certificate_t*))get_fingerprint; - - this->key = NULL; - this->version = 0; - this->created = 0; - this->valid = 0; - this->user_id = NULL; - this->fingerprint = chunk_empty; - this->encoding = chunk_empty; - this->ref = 1; + private_pgp_cert_t *this; + + INIT(this, + .public = { + .interface = { + .interface = { + .get_type = _get_type, + .get_subject = _get_subject, + .get_issuer = _get_issuer, + .has_subject = _has_subject, + .has_issuer = _has_issuer, + .issued_by = _issued_by, + .get_public_key = _get_public_key, + .get_validity = _get_validity, + .get_encoding = _get_encoding, + .equals = _equals, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_fingerprint = _get_fingerprint, + }, + }, + .ref = 1, + ); return this; } @@ -314,18 +286,18 @@ static bool parse_public_key(private_pgp_cert_t *this, chunk_t packet) } break; default: - DBG1(DBG_LIB, "PGP packet version V%d not supported", + DBG1(DBG_ASN, "PGP packet version V%d not supported", this->version); return FALSE; } if (this->valid) { - DBG2(DBG_LIB, "L2 - created %T, valid %d days", &this->created, FALSE, + DBG2(DBG_ASN, "L2 - created %T, valid %d days", &this->created, FALSE, this->valid); } else { - DBG2(DBG_LIB, "L2 - created %T, never expires", &this->created, FALSE); + DBG2(DBG_ASN, "L2 - created %T, never expires", &this->created, FALSE); } DESTROY_IF(this->key); this->key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, @@ -346,13 +318,13 @@ static bool parse_public_key(private_pgp_cert_t *this, chunk_t packet) hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); if (hasher == NULL) { - DBG1(DBG_LIB, "no SHA-1 hasher available"); + DBG1(DBG_ASN, "no SHA-1 hasher available"); return FALSE; } hasher->allocate_hash(hasher, pubkey_packet_header, NULL); hasher->allocate_hash(hasher, pubkey_packet, &this->fingerprint); hasher->destroy(hasher); - DBG2(DBG_LIB, "L2 - v4 fingerprint %#B", &this->fingerprint); + DBG2(DBG_ASN, "L2 - v4 fingerprint %#B", &this->fingerprint); } else { @@ -363,7 +335,7 @@ static bool parse_public_key(private_pgp_cert_t *this, chunk_t packet) return FALSE; } this->fingerprint = chunk_clone(this->fingerprint); - DBG2(DBG_LIB, "L2 - v3 fingerprint %#B", &this->fingerprint); + DBG2(DBG_ASN, "L2 - v3 fingerprint %#B", &this->fingerprint); } return TRUE; } @@ -383,7 +355,7 @@ static bool parse_signature(private_pgp_cert_t *this, chunk_t packet) /* we parse only v3 or v4 signature packets */ if (version != 3 && version != 4) { - DBG2(DBG_LIB, "L2 - v%d signature ignored", version); + DBG2(DBG_ASN, "L2 - v%d signature ignored", version); return TRUE; } if (version == 4) @@ -392,7 +364,7 @@ static bool parse_signature(private_pgp_cert_t *this, chunk_t packet) { return FALSE; } - DBG2(DBG_LIB, "L2 - v%d signature of type 0x%02x", version, type); + DBG2(DBG_ASN, "L2 - v%d signature of type 0x%02x", version, type); } else { @@ -405,7 +377,7 @@ static bool parse_signature(private_pgp_cert_t *this, chunk_t packet) { return FALSE; } - DBG2(DBG_LIB, "L2 - v3 signature of type 0x%02x, created %T", type, + DBG2(DBG_ASN, "L2 - v3 signature of type 0x%02x, created %T", type, &created, FALSE); } /* TODO: parse and save signature to a list */ @@ -419,7 +391,7 @@ static bool parse_user_id(private_pgp_cert_t *this, chunk_t packet) { DESTROY_IF(this->user_id); this->user_id = identification_create_from_encoding(ID_KEY_ID, packet); - DBG2(DBG_LIB, "L2 - '%Y'", this->user_id); + DBG2(DBG_ASN, "L2 - '%Y'", this->user_id); return TRUE; } @@ -469,14 +441,14 @@ pgp_cert_t *pgp_cert_load(certificate_type_t type, va_list args) if (!parse_signature(this, packet)) { destroy(this); - return FALSE; + return NULL; } break; case PGP_PKT_USER_ID: if (!parse_user_id(this, packet)) { destroy(this); - return FALSE; + return NULL; } break; default: diff --git a/src/libstrongswan/plugins/pgp/pgp_plugin.c b/src/libstrongswan/plugins/pgp/pgp_plugin.c index 52e9d96b1..a2cf403dc 100644 --- a/src/libstrongswan/plugins/pgp/pgp_plugin.c +++ b/src/libstrongswan/plugins/pgp/pgp_plugin.c @@ -39,17 +39,30 @@ METHOD(plugin_t, get_name, char*, return "pgp"; } -METHOD(plugin_t, destroy, void, - private_pgp_plugin_t *this) +METHOD(plugin_t, get_features, int, + private_pgp_plugin_t *this, plugin_feature_t *features[]) { - lib->creds->remove_builder(lib->creds, - (builder_function_t)pgp_public_key_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)pgp_private_key_load); + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRIVKEY, pgp_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), + PLUGIN_REGISTER(PRIVKEY, pgp_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), - lib->creds->remove_builder(lib->creds, - (builder_function_t)pgp_cert_load); + PLUGIN_REGISTER(PUBKEY, pgp_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + PLUGIN_REGISTER(PUBKEY, pgp_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + + PLUGIN_REGISTER(CERT_DECODE, pgp_cert_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_GPG), + }; + *features = f; + return countof(f); +} +METHOD(plugin_t, destroy, void, + private_pgp_plugin_t *this) +{ lib->encoding->remove_encoder(lib->encoding, pgp_encoder_encode); free(this); @@ -66,21 +79,12 @@ plugin_t *pgp_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE, - (builder_function_t)pgp_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, FALSE, - (builder_function_t)pgp_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE, - (builder_function_t)pgp_private_key_load); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE, - (builder_function_t)pgp_private_key_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_GPG, FALSE, - (builder_function_t)pgp_cert_load); + lib->encoding->add_encoder(lib->encoding, pgp_encoder_encode); return &this->public.plugin; diff --git a/src/libstrongswan/plugins/pgp/pgp_utils.c b/src/libstrongswan/plugins/pgp/pgp_utils.c index 2d85cc0c8..7fd905ce4 100644 --- a/src/libstrongswan/plugins/pgp/pgp_utils.c +++ b/src/libstrongswan/plugins/pgp/pgp_utils.c @@ -79,7 +79,7 @@ bool pgp_read_scalar(chunk_t *blob, size_t bytes, u_int32_t *scalar) if (bytes > blob->len) { - DBG1(DBG_LIB, "PGP data too short to read %d byte scalar", bytes); + DBG1(DBG_ASN, "PGP data too short to read %d byte scalar", bytes); return FALSE; } while (bytes-- > 0) @@ -100,13 +100,13 @@ bool pgp_read_mpi(chunk_t *blob, chunk_t *mpi) if (!pgp_read_scalar(blob, 2, &bits)) { - DBG1(DBG_LIB, "PGP data too short to read MPI length"); + DBG1(DBG_ASN, "PGP data too short to read MPI length"); return FALSE; } bytes = (bits + 7) / 8; if (bytes > blob->len) { - DBG1(DBG_LIB, "PGP data too short to read %d byte MPI", bytes); + DBG1(DBG_ASN, "PGP data too short to read %d byte MPI", bytes); return FALSE; } *mpi = chunk_create(blob->ptr, bytes); @@ -146,7 +146,7 @@ bool pgp_read_packet(chunk_t *blob, chunk_t *data, pgp_packet_tag_t *tag) if (!blob->len) { - DBG1(DBG_LIB, "missing input"); + DBG1(DBG_ASN, "missing input"); return FALSE; } t = blob->ptr[0]; @@ -154,27 +154,27 @@ bool pgp_read_packet(chunk_t *blob, chunk_t *data, pgp_packet_tag_t *tag) /* bit 7 must be set */ if (!(t & 0x80)) { - DBG1(DBG_LIB, "invalid packet tag"); + DBG1(DBG_ASN, "invalid packet tag"); return FALSE; } /* bit 6 set defines new packet format */ if (t & 0x40) { - DBG1(DBG_LIB, "new PGP packet format not supported"); + DBG1(DBG_ASN, "new PGP packet format not supported"); return FALSE; } t = (t & 0x3C) >> 2; if (!pgp_old_packet_length(blob, &len) || len > blob->len) { - DBG1(DBG_LIB, "invalid packet length"); + DBG1(DBG_ASN, "invalid packet length"); return FALSE; } *data = chunk_create(blob->ptr, len); *blob = chunk_skip(*blob, len); *tag = t; - DBG2(DBG_LIB, "L1 - PGP %N (%u bytes)", pgp_packet_tag_names, t, len); - DBG3(DBG_LIB, "%B", data); + DBG2(DBG_ASN, "L1 - PGP %N (%u bytes)", pgp_packet_tag_names, t, len); + DBG3(DBG_ASN, "%B", data); return TRUE; } diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in index 1ae880c3b..f9322a62d 100644 --- a/src/libstrongswan/plugins/pkcs1/Makefile.in +++ b/src/libstrongswan/plugins/pkcs1/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c index a605fabc7..6d022f362 100644 --- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c +++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c @@ -81,10 +81,10 @@ static public_key_t *parse_public_key(chunk_t blob) /* skip initial bit string octet defining 0 unused bits */ object = chunk_skip(object, 1); } - DBG2(DBG_LIB, "-- > --"); + DBG2(DBG_ASN, "-- > --"); key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type, BUILD_BLOB_ASN1_DER, object, BUILD_END); - DBG2(DBG_LIB, "-- < --"); + DBG2(DBG_ASN, "-- < --"); break; } } @@ -197,7 +197,7 @@ static private_key_t *parse_rsa_private_key(chunk_t blob) case PRIV_KEY_VERSION: if (object.len > 0 && *object.ptr != 0) { - DBG1(DBG_LIB, "PKCS#1 private key format is not version 1"); + DBG1(DBG_ASN, "PKCS#1 private key format is not version 1"); goto end; } break; diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c b/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c index e0e24cab2..b304a5101 100644 --- a/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c +++ b/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c @@ -38,14 +38,24 @@ METHOD(plugin_t, get_name, char*, return "pkcs1"; } +METHOD(plugin_t, get_features, int, + private_pkcs1_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRIVKEY, pkcs1_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), + PLUGIN_REGISTER(PUBKEY, pkcs1_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + PLUGIN_REGISTER(PUBKEY, pkcs1_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_pkcs1_plugin_t *this) { - lib->creds->remove_builder(lib->creds, - (builder_function_t)pkcs1_public_key_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)pkcs1_private_key_load); - lib->encoding->remove_encoder(lib->encoding, pkcs1_encoder_encode); free(this); @@ -62,19 +72,12 @@ plugin_t *pkcs1_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE, - (builder_function_t)pkcs1_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, FALSE, - (builder_function_t)pkcs1_public_key_load); - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE, - (builder_function_t)pkcs1_private_key_load); - lib->encoding->add_encoder(lib->encoding, pkcs1_encoder_encode); return &this->public.plugin; diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.am b/src/libstrongswan/plugins/pkcs11/Makefile.am index 199039d95..d032b879a 100644 --- a/src/libstrongswan/plugins/pkcs11/Makefile.am +++ b/src/libstrongswan/plugins/pkcs11/Makefile.am @@ -16,6 +16,8 @@ libstrongswan_pkcs11_la_SOURCES = \ pkcs11_private_key.h pkcs11_private_key.c \ pkcs11_public_key.h pkcs11_public_key.c \ pkcs11_hasher.h pkcs11_hasher.c \ + pkcs11_rng.h pkcs11_rng.c \ + pkcs11_dh.h pkcs11_dh.c \ pkcs11_manager.h pkcs11_manager.c libstrongswan_pkcs11_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in index 1a67f88cc..2ead77f5a 100644 --- a/src/libstrongswan/plugins/pkcs11/Makefile.in +++ b/src/libstrongswan/plugins/pkcs11/Makefile.in @@ -77,7 +77,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_pkcs11_la_LIBADD = am_libstrongswan_pkcs11_la_OBJECTS = pkcs11_plugin.lo \ pkcs11_library.lo pkcs11_creds.lo pkcs11_private_key.lo \ - pkcs11_public_key.lo pkcs11_hasher.lo pkcs11_manager.lo + pkcs11_public_key.lo pkcs11_hasher.lo pkcs11_rng.lo \ + pkcs11_dh.lo pkcs11_manager.lo libstrongswan_pkcs11_la_OBJECTS = \ $(am_libstrongswan_pkcs11_la_OBJECTS) libstrongswan_pkcs11_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -195,6 +196,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +207,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +224,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +274,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -288,6 +296,8 @@ libstrongswan_pkcs11_la_SOURCES = \ pkcs11_private_key.h pkcs11_private_key.c \ pkcs11_public_key.h pkcs11_public_key.c \ pkcs11_hasher.h pkcs11_hasher.c \ + pkcs11_rng.h pkcs11_rng.c \ + pkcs11_dh.h pkcs11_dh.c \ pkcs11_manager.h pkcs11_manager.c libstrongswan_pkcs11_la_LDFLAGS = -module -avoid-version @@ -375,12 +385,14 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_creds.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_dh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_hasher.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_library.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_private_key.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_public_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_rng.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11.h b/src/libstrongswan/plugins/pkcs11/pkcs11.h index 2e6a1e3ed..da29a77d0 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11.h @@ -179,6 +179,14 @@ extern "C" { #define unlock_mutex UnlockMutex #define reserved pReserved +#define ck_ec_kdf_type_t CK_EC_KDF_TYPE + +#define ck_ecdh1_derive_args _CK_ECDH1_DERIVE_PARAMS +#define shared_data_len ulSharedDataLen +#define shared_data pSharedData +#define public_data_len ulPublicDataLen +#define public_data pPublicData + #endif /* CRYPTOKI_COMPAT */ @@ -1090,6 +1098,19 @@ struct ck_c_initialize_args void *reserved; }; +typedef unsigned long ck_ec_kdf_type_t; + +#define CKD_NULL (1) +#define CKD_SHA1_DKF (2) + +struct ck_ecdh1_derive_params +{ + ck_ec_kdf_type_t kdf; + unsigned long shared_data_len; + void *shared_data; + unsigned long public_data_len; + void *public_data; +}; #define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0) #define CKF_OS_LOCKING_OK (1 << 1) @@ -1260,6 +1281,9 @@ typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; +typedef struct ck_ecdh1_derive_params CK_ECDH1_DERIVE_PARAMS; +typedef struct ck_ecdh1_derive_params *CK_ECDH1_DERIVE_PARAMS_PTR; + #define NULL_PTR NULL /* Delete the helper macros defined at the top of the file. */ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c new file mode 100644 index 000000000..c870370c8 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 + * 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 "pkcs11_dh.h" + +#include <debug.h> +#include <library.h> +#include <asn1/asn1.h> +#include <asn1/oid.h> + +#include "pkcs11_manager.h" + +typedef struct private_pkcs11_dh_t private_pkcs11_dh_t; + +/** + * Private data of an pkcs11_dh_t object. + */ +struct private_pkcs11_dh_t { + + /** + * Public pkcs11_dh_t interface + */ + pkcs11_dh_t public; + + /** + * PKCS#11 library + */ + pkcs11_library_t *lib; + + /** + * Session handle for this objct + */ + CK_SESSION_HANDLE session; + + /** + * Diffie Hellman group number. + */ + u_int16_t group; + + /** + * Handle for own private value + */ + CK_OBJECT_HANDLE pri_key; + + /** + * Own public value + */ + chunk_t pub_key; + + /** + * Shared secret + */ + chunk_t secret; + + /** + * Mechanism to use to generate a key pair + */ + CK_MECHANISM_TYPE mech_key; + + /** + * Mechanism to use to derive a shared secret + */ + CK_MECHANISM_TYPE mech_derive; + +}; + +/** + * Derive a DH/ECDH shared secret. + * + * If this succeeds the shared secret is stored in this->secret. + */ +static void derive_secret(private_pkcs11_dh_t *this, chunk_t other) +{ + CK_OBJECT_CLASS klass = CKO_SECRET_KEY; + CK_KEY_TYPE type = CKK_GENERIC_SECRET; + CK_ATTRIBUTE attr[] = { + { CKA_CLASS, &klass, sizeof(klass) }, + { CKA_KEY_TYPE, &type, sizeof(type) }, + }; + CK_MECHANISM mech = { + this->mech_derive, + other.ptr, + other.len, + }; + CK_OBJECT_HANDLE secret; + CK_RV rv; + + rv = this->lib->f->C_DeriveKey(this->session, &mech, this->pri_key, + attr, countof(attr), &secret); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_DeriveKey() error: %N", ck_rv_names, rv); + return; + } + if (!this->lib->get_ck_attribute(this->lib, this->session, secret, + CKA_VALUE, &this->secret)) + { + chunk_free(&this->secret); + return; + } +} + +METHOD(diffie_hellman_t, set_other_public_value, void, + private_pkcs11_dh_t *this, chunk_t value) +{ + switch (this->group) + { + case ECP_192_BIT: + case ECP_224_BIT: + case ECP_256_BIT: + case ECP_384_BIT: + case ECP_521_BIT: + { /* we expect the public value to just be the concatenated x and y + * coordinates, so we tag the value as an uncompressed ECPoint */ + chunk_t tag = chunk_from_chars(0x04); + chunk_t pubkey = chunk_cata("cc", tag, value); + CK_ECDH1_DERIVE_PARAMS params = { + CKD_NULL, + 0, + NULL, + pubkey.len, + pubkey.ptr, + }; + + if (!lib->settings->get_bool(lib->settings, + "libstrongswan.ecp_x_coordinate_only", TRUE)) + { /* we only get the x coordinate back */ + return; + } + value = chunk_from_thing(params); + break; + } + default: + break; + } + derive_secret(this, value); +} + +METHOD(diffie_hellman_t, get_my_public_value, void, + private_pkcs11_dh_t *this, chunk_t *value) +{ + *value = chunk_clone(this->pub_key); +} + +METHOD(diffie_hellman_t, get_shared_secret, status_t, + private_pkcs11_dh_t *this, chunk_t *secret) +{ + if (!this->secret.ptr) + { + return FAILED; + } + *secret = chunk_clone(this->secret); + return SUCCESS; +} + +METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, + private_pkcs11_dh_t *this) +{ + return this->group; +} + +METHOD(diffie_hellman_t, destroy, void, + private_pkcs11_dh_t *this) +{ + this->lib->f->C_CloseSession(this->session); + chunk_clear(&this->pub_key); + chunk_clear(&this->secret); + free(this); +} + +/** + * Generate a DH/ECDH key pair. + * + * If this succeeds, this->pri_key has a handle to the private key and + * this->pub_key stores the public key. + */ +static bool generate_key_pair(private_pkcs11_dh_t *this, CK_ATTRIBUTE_PTR pub, + int pub_len, CK_ATTRIBUTE_PTR pri, int pri_len, + CK_ATTRIBUTE_TYPE attr) +{ + CK_MECHANISM mech = { + this->mech_key, + NULL, + 0, + }; + CK_OBJECT_HANDLE pub_key; + CK_RV rv; + + rv = this->lib->f->C_GenerateKeyPair(this->session, &mech, pub, pub_len, + pri, pri_len, &pub_key, &this->pri_key); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GenerateKeyPair() error: %N", ck_rv_names, rv); + return FALSE; + } + if (!this->lib->get_ck_attribute(this->lib, this->session, pub_key, + attr, &this->pub_key)) + { + chunk_free(&this->pub_key); + return FALSE; + } + return TRUE; +} + +/** + * Generate DH key pair. + */ +static bool generate_key_pair_modp(private_pkcs11_dh_t *this, size_t exp_len, + chunk_t g, chunk_t p) +{ + CK_BBOOL ck_true = CK_TRUE; + CK_ATTRIBUTE pub_attr[] = { + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + { CKA_PRIME, p.ptr, p.len }, + { CKA_BASE, g.ptr, g.len }, + }; + CK_ULONG bits = exp_len * 8; + CK_ATTRIBUTE pri_attr[] = { + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + { CKA_VALUE_BITS, &bits, sizeof(bits) }, + }; + return generate_key_pair(this, pub_attr, countof(pub_attr), pri_attr, + countof(pri_attr), CKA_VALUE); +} + +/** + * Generate ECDH key pair. + */ +static bool generate_key_pair_ecp(private_pkcs11_dh_t *this, + chunk_t ecparams) +{ + CK_BBOOL ck_true = CK_TRUE; + CK_ATTRIBUTE pub_attr[] = { + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + { CKA_EC_PARAMS, ecparams.ptr, ecparams.len }, + }; + CK_ATTRIBUTE pri_attr[] = { + { CKA_DERIVE, &ck_true, sizeof(ck_true) }, + }; + chunk_t pub_key; + if (!generate_key_pair(this, pub_attr, countof(pub_attr), pri_attr, + countof(pri_attr), CKA_EC_POINT)) + { + return FALSE; + } + if (this->pub_key.len <= 0 || this->pub_key.ptr[0] != 0x04) + { /* we currently only support the point in uncompressed form which + * looks like this: 0x04 || x || y */ + chunk_clear(&this->pub_key); + return FALSE; + } + pub_key = chunk_clone(chunk_skip(this->pub_key, 1)); + chunk_clear(&this->pub_key); + this->pub_key = pub_key; + return TRUE; +} + +/** + * Find a token we can use for DH/ECDH algorithm + */ +static pkcs11_library_t *find_token(private_pkcs11_dh_t *this, + CK_SESSION_HANDLE *session) +{ + enumerator_t *tokens, *mechs; + pkcs11_manager_t *manager; + pkcs11_library_t *current, *found = NULL; + CK_MECHANISM_TYPE type; + CK_SLOT_ID slot; + + manager = lib->get(lib, "pkcs11-manager"); + if (!manager) + { + return NULL; + } + tokens = manager->create_token_enumerator(manager); + while (tokens->enumerate(tokens, ¤t, &slot)) + { + mechs = current->create_mechanism_enumerator(current, slot); + while (mechs->enumerate(mechs, &type, NULL)) + { /* we assume we can generate key pairs if the derive mechanism + * is supported */ + if (type == this->mech_derive) + { + if (current->f->C_OpenSession(slot, CKF_SERIAL_SESSION, + NULL, NULL, session) == CKR_OK) + { + found = current; + break; + } + } + } + mechs->destroy(mechs); + if (found) + { + break; + } + } + tokens->destroy(tokens); + return found; +} + +/** + * Generic internal constructor + */ +static private_pkcs11_dh_t *create_generic(diffie_hellman_group_t group, + CK_MECHANISM_TYPE key, + CK_MECHANISM_TYPE derive) +{ + private_pkcs11_dh_t *this; + + INIT(this, + .public = { + .dh = { + .get_shared_secret = _get_shared_secret, + .set_other_public_value = _set_other_public_value, + .get_my_public_value = _get_my_public_value, + .get_dh_group = _get_dh_group, + .destroy = _destroy, + }, + }, + .group = group, + .mech_key = key, + .mech_derive = derive, + ); + + this->lib = find_token(this, &this->session); + if (!this->lib) + { + free(this); + return NULL; + } + return this; +} + +static pkcs11_dh_t *create_ecp(diffie_hellman_group_t group, chunk_t ecparam) +{ + private_pkcs11_dh_t *this = create_generic(group, CKM_EC_KEY_PAIR_GEN, + CKM_ECDH1_DERIVE); + + if (this) + { + if (generate_key_pair_ecp(this, ecparam)) + { + chunk_free(&ecparam); + return &this->public; + } + chunk_free(&ecparam); + free(this); + } + return NULL; +} + +/** + * Constructor for MODP DH + */ +static pkcs11_dh_t *create_modp(diffie_hellman_group_t group, size_t exp_len, + chunk_t g, chunk_t p) +{ + private_pkcs11_dh_t *this = create_generic(group, CKM_DH_PKCS_KEY_PAIR_GEN, + CKM_DH_PKCS_DERIVE); + + if (this) + { + if (generate_key_pair_modp(this, exp_len, g, p)) + { + return &this->public; + } + free(this); + } + return NULL; +} + +/** + * Lookup the EC params for the given group. + */ +static chunk_t ecparams_lookup(diffie_hellman_group_t group) +{ + switch (group) + { + case ECP_192_BIT: + return asn1_build_known_oid(OID_PRIME192V1); + case ECP_224_BIT: + return asn1_build_known_oid(OID_SECT224R1); + case ECP_256_BIT: + return asn1_build_known_oid(OID_PRIME256V1); + case ECP_384_BIT: + return asn1_build_known_oid(OID_SECT384R1); + case ECP_521_BIT: + return asn1_build_known_oid(OID_SECT521R1); + default: + break; + } + return chunk_empty; +} + +/** + * Described in header. + */ +pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group, + chunk_t g, chunk_t p) +{ + switch (group) + { + case MODP_CUSTOM: + { + return create_modp(group, p.len, g, p); + } + case ECP_192_BIT: + case ECP_224_BIT: + case ECP_256_BIT: + case ECP_384_BIT: + case ECP_521_BIT: + { + chunk_t params = ecparams_lookup(group); + if (params.ptr) + { + return create_ecp(group, params); + } + break; + } + default: + { + diffie_hellman_params_t *params = diffie_hellman_get_params(group); + if (params) + { + return create_modp(group, params->exp_len, params->generator, + params->prime); + } + break; + } + } + return NULL; +} + diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h new file mode 100644 index 000000000..2654130c0 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 + * 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 pkcs11_dh pkcs11_dh + * @{ @ingroup pkcs11 + */ + +#ifndef PKCS11_DH_H_ +#define PKCS11_DH_H_ + +typedef struct pkcs11_dh_t pkcs11_dh_t; + +#include <library.h> + +/** + * Implementation of the Diffie-Hellman algorithm via PKCS#11. + */ +struct pkcs11_dh_t { + + /** + * Implements diffie_hellman_t interface. + */ + diffie_hellman_t dh; +}; + +/** + * Creates a new pkcs11_dh_t object. + * + * @param group Diffie Hellman group number to use + * @param g generator in case group is MODP_CUSTOM + * @param p prime in case group is MODP_CUSTOM + * @return pkcs11_dh_t object, NULL if not supported + */ +pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group, + chunk_t g, chunk_t p); + +#endif /** PKCS11_DH_H_ @}*/ + diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c b/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c index 6d327be40..069fa98b6 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c @@ -260,7 +260,7 @@ static pkcs11_library_t* find_token(hash_algorithm_t algo, { return NULL; } - manager = pkcs11_manager_get(); + manager = lib->get(lib, "pkcs11-manager"); if (!manager) { return NULL; @@ -315,6 +315,7 @@ pkcs11_hasher_t *pkcs11_hasher_create(hash_algorithm_t algo) this->lib = find_token(algo, &this->session, &this->mech, &this->size); if (!this->lib) { + this->mutex->destroy(this->mutex); free(this); return NULL; } diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c index 6f7926808..97c3d2fcf 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -447,6 +450,123 @@ ENUM_NEXT(ck_mech_names, CKM_DSA_PARAMETER_GEN, CKM_X9_42_DH_PARAMETER_GEN, "X9_42_DH_PARAMETER_GEN"); ENUM_END(ck_mech_names, CKM_X9_42_DH_PARAMETER_GEN); + +ENUM_BEGIN(ck_attr_names, CKA_CLASS, CKA_LABEL, + "CLASS", + "TOKEN", + "PRIVATE", + "LABEL"); +ENUM_NEXT(ck_attr_names, CKA_APPLICATION, CKA_OBJECT_ID, CKA_LABEL, + "APPLICATION", + "VALUE", + "OBJECT_ID"); +ENUM_NEXT(ck_attr_names, CKA_CERTIFICATE_TYPE, CKA_HASH_OF_ISSUER_PUBLIC_KEY, + CKA_OBJECT_ID, + "CERTIFICATE_TYPE", + "ISSUER", + "SERIAL_NUMBER", + "AC_ISSUER", + "OWNER", + "ATTR_TYPES", + "TRUSTED", + "CERTIFICATE_CATEGORY", + "JAVA_MIDP_SECURITY_DOMAIN", + "URL", + "HASH_OF_SUBJECT_PUBLIC_KEY", + "HASH_OF_ISSUER_PUBLIC_KEY"); +ENUM_NEXT(ck_attr_names, CKA_CHECK_VALUE, CKA_CHECK_VALUE, + CKA_HASH_OF_ISSUER_PUBLIC_KEY, + "CHECK_VALUE"); +ENUM_NEXT(ck_attr_names, CKA_KEY_TYPE, CKA_DERIVE, CKA_CHECK_VALUE, + "KEY_TYPE", + "SUBJECT", + "ID", + "SENSITIVE", + "ENCRYPT", + "DECRYPT", + "WRAP", + "UNWRAP", + "SIGN", + "SIGN_RECOVER", + "VERIFY", + "VERIFY_RECOVER", + "DERIVE"); +ENUM_NEXT(ck_attr_names, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE, + "START_DATE", + "END_DATE"); +ENUM_NEXT(ck_attr_names, CKA_MODULUS, CKA_COEFFICIENT, CKA_END_DATE, + "MODULUS", + "MODULUS_BITS", + "PUBLIC_EXPONENT", + "PRIVATE_EXPONENT", + "PRIME_1", + "PRIME_2", + "EXPONENT_1", + "EXPONENT_2", + "COEFFICIENT"); +ENUM_NEXT(ck_attr_names, CKA_PRIME, CKA_SUB_PRIME_BITS, CKA_COEFFICIENT, + "PRIME", + "SUBPRIME", + "BASE", + "PRIME_BITS", + "SUB_PRIME_BITS"); +ENUM_NEXT(ck_attr_names, CKA_VALUE_BITS, CKA_KEY_GEN_MECHANISM, + CKA_SUB_PRIME_BITS, + "VALUE_BITS", + "VALUE_LEN", + "EXTRACTABLE", + "LOCAL", + "NEVER_EXTRACTABLE", + "ALWAYS_SENSITIVE", + "KEY_GEN_MECHANISM"); +ENUM_NEXT(ck_attr_names, CKA_MODIFIABLE, CKA_MODIFIABLE, CKA_KEY_GEN_MECHANISM, + "MODIFIABLE"); +ENUM_NEXT(ck_attr_names, CKA_EC_PARAMS, CKA_EC_POINT, CKA_MODIFIABLE, + "EC_PARAMS", + "EC_POINT"); +ENUM_NEXT(ck_attr_names, CKA_SECONDARY_AUTH, CKA_ALWAYS_AUTHENTICATE, + CKA_EC_POINT, + "SECONDARY_AUTH", + "AUTH_PIN_FLAGS", + "ALWAYS_AUTHENTICATE"); +ENUM_NEXT(ck_attr_names, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_WITH_TRUSTED, + CKA_ALWAYS_AUTHENTICATE, + "WRAP_WITH_TRUSTED"); +ENUM_NEXT(ck_attr_names, CKA_HW_FEATURE_TYPE, CKA_HAS_RESET, + CKA_WRAP_WITH_TRUSTED, + "HW_FEATURE_TYPE", + "RESET_ON_INIT", + "HAS_RESET"); +ENUM_NEXT(ck_attr_names, CKA_PIXEL_X, CKA_BITS_PER_PIXEL, CKA_HAS_RESET, + "PIXEL_X", + "RESOLUTION", + "CHAR_ROWS", + "CHAR_COLUMNS", + "COLOR", + "BITS_PER_PIXEL"); +ENUM_NEXT(ck_attr_names, CKA_CHAR_SETS, CKA_MIME_TYPES, CKA_BITS_PER_PIXEL, + "CHAR_SETS", + "ENCODING_METHODS", + "MIME_TYPES"); +ENUM_NEXT(ck_attr_names, CKA_MECHANISM_TYPE, CKA_SUPPORTED_CMS_ATTRIBUTES, + CKA_MIME_TYPES, + "MECHANISM_TYPE", + "REQUIRED_CMS_ATTRIBUTES", + "DEFAULT_CMS_ATTRIBUTES", + "SUPPORTED_CMS_ATTRIBUTES"); +ENUM_NEXT(ck_attr_names, CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE, + CKA_SUPPORTED_CMS_ATTRIBUTES, + "WRAP_TEMPLATE", + "UNWRAP_TEMPLATE"); +ENUM_NEXT(ck_attr_names, CKA_ALLOWED_MECHANISMS, CKA_ALLOWED_MECHANISMS, + CKA_UNWRAP_TEMPLATE, + "ALLOWED_MECHANISMS"); +ENUM_END(ck_attr_names, CKA_ALLOWED_MECHANISMS); +/* the values in an enum_name_t are stored as int, thus CKA_VENDOR_DEFINED + * will overflow and is thus not defined here */ + + + /** * Private data of an pkcs11_library_t object. */ @@ -495,10 +615,12 @@ typedef struct { CK_SESSION_HANDLE session; /* pkcs11 library */ pkcs11_library_t *lib; - /* attributes to retreive */ + /* attributes to retrieve */ CK_ATTRIBUTE_PTR attr; /* number of attributes */ CK_ULONG count; + /* object handle in case of a single object */ + CK_OBJECT_HANDLE object; /* currently allocated attributes, to free */ linked_list_t *freelist; } object_enumerator_t; @@ -552,7 +674,7 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object) if (rv != CKR_OK) { free_attrs(this); - DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv); + DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv); return FALSE; } return TRUE; @@ -565,11 +687,19 @@ METHOD(enumerator_t, object_enumerate, bool, CK_ULONG found; CK_RV rv; - rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found); - if (rv != CKR_OK) + if (!this->object) { - DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv); - return FALSE; + rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv); + return FALSE; + } + } + else + { + object = this->object; + found = 1; } if (found) { @@ -580,7 +710,10 @@ METHOD(enumerator_t, object_enumerate, bool, return FALSE; } } - *out = object; + if (out) + { + *out = object; + } return TRUE; } return FALSE; @@ -589,7 +722,10 @@ METHOD(enumerator_t, object_enumerate, bool, METHOD(enumerator_t, object_destroy, void, object_enumerator_t *this) { - this->lib->f->C_FindObjectsFinal(this->session); + if (!this->object) + { + this->lib->f->C_FindObjectsFinal(this->session); + } free_attrs(this); this->freelist->destroy(this->freelist); free(this); @@ -624,6 +760,27 @@ METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*, return &enumerator->public; } +METHOD(pkcs11_library_t, create_object_attr_enumerator, enumerator_t*, + private_pkcs11_library_t *this, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attr, CK_ULONG count) +{ + object_enumerator_t *enumerator; + + INIT(enumerator, + .public = { + .enumerate = (void*)_object_enumerate, + .destroy = _object_destroy, + }, + .session = session, + .lib = &this->public, + .attr = attr, + .count = count, + .object = object, + .freelist = linked_list_create(), + ); + return &enumerator->public; +} + /** * Enumerator over mechanisms */ @@ -707,6 +864,32 @@ METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*, return &enumerator->public; } +METHOD(pkcs11_library_t, get_ck_attribute, bool, + private_pkcs11_library_t *this, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_TYPE type, chunk_t *data) +{ + CK_ATTRIBUTE attr = { type, NULL, 0 }; + CK_RV rv; + rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type, + ck_rv_names, rv); + return FALSE; + } + *data = chunk_alloc(attr.ulValueLen); + attr.pValue = data->ptr; + rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type, + ck_rv_names, rv); + chunk_free(data); + return FALSE; + } + return TRUE; +} + METHOD(pkcs11_library_t, destroy, void, private_pkcs11_library_t *this) { @@ -739,7 +922,7 @@ void pkcs11_library_trim(char *str, int len) */ static CK_RV CreateMutex(CK_VOID_PTR_PTR data) { - *data = mutex_create(MUTEX_TYPE_DEFAULT); + *data = mutex_create(MUTEX_TYPE_RECURSIVE); return CKR_OK; } @@ -889,7 +1072,9 @@ pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking) .get_name = _get_name, .get_features = _get_features, .create_object_enumerator = _create_object_enumerator, + .create_object_attr_enumerator = _create_object_attr_enumerator, .create_mechanism_enumerator = _create_mechanism_enumerator, + .get_ck_attribute = _get_ck_attribute, .destroy = _destroy, }, .name = name, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h index abe023448..e76e65e07 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -27,6 +30,7 @@ typedef struct pkcs11_library_t pkcs11_library_t; #include "pkcs11.h" #include <enum.h> +#include <chunk.h> #include <utils/enumerator.h> /** @@ -72,7 +76,7 @@ struct pkcs11_library_t { * * @param session session to use * @param tmpl search template - * @param tcount number of attributes in the search template + * @param tcount number of attributes in the search template * @param attr attributes to read from object * @param acount number of attributes to read */ @@ -81,6 +85,24 @@ struct pkcs11_library_t { CK_ATTRIBUTE_PTR attr, CK_ULONG acount); /** + * This is very similar to the object enumerator but is only used to + * easily retrieve multiple attributes from a single object for which + * a handle is already known. + * + * The given attribute array is automatically filled in with the + * associated attributes. If the value of an output attribute is NULL, + * the required memory gets allocated/freed during enumeration. + * + * @param session session to use + * @param object object handle + * @param attr attributes to read from object + * @param count number of attributes to read + */ + enumerator_t* (*create_object_attr_enumerator)(pkcs11_library_t *this, + CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR attr, CK_ULONG count); + + /** * Create an enumerator over supported mechanisms of a token. * * The resulting enumerator enumerates over the mechanism type, and if @@ -93,6 +115,21 @@ struct pkcs11_library_t { CK_SLOT_ID slot); /** + * Retrieve a single attribute from the given object. + * + * Memory for the data is allocated. + * + * @param session session with the PKCS#11 library + * @param obj object handle + * @param type attribute type to extract + * @param data extracted data + * @return TRUE if successful + */ + bool (*get_ck_attribute)(pkcs11_library_t *this, CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_TYPE type, + chunk_t *data); + + /** * Destroy a pkcs11_library_t. */ void (*destroy)(pkcs11_library_t *this); @@ -109,7 +146,12 @@ extern enum_name_t *ck_rv_names; extern enum_name_t *ck_mech_names; /** - * Trim/null terminate a string returned by the varius PKCS#11 functions. + * Enum names for CK_ATTRIBUTE_TYPE values + */ +extern enum_name_t *ck_attr_names; + +/** + * Trim/null terminate a string returned by the various PKCS#11 functions. * * @param str string to trim * @param len max length of the string diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c index 431cd6a2c..5b321b26e 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c @@ -323,17 +323,11 @@ METHOD(pkcs11_manager_t, create_token_enumerator, enumerator_t*, return &enumerator->public; } -/** - * Singleton instance - */ -static private_pkcs11_manager_t *singleton = NULL; - METHOD(pkcs11_manager_t, destroy, void, private_pkcs11_manager_t *this) { this->libs->destroy_function(this->libs, (void*)lib_entry_destroy); free(this); - singleton = NULL; } /** @@ -386,14 +380,12 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb, } enumerator->destroy(enumerator); - singleton = this; - enumerator = this->libs->create_enumerator(this->libs); while (enumerator->enumerate(enumerator, &entry)) { query_slots(entry); - entry->job = callback_job_create((void*)dispatch_slot_events, - entry, (void*)end_dispatch, NULL); + entry->job = callback_job_create_with_prio((void*)dispatch_slot_events, + entry, (void*)end_dispatch, NULL, JOB_PRIO_CRITICAL); lib->processor->queue_job(lib->processor, (job_t*)entry->job); } enumerator->destroy(enumerator); @@ -401,10 +393,3 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb, return &this->public; } -/** - * See header - */ -pkcs11_manager_t *pkcs11_manager_get() -{ - return (pkcs11_manager_t*)singleton; -} diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h index b80d67324..2f51fb30e 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h @@ -32,7 +32,7 @@ typedef struct pkcs11_manager_t pkcs11_manager_t; * * @param data user supplied data, as passed to pkcs11_manager_create() * @param p11 loaded PKCS#11 library token belongs to - * @param slot slot number the event occured in + * @param slot slot number the event occurred in * @param add TRUE if token was added to the slot, FALSE if removed */ typedef void (*pkcs11_manager_token_event_t)(void *data, pkcs11_library_t *p11, @@ -67,12 +67,4 @@ struct pkcs11_manager_t { pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb, void *data); - -/** - * Get the singleton instance of the manager - * - * @return instance, NULL if none available - */ -pkcs11_manager_t *pkcs11_manager_get(); - #endif /** PKCS11_MANAGER_H_ @}*/ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c index 7b537cfa7..183fce53a 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -19,12 +22,15 @@ #include <debug.h> #include <utils/linked_list.h> #include <threading/mutex.h> +#include <threading/rwlock.h> #include "pkcs11_manager.h" #include "pkcs11_creds.h" #include "pkcs11_private_key.h" #include "pkcs11_public_key.h" #include "pkcs11_hasher.h" +#include "pkcs11_rng.h" +#include "pkcs11_dh.h" typedef struct private_pkcs11_plugin_t private_pkcs11_plugin_t; @@ -52,6 +58,16 @@ struct private_pkcs11_plugin_t { * mutex to lock list */ mutex_t *mutex; + + /** + * TRUE if events from tokens are to be handled + */ + bool handle_events; + + /** + * Lock for the above flag + */ + rwlock_t *handle_events_lock; }; /** @@ -61,9 +77,10 @@ static void token_event_cb(private_pkcs11_plugin_t *this, pkcs11_library_t *p11, CK_SLOT_ID slot, bool add) { enumerator_t *enumerator; - pkcs11_creds_t *creds, *found = NULL;; + pkcs11_creds_t *creds, *found = NULL; - if (add) + this->handle_events_lock->read_lock(this->handle_events_lock); + if (add && this->handle_events) { creds = pkcs11_creds_create(p11, slot); if (creds) @@ -74,7 +91,7 @@ static void token_event_cb(private_pkcs11_plugin_t *this, pkcs11_library_t *p11, lib->credmgr->add_set(lib->credmgr, &creds->set); } } - else + else if (this->handle_events) { this->mutex->lock(this->mutex); enumerator = this->creds->create_enumerator(this->creds); @@ -99,6 +116,7 @@ static void token_event_cb(private_pkcs11_plugin_t *this, pkcs11_library_t *p11, lib->credmgr->flush_cache(lib->credmgr, CERT_X509); } } + this->handle_events_lock->unlock(this->handle_events_lock); } METHOD(plugin_t, get_name, char*, @@ -107,23 +125,158 @@ METHOD(plugin_t, get_name, char*, return "pkcs11"; } -METHOD(plugin_t, destroy, void, - private_pkcs11_plugin_t *this) +/** + * Load/unload certificates from tokens. + */ +static bool handle_certs(private_pkcs11_plugin_t *this, + plugin_feature_t *feature, bool reg, void *data) { - pkcs11_creds_t *creds; + this->handle_events_lock->write_lock(this->handle_events_lock); + this->handle_events = reg; + this->handle_events_lock->unlock(this->handle_events_lock); + + if (reg) + { + enumerator_t *enumerator; + pkcs11_library_t *p11; + CK_SLOT_ID slot; + + enumerator = this->manager->create_token_enumerator(this->manager); + while (enumerator->enumerate(enumerator, &p11, &slot)) + { + token_event_cb(this, p11, slot, TRUE); + } + enumerator->destroy(enumerator); + } + else + { + pkcs11_creds_t *creds; - lib->creds->remove_builder(lib->creds, - (builder_function_t)pkcs11_private_key_connect); - while (this->creds->remove_last(this->creds, (void**)&creds) == SUCCESS) + while (this->creds->remove_last(this->creds, (void**)&creds) == SUCCESS) + { + lib->credmgr->remove_set(lib->credmgr, &creds->set); + creds->destroy(creds); + } + } + return TRUE; +} +/** + * Add a set of features + */ +static inline void add_features(plugin_feature_t *f, plugin_feature_t *n, + int count, int *pos) +{ + int i; + for (i = 0; i < count; i++) { - lib->credmgr->remove_set(lib->credmgr, &creds->set); - creds->destroy(creds); + f[(*pos)++] = n[i]; } - lib->crypto->remove_hasher(lib->crypto, - (hasher_constructor_t)pkcs11_hasher_create); - this->creds->destroy(this->creds); +} + +METHOD(plugin_t, get_features, int, + private_pkcs11_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f_hash[] = { + PLUGIN_REGISTER(HASHER, pkcs11_hasher_create), + PLUGIN_PROVIDE(HASHER, HASH_MD2), + PLUGIN_PROVIDE(HASHER, HASH_MD5), + PLUGIN_PROVIDE(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(HASHER, HASH_SHA512), + }; + static plugin_feature_t f_dh[] = { + PLUGIN_REGISTER(DH, pkcs11_dh_create), + PLUGIN_PROVIDE(DH, MODP_2048_BIT), + PLUGIN_PROVIDE(DH, MODP_2048_224), + PLUGIN_PROVIDE(DH, MODP_2048_256), + PLUGIN_PROVIDE(DH, MODP_1536_BIT), + PLUGIN_PROVIDE(DH, MODP_3072_BIT), + PLUGIN_PROVIDE(DH, MODP_4096_BIT), + PLUGIN_PROVIDE(DH, MODP_6144_BIT), + PLUGIN_PROVIDE(DH, MODP_8192_BIT), + PLUGIN_PROVIDE(DH, MODP_1024_BIT), + PLUGIN_PROVIDE(DH, MODP_1024_160), + PLUGIN_PROVIDE(DH, MODP_768_BIT), + PLUGIN_PROVIDE(DH, MODP_CUSTOM), + }; + static plugin_feature_t f_ecdh[] = { + PLUGIN_REGISTER(DH, pkcs11_dh_create), + PLUGIN_PROVIDE(DH, ECP_192_BIT), + PLUGIN_PROVIDE(DH, ECP_224_BIT), + PLUGIN_PROVIDE(DH, ECP_256_BIT), + PLUGIN_PROVIDE(DH, ECP_384_BIT), + PLUGIN_PROVIDE(DH, ECP_521_BIT), + }; + static plugin_feature_t f_rng[] = { + PLUGIN_REGISTER(RNG, pkcs11_rng_create), + PLUGIN_PROVIDE(RNG, RNG_STRONG), + PLUGIN_PROVIDE(RNG, RNG_TRUE), + }; + static plugin_feature_t f_privkey[] = { + PLUGIN_REGISTER(PRIVKEY, pkcs11_private_key_connect, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), + }; + static plugin_feature_t f_pubkey[] = { + PLUGIN_REGISTER(PUBKEY, pkcs11_public_key_load, TRUE), + PLUGIN_PROVIDE(PUBKEY, KEY_RSA), + PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA), + }; + static plugin_feature_t f_manager[] = { + PLUGIN_CALLBACK((plugin_feature_callback_t)handle_certs, NULL), + PLUGIN_PROVIDE(CUSTOM, "pkcs11-certs"), + PLUGIN_DEPENDS(CERT_DECODE, CERT_X509), + }; + static plugin_feature_t f[countof(f_hash) + countof(f_dh) + countof(f_rng) + + countof(f_ecdh) + countof(f_privkey) + + countof(f_pubkey) + countof(f_manager)] = {}; + static int count = 0; + + if (!count) + { /* initialize only once */ + bool use_ecc = lib->settings->get_bool(lib->settings, + "libstrongswan.plugins.pkcs11.use_ecc", FALSE); + add_features(f, f_manager, countof(f_manager), &count); + /* private key handling for EC keys is not disabled by use_ecc */ + add_features(f, f_privkey, countof(f_privkey), &count); + if (lib->settings->get_bool(lib->settings, + "libstrongswan.plugins.pkcs11.use_pubkey", FALSE)) + { + add_features(f, f_pubkey, countof(f_pubkey) - (use_ecc ? 0 : 1), + &count); + } + if (lib->settings->get_bool(lib->settings, + "libstrongswan.plugins.pkcs11.use_hasher", FALSE)) + { + add_features(f, f_hash, countof(f_hash), &count); + } + if (lib->settings->get_bool(lib->settings, + "libstrongswan.plugins.pkcs11.use_rng", FALSE)) + { + add_features(f, f_rng, countof(f_rng), &count); + } + if (lib->settings->get_bool(lib->settings, + "libstrongswan.plugins.pkcs11.use_dh", FALSE)) + { + add_features(f, f_dh, countof(f_dh), &count); + if (use_ecc) + { + add_features(f, f_ecdh, countof(f_ecdh), &count); + } + } + } + *features = f; + return count; +} + +METHOD(plugin_t, destroy, void, + private_pkcs11_plugin_t *this) +{ + lib->set(lib, "pkcs11-manager", NULL); this->manager->destroy(this->manager); + this->creds->destroy(this->creds); this->mutex->destroy(this->mutex); + this->handle_events_lock->destroy(this->handle_events_lock); free(this); } @@ -133,52 +286,22 @@ METHOD(plugin_t, destroy, void, plugin_t *pkcs11_plugin_create() { private_pkcs11_plugin_t *this; - enumerator_t *enumerator; - pkcs11_library_t *p11; - CK_SLOT_ID slot; INIT(this, .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, .creds = linked_list_create(), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .handle_events_lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); this->manager = pkcs11_manager_create((void*)token_event_cb, this); - - if (lib->settings->get_bool(lib->settings, - "libstrongswan.plugins.pkcs11.use_hasher", FALSE)) - { - lib->crypto->add_hasher(lib->crypto, HASH_MD2, get_name(this), - (hasher_constructor_t)pkcs11_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_MD5, get_name(this), - (hasher_constructor_t)pkcs11_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this), - (hasher_constructor_t)pkcs11_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA256, get_name(this), - (hasher_constructor_t)pkcs11_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA384, get_name(this), - (hasher_constructor_t)pkcs11_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA512, get_name(this), - (hasher_constructor_t)pkcs11_hasher_create); - } - - lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE, - (builder_function_t)pkcs11_private_key_connect); - lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE, - (builder_function_t)pkcs11_public_key_load); - - enumerator = this->manager->create_token_enumerator(this->manager); - while (enumerator->enumerate(enumerator, &p11, &slot)) - { - token_event_cb(this, p11, slot, TRUE); - } - enumerator->destroy(enumerator); + lib->set(lib, "pkcs11-manager", this->manager); return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c index b4cc7a805..b616abc38 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -19,7 +22,6 @@ #include "pkcs11_manager.h" #include <debug.h> -#include <threading/mutex.h> typedef struct private_pkcs11_private_key_t private_pkcs11_private_key_t; @@ -39,14 +41,14 @@ struct private_pkcs11_private_key_t { pkcs11_library_t *lib; /** - * Token session + * Slot the token is in */ - CK_SESSION_HANDLE session; + CK_SLOT_ID slot; /** - * Mutex to lock session + * Token session */ - mutex_t *mutex; + CK_SESSION_HANDLE session; /** * Key object on the token @@ -72,12 +74,24 @@ struct private_pkcs11_private_key_t { * References to this key */ refcount_t ref; + + /** + * Type of this private key + */ + key_type_t type; }; +/** + * Implemented in pkcs11_public_key.c + */ +public_key_t *pkcs11_public_key_connect(pkcs11_library_t *p11, + int slot, key_type_t type, chunk_t keyid); + + METHOD(private_key_t, get_type, key_type_t, private_pkcs11_private_key_t *this) { - return this->pubkey->get_type(this->pubkey); + return this->type; } METHOD(private_key_t, get_keysize, int, @@ -89,18 +103,45 @@ METHOD(private_key_t, get_keysize, int, /** * See header. */ -CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme) +CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme, + key_type_t type, size_t keylen, + hash_algorithm_t *hash) { static struct { signature_scheme_t scheme; CK_MECHANISM mechanism; + key_type_t type; + size_t keylen; + hash_algorithm_t hash; } mappings[] = { - {SIGN_RSA_EMSA_PKCS1_NULL, {CKM_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_SHA1, {CKM_SHA1_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_SHA256, {CKM_SHA256_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_SHA384, {CKM_SHA384_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_SHA512, {CKM_SHA512_RSA_PKCS, NULL, 0}}, - {SIGN_RSA_EMSA_PKCS1_MD5, {CKM_MD5_RSA_PKCS, NULL, 0}}, + {SIGN_RSA_EMSA_PKCS1_NULL, {CKM_RSA_PKCS, NULL, 0}, + KEY_RSA, 0, HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_SHA1, {CKM_SHA1_RSA_PKCS, NULL, 0}, + KEY_RSA, 0, HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_SHA256, {CKM_SHA256_RSA_PKCS, NULL, 0}, + KEY_RSA, 0, HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_SHA384, {CKM_SHA384_RSA_PKCS, NULL, 0}, + KEY_RSA, 0, HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_SHA512, {CKM_SHA512_RSA_PKCS, NULL, 0}, + KEY_RSA, 0, HASH_UNKNOWN}, + {SIGN_RSA_EMSA_PKCS1_MD5, {CKM_MD5_RSA_PKCS, NULL, 0}, + KEY_RSA, 0, HASH_UNKNOWN}, + {SIGN_ECDSA_WITH_NULL, {CKM_ECDSA, NULL, 0}, + KEY_ECDSA, 0, HASH_UNKNOWN}, + {SIGN_ECDSA_WITH_SHA1_DER, {CKM_ECDSA_SHA1, NULL, 0}, + KEY_ECDSA, 0, HASH_UNKNOWN}, + {SIGN_ECDSA_WITH_SHA256_DER, {CKM_ECDSA, NULL, 0}, + KEY_ECDSA, 0, HASH_SHA256}, + {SIGN_ECDSA_WITH_SHA384_DER, {CKM_ECDSA, NULL, 0}, + KEY_ECDSA, 0, HASH_SHA384}, + {SIGN_ECDSA_WITH_SHA512_DER, {CKM_ECDSA, NULL, 0}, + KEY_ECDSA, 0, HASH_SHA512}, + {SIGN_ECDSA_256, {CKM_ECDSA, NULL, 0}, + KEY_ECDSA, 256, HASH_SHA256}, + {SIGN_ECDSA_384, {CKM_ECDSA, NULL, 0}, + KEY_ECDSA, 384, HASH_SHA384}, + {SIGN_ECDSA_521, {CKM_ECDSA, NULL, 0}, + KEY_ECDSA, 521, HASH_SHA512}, }; int i; @@ -108,6 +149,15 @@ CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme) { if (mappings[i].scheme == scheme) { + size_t len = mappings[i].keylen; + if (mappings[i].type != type || (len && keylen != len)) + { + return NULL; + } + if (hash) + { + *hash = mappings[i].hash; + } return &mappings[i].mechanism; } } @@ -141,7 +191,8 @@ CK_MECHANISM_PTR pkcs11_encryption_scheme_to_mech(encryption_scheme_t scheme) /** * Reauthenticate to do a signature */ -static bool reauth(private_pkcs11_private_key_t *this) +static bool reauth(private_pkcs11_private_key_t *this, + CK_SESSION_HANDLE session) { enumerator_t *enumerator; shared_key_t *shared; @@ -155,7 +206,7 @@ static bool reauth(private_pkcs11_private_key_t *this) { found = TRUE; pin = shared->get_key(shared); - rv = this->lib->f->C_Login(this->session, CKU_CONTEXT_SPECIFIC, + rv = this->lib->f->C_Login(session, CKU_CONTEXT_SPECIFIC, pin.ptr, pin.len); if (rv == CKR_OK) { @@ -179,33 +230,61 @@ METHOD(private_key_t, sign, bool, chunk_t data, chunk_t *signature) { CK_MECHANISM_PTR mechanism; + CK_SESSION_HANDLE session; CK_BYTE_PTR buf; CK_ULONG len; CK_RV rv; + hash_algorithm_t hash_alg; + chunk_t hash = chunk_empty; - mechanism = pkcs11_signature_scheme_to_mech(scheme); + mechanism = pkcs11_signature_scheme_to_mech(scheme, this->type, + get_keysize(this), &hash_alg); if (!mechanism) { DBG1(DBG_LIB, "signature scheme %N not supported", signature_scheme_names, scheme); return FALSE; } - this->mutex->lock(this->mutex); - rv = this->lib->f->C_SignInit(this->session, mechanism, this->object); - if (this->reauth && !reauth(this)) + rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL, + &session); + if (rv != CKR_OK) { + DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv); + return FALSE; + } + rv = this->lib->f->C_SignInit(session, mechanism, this->object); + if (this->reauth && !reauth(this, session)) + { + this->lib->f->C_CloseSession(session); return FALSE; } if (rv != CKR_OK) { - this->mutex->unlock(this->mutex); + this->lib->f->C_CloseSession(session); DBG1(DBG_LIB, "C_SignInit() failed: %N", ck_rv_names, rv); return FALSE; } + if (hash_alg != HASH_UNKNOWN) + { + hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); + if (!hasher) + { + this->lib->f->C_CloseSession(session); + return FALSE; + } + hasher->allocate_hash(hasher, data, &hash); + hasher->destroy(hasher); + data = hash; + } len = (get_keysize(this) + 7) / 8; + if (this->type == KEY_ECDSA) + { /* signature is twice the length of the base point order */ + len *= 2; + } buf = malloc(len); - rv = this->lib->f->C_Sign(this->session, data.ptr, data.len, buf, &len); - this->mutex->unlock(this->mutex); + rv = this->lib->f->C_Sign(session, data.ptr, data.len, buf, &len); + this->lib->f->C_CloseSession(session); + chunk_free(&hash); if (rv != CKR_OK) { DBG1(DBG_LIB, "C_Sign() failed: %N", ck_rv_names, rv); @@ -221,6 +300,7 @@ METHOD(private_key_t, decrypt, bool, chunk_t crypt, chunk_t *plain) { CK_MECHANISM_PTR mechanism; + CK_SESSION_HANDLE session; CK_BYTE_PTR buf; CK_ULONG len; CK_RV rv; @@ -232,22 +312,29 @@ METHOD(private_key_t, decrypt, bool, encryption_scheme_names, scheme); return FALSE; } - this->mutex->lock(this->mutex); - rv = this->lib->f->C_DecryptInit(this->session, mechanism, this->object); - if (this->reauth && !reauth(this)) + rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL, + &session); + if (rv != CKR_OK) { + DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv); + return FALSE; + } + rv = this->lib->f->C_DecryptInit(session, mechanism, this->object); + if (this->reauth && !reauth(this, session)) + { + this->lib->f->C_CloseSession(session); return FALSE; } if (rv != CKR_OK) { - this->mutex->unlock(this->mutex); + this->lib->f->C_CloseSession(session); DBG1(DBG_LIB, "C_DecryptInit() failed: %N", ck_rv_names, rv); return FALSE; } len = (get_keysize(this) + 7) / 8; buf = malloc(len); - rv = this->lib->f->C_Decrypt(this->session, crypt.ptr, crypt.len, buf, &len); - this->mutex->unlock(this->mutex); + rv = this->lib->f->C_Decrypt(session, crypt.ptr, crypt.len, buf, &len); + this->lib->f->C_CloseSession(session); if (rv != CKR_OK) { DBG1(DBG_LIB, "C_Decrypt() failed: %N", ck_rv_names, rv); @@ -294,7 +381,6 @@ METHOD(private_key_t, destroy, void, { this->pubkey->destroy(this->pubkey); } - this->mutex->destroy(this->mutex); this->keyid->destroy(this->keyid); this->lib->f->C_CloseSession(this->session); free(this); @@ -311,7 +397,7 @@ static pkcs11_library_t* find_lib(char *module) pkcs11_library_t *p11, *found = NULL; CK_SLOT_ID slot; - manager = pkcs11_manager_get(); + manager = lib->get(lib, "pkcs11-manager"); if (!manager) { return NULL; @@ -339,7 +425,7 @@ static pkcs11_library_t* find_lib_by_keyid(chunk_t keyid, int *slot) pkcs11_library_t *p11, *found = NULL; CK_SLOT_ID current; - manager = pkcs11_manager_get(); + manager = lib->get(lib, "pkcs11-manager"); if (!manager) { return NULL; @@ -404,13 +490,11 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid) CK_BBOOL reauth = FALSE; CK_ATTRIBUTE attr[] = { {CKA_KEY_TYPE, &type, sizeof(type)}, - {CKA_MODULUS, NULL, 0}, - {CKA_PUBLIC_EXPONENT, NULL, 0}, {CKA_ALWAYS_AUTHENTICATE, &reauth, sizeof(reauth)}, }; enumerator_t *enumerator; - chunk_t modulus, pubexp; int count = countof(attr); + bool found = FALSE; /* do not use CKA_ALWAYS_AUTHENTICATE if not supported */ if (!(this->lib->get_features(this->lib) & PKCS11_ALWAYS_AUTH_KEYS)) @@ -421,26 +505,16 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid) this->session, tmpl, countof(tmpl), attr, count); if (enumerator->enumerate(enumerator, &object)) { + this->type = KEY_RSA; switch (type) { + case CKK_ECDSA: + this->type = KEY_ECDSA; + /* fall-through */ case CKK_RSA: - if (attr[1].ulValueLen == -1 || attr[2].ulValueLen == -1) - { - DBG1(DBG_CFG, "reading modulus/exponent from PKCS#1 failed"); - break; - } - modulus = chunk_create(attr[1].pValue, attr[1].ulValueLen); - pubexp = chunk_create(attr[2].pValue, attr[2].ulValueLen); - this->pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, - KEY_RSA, BUILD_RSA_MODULUS, modulus, - BUILD_RSA_PUB_EXP, pubexp, BUILD_END); - if (!this->pubkey) - { - DBG1(DBG_CFG, "extracting public key from PKCS#11 RSA " - "private key failed"); - } this->reauth = reauth; this->object = object; + found = TRUE; break; default: DBG1(DBG_CFG, "PKCS#11 key type %d not supported", type); @@ -448,7 +522,7 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid) } } enumerator->destroy(enumerator); - return this->pubkey != NULL; + return found; } /** @@ -587,7 +661,7 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args) return NULL; } - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + this->slot = slot; this->keyid = identification_create_from_encoding(ID_KEY_ID, keyid); if (!login(this, slot)) @@ -602,5 +676,13 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args) return NULL; } + this->pubkey = pkcs11_public_key_connect(this->lib, slot, this->type, + keyid); + if (!this->pubkey) + { + destroy(this); + return NULL; + } + return &this->public; } diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h index 428913f0a..6d3a9556e 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -46,14 +49,23 @@ struct pkcs11_private_key_t { * * @param type type of the key * @param args builder_part_t argument list - * @return loaded key, NULL on failure + * @return loaded key, NULL on failure */ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args); /** * Get the Cryptoki mechanism for a signature scheme. + * + * Verifies that the given key is usable for this scheme. + * + * @param scheme signature scheme + * @param type key type + * @param keylen key length in bits + * @param hash hash algorithm to apply first (HASH_UNKNOWN if none) */ -CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme); +CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme, + key_type_t type, size_t keylen, + hash_algorithm_t *hash); /** * Get the Cryptoki mechanism for a encryption scheme. diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c index 8d32d9a3f..d4ec9235d 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -19,8 +22,10 @@ #include "pkcs11_private_key.h" #include "pkcs11_manager.h" +#include <asn1/oid.h> +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> #include <debug.h> -#include <threading/mutex.h> typedef struct private_pkcs11_public_key_t private_pkcs11_public_key_t; @@ -40,7 +45,7 @@ struct private_pkcs11_public_key_t { key_type_t type; /** - * Key size in bytes + * Key size in bits */ size_t k; @@ -65,16 +70,121 @@ struct private_pkcs11_public_key_t { CK_OBJECT_HANDLE object; /** - * Mutex to lock session - */ - mutex_t *mutex; - - /** * References to this key */ refcount_t ref; }; +/** + * Helper function that returns the base point order length in bits of the + * given named curve. + * + * Currently only a subset of defined curves is supported (namely the 5 curves + * over Fp recommended by NIST). IKEv2 only supports 3 out of these. + * + * 0 is returned if the given curve is not supported. + */ +static size_t basepoint_order_len(int oid) +{ + switch (oid) + { + case OID_PRIME192V1: + return 192; + case OID_SECT224R1: + return 224; + case OID_PRIME256V1: + return 256; + case OID_SECT384R1: + return 384; + case OID_SECT521R1: + return 521; + default: + return 0; + } +} + +/** + * Parses the given ecParameters (ASN.1) and returns the key length. + */ +static bool keylen_from_ecparams(chunk_t ecparams, size_t *keylen) +{ + if (!asn1_parse_simple_object(&ecparams, ASN1_OID, 0, "named curve")) + { + return FALSE; + } + *keylen = basepoint_order_len(asn1_known_oid(ecparams)); + return *keylen > 0; +} + +/** + * ASN.1 definition of a subjectPublicKeyInfo structure when used with ECDSA + * we currently only support named curves. + */ +static const asn1Object_t pkinfoObjects[] = { + { 0, "subjectPublicKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ + { 2, "algorithm", ASN1_OID, ASN1_BODY }, /* 2 */ + { 2, "namedCurve", ASN1_OID, ASN1_RAW }, /* 3 */ + { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 4 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM 2 +#define PKINFO_SUBJECT_PUBLIC_KEY_NAMEDCURVE 3 +#define PKINFO_SUBJECT_PUBLIC_KEY 4 + +/** + * Extract the DER encoded Parameters and ECPoint from the given DER encoded + * subjectPublicKeyInfo. + */ +static bool parse_ecdsa_public_key(chunk_t blob, chunk_t *ecparams, + chunk_t *ecpoint, size_t *keylen) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID; + bool success = FALSE; + + parser = asn1_parser_create(pkinfoObjects, blob); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM: + { + if (asn1_known_oid(object) != OID_EC_PUBLICKEY) + { + goto end; + } + break; + } + case PKINFO_SUBJECT_PUBLIC_KEY_NAMEDCURVE: + { + *ecparams = object; + if (!keylen_from_ecparams(object, keylen)) + { + goto end; + } + break; + } + case PKINFO_SUBJECT_PUBLIC_KEY: + { + if (object.len > 0 && *object.ptr == 0x00) + { /* skip initial bit string octet defining 0 unused bits */ + object = chunk_skip(object, 1); + } + *ecpoint = object; + break; + } + } + } + success = parser->success(parser); +end: + parser->destroy(parser); + return success; +} + + METHOD(public_key_t, get_type, key_type_t, private_pkcs11_public_key_t *this) { @@ -84,7 +194,7 @@ METHOD(public_key_t, get_type, key_type_t, METHOD(public_key_t, get_keysize, int, private_pkcs11_public_key_t *this) { - return this->k * 8; + return this->k; } METHOD(public_key_t, verify, bool, @@ -92,9 +202,13 @@ METHOD(public_key_t, verify, bool, chunk_t data, chunk_t sig) { CK_MECHANISM_PTR mechanism; + CK_SESSION_HANDLE session; CK_RV rv; + hash_algorithm_t hash_alg; + chunk_t hash = chunk_empty; - mechanism = pkcs11_signature_scheme_to_mech(scheme); + mechanism = pkcs11_signature_scheme_to_mech(scheme, this->type, this->k, + &hash_alg); if (!mechanism) { DBG1(DBG_LIB, "signature scheme %N not supported", @@ -105,17 +219,35 @@ METHOD(public_key_t, verify, bool, { /* trim leading zero byte in sig */ sig = chunk_skip(sig, 1); } - this->mutex->lock(this->mutex); - rv = this->lib->f->C_VerifyInit(this->session, mechanism, this->object); + rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL, + &session); if (rv != CKR_OK) { - this->mutex->unlock(this->mutex); + DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv); + return FALSE; + } + rv = this->lib->f->C_VerifyInit(session, mechanism, this->object); + if (rv != CKR_OK) + { + this->lib->f->C_CloseSession(session); DBG1(DBG_LIB, "C_VerifyInit() failed: %N", ck_rv_names, rv); return FALSE; } - rv = this->lib->f->C_Verify(this->session, data.ptr, data.len, - sig.ptr, sig.len); - this->mutex->unlock(this->mutex); + if (hash_alg != HASH_UNKNOWN) + { + hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); + if (!hasher) + { + this->lib->f->C_CloseSession(session); + return FALSE; + } + hasher->allocate_hash(hasher, data, &hash); + hasher->destroy(hasher); + data = hash; + } + rv = this->lib->f->C_Verify(session, data.ptr, data.len, sig.ptr, sig.len); + this->lib->f->C_CloseSession(session); + chunk_free(&hash); if (rv != CKR_OK) { DBG1(DBG_LIB, "C_Verify() failed: %N", ck_rv_names, rv); @@ -129,6 +261,7 @@ METHOD(public_key_t, encrypt, bool, chunk_t plain, chunk_t *crypt) { CK_MECHANISM_PTR mechanism; + CK_SESSION_HANDLE session; CK_BYTE_PTR buf; CK_ULONG len; CK_RV rv; @@ -140,18 +273,24 @@ METHOD(public_key_t, encrypt, bool, encryption_scheme_names, scheme); return FALSE; } - this->mutex->lock(this->mutex); - rv = this->lib->f->C_EncryptInit(this->session, mechanism, this->object); + rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL, + &session); if (rv != CKR_OK) { - this->mutex->unlock(this->mutex); + DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv); + return FALSE; + } + rv = this->lib->f->C_EncryptInit(session, mechanism, this->object); + if (rv != CKR_OK) + { + this->lib->f->C_CloseSession(session); DBG1(DBG_LIB, "C_EncryptInit() failed: %N", ck_rv_names, rv); return FALSE; } len = (get_keysize(this) + 7) / 8; buf = malloc(len); - rv = this->lib->f->C_Encrypt(this->session, plain.ptr, plain.len, buf, &len); - this->mutex->unlock(this->mutex); + rv = this->lib->f->C_Encrypt(session, plain.ptr, plain.len, buf, &len); + this->lib->f->C_CloseSession(session); if (rv != CKR_OK) { DBG1(DBG_LIB, "C_Encrypt() failed: %N", ck_rv_names, rv); @@ -163,40 +302,119 @@ METHOD(public_key_t, encrypt, bool, } /** + * Encode ECDSA key using a given encoding type + */ +static bool encode_ecdsa(private_pkcs11_public_key_t *this, + cred_encoding_type_t type, chunk_t *encoding) +{ + enumerator_t *enumerator; + bool success = FALSE; + CK_ATTRIBUTE attr[] = { + {CKA_EC_PARAMS, NULL, 0}, + {CKA_EC_POINT, NULL, 0}, + }; + + if (type != PUBKEY_SPKI_ASN1_DER && type != PUBKEY_PEM) + { + return FALSE; + } + + enumerator = this->lib->create_object_attr_enumerator(this->lib, + this->session, this->object, attr, countof(attr)); + if (enumerator && enumerator->enumerate(enumerator, NULL) && + attr[0].ulValueLen > 0 && attr[1].ulValueLen > 0) + { + chunk_t ecparams, ecpoint; + ecparams = chunk_create(attr[0].pValue, attr[0].ulValueLen); + ecpoint = chunk_create(attr[1].pValue, attr[1].ulValueLen); + /* encode as subjectPublicKeyInfo */ + *encoding = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_wrap(ASN1_SEQUENCE, "mc", + asn1_build_known_oid(OID_EC_PUBLICKEY), ecparams), + asn1_bitstring("c", ecpoint)); + success = TRUE; + if (type == PUBKEY_PEM) + { + chunk_t asn1 = *encoding; + success = lib->encoding->encode(lib->encoding, PUBKEY_PEM, + NULL, encoding, CRED_PART_ECDSA_PUB_ASN1_DER, + asn1, CRED_PART_END); + chunk_clear(&asn1); + } + } + DESTROY_IF(enumerator); + return success; +} + +/** + * Compute fingerprint of an ECDSA key + */ +static bool fingerprint_ecdsa(private_pkcs11_public_key_t *this, + cred_encoding_type_t type, chunk_t *fp) +{ + hasher_t *hasher; + chunk_t asn1; + + switch (type) + { + case KEYID_PUBKEY_SHA1: + if (!this->lib->get_ck_attribute(this->lib, this->session, + this->object, CKA_EC_POINT, &asn1)) + { + return FALSE; + } + break; + case KEYID_PUBKEY_INFO_SHA1: + if (!encode_ecdsa(this, PUBKEY_SPKI_ASN1_DER, &asn1)) + { + return FALSE; + } + break; + default: + return FALSE; + } + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher) + { + chunk_clear(&asn1); + return FALSE; + } + hasher->allocate_hash(hasher, asn1, fp); + hasher->destroy(hasher); + chunk_clear(&asn1); + lib->encoding->cache(lib->encoding, type, this, *fp); + return TRUE; +} + +/** * Encode RSA key using a given encoding type */ static bool encode_rsa(private_pkcs11_public_key_t *this, cred_encoding_type_t type, void *cache, chunk_t *encoding) { - CK_RV rv; + enumerator_t *enumerator; bool success = FALSE; - chunk_t n, e; CK_ATTRIBUTE attr[] = { {CKA_MODULUS, NULL, 0}, {CKA_PUBLIC_EXPONENT, NULL, 0}, }; - rv = this->lib->f->C_GetAttributeValue(this->session, this->object, - attr, countof(attr)); - if (rv != CKR_OK || - attr[0].ulValueLen == 0 || attr[0].ulValueLen == -1 || - attr[1].ulValueLen == 0 || attr[1].ulValueLen == -1) - { - return FALSE; - } - attr[0].pValue = malloc(attr[0].ulValueLen); - attr[1].pValue = malloc(attr[1].ulValueLen); - rv = this->lib->f->C_GetAttributeValue(this->session, this->object, - attr, countof(attr)); - if (rv == CKR_OK) + enumerator = this->lib->create_object_attr_enumerator(this->lib, + this->session, this->object, attr, countof(attr)); + if (enumerator && enumerator->enumerate(enumerator, NULL) && + attr[0].ulValueLen > 0 && attr[1].ulValueLen > 0) { + chunk_t n, e; n = chunk_create(attr[0].pValue, attr[0].ulValueLen); + if (n.ptr[0] & 0x80) + { /* add leading 0x00, encoders expect it already like this */ + n = chunk_cata("cc", chunk_from_chars(0x00), n); + } e = chunk_create(attr[1].pValue, attr[1].ulValueLen); success = lib->encoding->encode(lib->encoding, type, cache, encoding, CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_END); } - free(attr[0].pValue); - free(attr[1].pValue); + DESTROY_IF(enumerator); return success; } @@ -208,6 +426,8 @@ METHOD(public_key_t, get_encoding, bool, { case KEY_RSA: return encode_rsa(this, type, NULL, encoding); + case KEY_ECDSA: + return encode_ecdsa(this, type, encoding); default: return FALSE; } @@ -224,6 +444,8 @@ METHOD(public_key_t, get_fingerprint, bool, { case KEY_RSA: return encode_rsa(this, type, this, fp); + case KEY_ECDSA: + return fingerprint_ecdsa(this, type, fp); default: return FALSE; } @@ -243,7 +465,6 @@ METHOD(public_key_t, destroy, void, { lib->encoding->clear_cache(lib->encoding, this); this->lib->f->C_CloseSession(this->session); - this->mutex->destroy(this->mutex); free(this); } } @@ -278,7 +499,6 @@ static private_pkcs11_public_key_t *create(key_type_t type, size_t k, .slot = slot, .session = session, .object = object, - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), .ref = 1, ); @@ -288,7 +508,8 @@ static private_pkcs11_public_key_t *create(key_type_t type, size_t k, /** * Find a key object, including PKCS11 library and slot */ -static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e) +static private_pkcs11_public_key_t* find_key(key_type_t type, size_t keylen, + CK_ATTRIBUTE_PTR tmpl, int count) { private_pkcs11_public_key_t *this = NULL; pkcs11_manager_t *manager; @@ -296,7 +517,7 @@ static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e) pkcs11_library_t *p11; CK_SLOT_ID slot; - manager = pkcs11_manager_get(); + manager = lib->get(lib, "pkcs11-manager"); if (!manager) { return NULL; @@ -305,14 +526,6 @@ static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e) enumerator = manager->create_token_enumerator(manager); while (enumerator->enumerate(enumerator, &p11, &slot)) { - CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; - CK_KEY_TYPE type = CKK_RSA; - CK_ATTRIBUTE tmpl[] = { - {CKA_CLASS, &class, sizeof(class)}, - {CKA_KEY_TYPE, &type, sizeof(type)}, - {CKA_MODULUS, n.ptr, n.len}, - {CKA_PUBLIC_EXPONENT, e.ptr, e.len}, - }; CK_OBJECT_HANDLE object; CK_SESSION_HANDLE session; CK_RV rv; @@ -324,11 +537,11 @@ static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e) DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv); continue; } - keys = p11->create_object_enumerator(p11, session, - tmpl, countof(tmpl), NULL, 0); + keys = p11->create_object_enumerator(p11, session, tmpl, count, + NULL, 0); if (keys->enumerate(keys, &object)) { - this = create(KEY_RSA, n.len, p11, slot, session, object); + this = create(type, keylen, p11, slot, session, object); keys->destroy(keys); break; } @@ -340,9 +553,46 @@ static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e) } /** + * Find an RSA key object + */ +static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e, + size_t keylen) +{ + CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; + CK_KEY_TYPE type = CKK_RSA; + CK_ATTRIBUTE tmpl[] = { + {CKA_CLASS, &class, sizeof(class)}, + {CKA_KEY_TYPE, &type, sizeof(type)}, + {CKA_MODULUS, n.ptr, n.len}, + {CKA_PUBLIC_EXPONENT, e.ptr, e.len}, + }; + return find_key(KEY_RSA, keylen, tmpl, countof(tmpl)); +} + +/** + * Find an ECDSA key object + */ +static private_pkcs11_public_key_t* find_ecdsa_key(chunk_t ecparams, + chunk_t ecpoint, + size_t keylen) +{ + CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; + CK_KEY_TYPE type = CKK_ECDSA; + CK_ATTRIBUTE tmpl[] = { + {CKA_CLASS, &class, sizeof(class)}, + {CKA_KEY_TYPE, &type, sizeof(type)}, + {CKA_EC_PARAMS, ecparams.ptr, ecparams.len}, + {CKA_EC_POINT, ecpoint.ptr, ecpoint.len}, + }; + return find_key(KEY_ECDSA, keylen, tmpl, countof(tmpl)); +} + +/** * Create a key object in a suitable token session */ -static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e) +static private_pkcs11_public_key_t* create_key(key_type_t type, size_t keylen, + CK_MECHANISM_TYPE_PTR mechanisms, int mcount, + CK_ATTRIBUTE_PTR tmpl, int count) { private_pkcs11_public_key_t *this = NULL; pkcs11_manager_t *manager; @@ -350,7 +600,7 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e) pkcs11_library_t *p11; CK_SLOT_ID slot; - manager = pkcs11_manager_get(); + manager = lib->get(lib, "pkcs11-manager"); if (!manager) { return NULL; @@ -361,14 +611,6 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e) { CK_MECHANISM_TYPE mech; CK_MECHANISM_INFO info; - CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; - CK_KEY_TYPE type = CKK_RSA; - CK_ATTRIBUTE tmpl[] = { - {CKA_CLASS, &class, sizeof(class)}, - {CKA_KEY_TYPE, &type, sizeof(type)}, - {CKA_MODULUS, n.ptr, n.len}, - {CKA_PUBLIC_EXPONENT, e.ptr, e.len} - }; CK_OBJECT_HANDLE object; CK_SESSION_HANDLE session; CK_RV rv; @@ -376,21 +618,23 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e) mechs = p11->create_mechanism_enumerator(p11, slot); while (mechs->enumerate(mechs, &mech, &info)) { + bool found = FALSE; + int i; if (!(info.flags & CKF_VERIFY)) { continue; } - switch (mech) + for (i = 0; i < mcount; i++) { - case CKM_RSA_PKCS: - case CKM_SHA1_RSA_PKCS: - case CKM_SHA256_RSA_PKCS: - case CKM_SHA384_RSA_PKCS: - case CKM_SHA512_RSA_PKCS: - case CKM_MD5_RSA_PKCS: + if (mechanisms[i] == mech) + { + found = TRUE; break; - default: - continue; + } + } + if (!found) + { + continue; } rv = p11->f->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &session); @@ -400,20 +644,21 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e) ck_rv_names, rv); continue; } - rv = p11->f->C_CreateObject(session, tmpl, countof(tmpl), &object); + rv = p11->f->C_CreateObject(session, tmpl, count, &object); if (rv == CKR_OK) { - this = create(KEY_RSA, n.len, p11, slot, session, object); - DBG2(DBG_CFG, "created RSA public key on token '%s':%d ", - p11->get_name(p11), slot); - break; + this = create(type, keylen, p11, slot, session, object); + DBG2(DBG_CFG, "created %N public key on token '%s':%d ", + key_type_names, type, p11->get_name(p11), slot); } else { - DBG1(DBG_CFG, "creating RSA public key on token '%s':%d " - "failed: %N", p11->get_name(p11), slot, ck_rv_names, rv); + DBG1(DBG_CFG, "creating %N public key on token '%s':%d " + "failed: %N", key_type_names, type, p11->get_name(p11), + slot, ck_rv_names, rv); p11->f->C_CloseSession(session); } + break; } mechs->destroy(mechs); if (this) @@ -426,18 +671,71 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e) } /** + * Create an RSA key object in a suitable token session + */ +static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e, + size_t keylen) +{ + CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; + CK_KEY_TYPE type = CKK_RSA; + CK_ATTRIBUTE tmpl[] = { + {CKA_CLASS, &class, sizeof(class)}, + {CKA_KEY_TYPE, &type, sizeof(type)}, + {CKA_MODULUS, n.ptr, n.len}, + {CKA_PUBLIC_EXPONENT, e.ptr, e.len}, + }; + CK_MECHANISM_TYPE mechs[] = { + CKM_RSA_PKCS, + CKM_SHA1_RSA_PKCS, + CKM_SHA256_RSA_PKCS, + CKM_SHA384_RSA_PKCS, + CKM_SHA512_RSA_PKCS, + CKM_MD5_RSA_PKCS, + }; + return create_key(KEY_RSA, keylen, mechs, countof(mechs), tmpl, + countof(tmpl)); +} + +/** + * Create an ECDSA key object in a suitable token session + */ +static private_pkcs11_public_key_t* create_ecdsa_key(chunk_t ecparams, + chunk_t ecpoint, + size_t keylen) +{ + CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; + CK_KEY_TYPE type = CKK_ECDSA; + CK_ATTRIBUTE tmpl[] = { + {CKA_CLASS, &class, sizeof(class)}, + {CKA_KEY_TYPE, &type, sizeof(type)}, + {CKA_EC_PARAMS, ecparams.ptr, ecparams.len}, + {CKA_EC_POINT, ecpoint.ptr, ecpoint.len}, + }; + CK_MECHANISM_TYPE mechs[] = { + CKM_ECDSA, + CKM_ECDSA_SHA1, + }; + return create_key(KEY_ECDSA, keylen, mechs, + countof(mechs), tmpl, countof(tmpl)); +} + +/** * See header */ pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args) { private_pkcs11_public_key_t *this; - chunk_t n, e; + chunk_t n, e, blob; + size_t keylen = 0; - n = e = chunk_empty; + n = e = blob = chunk_empty; while (TRUE) { switch (va_arg(args, builder_part_t)) { + case BUILD_BLOB_ASN1_DER: + blob = va_arg(args, chunk_t); + continue; case BUILD_RSA_MODULUS: n = va_arg(args, chunk_t); continue; @@ -457,17 +755,152 @@ pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args) { /* trim leading zero byte in modulus */ n = chunk_skip(n, 1); } - this = find_rsa_key(n, e); + keylen = n.len * 8; + this = find_rsa_key(n, e, keylen); if (this) { return &this->public; } - this = create_rsa_key(n, e); + this = create_rsa_key(n, e, keylen); if (this) { return &this->public; } } + else if (type == KEY_ECDSA && blob.ptr) + { + chunk_t ecparams, ecpoint; + ecparams = ecpoint = chunk_empty; + if (parse_ecdsa_public_key(blob, &ecparams, &ecpoint, &keylen)) + { + this = find_ecdsa_key(ecparams, ecpoint, keylen); + if (this) + { + return &this->public; + } + this = create_ecdsa_key(ecparams, ecpoint, keylen); + if (this) + { + return &this->public; + } + } + } return NULL; } +static private_pkcs11_public_key_t *find_key_by_keyid(pkcs11_library_t *p11, + int slot, key_type_t key_type, + chunk_t keyid) +{ + CK_OBJECT_CLASS class = CKO_PUBLIC_KEY; + CK_KEY_TYPE type; + CK_ATTRIBUTE tmpl[] = { + {CKA_CLASS, &class, sizeof(class)}, + {CKA_ID, keyid.ptr, keyid.len}, + {CKA_KEY_TYPE, &type, sizeof(type)}, + }; + CK_OBJECT_HANDLE object; + CK_ATTRIBUTE attr[] = { + {CKA_KEY_TYPE, &type, sizeof(type)}, + }; + CK_SESSION_HANDLE session; + CK_RV rv; + enumerator_t *enumerator; + int count = countof(tmpl); + bool found = FALSE; + size_t keylen; + + switch (key_type) + { + case KEY_RSA: + type = CKK_RSA; + break; + case KEY_ECDSA: + type = CKK_ECDSA; + break; + default: + /* don't specify key type on KEY_ANY */ + count--; + break; + } + + rv = p11->f->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &session); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "opening public key session on '%s':%d failed: %N", + p11->get_name(p11), slot, ck_rv_names, rv); + return NULL; + } + + enumerator = p11->create_object_enumerator(p11, session, tmpl, count, attr, + countof(attr)); + if (enumerator->enumerate(enumerator, &object)) + { + switch (type) + { + case CKK_ECDSA: + { + chunk_t ecparams; + if (p11->get_ck_attribute(p11, session, object, CKA_EC_PARAMS, + &ecparams) && + keylen_from_ecparams(ecparams, &keylen)) + { + chunk_free(&ecparams); + key_type = KEY_ECDSA; + found = TRUE; + } + break; + } + case CKK_RSA: + { + chunk_t n; + if (p11->get_ck_attribute(p11, session, object, CKA_MODULUS, + &n) && n.len > 0) + { + keylen = n.len * 8; + chunk_free(&n); + key_type = KEY_RSA; + found = TRUE; + } + break; + } + default: + DBG1(DBG_CFG, "PKCS#11 key type %d not supported", type); + break; + } + } + enumerator->destroy(enumerator); + + if (found) + { + return create(key_type, keylen, p11, slot, session, object); + } + p11->f->C_CloseSession(session); + return NULL; +} + +/** + * Find a public key on the given token with a specific keyid. + * + * Used by pkcs11_private_key_t. + * + * TODO: if no public key is found, we should perhaps search for a certificate + * with the given keyid and extract the key from there + * + * @param p11 PKCS#11 module + * @param slot slot id + * @param type type of the key + * @param keyid key id + */ +pkcs11_public_key_t *pkcs11_public_key_connect(pkcs11_library_t *p11, + int slot, key_type_t type, chunk_t keyid) +{ + private_pkcs11_public_key_t *this; + + this = find_key_by_keyid(p11, slot, type, keyid); + if (!this) + { + return NULL; + } + return &this->public; +} diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h index 4fd94620e..b3ea725a2 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h @@ -42,7 +42,7 @@ struct pkcs11_public_key_t { * * @param type type of the key * @param args builder_part_t argument list - * @return loaded key, NULL on failure + * @return loaded key, NULL on failure */ pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args); diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c new file mode 100644 index 000000000..45cf0b7c2 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 + * 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 "pkcs11_rng.h" + +#include <debug.h> + +#include "pkcs11_manager.h" + +typedef struct private_pkcs11_rng_t private_pkcs11_rng_t; + +/** + * Private data of an pkcs11_rng_t object. + */ +struct private_pkcs11_rng_t { + + /** + * Public interface. + */ + pkcs11_rng_t public; + + /** + * PKCS#11 library + */ + pkcs11_library_t *lib; + + /** + * Mechanism for this rng + */ + CK_SESSION_HANDLE session; + +}; + +METHOD(rng_t, get_bytes, void, + private_pkcs11_rng_t *this, size_t bytes, u_int8_t *buffer) +{ + CK_RV rv; + rv = this->lib->f->C_GenerateRandom(this->session, buffer, bytes); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GenerateRandom() failed: %N", ck_rv_names, rv); + abort(); + } +} + +METHOD(rng_t, allocate_bytes, void, + private_pkcs11_rng_t *this, size_t bytes, chunk_t *chunk) +{ + *chunk = chunk_alloc(bytes); + get_bytes(this, chunk->len, chunk->ptr); +} + +METHOD(rng_t, destroy, void, + private_pkcs11_rng_t *this) +{ + this->lib->f->C_CloseSession(this->session); + free(this); +} + +/** + * Find a token with its own RNG + */ +static pkcs11_library_t *find_token(CK_SESSION_HANDLE *session) +{ + enumerator_t *tokens; + pkcs11_manager_t *manager; + pkcs11_library_t *current, *found = NULL; + CK_SLOT_ID slot; + + manager = lib->get(lib, "pkcs11-manager"); + if (!manager) + { + return NULL; + } + tokens = manager->create_token_enumerator(manager); + while (tokens->enumerate(tokens, ¤t, &slot)) + { + CK_TOKEN_INFO info; + CK_RV rv; + rv = current->f->C_GetTokenInfo(slot, &info); + if (rv != CKR_OK) + { + continue; + } + if (info.flags & CKF_RNG) + { + if (current->f->C_OpenSession(slot, CKF_SERIAL_SESSION, + NULL, NULL, session) == CKR_OK) + { + found = current; + break; + } + } + } + tokens->destroy(tokens); + return found; +} + +/* + * Described in header. + */ +pkcs11_rng_t *pkcs11_rng_create(rng_quality_t quality) +{ + private_pkcs11_rng_t *this; + + INIT(this, + .public = { + .rng = { + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .destroy = _destroy, + }, + }, + ); + + this->lib = find_token(&this->session); + if (!this->lib) + { + free(this); + return NULL; + } + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h new file mode 100644 index 000000000..998631f7e --- /dev/null +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 + * 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 pkcs11_rng pkcs11_rng + * @{ @ingroup pkcs11 + */ + +#ifndef PKCS11_RNG_H_ +#define PKCS11_RNG_H_ + +typedef struct pkcs11_rng_t pkcs11_rng_t; + +#include <library.h> + +/** + * rng_t implementation via PKCS#11 + */ +struct pkcs11_rng_t { + + /** + * Implements rng_t. + */ + rng_t rng; +}; + +/** + * Creates a pkcs11_rng_t instance. + * + * @param quality required quality of randomness + * @return created pkcs11_rng_t + */ +pkcs11_rng_t *pkcs11_rng_create(rng_quality_t quality); + +#endif /** PKCS11_RNG_H_ @} */ diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.am b/src/libstrongswan/plugins/pkcs8/Makefile.am new file mode 100644 index 000000000..bcaf2c6a5 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs8/Makefile.am @@ -0,0 +1,16 @@ + +INCLUDES = -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = -rdynamic + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-pkcs8.la +else +plugin_LTLIBRARIES = libstrongswan-pkcs8.la +endif + +libstrongswan_pkcs8_la_SOURCES = \ + pkcs8_plugin.h pkcs8_plugin.c \ + pkcs8_builder.h pkcs8_builder.c + +libstrongswan_pkcs8_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in new file mode 100644 index 000000000..2b9c6cf95 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs8/Makefile.in @@ -0,0 +1,611 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libstrongswan/plugins/pkcs8 +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +libstrongswan_pkcs8_la_LIBADD = +am_libstrongswan_pkcs8_la_OBJECTS = pkcs8_plugin.lo pkcs8_builder.lo +libstrongswan_pkcs8_la_OBJECTS = $(am_libstrongswan_pkcs8_la_OBJECTS) +libstrongswan_pkcs8_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libstrongswan_pkcs8_la_LDFLAGS) $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_pkcs8_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_pkcs8_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstrongswan_pkcs8_la_SOURCES) +DIST_SOURCES = $(libstrongswan_pkcs8_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PTHREADLIB = @PTHREADLIB@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYINCLUDE = @RUBYINCLUDE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +default_pkcs11 = @default_pkcs11@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +libcharon_plugins = @libcharon_plugins@ +libdir = @libdir@ +libexecdir = @libexecdir@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +oldincludedir = @oldincludedir@ +openac_plugins = @openac_plugins@ +p_plugins = @p_plugins@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pluto_plugins = @pluto_plugins@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +sysconfdir = @sysconfdir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +INCLUDES = -I$(top_srcdir)/src/libstrongswan +AM_CFLAGS = -rdynamic +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-pkcs8.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-pkcs8.la +libstrongswan_pkcs8_la_SOURCES = \ + pkcs8_plugin.h pkcs8_plugin.c \ + pkcs8_builder.h pkcs8_builder.c + +libstrongswan_pkcs8_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/pkcs8/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/pkcs8/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libstrongswan-pkcs8.la: $(libstrongswan_pkcs8_la_OBJECTS) $(libstrongswan_pkcs8_la_DEPENDENCIES) + $(libstrongswan_pkcs8_la_LINK) $(am_libstrongswan_pkcs8_la_rpath) $(libstrongswan_pkcs8_la_OBJECTS) $(libstrongswan_pkcs8_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs8_builder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs8_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + ctags distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c new file mode 100644 index 000000000..346240ae1 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c @@ -0,0 +1,632 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 "pkcs8_builder.h" + +#include <debug.h> +#include <asn1/oid.h> +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> +#include <credentials/keys/private_key.h> + +/** + * ASN.1 definition of a privateKeyInfo structure + */ +static const asn1Object_t pkinfoObjects[] = { + { 0, "privateKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */ + { 1, "privateKeyAlgorithm", ASN1_EOC, ASN1_RAW }, /* 2 */ + { 1, "privateKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */ + { 1, "attributes", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 5 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PKINFO_PRIVATE_KEY_ALGORITHM 2 +#define PKINFO_PRIVATE_KEY 3 + +/** + * Load a generic private key from an ASN.1 encoded blob + */ +static private_key_t *parse_private_key(chunk_t blob) +{ + asn1_parser_t *parser; + chunk_t object, params = chunk_empty; + int objectID; + private_key_t *key = NULL; + key_type_t type = KEY_ANY; + + parser = asn1_parser_create(pkinfoObjects, blob); + parser->set_flags(parser, FALSE, TRUE); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case PKINFO_PRIVATE_KEY_ALGORITHM: + { + int oid = asn1_parse_algorithmIdentifier(object, + parser->get_level(parser) + 1, ¶ms); + + switch (oid) + { + case OID_RSA_ENCRYPTION: + type = KEY_RSA; + break; + case OID_EC_PUBLICKEY: + type = KEY_ECDSA; + break; + default: + /* key type not supported */ + goto end; + } + break; + } + case PKINFO_PRIVATE_KEY: + { + DBG2(DBG_ASN, "-- > --"); + if (params.ptr) + { + key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, + type, BUILD_BLOB_ALGID_PARAMS, + params, BUILD_BLOB_ASN1_DER, + object, BUILD_END); + } + else + { + key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, + type, BUILD_BLOB_ASN1_DER, object, + BUILD_END); + } + DBG2(DBG_ASN, "-- < --"); + break; + } + } + } + +end: + parser->destroy(parser); + return key; +} + +/** + * Verify padding of decrypted blob. + * Length of blob is adjusted accordingly. + */ +static bool verify_padding(chunk_t *blob) +{ + u_int8_t padding, count; + + padding = count = blob->ptr[blob->len - 1]; + if (padding > 8) + { + return FALSE; + } + for (; blob->len && count; --blob->len, --count) + { + if (blob->ptr[blob->len - 1] != padding) + { + return FALSE; + } + } + return TRUE; +} + +/** + * Prototype for key derivation functions. + */ +typedef void (*kdf_t)(void *generator, chunk_t password, chunk_t salt, + u_int64_t iterations, chunk_t key); + +/** + * Try to decrypt the given blob with multiple passwords using the given + * key derivation function. keymat is where the kdf function writes the key + * to, key and iv point to the actual keys and initialization vectors resp. + */ +static private_key_t *decrypt_private_key(chunk_t blob, + encryption_algorithm_t encr, size_t key_len, kdf_t kdf, + void *generator, chunk_t salt, u_int64_t iterations, + chunk_t keymat, chunk_t key, chunk_t iv) +{ + enumerator_t *enumerator; + shared_key_t *shared; + crypter_t *crypter; + private_key_t *private_key = NULL; + + crypter = lib->crypto->create_crypter(lib->crypto, encr, key_len); + if (!crypter) + { + DBG1(DBG_ASN, " %N encryption algorithm not available", + encryption_algorithm_names, encr); + return NULL; + } + if (blob.len % crypter->get_block_size(crypter)) + { + DBG1(DBG_ASN, " data size is not a multiple of block size"); + crypter->destroy(crypter); + return NULL; + } + + enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, + SHARED_PRIVATE_KEY_PASS, NULL, NULL); + while (enumerator->enumerate(enumerator, &shared, NULL, NULL)) + { + chunk_t decrypted; + + kdf(generator, shared->get_key(shared), salt, iterations, keymat); + + crypter->set_key(crypter, key); + crypter->decrypt(crypter, blob, iv, &decrypted); + if (verify_padding(&decrypted)) + { + private_key = parse_private_key(decrypted); + if (private_key) + { + chunk_clear(&decrypted); + break; + } + } + chunk_free(&decrypted); + } + enumerator->destroy(enumerator); + crypter->destroy(crypter); + + return private_key; +} + +/** + * Function F of PBKDF2 + */ +static void pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed, + u_int64_t iterations) +{ + chunk_t u; + u_int64_t i; + + u = chunk_alloca(prf->get_block_size(prf)); + prf->get_bytes(prf, seed, u.ptr); + memcpy(block.ptr, u.ptr, block.len); + + for (i = 1; i < iterations; i++) + { + prf->get_bytes(prf, u, u.ptr); + memxor(block.ptr, u.ptr, block.len); + } +} + +/** + * PBKDF2 key derivation function + */ +static void pbkdf2(prf_t *prf, chunk_t password, chunk_t salt, + u_int64_t iterations, chunk_t key) +{ + chunk_t keymat, block, seed; + size_t blocks; + u_int32_t i = 0, *ni; + + prf->set_key(prf, password); + + block.len = prf->get_block_size(prf); + blocks = (key.len - 1) / block.len + 1; + keymat = chunk_alloca(blocks * block.len); + + seed = chunk_cata("cc", salt, chunk_from_thing(i)); + ni = (u_int32_t*)(seed.ptr + salt.len); + + for (; i < blocks; i++) + { + *ni = htonl(i + 1); + block.ptr = keymat.ptr + (i * block.len); + pbkdf2_f(block, prf, seed, iterations); + } + + memcpy(key.ptr, keymat.ptr, key.len); +} + +/** + * Decrypt an encrypted PKCS#8 encoded private key according to PBES2 + */ +static private_key_t *decrypt_private_key_pbes2(chunk_t blob, + encryption_algorithm_t encr, size_t key_len, + chunk_t iv, pseudo_random_function_t prf_func, + chunk_t salt, u_int64_t iterations) +{ + private_key_t *private_key; + prf_t *prf; + chunk_t key; + + prf = lib->crypto->create_prf(lib->crypto, prf_func); + if (!prf) + { + DBG1(DBG_ASN, " %N prf algorithm not available", + pseudo_random_function_names, prf_func); + return NULL; + } + + key = chunk_alloca(key_len); + + private_key = decrypt_private_key(blob, encr, key_len, (kdf_t)pbkdf2, prf, + salt, iterations, key, key, iv); + + prf->destroy(prf); + return private_key; +} + +/** + * PBKDF1 key derivation function + */ +static void pbkdf1(hasher_t *hasher, chunk_t password, chunk_t salt, + u_int64_t iterations, chunk_t key) +{ + chunk_t hash; + u_int64_t i; + + hash = chunk_alloca(hasher->get_hash_size(hasher)); + hasher->get_hash(hasher, password, NULL); + hasher->get_hash(hasher, salt, hash.ptr); + + for (i = 1; i < iterations; i++) + { + hasher->get_hash(hasher, hash, hash.ptr); + } + + memcpy(key.ptr, hash.ptr, key.len); +} + +/** + * Decrypt an encrypted PKCS#8 encoded private key according to PBES1 + */ +static private_key_t *decrypt_private_key_pbes1(chunk_t blob, + encryption_algorithm_t encr, size_t key_len, + hash_algorithm_t hash, chunk_t salt, + u_int64_t iterations) +{ + private_key_t *private_key = NULL; + hasher_t *hasher = NULL; + chunk_t keymat, key, iv; + + hasher = lib->crypto->create_hasher(lib->crypto, hash); + if (!hasher) + { + DBG1(DBG_ASN, " %N hash algorithm not available", + hash_algorithm_names, hash); + goto end; + } + if (hasher->get_hash_size(hasher) < key_len) + { + goto end; + } + + keymat = chunk_alloca(key_len * 2); + key.len = key_len; + key.ptr = keymat.ptr; + iv.len = key_len; + iv.ptr = keymat.ptr + key_len; + + private_key = decrypt_private_key(blob, encr, key_len, (kdf_t)pbkdf1, + hasher, salt, iterations, keymat, + key, iv); + +end: + DESTROY_IF(hasher); + return private_key; +} + +/** + * Parse an ASN1_INTEGER to a u_int64_t. + */ +static u_int64_t parse_asn1_integer_uint64(chunk_t blob) +{ + u_int64_t val = 0; + int i; + + for (i = 0; i < blob.len; i++) + { /* if it is longer than 8 bytes, we just use the 8 LSBs */ + val <<= 8; + val |= (u_int64_t)blob.ptr[i]; + } + return val; +} + +/** + * ASN.1 definition of a PBKDF2-params structure + * The salt is actually a CHOICE and could be an AlgorithmIdentifier from + * PBKDF2-SaltSources (but as per RFC 2898 that's for future versions). + */ +static const asn1Object_t pbkdf2ParamsObjects[] = { + { 0, "PBKDF2-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "salt", ASN1_OCTET_STRING, ASN1_BODY }, /* 1 */ + { 1, "iterationCount",ASN1_INTEGER, ASN1_BODY }, /* 2 */ + { 1, "keyLength", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 3 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */ + { 1, "prf", ASN1_EOC, ASN1_DEF|ASN1_RAW }, /* 5 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PBKDF2_SALT 1 +#define PBKDF2_ITERATION_COUNT 2 +#define PBKDF2_KEY_LENGTH 3 +#define PBKDF2_PRF 5 + +/** + * Parse a PBKDF2-params structure + */ +static void parse_pbkdf2_params(chunk_t blob, chunk_t *salt, + u_int64_t *iterations, size_t *key_len, + pseudo_random_function_t *prf) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID; + + parser = asn1_parser_create(pbkdf2ParamsObjects, blob); + + *key_len = 0; /* key_len is optional */ + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case PBKDF2_SALT: + { + *salt = object; + break; + } + case PBKDF2_ITERATION_COUNT: + { + *iterations = parse_asn1_integer_uint64(object); + break; + } + case PBKDF2_KEY_LENGTH: + { + *key_len = (size_t)parse_asn1_integer_uint64(object); + break; + } + case PBKDF2_PRF: + { /* defaults to id-hmacWithSHA1 */ + *prf = PRF_HMAC_SHA1; + break; + } + } + } + + parser->destroy(parser); +} + +/** + * ASN.1 definition of a PBES2-params structure + */ +static const asn1Object_t pbes2ParamsObjects[] = { + { 0, "PBES2-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "keyDerivationFunc", ASN1_EOC, ASN1_RAW }, /* 1 */ + { 1, "encryptionScheme", ASN1_EOC, ASN1_RAW }, /* 2 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PBES2PARAMS_KEY_DERIVATION_FUNC 1 +#define PBES2PARAMS_ENCRYPTION_SCHEME 2 + +/** + * Parse a PBES2-params structure + */ +static void parse_pbes2_params(chunk_t blob, chunk_t *salt, + u_int64_t *iterations, size_t *key_len, + pseudo_random_function_t *prf, + encryption_algorithm_t *encr, chunk_t *iv) +{ + asn1_parser_t *parser; + chunk_t object, params; + int objectID; + + parser = asn1_parser_create(pbes2ParamsObjects, blob); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case PBES2PARAMS_KEY_DERIVATION_FUNC: + { + int oid = asn1_parse_algorithmIdentifier(object, + parser->get_level(parser) + 1, ¶ms); + if (oid != OID_PBKDF2) + { /* unsupported key derivation function */ + goto end; + } + parse_pbkdf2_params(params, salt, iterations, key_len, prf); + break; + } + case PBES2PARAMS_ENCRYPTION_SCHEME: + { + int oid = asn1_parse_algorithmIdentifier(object, + parser->get_level(parser) + 1, ¶ms); + if (oid != OID_3DES_EDE_CBC) + { /* unsupported encryption scheme */ + goto end; + } + if (*key_len <= 0) + { /* default key len for DES-EDE3-CBC-Pad */ + *key_len = 24; + } + if (!asn1_parse_simple_object(¶ms, ASN1_OCTET_STRING, + parser->get_level(parser) + 1, "IV")) + { + goto end; + } + *encr = ENCR_3DES; + *iv = params; + break; + } + } + } + +end: + parser->destroy(parser); +} + +/** + * ASN.1 definition of a PBEParameter structure + */ +static const asn1Object_t pbeParameterObjects[] = { + { 0, "PBEParameter", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "salt", ASN1_OCTET_STRING, ASN1_BODY }, /* 1 */ + { 1, "iterationCount", ASN1_INTEGER, ASN1_BODY }, /* 2 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PBEPARAM_SALT 1 +#define PBEPARAM_ITERATION_COUNT 2 + +/** + * Parse a PBEParameter structure + */ +static void parse_pbe_parameters(chunk_t blob, chunk_t *salt, + u_int64_t *iterations) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID; + + parser = asn1_parser_create(pbeParameterObjects, blob); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case PBEPARAM_SALT: + { + *salt = object; + break; + } + case PBEPARAM_ITERATION_COUNT: + { + *iterations = parse_asn1_integer_uint64(object); + break; + } + } + } + + parser->destroy(parser); +} + +/** + * ASN.1 definition of an encryptedPrivateKeyInfo structure + */ +static const asn1Object_t encryptedPKIObjects[] = { + { 0, "encryptedPrivateKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 1 */ + { 1, "encryptedData", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define EPKINFO_ENCRYPTION_ALGORITHM 1 +#define EPKINFO_ENCRYPTED_DATA 2 + +/** + * Load an encrypted private key from an ASN.1 encoded blob + * Schemes per PKCS#5 (RFC 2898) + */ +static private_key_t *parse_encrypted_private_key(chunk_t blob) +{ + asn1_parser_t *parser; + chunk_t object, params, salt, iv; + u_int64_t iterations = 0; + int objectID; + encryption_algorithm_t encr = ENCR_UNDEFINED; + hash_algorithm_t hash = HASH_UNKNOWN; + pseudo_random_function_t prf = PRF_UNDEFINED; + private_key_t *key = NULL; + size_t key_len = 8; + + parser = asn1_parser_create(encryptedPKIObjects, blob); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case EPKINFO_ENCRYPTION_ALGORITHM: + { + int oid = asn1_parse_algorithmIdentifier(object, + parser->get_level(parser) + 1, ¶ms); + + switch (oid) + { + case OID_PBE_MD5_DES_CBC: + encr = ENCR_DES; + hash = HASH_MD5; + parse_pbe_parameters(params, &salt, &iterations); + break; + case OID_PBE_SHA1_DES_CBC: + encr = ENCR_DES; + hash = HASH_SHA1; + parse_pbe_parameters(params, &salt, &iterations); + break; + case OID_PBES2: + parse_pbes2_params(params, &salt, &iterations, + &key_len, &prf, &encr, &iv); + break; + default: + /* encryption scheme not supported */ + goto end; + } + break; + } + case EPKINFO_ENCRYPTED_DATA: + { + if (prf != PRF_UNDEFINED) + { + key = decrypt_private_key_pbes2(object, encr, key_len, iv, + prf, salt, iterations); + } + else + { + key = decrypt_private_key_pbes1(object, encr, key_len, hash, + salt, iterations); + } + break; + } + } + } + +end: + parser->destroy(parser); + return key; +} + +/** + * See header. + */ +private_key_t *pkcs8_private_key_load(key_type_t type, va_list args) +{ + chunk_t blob = chunk_empty; + private_key_t *key; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_BLOB_ASN1_DER: + blob = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + /* we don't know whether it is encrypted or not, try both ways */ + key = parse_encrypted_private_key(blob); + if (!key) + { + key = parse_private_key(blob); + } + return key; +} + diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h new file mode 100644 index 000000000..b07f2d927 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 pkcs8_builder pkcs8_builder + * @{ @ingroup pkcs8 + */ + +#ifndef PKCS8_BUILDER_H_ +#define PKCS8_BUILDER_H_ + +#include <credentials/builder.h> +#include <credentials/keys/private_key.h> + +/** + * Load an RSA or ECDSA private key from PKCS#8 data. + * + * @param type type of the key, KEY_RSA or KEY_ECDSA + * @param args builder_part_t argument list + * @return private key, NULL on failure + */ +private_key_t *pkcs8_private_key_load(key_type_t type, va_list args); + +#endif /** PKCS8_BUILDER_H_ @}*/ diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c new file mode 100644 index 000000000..f78c83054 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 "pkcs8_plugin.h" + +#include <library.h> + +#include "pkcs8_builder.h" + +typedef struct private_pkcs8_plugin_t private_pkcs8_plugin_t; + +/** + * private data of pkcs8_plugin + */ +struct private_pkcs8_plugin_t { + + /** + * public functions + */ + pkcs8_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_pkcs8_plugin_t *this) +{ + return "pkcs8"; +} + +METHOD(plugin_t, get_features, int, + private_pkcs8_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRIVKEY, pkcs8_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), + PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_pkcs8_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *pkcs8_plugin_create() +{ + private_pkcs8_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} + diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.h b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.h new file mode 100644 index 000000000..03ca950a3 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * 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 PURPSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup pkcs8 pkcs8 + * @ingroup plugins + * + * @defgroup pkcs8_plugin pkcs8_plugin + * @{ @ingroup pkcs8 + */ + +#ifndef PKCS8_PLUGIN_H_ +#define PKCS8_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct pkcs8_plugin_t pkcs8_plugin_t; + +/** + * Plugin providing PKCS#8 private key decoding functions + */ +struct pkcs8_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** PKCS8_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/plugin.h b/src/libstrongswan/plugins/plugin.h index 5c92fd1d8..7bfbdf1d4 100644 --- a/src/libstrongswan/plugins/plugin.h +++ b/src/libstrongswan/plugins/plugin.h @@ -21,10 +21,11 @@ #ifndef PLUGIN_H_ #define PLUGIN_H_ -#include <utils.h> - typedef struct plugin_t plugin_t; +#include <library.h> +#include <plugins/plugin_feature.h> + /** * Interface definition of a plugin. */ @@ -38,6 +39,17 @@ struct plugin_t { char* (*get_name)(plugin_t *this); /** + * Get plugin features with dependencies. + * + * The returned array contains features provided by the plugin and + * dependencies for that feature. See plugin_feature_t for details. + * + * @param features pointer receiving plugin features + * @return number of features + */ + int (*get_features)(plugin_t *this, plugin_feature_t *features[]); + + /** * Try to reload plugin configuration. * * @return TRUE if reloaded, FALSE if reloading not supporty by plugin @@ -52,7 +64,7 @@ struct plugin_t { /** - * Plugin constructor function definiton. + * Plugin constructor function definition. * * Each plugin has a constructor function. This function is called on daemon * startup to initialize each plugin. diff --git a/src/libstrongswan/plugins/plugin_feature.c b/src/libstrongswan/plugins/plugin_feature.c new file mode 100644 index 000000000..2a97205bb --- /dev/null +++ b/src/libstrongswan/plugins/plugin_feature.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 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. + */ + +#define _GNU_SOURCE +#include <stdio.h> + +#include "plugin_feature.h" + +#include <debug.h> + +ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM, + "NONE", + "CRYPTER", + "AEAD", + "SIGNER", + "HASHER", + "PRF", + "DH", + "RNG", + "PRIVKEY", + "PRIVKEY_GEN", + "PRIVKEY_SIGN", + "PRIVKEY_DECRYPT", + "PUBKEY", + "PUBKEY_VERIFY", + "PUBKEY_ENCRYPT", + "CERT_DECODE", + "CERT_ENCODE", + "EAP_SERVER", + "EAP_CLIENT", + "DATABASE", + "FETCHER", + "CUSTOM", +); + +/** + * See header. + */ +bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b) +{ + if (a->type == b->type) + { + switch (a->type) + { + case FEATURE_NONE: + return FALSE; + case FEATURE_CRYPTER: + return a->arg.crypter.alg == b->arg.crypter.alg && + a->arg.crypter.key_size == b->arg.crypter.key_size; + case FEATURE_AEAD: + return a->arg.aead.alg == b->arg.aead.alg && + a->arg.aead.key_size == b->arg.aead.key_size; + case FEATURE_SIGNER: + return a->arg.signer == b->arg.signer; + case FEATURE_HASHER: + return a->arg.hasher == b->arg.hasher; + case FEATURE_PRF: + return a->arg.prf == b->arg.prf; + case FEATURE_DH: + return a->arg.dh_group == b->arg.dh_group; + case FEATURE_RNG: + return a->arg.rng_quality <= b->arg.rng_quality; + case FEATURE_PRIVKEY: + case FEATURE_PRIVKEY_GEN: + case FEATURE_PUBKEY: + return a->arg.privkey == b->arg.privkey; + case FEATURE_PRIVKEY_SIGN: + case FEATURE_PUBKEY_VERIFY: + return a->arg.privkey_sign == b->arg.privkey_sign; + case FEATURE_PRIVKEY_DECRYPT: + case FEATURE_PUBKEY_ENCRYPT: + return a->arg.privkey_decrypt == b->arg.privkey_decrypt; + case FEATURE_CERT_DECODE: + case FEATURE_CERT_ENCODE: + return a->arg.cert == b->arg.cert; + case FEATURE_EAP_SERVER: + case FEATURE_EAP_PEER: + return a->arg.eap == b->arg.eap; + case FEATURE_DATABASE: + return a->arg.database == DB_ANY || + a->arg.database == b->arg.database; + case FEATURE_FETCHER: + return a->arg.fetcher == NULL || + streq(a->arg.fetcher, b->arg.fetcher); + case FEATURE_CUSTOM: + return streq(a->arg.custom, b->arg.custom); + } + } + return FALSE; +} + +/** + * See header. + */ +char* plugin_feature_get_string(plugin_feature_t *feature) +{ + char *str = NULL; + + if (feature->kind == FEATURE_REGISTER) + { + return strdup("(register function)"); + } + switch (feature->type) + { + case FEATURE_NONE: + return strdup("NONE"); + case FEATURE_CRYPTER: + if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type, + encryption_algorithm_names, feature->arg.crypter.alg, + feature->arg.crypter.key_size) > 0) + { + return str; + } + break; + case FEATURE_AEAD: + if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type, + encryption_algorithm_names, feature->arg.aead.alg, + feature->arg.aead.key_size) > 0) + { + return str; + } + break; + case FEATURE_SIGNER: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + integrity_algorithm_names, feature->arg.signer) > 0) + { + return str; + } + break; + case FEATURE_HASHER: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + hash_algorithm_names, feature->arg.hasher) > 0) + { + return str; + } + break; + case FEATURE_PRF: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + pseudo_random_function_names, feature->arg.prf) > 0) + { + return str; + } + break; + case FEATURE_DH: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + diffie_hellman_group_names, feature->arg.dh_group) > 0) + { + return str; + } + break; + case FEATURE_RNG: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + rng_quality_names, feature->arg.rng_quality) > 0) + { + return str; + } + break; + case FEATURE_PRIVKEY: + case FEATURE_PRIVKEY_GEN: + case FEATURE_PUBKEY: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + key_type_names, feature->arg.privkey) > 0) + { + return str; + } + break; + case FEATURE_PRIVKEY_SIGN: + case FEATURE_PUBKEY_VERIFY: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + signature_scheme_names, feature->arg.privkey_sign) > 0) + { + return str; + } + break; + case FEATURE_PRIVKEY_DECRYPT: + case FEATURE_PUBKEY_ENCRYPT: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + encryption_scheme_names, feature->arg.privkey_decrypt) > 0) + { + return str; + } + break; + case FEATURE_CERT_DECODE: + case FEATURE_CERT_ENCODE: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + certificate_type_names, feature->arg.cert) > 0) + { + return str; + } + break; + case FEATURE_EAP_SERVER: + case FEATURE_EAP_PEER: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + eap_type_short_names, feature->arg.eap) > 0) + { + return str; + } + break; + case FEATURE_DATABASE: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + db_driver_names, feature->arg.database) > 0) + { + return str; + } + break; + case FEATURE_FETCHER: + if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type, + feature->arg.fetcher) > 0) + { + return str; + } + break; + case FEATURE_CUSTOM: + if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type, + feature->arg.custom) > 0) + { + return str; + } + break; + } + if (!str) + { + str = strdup("(invalid)"); + } + return str; +} + +/** + * See header. + */ +bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature, + plugin_feature_t *reg) +{ + char *name; + + if (!reg) + { /* noting to do for this feature */ + return TRUE; + } + if (reg->kind == FEATURE_CALLBACK) + { + if (reg->arg.cb.f(plugin, feature, TRUE, reg->arg.cb.data)) + { + return TRUE; + } + return FALSE; + } + name = plugin->get_name(plugin); + switch (feature->type) + { + case FEATURE_CRYPTER: + lib->crypto->add_crypter(lib->crypto, feature->arg.crypter.alg, + name, reg->arg.reg.f); + break; + case FEATURE_AEAD: + lib->crypto->add_aead(lib->crypto, feature->arg.aead.alg, + name, reg->arg.reg.f); + break; + case FEATURE_SIGNER: + lib->crypto->add_signer(lib->crypto, feature->arg.signer, + name, reg->arg.reg.f); + break; + case FEATURE_HASHER: + lib->crypto->add_hasher(lib->crypto, feature->arg.hasher, + name, reg->arg.reg.f); + break; + case FEATURE_PRF: + lib->crypto->add_prf(lib->crypto, feature->arg.prf, + name, reg->arg.reg.f); + break; + case FEATURE_DH: + lib->crypto->add_dh(lib->crypto, feature->arg.dh_group, + name, reg->arg.reg.f); + break; + case FEATURE_RNG: + lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality, + name, reg->arg.reg.f); + break; + case FEATURE_PRIVKEY: + case FEATURE_PRIVKEY_GEN: + lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, + feature->arg.privkey, reg->arg.reg.final, + reg->arg.reg.f); + break; + case FEATURE_PUBKEY: + lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, + feature->arg.pubkey, reg->arg.reg.final, + reg->arg.reg.f); + break; + case FEATURE_CERT_DECODE: + case FEATURE_CERT_ENCODE: + lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, + feature->arg.cert, reg->arg.reg.final, + reg->arg.reg.f); + break; + case FEATURE_DATABASE: + lib->db->add_database(lib->db, reg->arg.reg.f); + break; + case FEATURE_FETCHER: + lib->fetcher->add_fetcher(lib->fetcher, reg->arg.reg.f, + feature->arg.fetcher); + break; + default: + break; + } + return TRUE; +} + +/** + * See header. + */ +bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature, + plugin_feature_t *reg) +{ + if (!reg) + { /* noting to do for this feature */ + return TRUE; + } + if (reg->kind == FEATURE_CALLBACK) + { + if (reg->arg.cb.f(plugin, feature, FALSE, reg->arg.cb.data)) + { + return TRUE; + } + return FALSE; + } + switch (feature->type) + { + case FEATURE_CRYPTER: + lib->crypto->remove_crypter(lib->crypto, reg->arg.reg.f); + break; + case FEATURE_AEAD: + lib->crypto->remove_aead(lib->crypto, reg->arg.reg.f); + break; + case FEATURE_SIGNER: + lib->crypto->remove_signer(lib->crypto, reg->arg.reg.f); + break; + case FEATURE_HASHER: + lib->crypto->remove_hasher(lib->crypto, reg->arg.reg.f); + break; + case FEATURE_PRF: + lib->crypto->remove_prf(lib->crypto, reg->arg.reg.f); + break; + case FEATURE_DH: + lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f); + break; + case FEATURE_RNG: + lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f); + break; + case FEATURE_PRIVKEY: + case FEATURE_PRIVKEY_GEN: + lib->creds->remove_builder(lib->creds, reg->arg.reg.f); + break; + case FEATURE_PUBKEY: + lib->creds->remove_builder(lib->creds, reg->arg.reg.f); + break; + case FEATURE_CERT_DECODE: + case FEATURE_CERT_ENCODE: + lib->creds->remove_builder(lib->creds, reg->arg.reg.f); + break; + case FEATURE_DATABASE: + lib->db->remove_database(lib->db, reg->arg.reg.f); + break; + case FEATURE_FETCHER: + lib->fetcher->remove_fetcher(lib->fetcher, reg->arg.reg.f); + break; + default: + break; + } + return TRUE; +} diff --git a/src/libstrongswan/plugins/plugin_feature.h b/src/libstrongswan/plugins/plugin_feature.h new file mode 100644 index 000000000..b1500feba --- /dev/null +++ b/src/libstrongswan/plugins/plugin_feature.h @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 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 plugin_feature plugin_feature + * @{ @ingroup plugins + */ + +#ifndef PLUGIN_FEATURE_H_ +#define PLUGIN_FEATURE_H_ + +typedef struct plugin_feature_t plugin_feature_t; + +#include <library.h> +#include <eap/eap.h> +#include <plugins/plugin.h> + +/** + * Callback function of a plugin to (un-)register a specified feature. + * + * @param plugin plugin instance + * @param feature feature to register + * @param reg TRUE to register, FALSE to unregister + * @param cb_data user data passed with callback function + * @return TRUE if registered successfully + */ +typedef bool (*plugin_feature_callback_t)(plugin_t *plugin, + plugin_feature_t *feature, + bool reg,void *cb_data); + +/** + * Feature a plugin provides or depends on, including registration functions. + * + * Each plugin returns a list of plugin features, allowing the plugin loader + * to resolve dependencies and register the feature. FEATURE_PROVIDE defines + * features provided by the plugin, hard (DEPENDS) or soft (SDEPEND) dependency + * specified is related to the previously defined PROVIDE feature. + * If a plugin feature requires to hook in functionality into the library + * or a daemon, it can use REGISTER or CALLBACK entries. Each PROVIDED feature + * uses the REGISTER/CALLBACK entry defined previously. The REGISTER entry + * defines a common feature registration function directly passed to the + * associated manager or factory (crypto/credential factory etc.). A callback + * function is more generic allows the loader to invoke a callback to do + * the registration. + * + * To conviently create feature lists, use the four macros PLUGIN_REGISTER, + * PLUGIN_CALLBACK, PLUGIN_PROVIDE, PLUGIN_DEPENDS and PLUGIN_SDEPEND. Use + * identation to show how the registration functions and dependencies are + * related to a provided feature, such as: + * + * @verbatim + // two features, one with two dependencies, both use a callback to register + PLUGIN_CALLBACK(...), + PLUGIN_PROVIDE(...), + PLUGIN_DEPENDS(...), + PLUGIN_SDEPEND(...), + PLUGIN_PROVIDE(...), + // common constructor to register for a feature with one dependency + PLUGIN_REGISTER(...), + PLUGIN_PROVIDE(...), + PLUGIN_DEPENDS(...), + // feature that does not use a registration function + PLUGIN_PROVIDE(...), + @endverbatim + */ +struct plugin_feature_t { + /** kind of entry */ + enum { + /* plugin provides this feature */ + FEATURE_PROVIDE, + /* a feature depends on this feature, hard dependency */ + FEATURE_DEPENDS, + /* a feature can optionally use this feature, soft dependency */ + FEATURE_SDEPEND, + /* register the specified function for all following features */ + FEATURE_REGISTER, + /* use a callback to register all following features */ + FEATURE_CALLBACK, + } kind; + /* type of feature */ + enum { + /** not a feature */ + FEATURE_NONE, + /** crypter_t */ + FEATURE_CRYPTER, + /** aead_t */ + FEATURE_AEAD, + /** signer_t */ + FEATURE_SIGNER, + /** hasher_t */ + FEATURE_HASHER, + /** prf_t */ + FEATURE_PRF, + /** diffie_hellman_t */ + FEATURE_DH, + /** rng_t */ + FEATURE_RNG, + /** generic private key support */ + FEATURE_PRIVKEY, + /** generating new private keys */ + FEATURE_PRIVKEY_GEN, + /** private_key_t->sign() */ + FEATURE_PRIVKEY_SIGN, + /** private_key_t->decrypt() */ + FEATURE_PRIVKEY_DECRYPT, + /** generic public key support */ + FEATURE_PUBKEY, + /** public_key_t->verify() */ + FEATURE_PUBKEY_VERIFY, + /** public_key_t->encrypt() */ + FEATURE_PUBKEY_ENCRYPT, + /** parsing certificates */ + FEATURE_CERT_DECODE, + /** generating certificates */ + FEATURE_CERT_ENCODE, + /** EAP server implementation */ + FEATURE_EAP_SERVER, + /** EAP peer implementation */ + FEATURE_EAP_PEER, + /** database_t */ + FEATURE_DATABASE, + /** fetcher_t */ + FEATURE_FETCHER, + /** custom feature, described with a string */ + FEATURE_CUSTOM, + } type; + /** More specific data for each type */ + union { + /** FEATURE_CRYPTER */ + struct { + encryption_algorithm_t alg; + size_t key_size; + } crypter; + /** FEATURE_AEAD */ + struct { + encryption_algorithm_t alg; + size_t key_size; + } aead; + /** FEATURE_SIGNER */ + integrity_algorithm_t signer; + /** FEATURE_PRF */ + pseudo_random_function_t prf; + /** FEATURE_HASHER */ + hash_algorithm_t hasher; + /** FEATURE_DH */ + diffie_hellman_group_t dh_group; + /** FEATURE_RNG */ + rng_quality_t rng_quality; + /** FEATURE_PRIVKEY */ + key_type_t privkey; + /** FEATURE_PRIVKEY_GEN */ + key_type_t privkey_gen; + /** FEATURE_PRIVKEY_SIGN */ + signature_scheme_t privkey_sign; + /** FEATURE_PRIVKEY_DECRYPT */ + encryption_scheme_t privkey_decrypt; + /** FEATURE_PUBKEY */ + key_type_t pubkey; + /** FEATURE_PUBKEY_VERIFY */ + signature_scheme_t pubkey_verify; + /** FEATURE_PUBKEY_ENCRYPT */ + encryption_scheme_t pubkey_encrypt; + /** FEATURE_CERT_DECODE/ENCODE */ + certificate_type_t cert; + /** FEATURE_EAP_SERVER/CLIENT */ + eap_type_t eap; + /** FEATURE_DATABASE */ + db_driver_t database; + /** FEATURE_FETCHER */ + char *fetcher; + /** FEATURE_CUSTOM */ + char *custom; + + /** FEATURE_REGISTER */ + struct { + /** final flag to pass for builder_function_t */ + bool final; + /** feature specific function to register for this type */ + void *f; + } reg; + + /** FEATURE_CALLBACK */ + struct { + /** callback function to invoke for registration */ + plugin_feature_callback_t f; + /** data to pass to callback */ + void *data; + } cb; + } arg; +}; + +#define FEATURE(kind, type, ...) _PLUGIN_FEATURE_##type(kind, __VA_ARGS__) + +/** + * Define function to register directly for all upcoming features. + * + * @param type feature type to register + * @param f type specific function to register + * @param ... type specific additional arguments + */ +#define PLUGIN_REGISTER(type, f, ...) _PLUGIN_FEATURE_REGISTER_##type(type, f, ##__VA_ARGS__) + +/** + * Define a callback to invoke for registering all upcoming features. + * + * @param cb type specific callback function to register + * @param data data pointer to pass to callback + */ +#define PLUGIN_CALLBACK(cb, data) _PLUGIN_FEATURE_CALLBACK(cb, data) + +/** + * Define a feature the plugin provides. + * + * @param type feature type to provide + * @param ... type specific arguments + */ +#define PLUGIN_PROVIDE(type, ...) _PLUGIN_FEATURE_##type(PROVIDE, __VA_ARGS__) + +/** + * Define a hard dependency for the previously defined feature. + * + * @param type feature type to provide + * @param ... type specific arguments + */ +#define PLUGIN_DEPENDS(type, ...) _PLUGIN_FEATURE_##type(DEPENDS, __VA_ARGS__) + +/** + * Define a soft dependency for the previously defined feature. + * + * @param type feature type to provide + * @param ... type specific arguments + */ +#define PLUGIN_SDEPEND(type, ...) _PLUGIN_FEATURE_##type(SDEPEND, __VA_ARGS__) + +#define __PLUGIN_FEATURE(kind, type, ...) (plugin_feature_t){ FEATURE_##kind, FEATURE_##type, { __VA_ARGS__ }} +#define _PLUGIN_FEATURE_CRYPTER(kind, alg, size) __PLUGIN_FEATURE(kind, CRYPTER, .crypter = { alg, size }) +#define _PLUGIN_FEATURE_AEAD(kind, alg, size) __PLUGIN_FEATURE(kind, AEAD, .aead = { alg, size }) +#define _PLUGIN_FEATURE_SIGNER(kind, alg) __PLUGIN_FEATURE(kind, SIGNER, .signer = alg) +#define _PLUGIN_FEATURE_HASHER(kind, alg) __PLUGIN_FEATURE(kind, HASHER, .hasher = alg) +#define _PLUGIN_FEATURE_PRF(kind, alg) __PLUGIN_FEATURE(kind, PRF, .prf = alg) +#define _PLUGIN_FEATURE_DH(kind, group) __PLUGIN_FEATURE(kind, DH, .dh_group = group) +#define _PLUGIN_FEATURE_RNG(kind, quality) __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality) +#define _PLUGIN_FEATURE_PRIVKEY(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY, .privkey = type) +#define _PLUGIN_FEATURE_PRIVKEY_GEN(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY_GEN, .privkey_gen = type) +#define _PLUGIN_FEATURE_PRIVKEY_SIGN(kind, scheme) __PLUGIN_FEATURE(kind, PRIVKEY_SIGN, .privkey_sign = scheme) +#define _PLUGIN_FEATURE_PRIVKEY_DECRYPT(kind, scheme) __PLUGIN_FEATURE(kind, PRIVKEY_DECRYPT, .privkey_decrypt = scheme) +#define _PLUGIN_FEATURE_PUBKEY(kind, type) __PLUGIN_FEATURE(kind, PUBKEY, .pubkey = type) +#define _PLUGIN_FEATURE_PUBKEY_VERIFY(kind, scheme) __PLUGIN_FEATURE(kind, PUBKEY_VERIFY, .pubkey_verify = scheme) +#define _PLUGIN_FEATURE_PUBKEY_ENCRYPT(kind, scheme) __PLUGIN_FEATURE(kind, PUBKEY_ENCRYPT, .pubkey_encrypt = scheme) +#define _PLUGIN_FEATURE_CERT_DECODE(kind, type) __PLUGIN_FEATURE(kind, CERT_DECODE, .cert = type) +#define _PLUGIN_FEATURE_CERT_ENCODE(kind, type) __PLUGIN_FEATURE(kind, CERT_ENCODE, .cert = type) +#define _PLUGIN_FEATURE_EAP_SERVER(kind, type) __PLUGIN_FEATURE(kind, EAP_SERVER, .eap = type) +#define _PLUGIN_FEATURE_EAP_PEER(kind, type) __PLUGIN_FEATURE(kind, EAP_PEER, .eap = type) +#define _PLUGIN_FEATURE_DATABASE(kind, type) __PLUGIN_FEATURE(kind, DATABASE, .database = type) +#define _PLUGIN_FEATURE_FETCHER(kind, type) __PLUGIN_FEATURE(kind, FETCHER, .fetcher = type) +#define _PLUGIN_FEATURE_CUSTOM(kind, name) __PLUGIN_FEATURE(kind, CUSTOM, .custom = name) + +#define __PLUGIN_FEATURE_REGISTER(type, _f) (plugin_feature_t){ FEATURE_REGISTER, FEATURE_##type, .arg.reg.f = _f } +#define __PLUGIN_FEATURE_REGISTER_BUILDER(type, _f, _final) (plugin_feature_t){ FEATURE_REGISTER, FEATURE_##type, .arg.reg = {.f = _f, .final = _final, }} +#define _PLUGIN_FEATURE_REGISTER_CRYPTER(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_AEAD(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_SIGNER(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_HASHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_PRF(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_DH(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_RNG(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_PRIVKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) +#define _PLUGIN_FEATURE_REGISTER_PRIVKEY_GEN(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) +#define _PLUGIN_FEATURE_REGISTER_PUBKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) +#define _PLUGIN_FEATURE_REGISTER_CERT_DECODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) +#define _PLUGIN_FEATURE_REGISTER_CERT_ENCODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final) +#define _PLUGIN_FEATURE_REGISTER_DATABASE(type, f) __PLUGIN_FEATURE_REGISTER(type, f) +#define _PLUGIN_FEATURE_REGISTER_FETCHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f) + +#define _PLUGIN_FEATURE_CALLBACK(_cb, _data) (plugin_feature_t){ FEATURE_CALLBACK, FEATURE_NONE, .arg.cb = { .f = _cb, .data = _data } } + +/** + * Names for plugin_feature_t types. + */ +extern enum_name_t *plugin_feature_names; + +/** + * Check if feature a matches to feature b. + * + * @param a feature to check + * @param b feature to match against + * @return TRUE if a matches b + */ +bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b); + +/** + * Get a string describing feature. + * + * @param feature feature to describe + * @return allocated string describing feature + */ +char* plugin_feature_get_string(plugin_feature_t *feature); + +/** + * Load a plugin feature using a REGISTER/CALLBACK feature entry. + * + * @param plugin plugin providing feature + * @param feature feature to load + * @param reg REGISTER/CALLBACK feature entry to use for registration + */ +bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature, + plugin_feature_t *reg); + +/** + * Unload a plugin feature using a REGISTER/CALLBACK feature entry. + * + * @param plugin plugin providing feature + * @param feature feature to unload + * @param reg REGISTER/CALLBACK feature entry to use for deregistration + */ +bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature, + plugin_feature_t *reg); + +#endif /** PLUGIN_FEATURE_H_ @}*/ diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index b4d7bf7c7..f97cbb31f 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Tobias Brunner + * Copyright (C) 2010-2012 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -23,11 +23,13 @@ #include <stdio.h> #include <debug.h> +#include <library.h> #include <integrity_checker.h> #include <utils/linked_list.h> #include <plugins/plugin.h> typedef struct private_plugin_loader_t private_plugin_loader_t; +typedef struct plugin_entry_t plugin_entry_t; /** * private data of plugin_loader @@ -40,20 +42,67 @@ struct private_plugin_loader_t { plugin_loader_t public; /** - * list of loaded plugins + * List of plugins, as plugin_entry_t */ linked_list_t *plugins; + + /** + * List of names of loaded plugins + */ + char *loaded_plugins; +}; + +/** + * Entry for a plugin + */ +struct plugin_entry_t { + + /** + * Plugin instance + */ + plugin_t *plugin; + + /** + * dlopen handle, if in separate lib + */ + void *handle; + + /** + * List of loaded features + */ + linked_list_t *loaded; + + /** + * List features failed to load + */ + linked_list_t *failed; }; /** + * Destroy a plugin entry + */ +static void plugin_entry_destroy(plugin_entry_t *entry) +{ + DESTROY_IF(entry->plugin); + if (entry->handle) + { + dlclose(entry->handle); + } + entry->loaded->destroy(entry->loaded); + entry->failed->destroy(entry->failed); + free(entry); +} + +/** * create a plugin * returns: NOT_FOUND, if the constructor was not found * FAILED, if the plugin could not be constructed */ static status_t create_plugin(private_plugin_loader_t *this, void *handle, - char *name, bool integrity, plugin_t **plugin) + char *name, bool integrity, plugin_entry_t **entry) { char create[128]; + plugin_t *plugin; plugin_constructor_t constructor; if (snprintf(create, sizeof(create), "%s_plugin_create", @@ -77,13 +126,18 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, DBG1(DBG_LIB, "plugin '%s': passed file and segment integrity tests", name); } - *plugin = constructor(); - if (*plugin == NULL) + plugin = constructor(); + if (plugin == NULL) { DBG1(DBG_LIB, "plugin '%s': failed to load - %s returned NULL", name, create); return FAILED; } + INIT(*entry, + .plugin = plugin, + .loaded = linked_list_create(), + .failed = linked_list_create(), + ); DBG2(DBG_LIB, "plugin '%s': loaded successfully", name); return SUCCESS; } @@ -91,28 +145,21 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, /** * load a single plugin */ -static plugin_t* load_plugin(private_plugin_loader_t *this, - char *path, char *name) +static bool load_plugin(private_plugin_loader_t *this, char *name, char *file) { - char file[PATH_MAX]; + plugin_entry_t *entry; void *handle; - plugin_t *plugin; - switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, &plugin)) + switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, &entry)) { case SUCCESS: - return plugin; + this->plugins->insert_last(this->plugins, entry); + return TRUE; case NOT_FOUND: /* try to load the plugin from a file */ break; default: - return NULL; - } - - if (snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", path, - name) >= sizeof(file)) - { - return NULL; + return FALSE; } if (lib->integrity) { @@ -120,26 +167,80 @@ static plugin_t* load_plugin(private_plugin_loader_t *this, { DBG1(DBG_LIB, "plugin '%s': failed file integrity test of '%s'", name, file); - return NULL; + return FALSE; } } handle = dlopen(file, RTLD_LAZY); if (handle == NULL) { DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror()); - return NULL; + return FALSE; } - if (create_plugin(this, handle, name, TRUE, &plugin) != SUCCESS) + if (create_plugin(this, handle, name, TRUE, &entry) != SUCCESS) { dlclose(handle); - return NULL; + return FALSE; } - /* we do not store or free dlopen() handles, leak_detective requires - * the modules to keep loaded until leak report */ - return plugin; + entry->handle = handle; + this->plugins->insert_last(this->plugins, entry); + return TRUE; } /** + * Convert enumerated entries to plugin_t + */ +static bool plugin_filter(void *null, plugin_entry_t **entry, plugin_t **plugin, + void *in, linked_list_t **list) +{ + *plugin = (*entry)->plugin; + if (list) + { + *list = (*entry)->loaded; + } + return TRUE; +} + +METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*, + private_plugin_loader_t *this) +{ + return enumerator_create_filter( + this->plugins->create_enumerator(this->plugins), + (void*)plugin_filter, NULL, NULL); +} + +/** + * Create a list of the names of all loaded plugins + */ +static char* loaded_plugins_list(private_plugin_loader_t *this) +{ + int buf_len = 128, len = 0; + char *buf, *name; + enumerator_t *enumerator; + plugin_t *plugin; + + buf = malloc(buf_len); + buf[0] = '\0'; + enumerator = create_plugin_enumerator(this); + while (enumerator->enumerate(enumerator, &plugin, NULL)) + { + name = plugin->get_name(plugin); + if (len + (strlen(name) + 1) >= buf_len) + { + buf_len <<= 1; + buf = realloc(buf, buf_len); + } + len += snprintf(&buf[len], buf_len - len, "%s ", name); + } + enumerator->destroy(enumerator); + if (len > 0 && buf[len - 1] == ' ') + { + buf[len - 1] = '\0'; + } + return buf; +} + + +/** * Check if a plugin is already loaded */ static bool plugin_loaded(private_plugin_loader_t *this, char *name) @@ -148,8 +249,8 @@ static bool plugin_loaded(private_plugin_loader_t *this, char *name) bool found = FALSE; plugin_t *plugin; - enumerator = this->plugins->create_enumerator(this->plugins); - while (enumerator->enumerate(enumerator, &plugin)) + enumerator = create_plugin_enumerator(this); + while (enumerator->enumerate(enumerator, &plugin, NULL)) { if (streq(plugin->get_name(plugin), name)) { @@ -161,6 +262,235 @@ static bool plugin_loaded(private_plugin_loader_t *this, char *name) return found; } +/** + * Check if a feature of a plugin is already loaded + */ +static bool feature_loaded(private_plugin_loader_t *this, plugin_entry_t *entry, + plugin_feature_t *feature) +{ + return entry->loaded->find_first(entry->loaded, NULL, + (void**)&feature) == SUCCESS; +} + +/** + * Check if loading a feature of a plugin failed + */ +static bool feature_failed(private_plugin_loader_t *this, plugin_entry_t *entry, + plugin_feature_t *feature) +{ + return entry->failed->find_first(entry->failed, NULL, + (void**)&feature) == SUCCESS; +} + +/** + * Check if dependencies are satisfied + */ +static bool dependencies_satisfied(private_plugin_loader_t *this, + plugin_entry_t *entry, bool soft, bool report, + plugin_feature_t *features, int count) +{ + int i; + + /* first entry is provided feature, followed by dependencies */ + for (i = 1; i < count; i++) + { + enumerator_t *entries, *loaded; + plugin_feature_t *feature; + plugin_entry_t *current; + bool found = FALSE; + + if (features[i].kind != FEATURE_DEPENDS && + features[i].kind != FEATURE_SDEPEND) + { /* end of dependencies */ + break; + } + entries = this->plugins->create_enumerator(this->plugins); + while (entries->enumerate(entries, ¤t)) + { + loaded = current->loaded->create_enumerator(current->loaded); + while (loaded->enumerate(loaded, &feature)) + { + if (plugin_feature_matches(&features[i], feature)) + { + found = TRUE; + break; + } + } + loaded->destroy(loaded); + } + entries->destroy(entries); + + if (!found && (features[i].kind != FEATURE_SDEPEND || soft)) + { + if (report) + { + char *provide, *depend, *name; + + name = entry->plugin->get_name(entry->plugin); + provide = plugin_feature_get_string(&features[0]); + depend = plugin_feature_get_string(&features[i]); + DBG2(DBG_LIB, "feature %s in '%s' plugin has unsatisfied " + "dependency: %s", provide, name, depend); + free(provide); + free(depend); + } + return FALSE; + } + } + return TRUE; +} + +/** + * Check if a given feature is still required as dependency + */ +static bool dependency_required(private_plugin_loader_t *this, + plugin_feature_t *dep) +{ + enumerator_t *enumerator; + plugin_feature_t *features; + plugin_entry_t *entry; + int count, i; + + enumerator = this->plugins->create_enumerator(this->plugins); + while (enumerator->enumerate(enumerator, &entry)) + { + if (!entry->plugin->get_features) + { /* features not supported */ + continue; + } + count = entry->plugin->get_features(entry->plugin, &features); + for (i = 0; i < count; i++) + { + if (feature_loaded(this, entry, &features[i])) + { + while (++i < count && (features[i].kind == FEATURE_DEPENDS || + features[i].kind == FEATURE_SDEPEND)) + { + if (plugin_feature_matches(&features[i], dep)) + { + enumerator->destroy(enumerator); + return TRUE; + } + } + } + } + } + enumerator->destroy(enumerator); + return FALSE; +} + +/** + * Load plugin features in correct order + */ +static int load_features(private_plugin_loader_t *this, bool soft, bool report) +{ + enumerator_t *enumerator; + plugin_feature_t *feature, *reg; + plugin_entry_t *entry; + int count, i, loaded = 0; + + enumerator = this->plugins->create_enumerator(this->plugins); + while (enumerator->enumerate(enumerator, &entry)) + { + if (!entry->plugin->get_features) + { /* feature interface not supported */ + continue; + } + reg = NULL; + count = entry->plugin->get_features(entry->plugin, &feature); + for (i = 0; i < count; i++) + { + switch (feature->kind) + { + case FEATURE_PROVIDE: + if (!feature_loaded(this, entry, feature) && + !feature_failed(this, entry, feature) && + dependencies_satisfied(this, entry, soft, report, + feature, count - i)) + { + if (plugin_feature_load(entry->plugin, feature, reg)) + { + entry->loaded->insert_last(entry->loaded, feature); + loaded++; + } + else + { + entry->failed->insert_last(entry->failed, feature); + } + } + break; + case FEATURE_REGISTER: + case FEATURE_CALLBACK: + reg = feature; + break; + default: + break; + } + feature++; + } + } + enumerator->destroy(enumerator); + return loaded; +} + +/** + * Try to unload plugin features on which is not depended anymore + */ +static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry) +{ + plugin_feature_t *feature, *reg = NULL; + int count, i, unloaded = 0; + + count = entry->plugin->get_features(entry->plugin, &feature); + for (i = 0; i < count; i++) + { + switch (feature->kind) + { + case FEATURE_PROVIDE: + if (feature_loaded(this, entry, feature) && + !dependency_required(this, feature) && + plugin_feature_unload(entry->plugin, feature, reg)) + { + entry->loaded->remove(entry->loaded, feature, NULL); + unloaded++; + } + break; + case FEATURE_REGISTER: + case FEATURE_CALLBACK: + reg = feature; + break; + default: + break; + } + feature++; + } + return unloaded; +} + +/** + * Remove plugins that we were not able to load any features from. + */ +static void purge_plugins(private_plugin_loader_t *this) +{ + enumerator_t *enumerator; + plugin_entry_t *entry; + + enumerator = this->plugins->create_enumerator(this->plugins); + while (enumerator->enumerate(enumerator, &entry)) + { + if (!entry->plugin->get_features) + { /* feature interface not supported */ + continue; + } + if (!entry->loaded->get_count(entry->loaded)) + { + this->plugins->remove_at(this->plugins, enumerator); + plugin_entry_destroy(entry); + } + } + enumerator->destroy(enumerator); +} + METHOD(plugin_loader_t, load_plugins, bool, private_plugin_loader_t *this, char *path, char *list) { @@ -176,8 +506,8 @@ METHOD(plugin_loader_t, load_plugins, bool, enumerator = enumerator_create_token(list, " ", " "); while (!critical_failed && enumerator->enumerate(enumerator, &token)) { - plugin_t *plugin; bool critical = FALSE; + char file[PATH_MAX]; int len; token = strdup(token); @@ -192,42 +522,86 @@ METHOD(plugin_loader_t, load_plugins, bool, free(token); continue; } - plugin = load_plugin(this, path, token); - if (plugin) + if (snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", + path, token) >= sizeof(file)) { - this->plugins->insert_last(this->plugins, plugin); + return FALSE; } - else + if (!load_plugin(this, token, file) && critical) { - if (critical) - { - critical_failed = TRUE; - DBG1(DBG_LIB, "loading critical plugin '%s' failed", token); - } + critical_failed = TRUE; + DBG1(DBG_LIB, "loading critical plugin '%s' failed", token); } free(token); + /* TODO: we currently load features after each plugin is loaded. This + * will not be necessary once we have features support in all plugins. + */ + while (load_features(this, TRUE, FALSE)) + { + /* try load new features until we don't get new ones */ + } } enumerator->destroy(enumerator); + if (!critical_failed) + { + while (load_features(this, FALSE, FALSE)) + { + /* enforce loading features, ignoring soft dependencies */ + } + /* report missing dependencies */ + load_features(this, FALSE, TRUE); + /* unload plugins that we were not able to load any features for */ + purge_plugins(this); + } + if (!critical_failed) + { + free(this->loaded_plugins); + this->loaded_plugins = loaded_plugins_list(this); + } return !critical_failed; } METHOD(plugin_loader_t, unload, void, private_plugin_loader_t *this) { - plugin_t *plugin; + enumerator_t *enumerator; + plugin_entry_t *entry; + linked_list_t *list; - /* unload plugins in reverse order */ - while (this->plugins->remove_last(this->plugins, - (void**)&plugin) == SUCCESS) + /* unload plugins in reverse order, for those not supporting features */ + list = linked_list_create(); + while (this->plugins->remove_last(this->plugins, (void**)&entry) == SUCCESS) { - plugin->destroy(plugin); + list->insert_last(list, entry); } -} - -METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*, - private_plugin_loader_t *this) -{ - return this->plugins->create_enumerator(this->plugins); + while (list->remove_last(list, (void**)&entry) == SUCCESS) + { + this->plugins->insert_first(this->plugins, entry); + } + list->destroy(list); + while (this->plugins->get_count(this->plugins)) + { + enumerator = this->plugins->create_enumerator(this->plugins); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->plugin->get_features) + { /* supports features */ + while (unload_features(this, entry)); + } + if (entry->loaded->get_count(entry->loaded) == 0) + { + if (lib->leak_detective) + { /* keep handle to report leaks properly */ + entry->handle = NULL; + } + this->plugins->remove_at(this->plugins, enumerator); + plugin_entry_destroy(entry); + } + } + enumerator->destroy(enumerator); + } + free(this->loaded_plugins); + this->loaded_plugins = NULL; } /** @@ -240,11 +614,11 @@ static u_int reload_by_name(private_plugin_loader_t *this, char *name) plugin_t *plugin; enumerator = create_plugin_enumerator(this); - while (enumerator->enumerate(enumerator, &plugin)) + while (enumerator->enumerate(enumerator, &plugin, NULL)) { if (name == NULL || streq(name, plugin->get_name(plugin))) { - if (plugin->reload(plugin)) + if (plugin->reload && plugin->reload(plugin)) { DBG2(DBG_LIB, "reloaded configuration of '%s' plugin", plugin->get_name(plugin)); @@ -276,10 +650,18 @@ METHOD(plugin_loader_t, reload, u_int, return reloaded; } +METHOD(plugin_loader_t, loaded_plugins, char*, + private_plugin_loader_t *this) +{ + return this->loaded_plugins ?: ""; +} + METHOD(plugin_loader_t, destroy, void, private_plugin_loader_t *this) { - this->plugins->destroy_offset(this->plugins, offsetof(plugin_t, destroy)); + unload(this); + this->plugins->destroy(this->plugins); + free(this->loaded_plugins); free(this); } @@ -296,6 +678,7 @@ plugin_loader_t *plugin_loader_create() .reload = _reload, .unload = _unload, .create_plugin_enumerator = _create_plugin_enumerator, + .loaded_plugins = _loaded_plugins, .destroy = _destroy, }, .plugins = linked_list_create(), diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h index e03da4543..7fd07044d 100644 --- a/src/libstrongswan/plugins/plugin_loader.h +++ b/src/libstrongswan/plugins/plugin_loader.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -15,7 +16,7 @@ /** * @defgroup plugin_loader plugin_loader - * @{ @ingroup plugin + * @{ @ingroup plugins */ #ifndef PLUGIN_LOADER_H_ @@ -59,11 +60,24 @@ struct plugin_loader_t { /** * Create an enumerator over all loaded plugins. * - * @return enumerator over plugin_t* + * In addition to the plugin, the enumerator returns a list of pointers to + * plugin features currently loaded (if the argument is not NULL). + * This list is to be read only. + * + * @return enumerator over plugin_t*, linked_list_t* */ enumerator_t* (*create_plugin_enumerator)(plugin_loader_t *this); /** + * Get a simple list the names of all loaded plugins. + * + * The function returns internal data, do not free. + * + * @return list of the names of all loaded plugins + */ + char* (*loaded_plugins)(plugin_loader_t *this); + + /** * Unload loaded plugins, destroy plugin_loader instance. */ void (*destroy)(plugin_loader_t *this); diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in index 97fba22fc..0de048791 100644 --- a/src/libstrongswan/plugins/pubkey/Makefile.in +++ b/src/libstrongswan/plugins/pubkey/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c index c50189a8b..67240fe0c 100644 --- a/src/libstrongswan/plugins/pubkey/pubkey_cert.c +++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c @@ -15,6 +15,8 @@ #include "pubkey_cert.h" +#include <time.h> + #include <debug.h> typedef struct private_pubkey_cert_t private_pubkey_cert_t; @@ -45,40 +47,41 @@ struct private_pubkey_cert_t { identification_t *subject; /** + * key inception time + */ + time_t notBefore; + + /** + * key expiration time + */ + time_t notAfter; + + /** * reference count */ refcount_t ref; }; -/** - * Implementation of certificate_t.get_type - */ -static certificate_type_t get_type(private_pubkey_cert_t *this) +METHOD(certificate_t, get_type, certificate_type_t, + private_pubkey_cert_t *this) { return CERT_TRUSTED_PUBKEY; } -/** - * Implementation of certificate_t.get_subject - */ -static identification_t* get_subject(private_pubkey_cert_t *this) +METHOD(certificate_t, get_subject, identification_t*, + private_pubkey_cert_t *this) { return this->subject; } -/** - * Implementation of certificate_t.get_issuer - */ -static identification_t* get_issuer(private_pubkey_cert_t *this) +METHOD(certificate_t, get_issuer, identification_t*, + private_pubkey_cert_t *this) { return this->issuer; } -/** - * Implementation of certificate_t.has_subject. - */ -static id_match_t has_subject(private_pubkey_cert_t *this, - identification_t *subject) +METHOD(certificate_t, has_subject, id_match_t, + private_pubkey_cert_t *this, identification_t *subject) { if (subject->get_type(subject) == ID_KEY_ID) { @@ -94,22 +97,18 @@ static id_match_t has_subject(private_pubkey_cert_t *this, } } } - return ID_MATCH_NONE; + + return this->subject->matches(this->subject, subject); } -/** - * Implementation of certificate_t.has_subject. - */ -static id_match_t has_issuer(private_pubkey_cert_t *this, - identification_t *issuer) +METHOD(certificate_t, has_issuer, id_match_t, + private_pubkey_cert_t *this, identification_t *issuer) { return ID_MATCH_NONE; } -/** - * Implementation of certificate_t.equals. - */ -static bool equals(private_pubkey_cert_t *this, certificate_t *other) +METHOD(certificate_t, equals, bool, + private_pubkey_cert_t *this, certificate_t *other) { public_key_t *other_key; @@ -126,62 +125,52 @@ static bool equals(private_pubkey_cert_t *this, certificate_t *other) return FALSE; } -/** - * Implementation of certificate_t.issued_by - */ -static bool issued_by(private_pubkey_cert_t *this, certificate_t *issuer) +METHOD(certificate_t, issued_by, bool, + private_pubkey_cert_t *this, certificate_t *issuer) { return equals(this, issuer); } -/** - * Implementation of certificate_t.get_public_key - */ -static public_key_t* get_public_key(private_pubkey_cert_t *this) +METHOD(certificate_t, get_public_key, public_key_t*, + private_pubkey_cert_t *this) { this->key->get_ref(this->key); return this->key; } -/** - * Implementation of certificate_t.get_validity. - */ -static bool get_validity(private_pubkey_cert_t *this, time_t *when, - time_t *not_before, time_t *not_after) +METHOD(certificate_t, get_validity, bool, + private_pubkey_cert_t *this, time_t *when, time_t *not_before, + time_t *not_after) { + time_t t = when ? *when : time(NULL); + if (not_before) { - *not_before = 0; + *not_before = this->notBefore; } if (not_after) { - *not_after = ~0; + *not_after = this->notAfter; } - return TRUE; + return ((this->notBefore == UNDEFINED_TIME || t >= this->notBefore) && + (this->notAfter == UNDEFINED_TIME || t <= this->notAfter)); } -/** - * Implementation of certificate_t.get_encoding. - */ -static bool get_encoding(private_pubkey_cert_t *this, cred_encoding_type_t type, - chunk_t *encoding) +METHOD(certificate_t, get_encoding, bool, + private_pubkey_cert_t *this, cred_encoding_type_t type, chunk_t *encoding) { - return this->key->get_encoding(this->key, PUBKEY_ASN1_DER, encoding); + return this->key->get_encoding(this->key, type, encoding); } -/** - * Implementation of certificate_t.get_ref - */ -static private_pubkey_cert_t* get_ref(private_pubkey_cert_t *this) +METHOD(certificate_t, get_ref, certificate_t*, + private_pubkey_cert_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface; } -/** - * Implementation of pubkey_cert_t.destroy - */ -static void destroy(private_pubkey_cert_t *this) +METHOD(certificate_t, destroy, void, + private_pubkey_cert_t *this) { if (ref_put(&this->ref)) { @@ -195,28 +184,42 @@ static void destroy(private_pubkey_cert_t *this) /* * see header file */ -static pubkey_cert_t *pubkey_cert_create(public_key_t *key) +static pubkey_cert_t *pubkey_cert_create(public_key_t *key, + time_t notBefore, time_t notAfter, + identification_t *subject) { - private_pubkey_cert_t *this = malloc_thing(private_pubkey_cert_t); + private_pubkey_cert_t *this; chunk_t fingerprint; - this->public.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type; - this->public.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject; - this->public.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer; - this->public.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject; - this->public.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer; - this->public.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by; - this->public.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key; - this->public.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity; - this->public.interface.get_encoding = (bool (*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding; - this->public.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals; - this->public.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref; - this->public.interface.destroy = (void (*)(certificate_t *this))destroy; - - this->ref = 1; - this->key = key; - this->issuer = identification_create_from_encoding(ID_ANY, chunk_empty); - if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &fingerprint)) + INIT(this, + .public = { + .interface = { + .get_type = _get_type, + .get_subject = _get_subject, + .get_issuer = _get_issuer, + .has_subject = _has_subject, + .has_issuer = _has_issuer, + .issued_by = _issued_by, + .get_public_key = _get_public_key, + .get_validity = _get_validity, + .get_encoding = _get_encoding, + .equals = _equals, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .ref = 1, + .key = key, + .notBefore = notBefore, + .notAfter = notAfter, + .issuer = identification_create_from_encoding(ID_ANY, chunk_empty), + ); + + if (subject) + { + this->subject = subject->clone(subject); + } + else if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &fingerprint)) { this->subject = identification_create_from_encoding(ID_KEY_ID, fingerprint); } @@ -235,6 +238,8 @@ pubkey_cert_t *pubkey_cert_wrap(certificate_type_t type, va_list args) { public_key_t *key = NULL; chunk_t blob = chunk_empty; + identification_t *subject = NULL; + time_t notBefore = UNDEFINED_TIME, notAfter = UNDEFINED_TIME; while (TRUE) { @@ -246,6 +251,15 @@ pubkey_cert_t *pubkey_cert_wrap(certificate_type_t type, va_list args) case BUILD_PUBLIC_KEY: key = va_arg(args, public_key_t*); continue; + case BUILD_NOT_BEFORE_TIME: + notBefore = va_arg(args, time_t); + continue; + case BUILD_NOT_AFTER_TIME: + notAfter = va_arg(args, time_t); + continue; + case BUILD_SUBJECT: + subject = va_arg(args, identification_t*); + continue; case BUILD_END: break; default: @@ -264,7 +278,7 @@ pubkey_cert_t *pubkey_cert_wrap(certificate_type_t type, va_list args) } if (key) { - return pubkey_cert_create(key); + return pubkey_cert_create(key, notBefore, notAfter, subject); } return NULL; } diff --git a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c index ae6607e5a..92bfc2e63 100644 --- a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c +++ b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c @@ -37,11 +37,19 @@ METHOD(plugin_t, get_name, char*, return "pubkey"; } +METHOD(plugin_t, get_features, int, + private_pubkey_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(CERT_ENCODE, pubkey_cert_wrap, FALSE), + PLUGIN_PROVIDE(CERT_ENCODE, CERT_TRUSTED_PUBKEY), + }; + *features = f; + return countof(f); +} METHOD(plugin_t, destroy, void, private_pubkey_plugin_t *this) { - lib->creds->remove_builder(lib->creds, - (builder_function_t)pubkey_cert_wrap); free(this); } @@ -56,15 +64,12 @@ plugin_t *pubkey_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY, FALSE, - (builder_function_t)pubkey_cert_wrap); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in index 761d2c96e..9b549b071 100644 --- a/src/libstrongswan/plugins/random/Makefile.in +++ b/src/libstrongswan/plugins/random/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/random/random_plugin.c b/src/libstrongswan/plugins/random/random_plugin.c index 00202a5a6..7f81e2622 100644 --- a/src/libstrongswan/plugins/random/random_plugin.c +++ b/src/libstrongswan/plugins/random/random_plugin.c @@ -37,11 +37,21 @@ METHOD(plugin_t, get_name, char*, return "random"; } +METHOD(plugin_t, get_features, int, + private_random_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(RNG, random_rng_create), + PLUGIN_PROVIDE(RNG, RNG_STRONG), + PLUGIN_PROVIDE(RNG, RNG_TRUE), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_random_plugin_t *this) { - lib->crypto->remove_rng(lib->crypto, - (rng_constructor_t)random_rng_create); free(this); } @@ -56,17 +66,12 @@ plugin_t *random_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->crypto->add_rng(lib->crypto, RNG_STRONG, get_name(this), - (rng_constructor_t)random_rng_create); - lib->crypto->add_rng(lib->crypto, RNG_TRUE, get_name(this), - (rng_constructor_t)random_rng_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in index e8856b7d7..a78762c82 100644 --- a/src/libstrongswan/plugins/revocation/Makefile.in +++ b/src/libstrongswan/plugins/revocation/Makefile.in @@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -203,6 +206,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -219,11 +223,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/revocation/revocation_validator.c b/src/libstrongswan/plugins/revocation/revocation_validator.c index def169275..34f347d1a 100644 --- a/src/libstrongswan/plugins/revocation/revocation_validator.c +++ b/src/libstrongswan/plugins/revocation/revocation_validator.c @@ -404,7 +404,15 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best, { DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N", &revocation, TRUE, crl_reason_names, reason); - *valid = VALIDATION_REVOKED; + if (reason != CRL_REASON_CERTIFICATE_HOLD) + { + *valid = VALIDATION_REVOKED; + } + else + { + /* if the cert is on hold, a newer CRL might not contain it */ + *valid = VALIDATION_ON_HOLD; + } enumerator->destroy(enumerator); DESTROY_IF(best); return cand; @@ -681,6 +689,7 @@ METHOD(cert_validator_t, validate, bool, DBG1(DBG_CFG, "certificate status is good"); return TRUE; case VALIDATION_REVOKED: + case VALIDATION_ON_HOLD: /* has already been logged */ return FALSE; case VALIDATION_SKIPPED: @@ -700,6 +709,7 @@ METHOD(cert_validator_t, validate, bool, DBG1(DBG_CFG, "certificate status is good"); return TRUE; case VALIDATION_REVOKED: + case VALIDATION_ON_HOLD: /* has already been logged */ return FALSE; case VALIDATION_FAILED: diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in index b4b275648..f59c7516d 100644 --- a/src/libstrongswan/plugins/sha1/Makefile.in +++ b/src/libstrongswan/plugins/sha1/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.c b/src/libstrongswan/plugins/sha1/sha1_hasher.c index 85bc89f37..4d69ad5a4 100644 --- a/src/libstrongswan/plugins/sha1/sha1_hasher.c +++ b/src/libstrongswan/plugins/sha1/sha1_hasher.c @@ -175,10 +175,8 @@ static void SHA1Final(private_sha1_hasher_t *this, u_int8_t *digest) } } -/** - * Implementation of hasher_t.reset. - */ -static void reset(private_sha1_hasher_t *this) +METHOD(hasher_t, reset, void, + private_sha1_hasher_t *this) { this->state[0] = 0x67452301; this->state[1] = 0xEFCDAB89; @@ -189,10 +187,8 @@ static void reset(private_sha1_hasher_t *this) this->count[1] = 0; } -/** - * Implementation of hasher_t.get_hash. - */ -static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer) +METHOD(hasher_t, get_hash, void, + private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { SHA1Update(this, chunk.ptr, chunk.len); if (buffer != NULL) @@ -202,10 +198,8 @@ static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffe } } -/** - * Implementation of hasher_t.allocate_hash. - */ -static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash) +METHOD(hasher_t, allocate_hash, void, + private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash) { SHA1Update(this, chunk.ptr, chunk.len); if (hash != NULL) @@ -218,18 +212,14 @@ static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *h } } -/** - * Implementation of hasher_t.get_hash_size. - */ -static size_t get_hash_size(private_sha1_hasher_t *this) +METHOD(hasher_t, get_hash_size, size_t, + private_sha1_hasher_t *this) { return HASH_SIZE_SHA1; } -/** - * Implementation of hasher_t.destroy. - */ -static void destroy(private_sha1_hasher_t *this) +METHOD(hasher_t, destroy, void, + private_sha1_hasher_t *this) { free(this); } @@ -240,16 +230,23 @@ static void destroy(private_sha1_hasher_t *this) sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo) { private_sha1_hasher_t *this; + if (algo != HASH_SHA1) { return NULL; } - this = malloc_thing(private_sha1_hasher_t); - this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash; - this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash; - this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size; - this->public.hasher_interface.reset = (void (*) (hasher_t*))reset; - this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy; + + INIT(this, + .public = { + .hasher_interface = { + .get_hash = _get_hash, + .allocate_hash = _allocate_hash, + .get_hash_size = _get_hash_size, + .reset = _reset, + .destroy = _destroy, + }, + }, + ); /* initialize */ reset(this); diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.c b/src/libstrongswan/plugins/sha1/sha1_plugin.c index a9b84e790..66c80b292 100644 --- a/src/libstrongswan/plugins/sha1/sha1_plugin.c +++ b/src/libstrongswan/plugins/sha1/sha1_plugin.c @@ -38,13 +38,22 @@ METHOD(plugin_t, get_name, char*, return "sha1"; } +METHOD(plugin_t, get_features, int, + private_sha1_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(HASHER, sha1_hasher_create), + PLUGIN_PROVIDE(HASHER, HASH_SHA1), + PLUGIN_REGISTER(PRF, sha1_prf_create), + PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_sha1_plugin_t *this) { - lib->crypto->remove_hasher(lib->crypto, - (hasher_constructor_t)sha1_hasher_create); - lib->crypto->remove_prf(lib->crypto, - (prf_constructor_t)sha1_prf_create); free(this); } @@ -59,17 +68,12 @@ plugin_t *sha1_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this), - (hasher_constructor_t)sha1_hasher_create); - lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1, get_name(this), - (prf_constructor_t)sha1_prf_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/sha1/sha1_prf.c b/src/libstrongswan/plugins/sha1/sha1_prf.c index a68779d37..11f588c9d 100644 --- a/src/libstrongswan/plugins/sha1/sha1_prf.c +++ b/src/libstrongswan/plugins/sha1/sha1_prf.c @@ -59,10 +59,8 @@ struct private_sha1_prf_t { */ extern void SHA1Update(private_sha1_hasher_t* this, u_int8_t *data, u_int32_t len); -/** - * Implementation of prf_t.get_bytes. - */ -static void get_bytes(private_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes) +METHOD(prf_t, get_bytes, void, + private_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes) { u_int32_t *hash = (u_int32_t*)bytes; @@ -75,35 +73,27 @@ static void get_bytes(private_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes) hash[4] = htonl(this->hasher->state[4]); } -/** - * Implementation of prf_t.get_block_size. - */ -static size_t get_block_size(private_sha1_prf_t *this) +METHOD(prf_t, get_block_size, size_t, + private_sha1_prf_t *this) { return HASH_SIZE_SHA1; } -/** - * Implementation of prf_t.allocate_bytes. - */ -static void allocate_bytes(private_sha1_prf_t *this, chunk_t seed, chunk_t *chunk) +METHOD(prf_t, allocate_bytes, void, + private_sha1_prf_t *this, chunk_t seed, chunk_t *chunk) { *chunk = chunk_alloc(HASH_SIZE_SHA1); get_bytes(this, seed, chunk->ptr); } -/** - * Implementation of prf_t.get_key_size. - */ -static size_t get_key_size(private_sha1_prf_t *this) +METHOD(prf_t, get_key_size, size_t, + private_sha1_prf_t *this) { return sizeof(this->hasher->state); } -/** - * Implementation of prf_t.set_key. - */ -static void set_key(private_sha1_prf_t *this, chunk_t key) +METHOD(prf_t, set_key, void, + private_sha1_prf_t *this, chunk_t key) { int i, rounds; u_int32_t *iv = (u_int32_t*)key.ptr; @@ -116,10 +106,8 @@ static void set_key(private_sha1_prf_t *this, chunk_t key) } } -/** - * Implementation of prf_t.destroy. - */ -static void destroy(private_sha1_prf_t *this) +METHOD(prf_t, destroy, void, + private_sha1_prf_t *this) { this->hasher->public.hasher_interface.destroy(&this->hasher->public.hasher_interface); free(this); @@ -131,19 +119,25 @@ static void destroy(private_sha1_prf_t *this) sha1_prf_t *sha1_prf_create(pseudo_random_function_t algo) { private_sha1_prf_t *this; + if (algo != PRF_KEYED_SHA1) { return NULL; } - this = malloc_thing(private_sha1_prf_t); - this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes; - this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes; - this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size; - this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size; - this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key; - this->public.prf_interface.destroy = (void (*) (prf_t *))destroy; - - this->hasher = (private_sha1_hasher_t*)sha1_hasher_create(HASH_SHA1); + + INIT(this, + .public = { + .prf_interface = { + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .get_block_size = _get_block_size, + .get_key_size = _get_key_size, + .set_key = _set_key, + .destroy = _destroy, + }, + }, + .hasher = (private_sha1_hasher_t*)sha1_hasher_create(HASH_SHA1), + ); return &this->public; } diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in index bdc235555..c99f30e43 100644 --- a/src/libstrongswan/plugins/sha2/Makefile.in +++ b/src/libstrongswan/plugins/sha2/Makefile.in @@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -199,6 +202,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -215,11 +219,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/sha2/sha2_hasher.c b/src/libstrongswan/plugins/sha2/sha2_hasher.c index d407fad1b..60fe4bd20 100644 --- a/src/libstrongswan/plugins/sha2/sha2_hasher.c +++ b/src/libstrongswan/plugins/sha2/sha2_hasher.c @@ -426,71 +426,90 @@ static void sha512_final(private_sha512_hasher_t *ctx) } while(++j < 8); } -/** - * Implementation of hasher_t.get_hash for SHA224. - */ -static void get_hash224(private_sha256_hasher_t *this, - chunk_t chunk, u_int8_t *buffer) +METHOD(hasher_t, reset224, void, + private_sha256_hasher_t *this) +{ + memcpy(&this->sha_H[0], &sha224_hashInit[0], sizeof(this->sha_H)); + this->sha_blocks = 0; + this->sha_bufCnt = 0; +} + +METHOD(hasher_t, reset256, void, + private_sha256_hasher_t *this) +{ + memcpy(&this->sha_H[0], &sha256_hashInit[0], sizeof(this->sha_H)); + this->sha_blocks = 0; + this->sha_bufCnt = 0; +} + +METHOD(hasher_t, reset384, void, + private_sha512_hasher_t *this) +{ + memcpy(&this->sha_H[0], &sha384_hashInit[0], sizeof(this->sha_H)); + this->sha_blocks = 0; + this->sha_blocksMSB = 0; + this->sha_bufCnt = 0; +} + +METHOD(hasher_t, reset512, void, + private_sha512_hasher_t *this) +{ + memcpy(&this->sha_H[0], &sha512_hashInit[0], sizeof(this->sha_H)); + this->sha_blocks = 0; + this->sha_blocksMSB = 0; + this->sha_bufCnt = 0; +} + +METHOD(hasher_t, get_hash224, void, + private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { sha256_write(this, chunk.ptr, chunk.len); if (buffer != NULL) { sha256_final(this); memcpy(buffer, this->sha_out, HASH_SIZE_SHA224); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset224(this); } } -/** - * Implementation of hasher_t.get_hash for SHA256. - */ -static void get_hash256(private_sha256_hasher_t *this, - chunk_t chunk, u_int8_t *buffer) +METHOD(hasher_t, get_hash256, void, + private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { sha256_write(this, chunk.ptr, chunk.len); if (buffer != NULL) { sha256_final(this); memcpy(buffer, this->sha_out, HASH_SIZE_SHA256); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset256(this); } } -/** - * Implementation of hasher_t.get_hash for SHA384. - */ -static void get_hash384(private_sha512_hasher_t *this, - chunk_t chunk, u_int8_t *buffer) +METHOD(hasher_t, get_hash384, void, + private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { sha512_write(this, chunk.ptr, chunk.len); if (buffer != NULL) { sha512_final(this); memcpy(buffer, this->sha_out, HASH_SIZE_SHA384); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset384(this); } } -/** - * Implementation of hasher_t.get_hash for SHA512. - */ -static void get_hash512(private_sha512_hasher_t *this, - chunk_t chunk, u_int8_t *buffer) +METHOD(hasher_t, get_hash512, void, + private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer) { sha512_write(this, chunk.ptr, chunk.len); if (buffer != NULL) { sha512_final(this); memcpy(buffer, this->sha_out, HASH_SIZE_SHA512); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset512(this); } } -/** - * Implementation of hasher_t.allocate_hash for SHA224. - */ -static void allocate_hash224(private_sha256_hasher_t *this, - chunk_t chunk, chunk_t *hash) +METHOD(hasher_t, allocate_hash224, void, + private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -500,16 +519,13 @@ static void allocate_hash224(private_sha256_hasher_t *this, sha256_final(this); allocated_hash = chunk_alloc(HASH_SIZE_SHA224); memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA224); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset224(this); *hash = allocated_hash; } } -/** - * Implementation of hasher_t.allocate_hash for SHA256. - */ -static void allocate_hash256(private_sha256_hasher_t *this, - chunk_t chunk, chunk_t *hash) +METHOD(hasher_t, allocate_hash256, void, + private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -519,16 +535,13 @@ static void allocate_hash256(private_sha256_hasher_t *this, sha256_final(this); allocated_hash = chunk_alloc(HASH_SIZE_SHA256); memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset256(this); *hash = allocated_hash; } } -/** - * Implementation of hasher_t.allocate_hash for SHA384. - */ -static void allocate_hash384(private_sha512_hasher_t *this, - chunk_t chunk, chunk_t *hash) +METHOD(hasher_t, allocate_hash384, void, + private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -538,16 +551,13 @@ static void allocate_hash384(private_sha512_hasher_t *this, sha512_final(this); allocated_hash = chunk_alloc(HASH_SIZE_SHA384); memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset384(this); *hash = allocated_hash; } } -/** - * Implementation of hasher_t.allocate_hash for SHA512. - */ -static void allocate_hash512(private_sha512_hasher_t *this, - chunk_t chunk, chunk_t *hash) +METHOD(hasher_t, allocate_hash512, void, + private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash) { chunk_t allocated_hash; @@ -557,89 +567,37 @@ static void allocate_hash512(private_sha512_hasher_t *this, sha512_final(this); allocated_hash = chunk_alloc(HASH_SIZE_SHA512); memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512); - this->public.hasher_interface.reset(&(this->public.hasher_interface)); + reset512(this); *hash = allocated_hash; } } -/** - * Implementation of hasher_t.get_hash_size for SHA224. - */ -static size_t get_hash_size224(private_sha256_hasher_t *this) +METHOD(hasher_t, get_hash_size224, size_t, + private_sha256_hasher_t *this) { return HASH_SIZE_SHA224; } -/** - * Implementation of hasher_t.get_hash_size for SHA256. - */ -static size_t get_hash_size256(private_sha256_hasher_t *this) +METHOD(hasher_t, get_hash_size256, size_t, + private_sha256_hasher_t *this) { return HASH_SIZE_SHA256; } -/** - * Implementation of hasher_t.get_hash_size for SHA384. - */ -static size_t get_hash_size384(private_sha512_hasher_t *this) +METHOD(hasher_t, get_hash_size384, size_t, + private_sha512_hasher_t *this) { return HASH_SIZE_SHA384; } -/** - * Implementation of hasher_t.get_hash_size for SHA512. - */ -static size_t get_hash_size512(private_sha512_hasher_t *this) +METHOD(hasher_t, get_hash_size512, size_t, + private_sha512_hasher_t *this) { return HASH_SIZE_SHA512; } -/** - * Implementation of hasher_t.reset for SHA224 - */ -static void reset224(private_sha256_hasher_t *ctx) -{ - memcpy(&ctx->sha_H[0], &sha224_hashInit[0], sizeof(ctx->sha_H)); - ctx->sha_blocks = 0; - ctx->sha_bufCnt = 0; -} - -/** - * Implementation of hasher_t.reset for SHA256 - */ -static void reset256(private_sha256_hasher_t *ctx) -{ - memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H)); - ctx->sha_blocks = 0; - ctx->sha_bufCnt = 0; -} - -/** - * Implementation of hasher_t.reset for SHA384 - */ -static void reset384(private_sha512_hasher_t *ctx) -{ - memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H)); - ctx->sha_blocks = 0; - ctx->sha_blocksMSB = 0; - ctx->sha_bufCnt = 0; -} - -/** - * Implementation of hasher_t.reset for SHA512 - */ -static void reset512(private_sha512_hasher_t *ctx) -{ - memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H)); - ctx->sha_blocks = 0; - ctx->sha_blocksMSB = 0; - ctx->sha_bufCnt = 0; -} - -/** - * Implementation of hasher_t.destroy. - */ -static void destroy(sha2_hasher_t *this) +METHOD(hasher_t, destroy, void, + sha2_hasher_t *this) { free(this); } @@ -649,46 +607,81 @@ static void destroy(sha2_hasher_t *this) */ sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm) { - sha2_hasher_t *this; - switch (algorithm) { case HASH_SHA224: - this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t); - this->hasher_interface.reset = (void(*)(hasher_t*))reset224; - this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size224; - this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash224; - this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash224; - break; + { + private_sha256_hasher_t *this; + + INIT(this, + .public = { + .hasher_interface = { + .reset = _reset224, + .get_hash_size = _get_hash_size224, + .get_hash = _get_hash224, + .allocate_hash = _allocate_hash224, + .destroy = _destroy, + }, + }, + ); + reset224(this); + return &this->public; + } case HASH_SHA256: - this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t); - this->hasher_interface.reset = (void(*)(hasher_t*))reset256; - this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256; - this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256; - this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256; - break; + { + private_sha256_hasher_t *this; + + INIT(this, + .public = { + .hasher_interface = { + .reset = _reset256, + .get_hash_size = _get_hash_size256, + .get_hash = _get_hash256, + .allocate_hash = _allocate_hash256, + .destroy = _destroy, + }, + }, + ); + reset256(this); + return &this->public; + } case HASH_SHA384: - /* uses SHA512 data structure */ - this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t); - this->hasher_interface.reset = (void(*)(hasher_t*))reset384; - this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384; - this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384; - this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384; - break; + { + private_sha512_hasher_t *this; + + INIT(this, + .public = { + .hasher_interface = { + .reset = _reset384, + .get_hash_size = _get_hash_size384, + .get_hash = _get_hash384, + .allocate_hash = _allocate_hash384, + .destroy = _destroy, + }, + }, + ); + reset384(this); + return &this->public; + } case HASH_SHA512: - this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t); - this->hasher_interface.reset = (void(*)(hasher_t*))reset512; - this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512; - this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512; - this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512; - break; + { + private_sha512_hasher_t *this; + + INIT(this, + .public = { + .hasher_interface = { + .reset = _reset512, + .get_hash_size = _get_hash_size512, + .get_hash = _get_hash512, + .allocate_hash = _allocate_hash512, + .destroy = _destroy, + }, + }, + ); + reset512(this); + return &this->public; + } default: return NULL; } - this->hasher_interface.destroy = (void(*)(hasher_t*))destroy; - - /* initialize */ - this->hasher_interface.reset(&this->hasher_interface); - - return this; } diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.c b/src/libstrongswan/plugins/sha2/sha2_plugin.c index 4ec03a268..94a7ccd61 100644 --- a/src/libstrongswan/plugins/sha2/sha2_plugin.c +++ b/src/libstrongswan/plugins/sha2/sha2_plugin.c @@ -37,11 +37,23 @@ METHOD(plugin_t, get_name, char*, return "sha2"; } +METHOD(plugin_t, get_features, int, + private_sha2_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(HASHER, sha2_hasher_create), + PLUGIN_PROVIDE(HASHER, HASH_SHA224), + PLUGIN_PROVIDE(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(HASHER, HASH_SHA512), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_sha2_plugin_t *this) { - lib->crypto->remove_hasher(lib->crypto, - (hasher_constructor_t)sha2_hasher_create); free(this); } @@ -56,21 +68,12 @@ plugin_t *sha2_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->crypto->add_hasher(lib->crypto, HASH_SHA224, get_name(this), - (hasher_constructor_t)sha2_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA256, get_name(this), - (hasher_constructor_t)sha2_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA384, get_name(this), - (hasher_constructor_t)sha2_hasher_create); - lib->crypto->add_hasher(lib->crypto, HASH_SHA512, get_name(this), - (hasher_constructor_t)sha2_hasher_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in index ec370d38c..ce4b07769 100644 --- a/src/libstrongswan/plugins/soup/Makefile.in +++ b/src/libstrongswan/plugins/soup/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/soup/soup_plugin.c b/src/libstrongswan/plugins/soup/soup_plugin.c index 22c8762e0..b21b28b9f 100644 --- a/src/libstrongswan/plugins/soup/soup_plugin.c +++ b/src/libstrongswan/plugins/soup/soup_plugin.c @@ -40,11 +40,21 @@ METHOD(plugin_t, get_name, char*, return "soup"; } +METHOD(plugin_t, get_features, int, + private_soup_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(FETCHER, soup_fetcher_create), + PLUGIN_PROVIDE(FETCHER, "http://"), + PLUGIN_PROVIDE(FETCHER, "https://"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_soup_plugin_t *this) { - lib->fetcher->remove_fetcher(lib->fetcher, - (fetcher_constructor_t)soup_fetcher_create); free(this); } @@ -65,16 +75,11 @@ plugin_t *soup_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->fetcher->add_fetcher(lib->fetcher, - (fetcher_constructor_t)soup_fetcher_create, "http://"); - lib->fetcher->add_fetcher(lib->fetcher, - (fetcher_constructor_t)soup_fetcher_create, "https://"); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in index e2ec799a9..391827724 100644 --- a/src/libstrongswan/plugins/sqlite/Makefile.in +++ b/src/libstrongswan/plugins/sqlite/Makefile.in @@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -202,6 +205,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -218,11 +222,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c index d8c6a560c..f554a9e4f 100644 --- a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c +++ b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c @@ -37,11 +37,20 @@ METHOD(plugin_t, get_name, char*, return "sqlite"; } +METHOD(plugin_t, get_features, int, + private_sqlite_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(DATABASE, sqlite_database_create), + PLUGIN_PROVIDE(DATABASE, DB_SQLITE), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_sqlite_plugin_t *this) { - lib->db->remove_database(lib->db, - (database_constructor_t)sqlite_database_create); free(this); } @@ -56,15 +65,12 @@ plugin_t *sqlite_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->db->add_database(lib->db, - (database_constructor_t)sqlite_database_create); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.am b/src/libstrongswan/plugins/test_vectors/Makefile.am index 049301977..5280300a8 100644 --- a/src/libstrongswan/plugins/test_vectors/Makefile.am +++ b/src/libstrongswan/plugins/test_vectors/Makefile.am @@ -15,6 +15,7 @@ libstrongswan_test_vectors_la_SOURCES = \ test_vectors/aes_cbc.c \ test_vectors/aes_ctr.c \ test_vectors/aes_xcbc.c \ + test_vectors/aes_cmac.c \ test_vectors/aes_ccm.c \ test_vectors/aes_gcm.c \ test_vectors/blowfish.c \ diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in index 70cdfd600..7e0271b13 100644 --- a/src/libstrongswan/plugins/test_vectors/Makefile.in +++ b/src/libstrongswan/plugins/test_vectors/Makefile.in @@ -76,11 +76,12 @@ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_test_vectors_la_LIBADD = am_libstrongswan_test_vectors_la_OBJECTS = test_vectors_plugin.lo \ - 3des_cbc.lo aes_cbc.lo aes_ctr.lo aes_xcbc.lo aes_ccm.lo \ - aes_gcm.lo blowfish.lo camellia_cbc.lo camellia_ctr.lo \ - camellia_xcbc.lo cast.lo des.lo idea.lo null.lo rc5.lo \ - serpent_cbc.lo twofish_cbc.lo md2.lo md4.lo md5.lo md5_hmac.lo \ - sha1.lo sha1_hmac.lo sha2.lo sha2_hmac.lo fips_prf.lo rng.lo + 3des_cbc.lo aes_cbc.lo aes_ctr.lo aes_xcbc.lo aes_cmac.lo \ + aes_ccm.lo aes_gcm.lo blowfish.lo camellia_cbc.lo \ + camellia_ctr.lo camellia_xcbc.lo cast.lo des.lo idea.lo \ + null.lo rc5.lo serpent_cbc.lo twofish_cbc.lo md2.lo md4.lo \ + md5.lo md5_hmac.lo sha1.lo sha1_hmac.lo sha2.lo sha2_hmac.lo \ + fips_prf.lo rng.lo libstrongswan_test_vectors_la_OBJECTS = \ $(am_libstrongswan_test_vectors_la_OBJECTS) libstrongswan_test_vectors_la_LINK = $(LIBTOOL) --tag=CC \ @@ -199,6 +200,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -207,6 +211,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -223,11 +228,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -271,6 +278,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ @@ -291,6 +299,7 @@ libstrongswan_test_vectors_la_SOURCES = \ test_vectors/aes_cbc.c \ test_vectors/aes_ctr.c \ test_vectors/aes_xcbc.c \ + test_vectors/aes_cmac.c \ test_vectors/aes_ccm.c \ test_vectors/aes_gcm.c \ test_vectors/blowfish.c \ @@ -402,6 +411,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/3des_cbc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_cbc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_ccm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_cmac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_ctr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_gcm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_xcbc.Plo@am__quote@ @@ -477,6 +487,13 @@ aes_xcbc.lo: test_vectors/aes_xcbc.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_xcbc.lo `test -f 'test_vectors/aes_xcbc.c' || echo '$(srcdir)/'`test_vectors/aes_xcbc.c +aes_cmac.lo: test_vectors/aes_cmac.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_cmac.lo -MD -MP -MF $(DEPDIR)/aes_cmac.Tpo -c -o aes_cmac.lo `test -f 'test_vectors/aes_cmac.c' || echo '$(srcdir)/'`test_vectors/aes_cmac.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/aes_cmac.Tpo $(DEPDIR)/aes_cmac.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/aes_cmac.c' object='aes_cmac.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o aes_cmac.lo `test -f 'test_vectors/aes_cmac.c' || echo '$(srcdir)/'`test_vectors/aes_cmac.c + aes_ccm.lo: test_vectors/aes_ccm.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_ccm.lo -MD -MP -MF $(DEPDIR)/aes_ccm.Tpo -c -o aes_ccm.lo `test -f 'test_vectors/aes_ccm.c' || echo '$(srcdir)/'`test_vectors/aes_ccm.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/aes_ccm.Tpo $(DEPDIR)/aes_ccm.Plo diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors.h b/src/libstrongswan/plugins/test_vectors/test_vectors.h index ab4689c1c..40fb51da6 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors.h +++ b/src/libstrongswan/plugins/test_vectors/test_vectors.h @@ -91,6 +91,10 @@ TEST_VECTOR_SIGNER(aes_xcbc_s2) TEST_VECTOR_SIGNER(aes_xcbc_s3) TEST_VECTOR_SIGNER(aes_xcbc_s4) TEST_VECTOR_SIGNER(aes_xcbc_s5) +TEST_VECTOR_SIGNER(aes_cmac_s1) +TEST_VECTOR_SIGNER(aes_cmac_s2) +TEST_VECTOR_SIGNER(aes_cmac_s3) +TEST_VECTOR_SIGNER(aes_cmac_s4) TEST_VECTOR_SIGNER(camellia_xcbc_s1) TEST_VECTOR_SIGNER(md5_hmac_s1) TEST_VECTOR_SIGNER(md5_hmac_s2) @@ -156,6 +160,13 @@ TEST_VECTOR_PRF(aes_xcbc_p4) TEST_VECTOR_PRF(aes_xcbc_p5) TEST_VECTOR_PRF(aes_xcbc_p6) TEST_VECTOR_PRF(aes_xcbc_p7) +TEST_VECTOR_PRF(aes_cmac_p1) +TEST_VECTOR_PRF(aes_cmac_p2) +TEST_VECTOR_PRF(aes_cmac_p3) +TEST_VECTOR_PRF(aes_cmac_p4) +TEST_VECTOR_PRF(aes_cmac_p5) +TEST_VECTOR_PRF(aes_cmac_p6) +TEST_VECTOR_PRF(aes_cmac_p7) TEST_VECTOR_PRF(camellia_xcbc_p1) TEST_VECTOR_PRF(camellia_xcbc_p2) TEST_VECTOR_PRF(camellia_xcbc_p3) diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cmac.c b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cmac.c new file mode 100644 index 000000000..cc4121424 --- /dev/null +++ b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cmac.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2012 Tobias Brunner + * 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 + * Free Software Foundation; either version 2 of the Licenseor (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 usefulbut + * 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 <crypto/crypto_tester.h> + +/** + * RFC 4493 Example #1: AES-CMAC with 0-byte input + */ +prf_test_vector_t aes_cmac_p1 = { + .alg = PRF_AES128_CMAC, .key_size = 16, .len = 0, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .seed = "", + .out = "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46" +}; + +/** + * RFC 4493 Example #2: AES-CMAC with 16-byte input + */ +prf_test_vector_t aes_cmac_p2 = { + .alg = PRF_AES128_CMAC, .key_size = 16, .len = 16, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .seed = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + .out = "\x07\x0a\x16\xb4\x6b\x4d\x41\x44\xf7\x9b\xdd\x9d\xd0\x4a\x28\x7c" +}; + +/** + * RFC 4493 Example #3: AES-CMAC with 40-byte input + */ +prf_test_vector_t aes_cmac_p3 = { + .alg = PRF_AES128_CMAC, .key_size = 16, .len = 40, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .seed = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", + .out = "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27" +}; + +/** + * RFC 4493 Example #4: AES-CMAC with 64-byte input + */ +prf_test_vector_t aes_cmac_p4 = { + .alg = PRF_AES128_CMAC, .key_size = 16, .len = 64, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .seed = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" + "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + .out = "\x51\xf0\xbe\xbf\x7e\x3b\x9d\x92\xfc\x49\x74\x17\x79\x36\x3c\xfe" +}; + +/** + * RFC 4615 Test Case #1: AES-CMAC with 20-byte input, 18-byte key + */ +prf_test_vector_t aes_cmac_p5 = { + .alg = PRF_AES128_CMAC, .key_size = 18, .len = 20, + .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\xed\xcb", + .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13", + .out = "\x84\xa3\x48\xa4\xa4\x5d\x23\x5b\xab\xff\xfc\x0d\x2b\x4d\xa0\x9a" +}; + +/** + * RFC 4615 Test Case #2: AES-CMAC with 20-byte input, 16-byte key + */ +prf_test_vector_t aes_cmac_p6 = { + .alg = PRF_AES128_CMAC, .key_size = 16, .len = 20, + .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13", + .out = "\x98\x0a\xe8\x7b\x5f\x4c\x9c\x52\x14\xf5\xb6\xa8\x45\x5e\x4c\x2d" +}; + +/** + * RFC 4615 Test Case #3: AES-CMAC with 20-byte input, 10-byte key + */ +prf_test_vector_t aes_cmac_p7 = { + .alg = PRF_AES128_CMAC, .key_size = 10, .len = 20, + .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09", + .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13", + .out = "\x29\x0d\x9e\x11\x2e\xdb\x09\xee\x14\x1f\xcf\x64\xc0\xb7\x2f\x3d" +}; + +/** + * RFC 4494 Test Case #1: AES-CMAC-96 with 0-byte input + */ +signer_test_vector_t aes_cmac_s1 = { + .alg = AUTH_AES_CMAC_96, .len = 0, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .data = "", + .mac = "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12" +}; + + +/** + * RFC 4494 Test Case #2: AES-CMAC-96 with 16-byte input + */ +signer_test_vector_t aes_cmac_s2 = { + .alg = AUTH_AES_CMAC_96, .len = 16, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .data = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + .mac = "\x07\x0a\x16\xb4\x6b\x4d\x41\x44\xf7\x9b\xdd\x9d" +}; + +/** + * RFC 4494 Test Case #3: AES-CMAC-96 with 40-byte input + */ +signer_test_vector_t aes_cmac_s3 = { + .alg = AUTH_AES_CMAC_96, .len = 40, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .data = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", + .mac = "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61" +}; + +/** + * RFC 4494 Test Case #4: AES-CMAC-96 with 64-byte input + */ +signer_test_vector_t aes_cmac_s4 = { + .alg = AUTH_AES_CMAC_96, .len = 64, + .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + .data = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" + "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" + "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" + "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + .mac = "\x51\xf0\xbe\xbf\x7e\x3b\x9d\x92\xfc\x49\x74\x17" +}; diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in index 58cdf2c7c..8c05cb22d 100644 --- a/src/libstrongswan/plugins/x509/Makefile.in +++ b/src/libstrongswan/plugins/x509/Makefile.in @@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -201,6 +204,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -217,11 +221,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index ba0357cc4..a2cb589e0 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -179,11 +179,11 @@ static bool parse_directoryName(chunk_t blob, int level, bool implicit, identifi if (has_directoryName) { - iterator_t *iterator = list->create_iterator(list, TRUE); + enumerator_t *enumerator = list->create_enumerator(list); identification_t *directoryName; bool first = TRUE; - while (iterator->iterate(iterator, (void**)&directoryName)) + while (enumerator->enumerate(enumerator, (void**)&directoryName)) { if (first) { @@ -192,15 +192,15 @@ static bool parse_directoryName(chunk_t blob, int level, bool implicit, identifi } else { - DBG1(DBG_LIB, "more than one directory name - first selected"); + DBG1(DBG_ASN, "more than one directory name - first selected"); directoryName->destroy(directoryName); } } - iterator->destroy(iterator); + enumerator->destroy(enumerator); } else { - DBG1(DBG_LIB, "no directoryName found"); + DBG1(DBG_ASN, "no directoryName found"); } list->destroy(list); @@ -359,10 +359,10 @@ static bool parse_certificate(private_x509_ac_t *this) break; case AC_OBJ_VERSION: this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1; - DBG2(DBG_LIB, " v%d", this->version); + DBG2(DBG_ASN, " v%d", this->version); if (this->version != 2) { - DBG1(DBG_LIB, "v%d attribute certificates are not " + DBG1(DBG_ASN, "v%d attribute certificates are not " "supported", this->version); goto end; } @@ -408,20 +408,20 @@ static bool parse_certificate(private_x509_ac_t *this) switch (type) { case OID_AUTHENTICATION_INFO: - DBG2(DBG_LIB, " need to parse authenticationInfo"); + DBG2(DBG_ASN, " need to parse authenticationInfo"); break; case OID_ACCESS_IDENTITY: - DBG2(DBG_LIB, " need to parse accessIdentity"); + DBG2(DBG_ASN, " need to parse accessIdentity"); break; case OID_CHARGING_IDENTITY: - DBG2(DBG_LIB, "-- > --"); + DBG2(DBG_ASN, "-- > --"); this->charging = ietf_attributes_create_from_encoding(object); - DBG2(DBG_LIB, "-- < --"); + DBG2(DBG_ASN, "-- < --"); break; case OID_GROUP: - DBG2(DBG_LIB, "-- > --"); + DBG2(DBG_ASN, "-- > --"); this->groups = ietf_attributes_create_from_encoding(object); - DBG2(DBG_LIB, "-- < --"); + DBG2(DBG_ASN, "-- < --"); break; case OID_ROLE: parse_roleSyntax(object, level); @@ -436,21 +436,21 @@ static bool parse_certificate(private_x509_ac_t *this) break; case AC_OBJ_CRITICAL: critical = object.len && *object.ptr; - DBG2(DBG_LIB, " %s",(critical)?"TRUE":"FALSE"); + DBG2(DBG_ASN, " %s",(critical)?"TRUE":"FALSE"); break; case AC_OBJ_EXTN_VALUE: { switch (extn_oid) { case OID_CRL_DISTRIBUTION_POINTS: - DBG2(DBG_LIB, " need to parse crlDistributionPoints"); + DBG2(DBG_ASN, " need to parse crlDistributionPoints"); break; case OID_AUTHORITY_KEY_ID: this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object, level, &this->authKeySerialNumber); break; case OID_TARGET_INFORMATION: - DBG2(DBG_LIB, " need to parse targetInformation"); + DBG2(DBG_ASN, " need to parse targetInformation"); break; case OID_NO_REV_AVAIL: this->noRevAvail = TRUE; @@ -465,7 +465,7 @@ static bool parse_certificate(private_x509_ac_t *this) NULL); if (this->algorithm != sig_alg) { - DBG1(DBG_LIB, " signature algorithms do not agree"); + DBG1(DBG_ASN, " signature algorithms do not agree"); success = FALSE; goto end; } @@ -528,7 +528,7 @@ static chunk_t build_attr_cert_validity(private_x509_ac_t *this) { return asn1_wrap(ASN1_SEQUENCE, "mm", asn1_from_time(&this->notBefore, ASN1_GENERALIZEDTIME), - asn1_from_time(&this->notAfter, ASN1_GENERALIZEDTIME)); + asn1_from_time(&this->notAfter, ASN1_GENERALIZEDTIME)); } @@ -616,7 +616,6 @@ static chunk_t build_attr_cert_info(private_x509_ac_t *this) build_extensions(this)); } - /** * build an X.509 attribute certificate */ @@ -636,82 +635,62 @@ static chunk_t build_ac(private_x509_ac_t *this) asn1_bitstring("m", signatureValue)); } -/** - * Implementation of ac_t.get_serial. - */ -static chunk_t get_serial(private_x509_ac_t *this) +METHOD(ac_t, get_serial, chunk_t, + private_x509_ac_t *this) { return this->serialNumber; } -/** - * Implementation of ac_t.get_holderSerial. - */ -static chunk_t get_holderSerial(private_x509_ac_t *this) +METHOD(ac_t, get_holderSerial, chunk_t, + private_x509_ac_t *this) { return this->holderSerial; } -/** - * Implementation of ac_t.get_holderIssuer. - */ -static identification_t* get_holderIssuer(private_x509_ac_t *this) +METHOD(ac_t, get_holderIssuer, identification_t*, + private_x509_ac_t *this) { return this->holderIssuer; } -/** - * Implementation of ac_t.get_authKeyIdentifier. - */ -static chunk_t get_authKeyIdentifier(private_x509_ac_t *this) +METHOD(ac_t, get_authKeyIdentifier, chunk_t, + private_x509_ac_t *this) { return this->authKeyIdentifier; } -/** - * Implementation of certificate_t.get_groups. - */ -static ietf_attributes_t* get_groups(private_x509_ac_t *this) +METHOD(ac_t, get_groups, ietf_attributes_t*, + private_x509_ac_t *this) { return this->groups ? this->groups->get_ref(this->groups) : NULL; } -/** - * Implementation of certificate_t.get_type - */ -static certificate_type_t get_type(private_x509_ac_t *this) +METHOD(certificate_t, get_type, certificate_type_t, + private_x509_ac_t *this) { return CERT_X509_AC; } -/** - * Implementation of certificate_t.get_subject - */ -static identification_t* get_subject(private_x509_ac_t *this) +METHOD(certificate_t, get_subject, identification_t*, + private_x509_ac_t *this) { return this->entityName; } -/** - * Implementation of certificate_t.get_issuer - */ -static identification_t* get_issuer(private_x509_ac_t *this) +METHOD(certificate_t, get_issuer, identification_t*, + private_x509_ac_t *this) { return this->issuerName; } -/** - * Implementation of certificate_t.has_subject. - */ -static id_match_t has_subject(private_x509_ac_t *this, identification_t *subject) +METHOD(certificate_t, has_subject, id_match_t, + private_x509_ac_t *this, identification_t *subject) { return ID_MATCH_NONE; } -/** - * Implementation of certificate_t.has_issuer. - */ -static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer) +METHOD(certificate_t, has_issuer, id_match_t, + private_x509_ac_t *this, identification_t *issuer) { if (issuer->get_type(issuer) == ID_KEY_ID && this->authKeyIdentifier.ptr && chunk_equals(this->authKeyIdentifier, issuer->get_encoding(issuer))) @@ -721,10 +700,8 @@ static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer) return this->issuerName->matches(this->issuerName, issuer); } -/** - * Implementation of certificate_t.issued_by - */ -static bool issued_by(private_x509_ac_t *this, certificate_t *issuer) +METHOD(certificate_t, issued_by, bool, + private_x509_ac_t *this, certificate_t *issuer) { public_key_t *key; signature_scheme_t scheme; @@ -776,28 +753,21 @@ static bool issued_by(private_x509_ac_t *this, certificate_t *issuer) return valid; } -/** - * Implementation of certificate_t.get_public_key. - */ -static public_key_t* get_public_key(private_x509_ac_t *this) +METHOD(certificate_t, get_public_key, public_key_t*, + private_x509_ac_t *this) { return NULL; } -/** - * Implementation of certificate_t.get_ref. - */ -static private_x509_ac_t* get_ref(private_x509_ac_t *this) +METHOD(certificate_t, get_ref, certificate_t*, + private_x509_ac_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface.certificate; } -/** - * Implementation of certificate_t.get_validity. - */ -static bool get_validity(private_x509_ac_t *this, time_t *when, - time_t *not_before, time_t *not_after) +METHOD(certificate_t, get_validity, bool, + private_x509_ac_t *this, time_t *when, time_t *not_before, time_t *not_after) { time_t t = when ? *when : time(NULL); @@ -812,11 +782,8 @@ static bool get_validity(private_x509_ac_t *this, time_t *when, return (t >= this->notBefore && t <= this->notAfter); } -/** - * Implementation of certificate_t.get_encoding. - */ -static bool get_encoding(private_x509_ac_t *this, cred_encoding_type_t type, - chunk_t *encoding) +METHOD(certificate_t, get_encoding, bool, + private_x509_ac_t *this, cred_encoding_type_t type, chunk_t *encoding) { if (type == CERT_ASN1_DER) { @@ -827,10 +794,8 @@ static bool get_encoding(private_x509_ac_t *this, cred_encoding_type_t type, CRED_PART_X509_AC_ASN1_DER, this->encoding, CRED_PART_END); } -/** - * Implementation of certificate_t.equals. - */ -static bool equals(private_x509_ac_t *this, certificate_t *other) +METHOD(certificate_t, equals, bool, + private_x509_ac_t *this, certificate_t *other) { chunk_t encoding; bool equal; @@ -852,10 +817,8 @@ static bool equals(private_x509_ac_t *this, certificate_t *other) return equal; } -/** - * Implementation of x509_ac_t.destroy - */ -static void destroy(private_x509_ac_t *this) +METHOD(certificate_t, destroy, void, + private_x509_ac_t *this) { if (ref_put(&this->ref)) { @@ -879,41 +842,34 @@ static void destroy(private_x509_ac_t *this) */ static private_x509_ac_t *create_empty(void) { - private_x509_ac_t *this = malloc_thing(private_x509_ac_t); - - /* public functions */ - this->public.interface.get_serial = (chunk_t (*)(ac_t*))get_serial; - this->public.interface.get_holderSerial = (chunk_t (*)(ac_t*))get_holderSerial; - this->public.interface.get_holderIssuer = (identification_t* (*)(ac_t*))get_holderIssuer; - this->public.interface.get_authKeyIdentifier = (chunk_t (*)(ac_t*))get_authKeyIdentifier; - this->public.interface.get_groups = (ietf_attributes_t* (*)(ac_t*))get_groups; - this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type; - this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject; - this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer; - this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject; - this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer; - this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by; - this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key; - this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity; - this->public.interface.certificate.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding; - this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals; - this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref; - this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy; - - /* initialize */ - this->encoding = chunk_empty; - this->serialNumber = chunk_empty; - this->holderSerial = chunk_empty; - this->authKeyIdentifier = chunk_empty; - this->holderIssuer = NULL; - this->entityName = NULL; - this->issuerName = NULL; - this->holderCert = NULL; - this->signerCert = NULL; - this->signerKey = NULL; - this->charging = NULL; - this->groups = NULL; - this->ref = 1; + private_x509_ac_t *this; + + INIT(this, + .public = { + .interface = { + .certificate = { + .get_type = _get_type, + .get_subject = _get_subject, + .get_issuer = _get_issuer, + .has_subject = _has_subject, + .has_issuer = _has_issuer, + .issued_by = _issued_by, + .get_public_key = _get_public_key, + .get_validity = _get_validity, + .get_encoding = _get_encoding, + .equals = _equals, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_serial = _get_serial, + .get_holderSerial = _get_holderSerial, + .get_holderIssuer = _get_holderIssuer, + .get_authKeyIdentifier = _get_authKeyIdentifier, + .get_groups = _get_groups, + }, + }, + .ref = 1, + ); return this; } diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index 8b228a2b6..4859f4310 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -275,8 +275,8 @@ static const asn1Object_t basicConstraintsObjects[] = { { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */ { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */ - { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ - { 0, "exit", ASN1_EOC, ASN1_EXIT } + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } }; #define BASIC_CONSTRAINTS_CA 1 #define BASIC_CONSTRAINTS_PATH_LEN 2 @@ -301,7 +301,7 @@ static void parse_basicConstraints(chunk_t blob, int level0, { case BASIC_CONSTRAINTS_CA: isCA = object.len && *object.ptr; - DBG2(DBG_LIB, " %s", isCA ? "TRUE" : "FALSE"); + DBG2(DBG_ASN, " %s", isCA ? "TRUE" : "FALSE"); if (isCA) { this->flags |= X509_CA; @@ -394,7 +394,7 @@ static const asn1Object_t generalNameObjects[] = { { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */ { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */ - { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */ + { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */ { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */ { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */ @@ -482,7 +482,7 @@ static identification_t *parse_generalName(chunk_t blob, int level0) if (id_type != ID_ANY) { gn = identification_create_from_encoding(id_type, object); - DBG2(DBG_LIB, " '%Y'", gn); + DBG2(DBG_ASN, " '%Y'", gn); goto end; } } @@ -536,14 +536,14 @@ void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_lis * ASN.1 definition of a authorityKeyIdentifier extension */ static const asn1Object_t authKeyIdentifierObjects[] = { - { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */ - { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */ { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */ - { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */ + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */ { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */ - { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */ - { 0, "exit", ASN1_EOC, ASN1_EXIT } + { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } }; #define AUTH_KEY_ID_KEY_ID 1 #define AUTH_KEY_ID_CERT_ISSUER 3 @@ -638,7 +638,7 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0, /* parsing went wrong - abort */ goto end; } - DBG2(DBG_LIB, " '%Y'", id); + DBG2(DBG_ASN, " '%Y'", id); if (accessMethod == OID_OCSP && asprintf(&uri, "%Y", id) > 0) { @@ -1107,10 +1107,10 @@ static void parse_policyConstraints(chunk_t blob, int level0, static const asn1Object_t ipAddrBlocksObjects[] = { { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ { 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ - { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ + { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ { 2, "inherit", ASN1_NULL, ASN1_OPT|ASN1_NONE }, /* 3 */ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 4 */ - { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */ + { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */ { 3, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 6 */ { 3, "end choice", ASN1_EOC, ASN1_END }, /* 7 */ { 3, "addressRange", ASN1_SEQUENCE, ASN1_OPT|ASN1_NONE }, /* 8 */ @@ -1134,36 +1134,36 @@ static bool check_address_object(ts_type_t ts_type, chunk_t object) case TS_IPV4_ADDR_RANGE: if (object.len > 5) { - DBG1(DBG_LIB, "IPv4 address object is larger than 5 octets"); + DBG1(DBG_ASN, "IPv4 address object is larger than 5 octets"); return FALSE; } break; case TS_IPV6_ADDR_RANGE: if (object.len > 17) { - DBG1(DBG_LIB, "IPv6 address object is larger than 17 octets"); + DBG1(DBG_ASN, "IPv6 address object is larger than 17 octets"); return FALSE; } break; default: - DBG1(DBG_LIB, "unknown address family"); + DBG1(DBG_ASN, "unknown address family"); return FALSE; } if (object.len == 0) { - DBG1(DBG_LIB, "An ASN.1 bit string must contain at least the " + DBG1(DBG_ASN, "An ASN.1 bit string must contain at least the " "initial octet"); return FALSE; } if (object.len == 1 && object.ptr[0] != 0) { - DBG1(DBG_LIB, "An empty ASN.1 bit string must contain a zero " + DBG1(DBG_ASN, "An empty ASN.1 bit string must contain a zero " "initial octet"); return FALSE; } if (object.ptr[0] > 7) { - DBG1(DBG_LIB, "number of unused bits is too large"); + DBG1(DBG_ASN, "number of unused bits is too large"); return FALSE; } return TRUE; @@ -1201,11 +1201,11 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0, { break; } - DBG2(DBG_LIB, " %N", ts_type_name, ts_type); + DBG2(DBG_ASN, " %N", ts_type_name, ts_type); } break; case IP_ADDR_BLOCKS_INHERIT: - DBG1(DBG_LIB, "inherit choice is not supported"); + DBG1(DBG_ASN, "inherit choice is not supported"); break; case IP_ADDR_BLOCKS_PREFIX: if (!check_address_object(ts_type, object)) @@ -1214,7 +1214,7 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0, } ts = traffic_selector_create_from_rfc3779_format(ts_type, object, object); - DBG2(DBG_LIB, " %R", ts); + DBG2(DBG_ASN, " %R", ts); this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts); break; case IP_ADDR_BLOCKS_MIN: @@ -1231,7 +1231,7 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0, } ts = traffic_selector_create_from_rfc3779_format(ts_type, min_object, object); - DBG2(DBG_LIB, " %R", ts); + DBG2(DBG_ASN, " %R", ts); this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts); break; default: @@ -1280,7 +1280,7 @@ static const asn1Object_t certObjects[] = { #define X509_OBJ_VERSION 3 #define X509_OBJ_SERIAL_NUMBER 4 #define X509_OBJ_SIG_ALG 5 -#define X509_OBJ_ISSUER 6 +#define X509_OBJ_ISSUER 6 #define X509_OBJ_NOT_BEFORE 8 #define X509_OBJ_NOT_AFTER 9 #define X509_OBJ_SUBJECT 10 @@ -1320,12 +1320,12 @@ static bool parse_certificate(private_x509_cert_t *this) this->version = (object.len) ? (1+(u_int)*object.ptr) : 1; if (this->version < 1 || this->version > 3) { - DBG1(DBG_LIB, "X.509v%d not supported", this->version); + DBG1(DBG_ASN, "X.509v%d not supported", this->version); goto end; } else { - DBG2(DBG_LIB, " X.509v%d", this->version); + DBG2(DBG_ASN, " X.509v%d", this->version); } break; case X509_OBJ_SERIAL_NUMBER: @@ -1336,7 +1336,7 @@ static bool parse_certificate(private_x509_cert_t *this) break; case X509_OBJ_ISSUER: this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); - DBG2(DBG_LIB, " '%Y'", this->issuer); + DBG2(DBG_ASN, " '%Y'", this->issuer); break; case X509_OBJ_NOT_BEFORE: this->notBefore = asn1_parse_time(object, level); @@ -1346,13 +1346,13 @@ static bool parse_certificate(private_x509_cert_t *this) break; case X509_OBJ_SUBJECT: this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object); - DBG2(DBG_LIB, " '%Y'", this->subject); + DBG2(DBG_ASN, " '%Y'", this->subject); break; case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO: - DBG2(DBG_LIB, "-- > --"); + DBG2(DBG_ASN, "-- > --"); this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END); - DBG2(DBG_LIB, "-- < --"); + DBG2(DBG_ASN, "-- < --"); if (this->public_key == NULL) { goto end; @@ -1361,7 +1361,7 @@ static bool parse_certificate(private_x509_cert_t *this) case X509_OBJ_OPTIONAL_EXTENSIONS: if (this->version != 3) { - DBG1(DBG_LIB, "Only X.509v3 certificates have extensions"); + DBG1(DBG_ASN, "Only X.509v3 certificates have extensions"); goto end; } break; @@ -1370,7 +1370,7 @@ static bool parse_certificate(private_x509_cert_t *this) break; case X509_OBJ_CRITICAL: critical = object.len && *object.ptr; - DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE"); + DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE"); break; case X509_OBJ_EXTN_VALUE: { @@ -1445,7 +1445,7 @@ static bool parse_certificate(private_x509_cert_t *this) if (critical && lib->settings->get_bool(lib->settings, "libstrongswan.x509.enforce_critical", TRUE)) { - DBG1(DBG_LIB, "critical '%s' extension not supported", + DBG1(DBG_ASN, "critical '%s' extension not supported", (extn_oid == OID_UNKNOWN) ? "unknown" : (char*)oid_names[extn_oid].name); goto end; @@ -1458,7 +1458,7 @@ static bool parse_certificate(private_x509_cert_t *this) this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL); if (this->algorithm != sig_alg) { - DBG1(DBG_LIB, " signature algorithms do not agree"); + DBG1(DBG_ASN, " signature algorithms do not agree"); goto end; } break; @@ -1488,8 +1488,8 @@ end: hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); if (hasher == NULL) { - DBG1(DBG_LIB, " unable to create hash of certificate, SHA1 not supported"); - return NULL; + DBG1(DBG_ASN, " unable to create hash of certificate, SHA1 not supported"); + return FALSE; } hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash); hasher->destroy(hasher); @@ -1706,7 +1706,7 @@ METHOD(x509_t, get_subjectKeyIdentifier, chunk_t, chunk_t fingerprint; if (this->public_key->get_fingerprint(this->public_key, - KEYID_PUBKEY_SHA1, &fingerprint)) + KEYID_PUBKEY_SHA1, &fingerprint)) { return fingerprint; } @@ -1901,7 +1901,7 @@ chunk_t build_generalName(identification_t *id) context = ASN1_CONTEXT_S_7; break; default: - DBG1(DBG_LIB, "encoding %N as generalName not supported", + DBG1(DBG_ASN, "encoding %N as generalName not supported", id_type_names, id->get_type(id)); return chunk_empty; } diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c index 758505ab5..7bcca16a3 100644 --- a/src/libstrongswan/plugins/x509/x509_crl.c +++ b/src/libstrongswan/plugins/x509/x509_crl.c @@ -242,14 +242,14 @@ static bool parse(private_x509_crl_t *this) break; case CRL_OBJ_VERSION: this->version = (object.len) ? (1+(u_int)*object.ptr) : 1; - DBG2(DBG_LIB, " v%d", this->version); + DBG2(DBG_ASN, " v%d", this->version); break; case CRL_OBJ_SIG_ALG: sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL); break; case CRL_OBJ_ISSUER: this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object); - DBG2(DBG_LIB, " '%Y'", this->issuer); + DBG2(DBG_ASN, " '%Y'", this->issuer); break; case CRL_OBJ_THIS_UPDATE: this->thisUpdate = asn1_parse_time(object, level); @@ -274,7 +274,7 @@ static bool parse(private_x509_crl_t *this) case CRL_OBJ_CRL_ENTRY_CRITICAL: case CRL_OBJ_CRITICAL: critical = object.len && *object.ptr; - DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE"); + DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE"); break; case CRL_OBJ_CRL_ENTRY_EXTN_VALUE: case CRL_OBJ_EXTN_VALUE: @@ -291,7 +291,7 @@ static bool parse(private_x509_crl_t *this) { revoked->reason = *object.ptr; } - DBG2(DBG_LIB, " '%N'", crl_reason_names, + DBG2(DBG_ASN, " '%N'", crl_reason_names, revoked->reason); } break; @@ -324,7 +324,7 @@ static bool parse(private_x509_crl_t *this) if (critical && lib->settings->get_bool(lib->settings, "libstrongswan.x509.enforce_critical", TRUE)) { - DBG1(DBG_LIB, "critical '%s' extension not supported", + DBG1(DBG_ASN, "critical '%s' extension not supported", (extn_oid == OID_UNKNOWN) ? "unknown" : (char*)oid_names[extn_oid].name); goto end; @@ -338,7 +338,7 @@ static bool parse(private_x509_crl_t *this) this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL); if (this->algorithm != sig_alg) { - DBG1(DBG_LIB, " signature algorithms do not agree"); + DBG1(DBG_ASN, " signature algorithms do not agree"); goto end; } break; diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c index ea02cbab5..33d0aa792 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c @@ -304,18 +304,14 @@ static chunk_t build_OCSPRequest(private_x509_ocsp_request_t *this) } -/** - * Implementation of certificate_t.get_type - */ -static certificate_type_t get_type(private_x509_ocsp_request_t *this) +METHOD(certificate_t, get_type, certificate_type_t, + private_x509_ocsp_request_t *this) { return CERT_X509_OCSP_REQUEST; } -/** - * Implementation of certificate_t.get_subject - */ -static identification_t* get_subject(private_x509_ocsp_request_t *this) +METHOD(certificate_t, get_subject, identification_t*, + private_x509_ocsp_request_t *this) { certificate_t *ca = (certificate_t*)this->ca; @@ -330,21 +326,16 @@ static identification_t* get_subject(private_x509_ocsp_request_t *this) return ca->get_subject(ca); } -/** - * Implementation of certificate_t.get_issuer - */ -static identification_t* get_issuer(private_x509_ocsp_request_t *this) +METHOD(certificate_t, get_issuer, identification_t*, + private_x509_ocsp_request_t *this) { certificate_t *ca = (certificate_t*)this->ca; return ca->get_subject(ca); } -/** - * Implementation of certificate_t.has_subject. - */ -static id_match_t has_subject(private_x509_ocsp_request_t *this, - identification_t *subject) +METHOD(certificate_t, has_subject, id_match_t, + private_x509_ocsp_request_t *this, identification_t *subject) { certificate_t *current; enumerator_t *enumerator; @@ -363,10 +354,8 @@ static id_match_t has_subject(private_x509_ocsp_request_t *this, return best; } -/** - * Implementation of certificate_t.has_subject. - */ -static id_match_t has_issuer(private_x509_ocsp_request_t *this, +METHOD(certificate_t, has_issuer, id_match_t, + private_x509_ocsp_request_t *this, identification_t *issuer) { certificate_t *ca = (certificate_t*)this->ca; @@ -374,28 +363,22 @@ static id_match_t has_issuer(private_x509_ocsp_request_t *this, return ca->has_subject(ca, issuer); } -/** - * Implementation of certificate_t.issued_by - */ -static bool issued_by(private_x509_ocsp_request_t *this, certificate_t *issuer) +METHOD(certificate_t, issued_by, bool, + private_x509_ocsp_request_t *this, certificate_t *issuer) { DBG1(DBG_LIB, "OCSP request validation not implemented!"); return FALSE; } -/** - * Implementation of certificate_t.get_public_key - */ -static public_key_t* get_public_key(private_x509_ocsp_request_t *this) +METHOD(certificate_t, get_public_key, public_key_t*, + private_x509_ocsp_request_t *this) { return NULL; } -/** - * Implementation of x509_cert_t.get_validity. - */ -static bool get_validity(private_x509_ocsp_request_t *this, time_t *when, - time_t *not_before, time_t *not_after) +METHOD(certificate_t, get_validity, bool, + private_x509_ocsp_request_t *this, time_t *when, time_t *not_before, + time_t *not_after) { certificate_t *cert; @@ -410,11 +393,9 @@ static bool get_validity(private_x509_ocsp_request_t *this, time_t *when, return cert->get_validity(cert, when, not_before, not_after); } -/** - * Implementation of certificate_t.get_encoding. - */ -static bool get_encoding(private_x509_ocsp_request_t *this, - cred_encoding_type_t type, chunk_t *encoding) +METHOD(certificate_t, get_encoding, bool, + private_x509_ocsp_request_t *this, cred_encoding_type_t type, + chunk_t *encoding) { if (type == CERT_ASN1_DER) { @@ -425,10 +406,8 @@ static bool get_encoding(private_x509_ocsp_request_t *this, CRED_PART_X509_OCSP_REQ_ASN1_DER, this->encoding, CRED_PART_END); } -/** - * Implementation of certificate_t.equals. - */ -static bool equals(private_x509_ocsp_request_t *this, certificate_t *other) +METHOD(certificate_t, equals, bool, + private_x509_ocsp_request_t *this, certificate_t *other) { chunk_t encoding; bool equal; @@ -454,19 +433,15 @@ static bool equals(private_x509_ocsp_request_t *this, certificate_t *other) return equal; } -/** - * Implementation of certificate_t.asdf - */ -static private_x509_ocsp_request_t* get_ref(private_x509_ocsp_request_t *this) +METHOD(certificate_t, get_ref, certificate_t*, + private_x509_ocsp_request_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface.interface; } -/** - * Implementation of x509_ocsp_request_t.destroy - */ -static void destroy(private_x509_ocsp_request_t *this) +METHOD(certificate_t, destroy, void, + private_x509_ocsp_request_t *this) { if (ref_put(&this->ref)) { @@ -486,29 +461,30 @@ static void destroy(private_x509_ocsp_request_t *this) */ static private_x509_ocsp_request_t *create_empty() { - private_x509_ocsp_request_t *this = malloc_thing(private_x509_ocsp_request_t); - - this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type; - this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject; - this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer; - this->public.interface.interface.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject; - this->public.interface.interface.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer; - this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by; - this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key; - this->public.interface.interface.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity; - this->public.interface.interface.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding; - this->public.interface.interface.equals = (bool(*)(certificate_t*, certificate_t *other))equals; - this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref; - this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy; - - this->ca = NULL; - this->requestor = NULL; - this->cert = NULL; - this->key = NULL; - this->nonce = chunk_empty; - this->encoding = chunk_empty; - this->candidates = linked_list_create(); - this->ref = 1; + private_x509_ocsp_request_t *this; + + INIT(this, + .public = { + .interface = { + .interface = { + .get_type = _get_type, + .get_subject = _get_subject, + .get_issuer = _get_issuer, + .has_subject = _has_subject, + .has_issuer = _has_issuer, + .issued_by = _issued_by, + .get_public_key = _get_public_key, + .get_validity = _get_validity, + .get_encoding = _get_encoding, + .equals = _equals, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + }, + .candidates = linked_list_create(), + .ref = 1, + ); return this; } diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index 4cbe3f718..7dfef3993 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -148,14 +148,10 @@ static const chunk_t ASN1_response_content = chunk_from_chars( 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01 ); -/** - * Implementaiton of ocsp_response_t.get_status - */ -static cert_validation_t get_status(private_x509_ocsp_response_t *this, - x509_t *subject, x509_t *issuer, - time_t *revocation_time, - crl_reason_t *revocation_reason, - time_t *this_update, time_t *next_update) +METHOD(ocsp_response_t, get_status, cert_validation_t, + private_x509_ocsp_response_t *this, x509_t *subject, x509_t *issuer, + time_t *revocation_time, crl_reason_t *revocation_reason, + time_t *this_update, time_t *next_update) { enumerator_t *enumerator; single_response_t *response; @@ -236,10 +232,8 @@ static cert_validation_t get_status(private_x509_ocsp_response_t *this, return status; } -/** - * Implementation of ocsp_response_t.create_cert_enumerator. - */ -static enumerator_t* create_cert_enumerator(private_x509_ocsp_response_t *this) +METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*, + private_x509_ocsp_response_t *this) { return this->certs->create_enumerator(this->certs); } @@ -379,6 +373,10 @@ static bool parse_singleResponse(private_x509_ocsp_response_t *this, } this->responses->insert_last(this->responses, response); } + else + { + free(response); + } return success; } @@ -509,7 +507,7 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this, if (version != OCSP_BASIC_RESPONSE_VERSION) { - DBG1(DBG_LIB, " ocsp ResponseData version %d not " + DBG1(DBG_ASN, " ocsp ResponseData version %d not " "supported", version); goto end; } @@ -518,12 +516,12 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this, case BASIC_RESPONSE_ID_BY_NAME: this->responderId = identification_create_from_encoding( ID_DER_ASN1_DN, object); - DBG2(DBG_LIB, " '%Y'", this->responderId); + DBG2(DBG_ASN, " '%Y'", this->responderId); break; case BASIC_RESPONSE_ID_BY_KEY: this->responderId = identification_create_from_encoding( ID_KEY_ID, object); - DBG2(DBG_LIB, " '%Y'", this->responderId); + DBG2(DBG_ASN, " '%Y'", this->responderId); break; case BASIC_RESPONSE_PRODUCED_AT: this->producedAt = asn1_to_time(&object, ASN1_GENERALIZEDTIME); @@ -537,7 +535,7 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this, break; case BASIC_RESPONSE_CRITICAL: critical = object.len && *object.ptr; - DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE"); + DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE"); break; case BASIC_RESPONSE_EXT_VALUE: if (extn_oid == OID_NONCE) @@ -653,35 +651,26 @@ end: return success; } -/** - * Implementation of certificate_t.get_type - */ -static certificate_type_t get_type(private_x509_ocsp_response_t *this) +METHOD(certificate_t, get_type, certificate_type_t, + private_x509_ocsp_response_t *this) { return CERT_X509_OCSP_RESPONSE; } -/** - * Implementation of certificate_t.get_issuer - */ -static identification_t* get_issuer(private_x509_ocsp_response_t *this) +METHOD(certificate_t, get_issuer, identification_t*, + private_x509_ocsp_response_t *this) { return this->responderId; } -/** - * Implementation of certificate_t.has_subject. - */ -static id_match_t has_issuer(private_x509_ocsp_response_t *this, - identification_t *issuer) +METHOD(certificate_t, has_issuer, id_match_t, + private_x509_ocsp_response_t *this, identification_t *issuer) { return this->responderId->matches(this->responderId, issuer); } -/** - * Implementation of certificate_t.issued_by - */ -static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer) +METHOD(certificate_t, issued_by, bool, + private_x509_ocsp_response_t *this, certificate_t *issuer) { public_key_t *key; signature_scheme_t scheme; @@ -736,19 +725,15 @@ static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer) return valid; } -/** - * Implementation of certificate_t.get_public_key - */ -static public_key_t* get_public_key(private_x509_ocsp_response_t *this) +METHOD(certificate_t, get_public_key, public_key_t*, + private_x509_ocsp_response_t *this) { return NULL; } -/** - * Implementation of certificate_t.get_validity. - */ -static bool get_validity(private_x509_ocsp_response_t *this, time_t *when, - time_t *not_before, time_t *not_after) +METHOD(certificate_t, get_validity, bool, + private_x509_ocsp_response_t *this, time_t *when, + time_t *not_before, time_t *not_after) { time_t t = when ? *when : time(NULL); @@ -763,11 +748,9 @@ static bool get_validity(private_x509_ocsp_response_t *this, time_t *when, return (t < this->usableUntil); } -/** - * Implementation of certificate_t.get_encoding. - */ -static bool get_encoding(private_x509_ocsp_response_t *this, - cred_encoding_type_t type, chunk_t *encoding) +METHOD(certificate_t, get_encoding, bool, + private_x509_ocsp_response_t *this, cred_encoding_type_t type, + chunk_t *encoding) { if (type == CERT_ASN1_DER) { @@ -778,10 +761,8 @@ static bool get_encoding(private_x509_ocsp_response_t *this, CRED_PART_X509_OCSP_RES_ASN1_DER, this->encoding, CRED_PART_END); } -/** - * Implementation of certificate_t.equals. - */ -static bool equals(private_x509_ocsp_response_t *this, certificate_t *other) +METHOD(certificate_t, equals, bool, + private_x509_ocsp_response_t *this, certificate_t *other) { chunk_t encoding; bool equal; @@ -807,19 +788,15 @@ static bool equals(private_x509_ocsp_response_t *this, certificate_t *other) return equal; } -/** - * Implementation of certificate_t.get_ref - */ -static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this) +METHOD(certificate_t, get_ref, certificate_t*, + private_x509_ocsp_response_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface.certificate; } -/** - * Implements ocsp_t.destroy. - */ -static void destroy(private_x509_ocsp_response_t *this) +METHOD(certificate_t, destroy, void, + private_x509_ocsp_response_t *this) { if (ref_put(&this->ref)) { @@ -838,34 +815,35 @@ static x509_ocsp_response_t *load(chunk_t blob) { private_x509_ocsp_response_t *this; - this = malloc_thing(private_x509_ocsp_response_t); - - this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type; - this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer; - this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer; - this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer; - this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer; - this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by; - this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key; - this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity; - this->public.interface.certificate.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding; - this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals; - this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref; - this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy; - this->public.interface.get_status = (cert_validation_t(*)(ocsp_response_t*, x509_t *subject, x509_t *issuer, time_t *revocation_time,crl_reason_t *revocation_reason,time_t *this_update, time_t *next_update))get_status; - this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator; - - this->ref = 1; - this->encoding = chunk_clone(blob); - this->tbsResponseData = chunk_empty; - this->responderId = NULL; - this->producedAt = UNDEFINED_TIME; - this->usableUntil = UNDEFINED_TIME; - this->responses = linked_list_create(); - this->nonce = chunk_empty; - this->signatureAlgorithm = OID_UNKNOWN; - this->signature = chunk_empty; - this->certs = linked_list_create(); + INIT(this, + .public = { + .interface = { + .certificate = { + .get_type = _get_type, + .get_subject = _get_issuer, + .get_issuer = _get_issuer, + .has_subject = _has_issuer, + .has_issuer = _has_issuer, + .issued_by = _issued_by, + .get_public_key = _get_public_key, + .get_validity = _get_validity, + .get_encoding = _get_encoding, + .equals = _equals, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_status = _get_status, + .create_cert_enumerator = _create_cert_enumerator, + }, + }, + .ref = 1, + .encoding = chunk_clone(blob), + .producedAt = UNDEFINED_TIME, + .usableUntil = UNDEFINED_TIME, + .responses = linked_list_create(), + .signatureAlgorithm = OID_UNKNOWN, + .certs = linked_list_create(), + ); if (!parse_OCSPResponse(this)) { diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c index 7b488484e..ca08db2c6 100644 --- a/src/libstrongswan/plugins/x509/x509_pkcs10.c +++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c @@ -104,34 +104,26 @@ struct private_x509_pkcs10_t { extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list); extern chunk_t x509_build_subjectAltNames(linked_list_t *list); -/** - * Implementation of certificate_t.get_type. - */ -static certificate_type_t get_type(private_x509_pkcs10_t *this) +METHOD(certificate_t, get_type, certificate_type_t, + private_x509_pkcs10_t *this) { return CERT_PKCS10_REQUEST; } -/** - * Implementation of certificate_t.get_subject and get_issuer. - */ -static identification_t* get_subject(private_x509_pkcs10_t *this) +METHOD(certificate_t, get_subject, identification_t*, + private_x509_pkcs10_t *this) { return this->subject; } -/** - * Implementation of certificate_t.has_subject and has_issuer. - */ -static id_match_t has_subject(private_x509_pkcs10_t *this, identification_t *subject) +METHOD(certificate_t, has_subject, id_match_t, + private_x509_pkcs10_t *this, identification_t *subject) { return this->subject->matches(this->subject, subject); } -/** - * Implementation of certificate_t.issued_by. - */ -static bool issued_by(private_x509_pkcs10_t *this, certificate_t *issuer) +METHOD(certificate_t, issued_by, bool, + private_x509_pkcs10_t *this, certificate_t *issuer) { public_key_t *key; signature_scheme_t scheme; @@ -162,20 +154,16 @@ static bool issued_by(private_x509_pkcs10_t *this, certificate_t *issuer) this->signature); } -/** - * Implementation of certificate_t.get_public_key. - */ -static public_key_t* get_public_key(private_x509_pkcs10_t *this) +METHOD(certificate_t, get_public_key, public_key_t*, + private_x509_pkcs10_t *this) { this->public_key->get_ref(this->public_key); return this->public_key; } -/** - * Implementation of certificate_t.get_validity. - */ -static bool get_validity(private_x509_pkcs10_t *this, time_t *when, - time_t *not_before, time_t *not_after) +METHOD(certificate_t, get_validity, bool, + private_x509_pkcs10_t *this, time_t *when, time_t *not_before, + time_t *not_after) { if (not_before) { @@ -188,11 +176,8 @@ static bool get_validity(private_x509_pkcs10_t *this, time_t *when, return TRUE; } -/** - * Implementation of certificate_t.get_encoding. - */ -static bool get_encoding(private_x509_pkcs10_t *this, cred_encoding_type_t type, - chunk_t *encoding) +METHOD(certificate_t, get_encoding, bool, + private_x509_pkcs10_t *this, cred_encoding_type_t type, chunk_t *encoding) { if (type == CERT_ASN1_DER) { @@ -203,10 +188,8 @@ static bool get_encoding(private_x509_pkcs10_t *this, cred_encoding_type_t type, CRED_PART_PKCS10_ASN1_DER, this->encoding, CRED_PART_END); } -/** - * Implementation of certificate_t.equals. - */ -static bool equals(private_x509_pkcs10_t *this, certificate_t *other) +METHOD(certificate_t, equals, bool, + private_x509_pkcs10_t *this, certificate_t *other) { chunk_t encoding; bool equal; @@ -232,27 +215,21 @@ static bool equals(private_x509_pkcs10_t *this, certificate_t *other) return equal; } -/** - * Implementation of certificate_t.get_ref - */ -static private_x509_pkcs10_t* get_ref(private_x509_pkcs10_t *this) +METHOD(certificate_t, get_ref, certificate_t*, + private_x509_pkcs10_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface.interface; } -/** - * Implementation of certificate_t.get_challengePassword. - */ -static chunk_t get_challengePassword(private_x509_pkcs10_t *this) +METHOD(pkcs10_t, get_challengePassword, chunk_t, + private_x509_pkcs10_t *this) { return this->challengePassword; } -/** - * Implementation of pkcs10_t.create_subjectAltName_enumerator. - */ -static enumerator_t* create_subjectAltName_enumerator(private_x509_pkcs10_t *this) +METHOD(pkcs10_t, create_subjectAltName_enumerator, enumerator_t*, + private_x509_pkcs10_t *this) { return this->subjectAltNames->create_enumerator(this->subjectAltNames); } @@ -299,7 +276,7 @@ static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, i break; case PKCS10_EXTN_CRITICAL: critical = object.len && *object.ptr; - DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE"); + DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE"); break; case PKCS10_EXTN_VALUE: { @@ -332,25 +309,25 @@ static bool parse_challengePassword(private_x509_pkcs10_t *this, chunk_t blob, i if (blob.len < 2) { - DBG1(DBG_LIB, "L%d - challengePassword: ASN.1 object smaller " + DBG1(DBG_ASN, "L%d - challengePassword: ASN.1 object smaller " "than 2 octets", level); return FALSE; } tag = *blob.ptr; if (tag < ASN1_UTF8STRING || tag > ASN1_IA5STRING) { - DBG1(DBG_LIB, "L%d - challengePassword: ASN.1 object is not " + DBG1(DBG_ASN, "L%d - challengePassword: ASN.1 object is not " "a character string", level); return FALSE; } if (asn1_length(&blob) == ASN1_INVALID_LENGTH) { - DBG1(DBG_LIB, "L%d - challengePassword: ASN.1 object has an " + DBG1(DBG_ASN, "L%d - challengePassword: ASN.1 object has an " "invalid length", level); return FALSE; } - DBG2(DBG_LIB, "L%d - challengePassword:", level); - DBG4(DBG_LIB, " '%.*s'", blob.len, blob.ptr); + DBG2(DBG_ASN, "L%d - challengePassword:", level); + DBG4(DBG_ASN, " '%.*s'", blob.len, blob.ptr); return TRUE; } @@ -408,14 +385,14 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this) case PKCS10_VERSION: if (object.len > 0 && *object.ptr != 0) { - DBG1(DBG_LIB, "PKCS#10 certificate request format is " + DBG1(DBG_ASN, "PKCS#10 certificate request format is " "not version 1"); goto end; } break; case PKCS10_SUBJECT: this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object); - DBG2(DBG_LIB, " '%Y'", this->subject); + DBG2(DBG_ASN, " '%Y'", this->subject); break; case PKCS10_SUBJECT_PUBLIC_KEY_INFO: this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, @@ -477,10 +454,8 @@ end: return success; } -/** - * Implementation of certificate_t.destroy - */ -static void destroy(private_x509_pkcs10_t *this) +METHOD(certificate_t, destroy, void, + private_x509_pkcs10_t *this) { if (ref_put(&this->ref)) { @@ -504,33 +479,32 @@ static void destroy(private_x509_pkcs10_t *this) */ static private_x509_pkcs10_t* create_empty(void) { - private_x509_pkcs10_t *this = malloc_thing(private_x509_pkcs10_t); - - this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type; - this->public.interface.interface.get_subject = (identification_t* (*) (certificate_t*))get_subject; - this->public.interface.interface.get_issuer = (identification_t* (*) (certificate_t*))get_subject; - this->public.interface.interface.has_subject = (id_match_t (*) (certificate_t*, identification_t*))has_subject; - this->public.interface.interface.has_issuer = (id_match_t (*) (certificate_t*, identification_t*))has_subject; - this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by; - this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key; - this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity; - this->public.interface.interface.get_encoding = (bool (*) (certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding; - this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals; - this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref; - this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy; - this->public.interface.get_challengePassword = (chunk_t (*)(pkcs10_t*))get_challengePassword; - this->public.interface.create_subjectAltName_enumerator = (enumerator_t* (*)(pkcs10_t*))create_subjectAltName_enumerator; - - this->encoding = chunk_empty; - this->certificationRequestInfo = chunk_empty; - this->subject = NULL; - this->public_key = NULL; - this->subjectAltNames = linked_list_create(); - this->challengePassword = chunk_empty; - this->signature = chunk_empty; - this->ref = 1; - this->self_signed = FALSE; - this->parsed = FALSE; + private_x509_pkcs10_t *this; + + INIT(this, + .public = { + .interface = { + .interface = { + .get_type = _get_type, + .get_subject = _get_subject, + .get_issuer = _get_subject, + .has_subject = _has_subject, + .has_issuer = _has_subject, + .issued_by = _issued_by, + .get_public_key = _get_public_key, + .get_validity = _get_validity, + .get_encoding = _get_encoding, + .equals = _equals, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_challengePassword = _get_challengePassword, + .create_subjectAltName_enumerator = _create_subjectAltName_enumerator, + }, + }, + .subjectAltNames = linked_list_create(), + .ref = 1, + ); return this; } diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c index bfeb74b0e..ed6fbfd91 100644 --- a/src/libstrongswan/plugins/x509/x509_plugin.c +++ b/src/libstrongswan/plugins/x509/x509_plugin.c @@ -42,29 +42,46 @@ METHOD(plugin_t, get_name, char*, return "x509"; } +METHOD(plugin_t, get_features, int, + private_x509_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(CERT_ENCODE, x509_cert_gen, FALSE), + PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_REGISTER(CERT_DECODE, x509_cert_load, TRUE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + + PLUGIN_REGISTER(CERT_ENCODE, x509_ac_gen, FALSE), + PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509_AC), + PLUGIN_REGISTER(CERT_DECODE, x509_ac_load, TRUE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_AC), + + PLUGIN_REGISTER(CERT_ENCODE, x509_crl_gen, FALSE), + PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509_CRL), + PLUGIN_REGISTER(CERT_DECODE, x509_crl_load, TRUE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL), + + PLUGIN_REGISTER(CERT_ENCODE, x509_ocsp_request_gen, FALSE), + PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509_OCSP_REQUEST), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_DEPENDS(RNG, RNG_WEAK), + PLUGIN_REGISTER(CERT_DECODE, x509_ocsp_response_load, TRUE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_OCSP_RESPONSE), + + PLUGIN_REGISTER(CERT_ENCODE, x509_pkcs10_gen, FALSE), + PLUGIN_PROVIDE(CERT_ENCODE, CERT_PKCS10_REQUEST), + PLUGIN_REGISTER(CERT_DECODE, x509_pkcs10_load, TRUE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_PKCS10_REQUEST), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_x509_plugin_t *this) { - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_cert_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_cert_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_ac_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_ac_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_crl_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_crl_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_ocsp_request_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_ocsp_response_load); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_pkcs10_gen); - lib->creds->remove_builder(lib->creds, - (builder_function_t)x509_pkcs10_load); free(this); } @@ -79,33 +96,12 @@ plugin_t *x509_plugin_create() .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, FALSE, - (builder_function_t)x509_cert_gen); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, TRUE, - (builder_function_t)x509_cert_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC, FALSE, - (builder_function_t)x509_ac_gen); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC, TRUE, - (builder_function_t)x509_ac_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, TRUE, - (builder_function_t)x509_crl_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, FALSE, - (builder_function_t)x509_crl_gen); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST, FALSE, - (builder_function_t)x509_ocsp_request_gen); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE, TRUE, - (builder_function_t)x509_ocsp_response_load); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST, FALSE, - (builder_function_t)x509_pkcs10_gen); - lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST, TRUE, - (builder_function_t)x509_pkcs10_load); - return &this->public.plugin; } diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in index 35f868de4..ae23ce730 100644 --- a/src/libstrongswan/plugins/xcbc/Makefile.in +++ b/src/libstrongswan/plugins/xcbc/Makefile.in @@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +axis2c_CFLAGS = @axis2c_CFLAGS@ +axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -200,6 +203,7 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +clearsilver_LIBS = @clearsilver_LIBS@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ @@ -216,11 +220,13 @@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ +imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@ soup_CFLAGS = @soup_CFLAGS@ soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ +starter_plugins = @starter_plugins@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ diff --git a/src/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c index 8ddde962c..53629abe5 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc.c +++ b/src/libstrongswan/plugins/xcbc/xcbc.c @@ -3,13 +3,13 @@ * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General xcbc License as published by the + * 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 xcbc License + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ diff --git a/src/libstrongswan/plugins/xcbc/xcbc.h b/src/libstrongswan/plugins/xcbc/xcbc.h index f28e0b8e0..5d5eb04fb 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc.h +++ b/src/libstrongswan/plugins/xcbc/xcbc.h @@ -28,7 +28,7 @@ typedef struct xcbc_t xcbc_t; /** * Message authentication using CBC crypter. * - * This class implements the message authenticaion algorithm + * This class implements the message authentication algorithm * described in RFC3566. */ struct xcbc_t { diff --git a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c index 0fcb093c8..3c3b9d12a 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c +++ b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c @@ -38,13 +38,28 @@ METHOD(plugin_t, get_name, char*, return "xcbc"; } +METHOD(plugin_t, get_features, int, + private_xcbc_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(PRF, xcbc_prf_create), + PLUGIN_PROVIDE(PRF, PRF_AES128_XCBC), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + PLUGIN_PROVIDE(PRF, PRF_CAMELLIA128_XCBC), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16), + PLUGIN_REGISTER(SIGNER, xcbc_signer_create), + PLUGIN_PROVIDE(SIGNER, AUTH_CAMELLIA_XCBC_96), + PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16), + PLUGIN_PROVIDE(SIGNER, AUTH_AES_XCBC_96), + PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_xcbc_plugin_t *this) { - lib->crypto->remove_prf(lib->crypto, - (prf_constructor_t)xcbc_prf_create); - lib->crypto->remove_signer(lib->crypto, - (signer_constructor_t)xcbc_signer_create); free(this); } @@ -54,36 +69,17 @@ METHOD(plugin_t, destroy, void, plugin_t *xcbc_plugin_create() { private_xcbc_plugin_t *this; - crypter_t *crypter; INIT(this, .public = { .plugin = { .get_name = _get_name, - .reload = (void*)return_false, + .get_features = _get_features, .destroy = _destroy, }, }, ); - crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 16); - if (crypter) - { - crypter->destroy(crypter); - lib->crypto->add_prf(lib->crypto, PRF_AES128_XCBC, get_name(this), - (prf_constructor_t)xcbc_prf_create); - lib->crypto->add_signer(lib->crypto, AUTH_AES_XCBC_96, get_name(this), - (signer_constructor_t)xcbc_signer_create); - } - crypter = lib->crypto->create_crypter(lib->crypto, ENCR_CAMELLIA_CBC, 16); - if (crypter) - { - crypter->destroy(crypter); - lib->crypto->add_prf(lib->crypto, PRF_CAMELLIA128_XCBC, get_name(this), - (prf_constructor_t)xcbc_prf_create); - lib->crypto->add_signer(lib->crypto, AUTH_CAMELLIA_XCBC_96, get_name(this), - (signer_constructor_t)xcbc_signer_create); - } return &this->public.plugin; } |