aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-09-13 15:50:52 +0200
committerTobias Brunner <tobias@strongswan.org>2012-09-13 15:50:52 +0200
commit7d786057b4e62bb46fbc33fea6063abc9a13bc66 (patch)
tree3d35a16fc979238bf7aa6f8b31d08f221eb251dd /src
parentbc6ec4de7314885d2725bccc186a527bda37c2bc (diff)
parent08ad639f327d2e5445d7274b7705093704151f35 (diff)
downloadstrongswan-7d786057b4e62bb46fbc33fea6063abc9a13bc66.tar.bz2
strongswan-7d786057b4e62bb46fbc33fea6063abc9a13bc66.tar.xz
Merge branch 'custom-crypto'
This provides plugins with an interface to register keywords for proposals (e.g. when parsing the esp and ike options from ipsec.conf) and the possibility to register identifiers for kernel algorithms. It is based on patches contributed by Nanoteq Pty Ltd.
Diffstat (limited to 'src')
-rw-r--r--src/conftest/hooks/custom_proposal.c3
-rw-r--r--src/libcharon/config/proposal.c49
-rw-r--r--src/libhydra/kernel/kernel_interface.c125
-rw-r--r--src/libhydra/kernel/kernel_interface.h48
-rw-r--r--src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c24
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c35
-rw-r--r--src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c24
-rw-r--r--src/libstrongswan/.gitignore1
-rw-r--r--src/libstrongswan/Android.mk3
-rw-r--r--src/libstrongswan/Makefile.am18
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.c146
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.h109
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords_static.h25
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords_static.txt (renamed from src/libstrongswan/crypto/proposal/proposal_keywords.txt)8
-rw-r--r--src/libstrongswan/crypto/transform.c7
-rw-r--r--src/libstrongswan/crypto/transform.h3
-rw-r--r--src/libstrongswan/library.c2
-rw-r--r--src/libstrongswan/library.h6
-rw-r--r--src/libstrongswan/utils/enumerator.c12
-rw-r--r--src/libstrongswan/utils/enumerator.h5
-rw-r--r--src/scepclient/scepclient.c4
21 files changed, 573 insertions, 84 deletions
diff --git a/src/conftest/hooks/custom_proposal.c b/src/conftest/hooks/custom_proposal.c
index 958bc1052..38d4286c4 100644
--- a/src/conftest/hooks/custom_proposal.c
+++ b/src/conftest/hooks/custom_proposal.c
@@ -19,7 +19,6 @@
#include <encoding/payloads/sa_payload.h>
#include <config/proposal.h>
-#include <crypto/proposal/proposal_keywords.h>
typedef struct private_custom_proposal_t private_custom_proposal_t;
@@ -91,7 +90,7 @@ static linked_list_t* load_proposals(private_custom_proposal_t *this,
alg = strtoul(value, &end, 10);
if (end == value || errno)
{
- token = proposal_get_token(value, strlen(value));
+ token = lib->proposal->get_token(lib->proposal, value);
if (!token)
{
DBG1(DBG_CFG, "unknown algorithm: '%s', skipped", value);
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 6523fd351..43b467f46 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Tobias Brunner
+ * Copyright (C) 2008-2012 Tobias Brunner
* Copyright (C) 2006-2010 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -21,12 +21,11 @@
#include <daemon.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
-#include <utils/lexparser.h>
+
#include <crypto/transform.h>
#include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
-#include <crypto/proposal/proposal_keywords.h>
ENUM(protocol_id_names, PROTO_NONE, PROTO_IPCOMP,
"PROTO_NONE",
@@ -560,14 +559,15 @@ static void check_proposal(private_proposal_t *this)
/**
* add a algorithm identified by a string to the proposal.
*/
-static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
+static bool add_string_algo(private_proposal_t *this, const char *alg)
{
- const proposal_token_t *token = proposal_get_token(alg.ptr, alg.len);
+ const proposal_token_t *token;
+ token = lib->proposal->get_token(lib->proposal, alg);
if (token == NULL)
{
- DBG1(DBG_CFG, "algorithm '%.*s' not recognized", alg.len, alg.ptr);
- return FAILED;
+ DBG1(DBG_CFG, "algorithm '%s' not recognized", alg);
+ return FALSE;
}
add_algorithm(this, token->type, token->algorithm, token->keysize);
@@ -610,7 +610,7 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0);
}
}
- return SUCCESS;
+ return TRUE;
}
/**
@@ -901,28 +901,27 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
*/
proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs)
{
- private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0);
- chunk_t string = {(void*)algs, strlen(algs)};
- chunk_t alg;
- status_t status = SUCCESS;
+ private_proposal_t *this;
+ enumerator_t *enumerator;
+ bool failed = TRUE;
+ char *alg;
- eat_whitespace(&string);
- if (string.len < 1)
- {
- destroy(this);
- return NULL;
- }
+ this = (private_proposal_t*)proposal_create(protocol, 0);
/* get all tokens, separated by '-' */
- while (extract_token(&alg, '-', &string))
- {
- status |= add_string_algo(this, alg);
- }
- if (string.len)
+ enumerator = enumerator_create_token(algs, "-", " ");
+ while (enumerator->enumerate(enumerator, &alg))
{
- status |= add_string_algo(this, string);
+ if (!add_string_algo(this, alg))
+ {
+ failed = TRUE;
+ break;
+ }
+ failed = FALSE;
}
- if (status != SUCCESS)
+ enumerator->destroy(enumerator);
+
+ if (failed)
{
destroy(this);
return NULL;
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c
index 650cb1e9e..0ee5e1a55 100644
--- a/src/libhydra/kernel/kernel_interface.c
+++ b/src/libhydra/kernel/kernel_interface.c
@@ -15,6 +15,28 @@
* for more details.
*/
+/*
+ * Copyright (c) 2012 Nanoteq Pty Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
#include "kernel_interface.h"
#include <debug.h>
@@ -23,6 +45,34 @@
typedef struct private_kernel_interface_t private_kernel_interface_t;
+typedef struct kernel_algorithm_t kernel_algorithm_t;
+
+/**
+ * Mapping of IKE algorithms to kernel-specific algorithm identifiers
+ */
+struct kernel_algorithm_t {
+
+ /**
+ * Transform type of the algorithm
+ */
+ transform_type_t type;
+
+ /**
+ * Identifier specified in IKE
+ */
+ u_int16_t ike;
+
+ /**
+ * Identifier as defined in pfkeyv2.h
+ */
+ u_int16_t kernel;
+
+ /**
+ * Name of the algorithm in linux crypto API
+ */
+ char *name;
+};
+
/**
* Private data of a kernel_interface_t object.
*/
@@ -62,6 +112,16 @@ struct private_kernel_interface_t {
* list of registered listeners
*/
linked_list_t *listeners;
+
+ /**
+ * mutex for algorithm mappings
+ */
+ mutex_t *mutex_algs;
+
+ /**
+ * List of algorithm mappings (kernel_algorithm_t*)
+ */
+ linked_list_t *algorithms;
};
METHOD(kernel_interface_t, get_spi, status_t,
@@ -510,13 +570,72 @@ METHOD(kernel_interface_t, roam, void,
this->mutex->unlock(this->mutex);
}
+METHOD(kernel_interface_t, register_algorithm, void,
+ private_kernel_interface_t *this, u_int16_t alg_id, transform_type_t type,
+ u_int16_t kernel_id, char *kernel_name)
+{
+ kernel_algorithm_t *algorithm;
+
+ INIT(algorithm,
+ .type = type,
+ .ike = alg_id,
+ .kernel = kernel_id,
+ .name = strdup(kernel_name),
+ );
+
+ this->mutex_algs->lock(this->mutex_algs);
+ this->algorithms->insert_first(this->algorithms, algorithm);
+ this->mutex_algs->unlock(this->mutex_algs);
+}
+
+METHOD(kernel_interface_t, lookup_algorithm, bool,
+ private_kernel_interface_t *this, u_int16_t alg_id, transform_type_t type,
+ u_int16_t *kernel_id, char **kernel_name)
+{
+ kernel_algorithm_t *algorithm;
+ enumerator_t *enumerator;
+ bool found = FALSE;
+
+ this->mutex_algs->lock(this->mutex_algs);
+ enumerator = this->algorithms->create_enumerator(this->algorithms);
+ while (enumerator->enumerate(enumerator, &algorithm))
+ {
+ if (algorithm->type == type && algorithm->ike == alg_id)
+ {
+ if (kernel_id)
+ {
+ *kernel_id = algorithm->kernel;
+ }
+ if (kernel_name)
+ {
+ *kernel_name = algorithm->name;
+ }
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex_algs->unlock(this->mutex_algs);
+ return found;
+}
+
METHOD(kernel_interface_t, destroy, void,
private_kernel_interface_t *this)
{
+ kernel_algorithm_t *algorithm;
+
+ while (this->algorithms->remove_first(this->algorithms,
+ (void**)&algorithm) == SUCCESS)
+ {
+ free(algorithm->name);
+ free(algorithm);
+ }
+ this->algorithms->destroy(this->algorithms);
+ this->mutex_algs->destroy(this->mutex_algs);
DESTROY_IF(this->ipsec);
DESTROY_IF(this->net);
- this->mutex->destroy(this->mutex);
this->listeners->destroy(this->listeners);
+ this->mutex->destroy(this->mutex);
free(this);
}
@@ -559,6 +678,8 @@ kernel_interface_t *kernel_interface_create()
.add_listener = _add_listener,
.remove_listener = _remove_listener,
+ .register_algorithm = _register_algorithm,
+ .lookup_algorithm = _lookup_algorithm,
.acquire = _acquire,
.expire = _expire,
.mapping = _mapping,
@@ -568,6 +689,8 @@ kernel_interface_t *kernel_interface_create()
},
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.listeners = linked_list_create(),
+ .mutex_algs = mutex_create(MUTEX_TYPE_DEFAULT),
+ .algorithms = linked_list_create(),
);
return &this->public;
diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h
index 37b72f8bb..a17e8c6bb 100644
--- a/src/libhydra/kernel/kernel_interface.h
+++ b/src/libhydra/kernel/kernel_interface.h
@@ -16,6 +16,28 @@
* for more details.
*/
+/*
+ * Copyright (c) 2012 Nanoteq Pty Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
/**
* @defgroup kernel_interface kernel_interface
* @{ @ingroup hkernel
@@ -493,6 +515,32 @@ struct kernel_interface_t {
void (*roam)(kernel_interface_t *this, bool address);
/**
+ * Register a new algorithm with the kernel interface.
+ *
+ * @param alg_id the IKE id of the algorithm
+ * @param type the transform type of the algorithm
+ * @param kernel_id the kernel id of the algorithm
+ * @param kernel_name the kernel name of the algorithm
+ */
+ void (*register_algorithm)(kernel_interface_t *this, u_int16_t alg_id,
+ transform_type_t type, u_int16_t kernel_id,
+ char *kernel_name);
+
+ /**
+ * Return the kernel-specific id and/or name for an algorithms depending on
+ * the arguments specified.
+ *
+ * @param alg_id the IKE id of the algorithm
+ * @param type the transform type of the algorithm
+ * @param kernel_id the kernel id of the algorithm (optional)
+ * @param kernel_name the kernel name of the algorithm (optional)
+ * @return TRUE if algorithm was found
+ */
+ bool (*lookup_algorithm)(kernel_interface_t *this, u_int16_t alg_id,
+ transform_type_t type, u_int16_t *kernel_id,
+ char **kernel_name);
+
+ /**
* Destroys a kernel_interface_manager_t object.
*/
void (*destroy) (kernel_interface_t *this);
diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
index 5f077b234..fa7f6107c 100644
--- a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
+++ b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
@@ -820,8 +820,22 @@ static kernel_algorithm_t compression_algs[] = {
/**
* Look up a kernel algorithm ID and its key size
*/
-static int lookup_algorithm(kernel_algorithm_t *list, int ikev2)
+static int lookup_algorithm(transform_type_t type, int ikev2)
{
+ kernel_algorithm_t *list;
+ int alg = 0;
+
+ switch (type)
+ {
+ case ENCRYPTION_ALGORITHM:
+ list = encryption_algs;
+ break;
+ case INTEGRITY_ALGORITHM:
+ list = integrity_algs;
+ break;
+ default:
+ return 0;
+ }
while (list->ikev2 != END_OF_LIST)
{
if (ikev2 == list->ikev2)
@@ -830,7 +844,9 @@ static int lookup_algorithm(kernel_algorithm_t *list, int ikev2)
}
list++;
}
- return 0;
+ hydra->kernel_interface->lookup_algorithm(hydra->kernel_interface, ikev2,
+ type, &alg, NULL);
+ return alg;
}
/**
@@ -1713,8 +1729,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
sa->sadb_sa_spi = spi;
sa->sadb_sa_state = SADB_SASTATE_MATURE;
sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32;
- sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg);
- sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg);
+ sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg);
+ sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg);
PFKEY_EXT_ADD(msg, sa);
add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC);
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index ef0a08c42..ac9d9fe77 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -243,8 +243,25 @@ static kernel_algorithm_t compression_algs[] = {
/**
* Look up a kernel algorithm name and its key size
*/
-static char* lookup_algorithm(kernel_algorithm_t *list, int ikev2)
+static char* lookup_algorithm(transform_type_t type, int ikev2)
{
+ kernel_algorithm_t *list;
+ char *name = NULL;
+
+ switch (type)
+ {
+ case ENCRYPTION_ALGORITHM:
+ list = encryption_algs;
+ break;
+ case INTEGRITY_ALGORITHM:
+ list = integrity_algs;
+ break;
+ case COMPRESSION_ALGORITHM:
+ list = compression_algs;
+ break;
+ default:
+ return NULL;
+ }
while (list->ikev2 != END_OF_LIST)
{
if (list->ikev2 == ikev2)
@@ -253,7 +270,9 @@ static char* lookup_algorithm(kernel_algorithm_t *list, int ikev2)
}
list++;
}
- return NULL;
+ hydra->kernel_interface->lookup_algorithm(hydra->kernel_interface, ikev2,
+ type, NULL, &name);
+ return name;
}
typedef struct private_kernel_netlink_ipsec_t private_kernel_netlink_ipsec_t;
@@ -1222,12 +1241,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
{
struct xfrm_algo_aead *algo;
- alg_name = lookup_algorithm(encryption_algs, enc_alg);
+ alg_name = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg);
if (alg_name == NULL)
{
DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- encryption_algorithm_names, enc_alg);
- goto failed;
+ encryption_algorithm_names, enc_alg);
+ goto failed;
}
DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
encryption_algorithm_names, enc_alg, enc_key.len * 8);
@@ -1254,7 +1273,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
{
struct xfrm_algo *algo;
- alg_name = lookup_algorithm(encryption_algs, enc_alg);
+ alg_name = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg);
if (alg_name == NULL)
{
DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
@@ -1285,7 +1304,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
{
u_int trunc_len = 0;
- alg_name = lookup_algorithm(integrity_algs, int_alg);
+ alg_name = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg);
if (alg_name == NULL)
{
DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
@@ -1355,7 +1374,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (ipcomp != IPCOMP_NONE)
{
rthdr->rta_type = XFRMA_ALG_COMP;
- alg_name = lookup_algorithm(compression_algs, ipcomp);
+ alg_name = lookup_algorithm(COMPRESSION_ALGORITHM, ipcomp);
if (alg_name == NULL)
{
DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 13422670a..a562dddaa 100644
--- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -807,8 +807,22 @@ static kernel_algorithm_t compression_algs[] = {
/**
* Look up a kernel algorithm ID and its key size
*/
-static int lookup_algorithm(kernel_algorithm_t *list, int ikev2)
+static int lookup_algorithm(transform_type_t type, int ikev2)
{
+ kernel_algorithm_t *list;
+ int alg = 0;
+
+ switch (type)
+ {
+ case ENCRYPTION_ALGORITHM:
+ list = encryption_algs;
+ break;
+ case INTEGRITY_ALGORITHM:
+ list = integrity_algs;
+ break;
+ default:
+ return 0;
+ }
while (list->ikev2 != END_OF_LIST)
{
if (ikev2 == list->ikev2)
@@ -817,7 +831,9 @@ static int lookup_algorithm(kernel_algorithm_t *list, int ikev2)
}
list++;
}
- return 0;
+ hydra->kernel_interface->lookup_algorithm(hydra->kernel_interface, ikev2,
+ type, &alg, NULL);
+ return alg;
}
/**
@@ -1510,8 +1526,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
sa->sadb_sa_len = PFKEY_LEN(len);
sa->sadb_sa_spi = spi;
sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32;
- sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg);
- sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg);
+ sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg);
+ sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg);
PFKEY_EXT_ADD(msg, sa);
sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg);
diff --git a/src/libstrongswan/.gitignore b/src/libstrongswan/.gitignore
index 48a8d1d38..46b69ab15 100644
--- a/src/libstrongswan/.gitignore
+++ b/src/libstrongswan/.gitignore
@@ -1 +1,2 @@
oid.[ch]
+proposal_keywords_static.c
diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk
index 9125079a4..4912576df 100644
--- a/src/libstrongswan/Android.mk
+++ b/src/libstrongswan/Android.mk
@@ -6,7 +6,8 @@ LOCAL_SRC_FILES := \
library.c chunk.c debug.c enum.c settings.c printf_hook.c asn1/asn1.c \
asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \
crypto/crypters/crypter.c crypto/hashers/hasher.c crypto/pkcs7.c crypto/pkcs9.c \
-crypto/proposal/proposal_keywords.c crypto/prfs/prf.c crypto/prfs/mac_prf.c \
+crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \
+crypto/prfs/prf.c crypto/prfs/mac_prf.c \
crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \
crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index a38a17c38..699fff85e 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -4,7 +4,8 @@ libstrongswan_la_SOURCES = \
library.c chunk.c debug.c enum.c settings.c printf_hook.c asn1/asn1.c \
asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \
crypto/crypters/crypter.c crypto/hashers/hasher.c crypto/pkcs7.c crypto/pkcs9.c \
-crypto/proposal/proposal_keywords.c crypto/prfs/prf.c crypto/prfs/mac_prf.c \
+crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \
+crypto/prfs/prf.c crypto/prfs/mac_prf.c \
crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \
crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
@@ -34,6 +35,7 @@ library.h chunk.h debug.h enum.h settings.h printf_hook.h \
asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \
crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \
crypto/pkcs7.h crypto/pkcs9.h crypto/proposal/proposal_keywords.h \
+crypto/proposal/proposal_keywords_static.h \
crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \
crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \
crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \
@@ -101,16 +103,16 @@ endif
EXTRA_DIST = \
asn1/oid.txt asn1/oid.pl \
-crypto/proposal/proposal_keywords.txt \
+crypto/proposal/proposal_keywords_static.txt \
Android.mk AndroidConfigLocal.h
BUILT_SOURCES = \
$(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \
-$(srcdir)/crypto/proposal/proposal_keywords.c
+$(srcdir)/crypto/proposal/proposal_keywords_static.c
MAINTAINERCLEANFILES = \
$(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \
-$(srcdir)/crypto/proposal/proposal_keywords.c
+$(srcdir)/crypto/proposal/proposal_keywords_static.c
$(srcdir)/asn1/oid.c : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt
(cd $(srcdir)/asn1/ && $(PERL) oid.pl)
@@ -118,10 +120,10 @@ $(srcdir)/asn1/oid.c : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt
$(srcdir)/asn1/oid.h : $(srcdir)/asn1/oid.pl $(srcdir)/asn1/oid.txt
(cd $(srcdir)/asn1/ && $(PERL) oid.pl)
-$(srcdir)/crypto/proposal/proposal_keywords.c: $(srcdir)/crypto/proposal/proposal_keywords.txt \
- $(srcdir)/crypto/proposal/proposal_keywords.h
- $(GPERF) -N proposal_get_token -m 10 -C -G -c -t -D < \
- $(srcdir)/crypto/proposal/proposal_keywords.txt > $@
+$(srcdir)/crypto/proposal/proposal_keywords_static.c: $(srcdir)/crypto/proposal/proposal_keywords_static.txt \
+ $(srcdir)/crypto/proposal/proposal_keywords_static.h
+ $(GPERF) -N proposal_get_token_static -m 10 -C -G -c -t -D < \
+ $(srcdir)/crypto/proposal/proposal_keywords_static.txt > $@
# build plugins with their own Makefile
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.c b/src/libstrongswan/crypto/proposal/proposal_keywords.c
new file mode 100644
index 000000000..7356dc367
--- /dev/null
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.c
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2012 Nanoteq Pty Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "proposal_keywords.h"
+#include "proposal_keywords_static.h"
+
+#include <utils/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_proposal_keywords_t private_proposal_keywords_t;
+
+struct private_proposal_keywords_t {
+
+ /**
+ * public interface
+ */
+ proposal_keywords_t public;
+
+ /**
+ * registered tokens, as proposal_token_t
+ */
+ linked_list_t * tokens;
+
+ /**
+ * rwlock to lock access to modules
+ */
+ rwlock_t *lock;
+};
+
+/**
+ * Find the token object for the algorithm specified.
+ */
+static const proposal_token_t* find_token(private_proposal_keywords_t *this,
+ const char *str)
+{
+ proposal_token_t *token, *found = NULL;
+ enumerator_t *enumerator;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->tokens->create_enumerator(this->tokens);
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ if (streq(token->name, str))
+ {
+ found = token;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+ return found;
+}
+
+METHOD(proposal_keywords_t, get_token, const proposal_token_t*,
+ private_proposal_keywords_t *this, const char *str)
+{
+ const proposal_token_t *token = proposal_get_token_static(str, strlen(str));
+ return token ?: find_token(this, str);
+}
+
+METHOD(proposal_keywords_t, register_token, void,
+ private_proposal_keywords_t *this, const char *name, transform_type_t type,
+ u_int16_t algorithm, u_int16_t keysize)
+{
+ proposal_token_t *token;
+
+ INIT(token,
+ .name = strdup(name),
+ .type = type,
+ .algorithm = algorithm,
+ .keysize = keysize,
+ );
+
+ this->lock->write_lock(this->lock);
+ this->tokens->insert_first(this->tokens, token);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(proposal_keywords_t, destroy, void,
+ private_proposal_keywords_t *this)
+{
+ proposal_token_t *token;
+
+ while (this->tokens->remove_first(this->tokens, (void**)&token) == SUCCESS)
+ {
+ free(token->name);
+ free(token);
+ }
+ this->tokens->destroy(this->tokens);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+proposal_keywords_t *proposal_keywords_create()
+{
+ private_proposal_keywords_t *this;
+
+ INIT(this,
+ .public = {
+ .get_token = _get_token,
+ .register_token = _register_token,
+ .destroy = _destroy,
+ },
+ .tokens = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.h b/src/libstrongswan/crypto/proposal/proposal_keywords.h
index 53fa1728f..05f8958e0 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords.h
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.h
@@ -1,6 +1,6 @@
-/* proposal keywords
- * Copyright (C) 2009 Andreas Steffen
- * Hochschule fuer Technik Rapperswil, Switzerland
+/*
+ * 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
@@ -13,22 +13,103 @@
* for more details.
*/
-#ifndef _PROPOSAL_KEYWORDS_H_
-#define _PROPOSAL_KEYWORDS_H_
+/*
+ * Copyright (c) 2012 Nanoteq Pty Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/**
+ * @defgroup proposal_keywords proposal_keywords
+ * @{ @ingroup crypto
+ */
+
+#ifndef PROPOSAL_KEYWORDS_H_
+#define PROPOSAL_KEYWORDS_H_
+
+typedef struct proposal_token_t proposal_token_t;
+typedef struct proposal_keywords_t proposal_keywords_t;
+
+#include <library.h>
#include <crypto/transform.h>
-typedef struct proposal_token proposal_token_t;
+/**
+ * Class representing a proposal token..
+ */
+struct proposal_token_t {
+
+ /**
+ * The name of the token.
+ */
+ char *name;
+
+ /**
+ * The type of transform in the token.
+ */
+ transform_type_t type;
+
+ /**
+ * The IKE id of the algorithm.
+ */
+ u_int16_t algorithm;
-struct proposal_token {
- char *name;
- transform_type_t type;
- u_int16_t algorithm;
- u_int16_t keysize;
+ /**
+ * The key size associated with the specific algorithm.
+ */
+ u_int16_t keysize;
};
-extern const proposal_token_t* proposal_get_token(register const char *str,
- register unsigned int len);
+/**
+ * Class to manage proposal keywords
+ */
+struct proposal_keywords_t {
+
+ /**
+ * Returns the proposal token for the specified string if a token exists.
+ *
+ * @param str the string containing the name of the token
+ * @return proposal_token if found, NULL otherwise
+ */
+ const proposal_token_t *(*get_token)(proposal_keywords_t *this,
+ const char *str);
-#endif /* _PROPOSAL_KEYWORDS_H_ */
+ /**
+ * Register a new proposal token for an algorithm.
+ *
+ * @param name the string containing the name of the token
+ * @param type the transform_type_t for the token
+ * @param algorithm the IKE id of the algorithm
+ * @param keysize the key size associated with the specific algorithm
+ */
+ void (*register_token)(proposal_keywords_t *this, const char *name,
+ transform_type_t type, u_int16_t algorithm,
+ u_int16_t keysize);
+
+ /**
+ * Destroy a proposal_keywords_t instance.
+ */
+ void (*destroy)(proposal_keywords_t *this);
+};
+
+/**
+ * Create a proposal_keywords_t instance.
+ */
+proposal_keywords_t *proposal_keywords_create();
+#endif /** PROPOSAL_KEYWORDS_H_ @}*/
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords_static.h b/src/libstrongswan/crypto/proposal/proposal_keywords_static.h
new file mode 100644
index 000000000..bc421dcc5
--- /dev/null
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * 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.
+ */
+
+#ifndef PROPOSAL_KEYWORDS_STATIC_H_
+#define PROPOSAL_KEYWORDS_STATIC_H_
+
+#include "proposal_keywords.h"
+
+const proposal_token_t* proposal_get_token_static(register const char *str,
+ register unsigned int len);
+
+#endif /* PROPOSAL_KEYWORDS_STATIC_H_ */
+
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.txt b/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt
index 1d04f2dc4..7f8c95757 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords.txt
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords_static.txt
@@ -1,5 +1,5 @@
%{
-/* proposal keywords
+/*
* Copyright (C) 2009 Andreas Steffen
* Hochschule fuer Technik Rapperswil, Switzerland
*
@@ -23,10 +23,10 @@
%}
struct proposal_token {
- char *name;
- transform_type_t type;
+ char *name;
+ transform_type_t type;
u_int16_t algorithm;
- u_int16_t keysize;
+ u_int16_t keysize;
};
%%
null, ENCRYPTION_ALGORITHM, ENCR_NULL, 0
diff --git a/src/libstrongswan/crypto/transform.c b/src/libstrongswan/crypto/transform.c
index 1e108f1de..56252971a 100644
--- a/src/libstrongswan/crypto/transform.c
+++ b/src/libstrongswan/crypto/transform.c
@@ -15,12 +15,13 @@
#include <crypto/transform.h>
-ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, AEAD_ALGORITHM,
+ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, COMPRESSION_ALGORITHM,
"UNDEFINED_TRANSFORM_TYPE",
"HASH_ALGORITHM",
"RANDOM_NUMBER_GENERATOR",
- "AEAD_ALGORITHM");
-ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, AEAD_ALGORITHM,
+ "AEAD_ALGORITHM",
+ "COMPRESSION_ALGORITHM");
+ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, COMPRESSION_ALGORITHM,
"ENCRYPTION_ALGORITHM",
"PSEUDO_RANDOM_FUNCTION",
"INTEGRITY_ALGORITHM",
diff --git a/src/libstrongswan/crypto/transform.h b/src/libstrongswan/crypto/transform.h
index 1393c674c..311df068f 100644
--- a/src/libstrongswan/crypto/transform.h
+++ b/src/libstrongswan/crypto/transform.h
@@ -23,7 +23,7 @@
typedef enum transform_type_t transform_type_t;
-#include <library.h>
+#include <enum.h>
/**
* Type of a transform, as in IKEv2 RFC 3.3.2.
@@ -33,6 +33,7 @@ enum transform_type_t {
HASH_ALGORITHM = 242,
RANDOM_NUMBER_GENERATOR = 243,
AEAD_ALGORITHM = 244,
+ COMPRESSION_ALGORITHM = 245,
ENCRYPTION_ALGORITHM = 1,
PSEUDO_RANDOM_FUNCTION = 2,
INTEGRITY_ALGORITHM = 3,
diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c
index ed3f52027..1179b468c 100644
--- a/src/libstrongswan/library.c
+++ b/src/libstrongswan/library.c
@@ -73,6 +73,7 @@ void library_deinit()
this->public.creds->destroy(this->public.creds);
this->public.encoding->destroy(this->public.encoding);
this->public.crypto->destroy(this->public.crypto);
+ this->public.proposal->destroy(this->public.proposal);
this->public.fetcher->destroy(this->public.fetcher);
this->public.db->destroy(this->public.db);
this->public.printf_hook->destroy(this->public.printf_hook);
@@ -182,6 +183,7 @@ bool library_init(char *settings)
this->objects = hashtable_create((hashtable_hash_t)hash,
(hashtable_equals_t)equals, 4);
this->public.settings = settings_create(settings);
+ this->public.proposal = proposal_keywords_create();
this->public.crypto = crypto_factory_create();
this->public.creds = credential_factory_create();
this->public.credmgr = credential_manager_create();
diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h
index 634128fe9..b79bd91be 100644
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
@@ -82,6 +82,7 @@
#include "processing/processor.h"
#include "processing/scheduler.h"
#include "crypto/crypto_factory.h"
+#include "crypto/proposal/proposal_keywords.h"
#include "fetcher/fetcher_manager.h"
#include "database/database_factory.h"
#include "credentials/credential_factory.h"
@@ -120,6 +121,11 @@ struct library_t {
printf_hook_t *printf_hook;
/**
+ * Proposal keywords registry
+ */
+ proposal_keywords_t *proposal;
+
+ /**
* crypto algorithm registry and factory
*/
crypto_factory_t *crypto;
diff --git a/src/libstrongswan/utils/enumerator.c b/src/libstrongswan/utils/enumerator.c
index fb461b448..53c94f9dd 100644
--- a/src/libstrongswan/utils/enumerator.c
+++ b/src/libstrongswan/utils/enumerator.c
@@ -121,7 +121,7 @@ static bool enumerate_dir_enum(dir_enum_t *this, char **relative,
/**
* See header
*/
-enumerator_t* enumerator_create_directory(char *path)
+enumerator_t* enumerator_create_directory(const char *path)
{
int len;
dir_enum_t *this = malloc_thing(dir_enum_t);
@@ -168,9 +168,9 @@ typedef struct {
/** current position */
char *pos;
/** separater chars */
- char *sep;
+ const char *sep;
/** trim chars */
- char *trim;
+ const char *trim;
} token_enum_t;
/**
@@ -187,7 +187,8 @@ static void destroy_token_enum(token_enum_t *this)
*/
static bool enumerate_token_enum(token_enum_t *this, char **token)
{
- char *pos = NULL, *tmp, *sep, *trim;
+ const char *sep, *trim;
+ char *pos = NULL, *tmp;
bool last = FALSE;
/* trim leading characters/separators */
@@ -303,7 +304,8 @@ static bool enumerate_token_enum(token_enum_t *this, char **token)
/**
* See header
*/
-enumerator_t* enumerator_create_token(char *string, char *sep, char *trim)
+enumerator_t* enumerator_create_token(const char *string, const char *sep,
+ const char *trim)
{
token_enum_t *enumerator = malloc_thing(token_enum_t);
diff --git a/src/libstrongswan/utils/enumerator.h b/src/libstrongswan/utils/enumerator.h
index 12b5712ae..8c3d70173 100644
--- a/src/libstrongswan/utils/enumerator.h
+++ b/src/libstrongswan/utils/enumerator.h
@@ -93,7 +93,7 @@ enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item));
* @param path path of the directory
* @return the directory enumerator, NULL on failure
*/
-enumerator_t* enumerator_create_directory(char *path);
+enumerator_t* enumerator_create_directory(const char *path);
/**
* Create an enumerator over tokens of a string.
@@ -106,7 +106,8 @@ enumerator_t* enumerator_create_directory(char *path);
* @param trim characters to trim from tokens
* @return enumerator over char* tokens
*/
-enumerator_t* enumerator_create_token(char *string, char *sep, char *trim);
+enumerator_t* enumerator_create_token(const char *string, const char *sep,
+ const char *trim);
/**
* Creates an enumerator which enumerates over enumerated enumerators :-).
diff --git a/src/scepclient/scepclient.c b/src/scepclient/scepclient.c
index 76d639a84..78b0d7e7a 100644
--- a/src/scepclient/scepclient.c
+++ b/src/scepclient/scepclient.c
@@ -828,7 +828,7 @@ int main(int argc, char **argv)
if (strcaseeq("enc", type))
{
- token = proposal_get_token(algo, strlen(algo));
+ token = lib->proposal->get_token(lib->proposal, algo);
if (token == NULL || token->type != ENCRYPTION_ALGORITHM)
{
usage("invalid algorithm specified");
@@ -846,7 +846,7 @@ int main(int argc, char **argv)
{
hash_algorithm_t hash;
- token = proposal_get_token(algo, strlen(algo));
+ token = lib->proposal->get_token(lib->proposal, algo);
if (token == NULL || token->type != INTEGRITY_ALGORITHM)
{
usage("invalid algorithm specified");