diff options
Diffstat (limited to 'src/libcharon/config')
-rw-r--r-- | src/libcharon/config/child_cfg.c | 31 | ||||
-rw-r--r-- | src/libcharon/config/child_cfg.h | 20 | ||||
-rw-r--r-- | src/libcharon/config/ike_cfg.c | 5 | ||||
-rw-r--r-- | src/libcharon/config/ike_cfg.h | 5 | ||||
-rw-r--r-- | src/libcharon/config/peer_cfg.c | 3 | ||||
-rw-r--r-- | src/libcharon/config/proposal.c | 170 | ||||
-rw-r--r-- | src/libcharon/config/proposal.h | 8 |
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. |