summaryrefslogtreecommitdiff
path: root/src/libcharon/config
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/config')
-rw-r--r--src/libcharon/config/child_cfg.c31
-rw-r--r--src/libcharon/config/child_cfg.h20
-rw-r--r--src/libcharon/config/ike_cfg.c5
-rw-r--r--src/libcharon/config/ike_cfg.h5
-rw-r--r--src/libcharon/config/peer_cfg.c3
-rw-r--r--src/libcharon/config/proposal.c170
-rw-r--r--src/libcharon/config/proposal.h8
7 files changed, 172 insertions, 70 deletions
diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c
index 6fe7d44b8..7e4a1433d 100644
--- a/src/libcharon/config/child_cfg.c
+++ b/src/libcharon/config/child_cfg.c
@@ -27,6 +27,9 @@ ENUM(action_names, ACTION_NONE, ACTION_RESTART,
"restart",
);
+/** Default replay window size, if not set using charon.replay_window */
+#define DEFAULT_REPLAY_WINDOW 32
+
typedef struct private_child_cfg_t private_child_cfg_t;
/**
@@ -138,6 +141,11 @@ struct private_child_cfg_t {
* enable installation and removal of kernel IPsec policies
*/
bool install_policy;
+
+ /**
+ * anti-replay window size
+ */
+ u_int32_t replay_window;
};
METHOD(child_cfg_t, get_name, char*,
@@ -149,7 +157,10 @@ METHOD(child_cfg_t, get_name, char*,
METHOD(child_cfg_t, add_proposal, void,
private_child_cfg_t *this, proposal_t *proposal)
{
- this->proposals->insert_last(this->proposals, proposal);
+ if (proposal)
+ {
+ this->proposals->insert_last(this->proposals, proposal);
+ }
}
METHOD(child_cfg_t, get_proposals, linked_list_t*,
@@ -354,11 +365,11 @@ METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*,
{
result->remove_at(result, e1);
ts1->destroy(ts1);
- result->reset_enumerator(result, e2);
break;
}
}
}
+ result->reset_enumerator(result, e2);
}
e1->destroy(e1);
e2->destroy(e2);
@@ -478,6 +489,18 @@ METHOD(child_cfg_t, get_tfc, u_int32_t,
return this->tfc;
}
+METHOD(child_cfg_t, get_replay_window, u_int32_t,
+ private_child_cfg_t *this)
+{
+ return this->replay_window;
+}
+
+METHOD(child_cfg_t, set_replay_window, void,
+ private_child_cfg_t *this, u_int32_t replay_window)
+{
+ this->replay_window = replay_window;
+}
+
METHOD(child_cfg_t, set_mipv6_options, void,
private_child_cfg_t *this, bool proxy_mode, bool install_policy)
{
@@ -555,6 +578,8 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
.get_reqid = _get_reqid,
.get_mark = _get_mark,
.get_tfc = _get_tfc,
+ .get_replay_window = _get_replay_window,
+ .set_replay_window = _set_replay_window,
.use_proxy_mode = _use_proxy_mode,
.install_policy = _install_policy,
.get_ref = _get_ref,
@@ -577,6 +602,8 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
.my_ts = linked_list_create(),
.other_ts = linked_list_create(),
.tfc = tfc,
+ .replay_window = lib->settings->get_int(lib->settings,
+ "%s.replay_window", DEFAULT_REPLAY_WINDOW, lib->ns),
);
if (mark_in)
diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h
index 20d1fa811..9f7a92b70 100644
--- a/src/libcharon/config/child_cfg.h
+++ b/src/libcharon/config/child_cfg.h
@@ -73,10 +73,10 @@ struct child_cfg_t {
* Add a proposal to the list.
*
* The proposals are stored by priority, first added
- * is the most preferred.
- * After add, proposal is owned by child_cfg.
+ * is the most preferred. It is safe to add NULL as proposal, which has no
+ * effect. After add, proposal is owned by child_cfg.
*
- * @param proposal proposal to add
+ * @param proposal proposal to add, or NULL
*/
void (*add_proposal) (child_cfg_t *this, proposal_t *proposal);
@@ -235,6 +235,20 @@ struct child_cfg_t {
u_int32_t (*get_tfc)(child_cfg_t *this);
/**
+ * Get anti-replay window size
+ *
+ * @return anti-replay window size
+ */
+ u_int32_t (*get_replay_window)(child_cfg_t *this);
+
+ /**
+ * Set anti-replay window size
+ *
+ * @param window anti-replay window size
+ */
+ void (*set_replay_window)(child_cfg_t *this, u_int32_t window);
+
+ /**
* Sets two options needed for Mobile IPv6 interoperability.
*
* @param proxy_mode use IPsec transport proxy mode (default FALSE)
diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c
index e08bb3f67..42a3e9057 100644
--- a/src/libcharon/config/ike_cfg.c
+++ b/src/libcharon/config/ike_cfg.c
@@ -281,7 +281,10 @@ METHOD(ike_cfg_t, get_dscp, u_int8_t,
METHOD(ike_cfg_t, add_proposal, void,
private_ike_cfg_t *this, proposal_t *proposal)
{
- this->proposals->insert_last(this->proposals, proposal);
+ if (proposal)
+ {
+ this->proposals->insert_last(this->proposals, proposal);
+ }
}
METHOD(ike_cfg_t, get_proposals, linked_list_t*,
diff --git a/src/libcharon/config/ike_cfg.h b/src/libcharon/config/ike_cfg.h
index f9e4fbebc..adfcabf70 100644
--- a/src/libcharon/config/ike_cfg.h
+++ b/src/libcharon/config/ike_cfg.h
@@ -148,9 +148,10 @@ struct ike_cfg_t {
* Adds a proposal to the list.
*
* The first added proposal has the highest priority, the last
- * added the lowest.
+ * added the lowest. It is safe to add NULL as proposal, which has no
+ * effect.
*
- * @param proposal proposal to add
+ * @param proposal proposal to add, or NULL
*/
void (*add_proposal) (ike_cfg_t *this, proposal_t *proposal);
diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c
index d198503d0..ce9301006 100644
--- a/src/libcharon/config/peer_cfg.c
+++ b/src/libcharon/config/peer_cfg.c
@@ -31,7 +31,8 @@ ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
"CERT_NEVER_SEND",
);
-ENUM(unique_policy_names, UNIQUE_NO, UNIQUE_KEEP,
+ENUM(unique_policy_names, UNIQUE_NEVER, UNIQUE_KEEP,
+ "UNIQUE_NEVER",
"UNIQUE_NO",
"UNIQUE_REPLACE",
"UNIQUE_KEEP",
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 2ecdb4f2e..4d881cd2f 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -627,7 +627,7 @@ proposal_t *proposal_create(protocol_id_t protocol, u_int number)
/**
* Add supported IKE algorithms to proposal
*/
-static void proposal_add_supported_ike(private_proposal_t *this)
+static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
{
enumerator_t *enumerator;
encryption_algorithm_t encryption;
@@ -636,76 +636,91 @@ static void proposal_add_supported_ike(private_proposal_t *this)
diffie_hellman_group_t group;
const char *plugin_name;
- enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
+ if (aead)
{
- switch (encryption)
+ enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
{
- case ENCR_AES_CBC:
- case ENCR_AES_CTR:
- case ENCR_CAMELLIA_CBC:
- case ENCR_CAMELLIA_CTR:
- /* we assume that we support all AES/Camellia sizes */
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
- break;
- case ENCR_3DES:
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0);
- break;
- case ENCR_DES:
- /* no, thanks */
- break;
- default:
- break;
+ switch (encryption)
+ {
+ case ENCR_AES_CCM_ICV8:
+ case ENCR_AES_CCM_ICV12:
+ case ENCR_AES_CCM_ICV16:
+ case ENCR_AES_GCM_ICV8:
+ case ENCR_AES_GCM_ICV12:
+ case ENCR_AES_GCM_ICV16:
+ case ENCR_CAMELLIA_CCM_ICV8:
+ case ENCR_CAMELLIA_CCM_ICV12:
+ case ENCR_CAMELLIA_CCM_ICV16:
+ /* we assume that we support all AES/Camellia sizes */
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
+ break;
+ default:
+ break;
+ }
}
- }
- enumerator->destroy(enumerator);
+ enumerator->destroy(enumerator);
- enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
- {
- switch (encryption)
+ if (!array_count(this->transforms))
{
- case ENCR_AES_CCM_ICV8:
- case ENCR_AES_CCM_ICV12:
- case ENCR_AES_CCM_ICV16:
- case ENCR_AES_GCM_ICV8:
- case ENCR_AES_GCM_ICV12:
- case ENCR_AES_GCM_ICV16:
- case ENCR_CAMELLIA_CCM_ICV8:
- case ENCR_CAMELLIA_CCM_ICV12:
- case ENCR_CAMELLIA_CCM_ICV16:
- /* we assume that we support all AES/Camellia sizes */
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
- break;
- default:
- break;
+ return FALSE;
}
}
- enumerator->destroy(enumerator);
-
- enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
- while (enumerator->enumerate(enumerator, &integrity, &plugin_name))
+ else
{
- switch (integrity)
+ enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
{
- case AUTH_HMAC_SHA1_96:
- case AUTH_HMAC_SHA2_256_128:
- case AUTH_HMAC_SHA2_384_192:
- case AUTH_HMAC_SHA2_512_256:
- case AUTH_HMAC_MD5_96:
- case AUTH_AES_XCBC_96:
- case AUTH_AES_CMAC_96:
- add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0);
- break;
- default:
- break;
+ switch (encryption)
+ {
+ case ENCR_AES_CBC:
+ case ENCR_AES_CTR:
+ case ENCR_CAMELLIA_CBC:
+ case ENCR_CAMELLIA_CTR:
+ /* we assume that we support all AES/Camellia sizes */
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
+ break;
+ case ENCR_3DES:
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0);
+ break;
+ case ENCR_DES:
+ /* no, thanks */
+ break;
+ default:
+ break;
+ }
}
+ enumerator->destroy(enumerator);
+
+ if (!array_count(this->transforms))
+ {
+ return FALSE;
+ }
+
+ enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &integrity, &plugin_name))
+ {
+ switch (integrity)
+ {
+ case AUTH_HMAC_SHA1_96:
+ case AUTH_HMAC_SHA2_256_128:
+ case AUTH_HMAC_SHA2_384_192:
+ case AUTH_HMAC_SHA2_512_256:
+ case AUTH_HMAC_MD5_96:
+ case AUTH_AES_XCBC_96:
+ case AUTH_AES_CMAC_96:
+ add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0);
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
}
- enumerator->destroy(enumerator);
enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
while (enumerator->enumerate(enumerator, &prf, &plugin_name))
@@ -767,6 +782,8 @@ static void proposal_add_supported_ike(private_proposal_t *this)
}
}
enumerator->destroy(enumerator);
+
+ return TRUE;
}
/*
@@ -779,7 +796,11 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
switch (protocol)
{
case PROTO_IKE:
- proposal_add_supported_ike(this);
+ if (!proposal_add_supported_ike(this, FALSE))
+ {
+ destroy(this);
+ return NULL;
+ }
break;
case PROTO_ESP:
add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128);
@@ -807,6 +828,33 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
/*
* Describtion in header-file
*/
+proposal_t *proposal_create_default_aead(protocol_id_t protocol)
+{
+ private_proposal_t *this;
+
+ switch (protocol)
+ {
+ case PROTO_IKE:
+ this = (private_proposal_t*)proposal_create(protocol, 0);
+ if (!proposal_add_supported_ike(this, TRUE))
+ {
+ destroy(this);
+ return NULL;
+ }
+ return &this->public;
+ case PROTO_ESP:
+ /* we currently don't include any AEAD proposal for ESP, as we
+ * don't know if our kernel backend actually supports it. */
+ return NULL;
+ case PROTO_AH:
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Describtion in header-file
+ */
proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs)
{
private_proposal_t *this;
diff --git a/src/libcharon/config/proposal.h b/src/libcharon/config/proposal.h
index 7733143a8..78b868868 100644
--- a/src/libcharon/config/proposal.h
+++ b/src/libcharon/config/proposal.h
@@ -196,6 +196,14 @@ proposal_t *proposal_create(protocol_id_t protocol, u_int number);
proposal_t *proposal_create_default(protocol_id_t protocol);
/**
+ * Create a default proposal for supported AEAD algorithms
+ *
+ * @param protocol protocol, such as PROTO_ESP
+ * @return proposal_t object, NULL if none supported
+ */
+proposal_t *proposal_create_default_aead(protocol_id_t protocol);
+
+/**
* Create a proposal from a string identifying the algorithms.
*
* The string is in the same form as a in the ipsec.conf file.