diff options
author | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2007-06-03 17:36:35 +0000 |
---|---|---|
committer | Rene Mayrhofer <rene@mayrhofer.eu.org> | 2007-06-03 17:36:35 +0000 |
commit | 08ee5250bd9c43fda5f24d10b791ca2c4c17fcee (patch) | |
tree | d4e2fc7144e288d624555a38955593e1ee066531 /src/charon/sa/authenticators | |
parent | b0d8ed94fe9e74afb49fdf5f11e4add29879c65c (diff) | |
download | vyos-strongswan-08ee5250bd9c43fda5f24d10b791ca2c4c17fcee.tar.gz vyos-strongswan-08ee5250bd9c43fda5f24d10b791ca2c4c17fcee.zip |
[svn-upgrade] Integrating new upstream version, strongswan (4.1.3)
Diffstat (limited to 'src/charon/sa/authenticators')
-rw-r--r-- | src/charon/sa/authenticators/eap/eap_method.c | 35 | ||||
-rw-r--r-- | src/charon/sa/authenticators/eap/eap_sim.c | 104 | ||||
-rw-r--r-- | src/charon/sa/authenticators/eap_authenticator.c | 58 | ||||
-rw-r--r-- | src/charon/sa/authenticators/psk_authenticator.c | 10 | ||||
-rw-r--r-- | src/charon/sa/authenticators/rsa_authenticator.c | 37 |
5 files changed, 162 insertions, 82 deletions
diff --git a/src/charon/sa/authenticators/eap/eap_method.c b/src/charon/sa/authenticators/eap/eap_method.c index a4d8abb58..e4a58f0a3 100644 --- a/src/charon/sa/authenticators/eap/eap_method.c +++ b/src/charon/sa/authenticators/eap/eap_method.c @@ -85,7 +85,7 @@ void eap_method_unload() while (modules->remove_last(modules, (void**)&entry) == SUCCESS) { - DBG2(DBG_CFG, "unloaded module for %s", eap_type_names, entry->type); + DBG2(DBG_CFG, "unloaded module for %N", eap_type_names, entry->type); dlclose(entry->handle); free(entry); } @@ -100,27 +100,10 @@ void eap_method_unload() void eap_method_load(char *directory) { struct dirent* entry; - struct stat stb; DIR* dir; eap_method_unload(); modules = linked_list_create(); - - if (stat(directory, &stb) == -1 || !(stb.st_mode & S_IFDIR)) - { - DBG1(DBG_CFG, "error opening EAP modules directory %s", directory); - return; - } - if (stb.st_uid != 0) - { - DBG1(DBG_CFG, "EAP modules directory %s not owned by root, skipped", directory); - return; - } - if (stb.st_mode & S_IWOTH || stb.st_mode & S_IWGRP) - { - DBG1(DBG_CFG, "EAP modules directory %s writable by others, skipped", directory); - return; - } dir = opendir(directory); if (dir == NULL) @@ -141,12 +124,6 @@ void eap_method_load(char *directory) snprintf(file, sizeof(file), "%s/%s", directory, entry->d_name); - if (stat(file, &stb) == -1 || !(stb.st_mode & S_IFREG)) - { - DBG2(DBG_CFG, " skipping %s, doesn't look like a file", - entry->d_name); - continue; - } ending = entry->d_name + strlen(entry->d_name) - 3; if (ending <= entry->d_name || !streq(ending, ".so")) { @@ -155,16 +132,6 @@ void eap_method_load(char *directory) entry->d_name); continue; } - if (stb.st_uid != 0) - { - DBG1(DBG_CFG, " skipping %s, file is not owned by root", entry->d_name); - return; - } - if (stb.st_mode & S_IWOTH || stb.st_mode & S_IWGRP) - { - DBG1(DBG_CFG, " skipping %s, file is writeable by others", entry->d_name); - continue; - } /* try to load the library */ module.handle = dlopen(file, RTLD_LAZY); diff --git a/src/charon/sa/authenticators/eap/eap_sim.c b/src/charon/sa/authenticators/eap/eap_sim.c index 3dc59fb6b..38d7f2534 100644 --- a/src/charon/sa/authenticators/eap/eap_sim.c +++ b/src/charon/sa/authenticators/eap/eap_sim.c @@ -398,6 +398,30 @@ static status_t process_start(private_eap_sim_t *this, eap_payload_t *in, /* only include AT_IDENTITY if requested */ include_id = AT_IDENTITY; break; + case AT_NOTIFICATION: + { + u_int16_t code = 0; + if (data.len == 2) + { + code = ntohs(*(u_int16_t*)data.ptr); + } + if (code <= 32767) /* no success bit */ + { + DBG1(DBG_IKE, "received %N error %d", + sim_attribute_names, attribute, code); + *out = build_payload(this, + in->get_identifier(in), SIM_CLIENT_ERROR, + AT_CLIENT_ERROR_CODE, client_error_general, + AT_END); + return NEED_MORE; + } + else + { + DBG1(DBG_IKE, "received %N code %d", + sim_attribute_names, attribute, code); + } + break; + } default: DBG1(DBG_IKE, "ignoring EAP_SIM attribute %N", sim_attribute_names, attribute); @@ -456,6 +480,30 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in, memset(data.ptr, 0, data.len); break; } + case AT_NOTIFICATION: + { + u_int16_t code = 0; + if (data.len == 2) + { + code = ntohs(*(u_int16_t*)data.ptr); + } + if (code <= 32767) /* no success bit */ + { + DBG1(DBG_IKE, "received %N error %d", + sim_attribute_names, attribute, code); + *out = build_payload(this, + in->get_identifier(in), SIM_CLIENT_ERROR, + AT_CLIENT_ERROR_CODE, client_error_general, + AT_END); + return NEED_MORE; + } + else + { + DBG1(DBG_IKE, "received %N code %d", + sim_attribute_names, attribute, code); + } + break; + } default: DBG1(DBG_IKE, "ignoring EAP_SIM attribute %N", sim_attribute_names, attribute); @@ -472,7 +520,7 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in, *out = build_payload(this, identifier, SIM_CLIENT_ERROR, AT_CLIENT_ERROR_CODE, client_error_insufficient, AT_END); - return FAILED; + return NEED_MORE; } if (mac.len != MAC_LEN) { @@ -557,6 +605,58 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in, } /** + * process an EAP-SIM/Request/Notification message + */ +static status_t process_notification(private_eap_sim_t *this, eap_payload_t *in, + eap_payload_t **out) +{ + chunk_t message, data; + sim_attribute_t attribute; + + message = in->get_data(in); + read_header(&message); + + while ((attribute = read_attribute(&message, &data)) != AT_END) + { + switch (attribute) + { + case AT_NOTIFICATION: + { + u_int16_t code = 0; + if (data.len == 2) + { + code = ntohs(*(u_int16_t*)data.ptr); + } + if (code <= 32767) /* no success bit */ + { + DBG1(DBG_IKE, "received %N error %d", + sim_attribute_names, attribute, code); + *out = build_payload(this, + in->get_identifier(in), SIM_CLIENT_ERROR, + AT_CLIENT_ERROR_CODE, client_error_general, + AT_END); + return NEED_MORE; + } + else + { + DBG1(DBG_IKE, "received %N code %d", + sim_attribute_names, attribute, code); + } + break; + } + default: + DBG1(DBG_IKE, "ignoring EAP_SIM attribute %N", + sim_attribute_names, attribute); + break; + } + } + /* reply with empty notification */ + *out = build_payload(this, in->get_identifier(in), SIM_NOTIFICATION, AT_END); + return NEED_MORE; +} + + +/** * Implementation of eap_method_t.process for the peer */ static status_t process(private_eap_sim_t *this, @@ -574,6 +674,8 @@ static status_t process(private_eap_sim_t *this, return process_start(this, in, out); case SIM_CHALLENGE: return process_challenge(this, in, out); + case SIM_NOTIFICATION: + return process_notification(this, in, out); default: DBG1(DBG_IKE, "unable to process EAP_SIM subtype %N", sim_subtype_names, type); diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c index 6c8ca8d8f..6e2f73a43 100644 --- a/src/charon/sa/authenticators/eap_authenticator.c +++ b/src/charon/sa/authenticators/eap_authenticator.c @@ -25,7 +25,7 @@ #include "eap_authenticator.h" #include <daemon.h> -#include <config/policies/policy.h> +#include <config/peer_cfg.h> #include <sa/authenticators/eap/eap_method.h> typedef struct private_eap_authenticator_t private_eap_authenticator_t; @@ -61,21 +61,31 @@ struct private_eap_authenticator_t { chunk_t msk; }; +/** + * reuse shared key signature function from PSK authenticator + */ extern chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce, - chunk_t secret, identification_t *id, - prf_t *prf_skp, prf_t *prf); - + chunk_t secret, identification_t *id, + chunk_t skp, prf_t *prf); /** * Implementation of authenticator_t.verify. */ static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init, chunk_t my_nonce, auth_payload_t *auth_payload) { - chunk_t auth_data, recv_auth_data; + chunk_t auth_data, recv_auth_data, secret; identification_t *other_id = this->ike_sa->get_other_id(this->ike_sa); - auth_data = build_shared_key_signature(ike_sa_init, my_nonce, this->msk, - other_id, this->ike_sa->get_auth_verify(this->ike_sa), + if (this->msk.len) + { /* use MSK if EAP method established one... */ + secret = this->msk; + } + else + { /* ... or use SKp if not */ + secret = this->ike_sa->get_skp_verify(this->ike_sa); + } + auth_data = build_shared_key_signature(ike_sa_init, my_nonce, secret, + other_id, this->ike_sa->get_skp_verify(this->ike_sa), this->ike_sa->get_prf(this->ike_sa)); recv_auth_data = auth_payload->get_data(auth_payload); @@ -98,14 +108,22 @@ static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init, static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init, chunk_t other_nonce, auth_payload_t **auth_payload) { - chunk_t auth_data; + chunk_t auth_data, secret; identification_t *my_id = this->ike_sa->get_my_id(this->ike_sa); DBG1(DBG_IKE, "authentication of '%D' (myself) with %N", my_id, auth_method_names, AUTH_EAP); - - auth_data = build_shared_key_signature(ike_sa_init, other_nonce, this->msk, - my_id, this->ike_sa->get_auth_build(this->ike_sa), + + if (this->msk.len) + { /* use MSK if EAP method established one... */ + secret = this->msk; + } + else + { /* ... or use SKp if not */ + secret = this->ike_sa->get_skp_build(this->ike_sa); + } + auth_data = build_shared_key_signature(ike_sa_init, other_nonce, secret, + my_id, this->ike_sa->get_skp_build(this->ike_sa), this->ike_sa->get_prf(this->ike_sa)); *auth_payload = auth_payload_create(); @@ -233,13 +251,14 @@ static status_t process_server(private_eap_authenticator_t *this, DBG1(DBG_IKE, "EAP method %N succeded, MSK established", eap_type_names, this->method->get_type(this->method)); this->msk = chunk_clone(this->msk); - *out = eap_payload_create_code(EAP_SUCCESS); - return SUCCESS; } - DBG1(DBG_IKE, "EAP method %N succeded, but no MSK established", - eap_type_names, this->method->get_type(this->method)); - *out = eap_payload_create_code(EAP_FAILURE); - return FAILED; + else + { + DBG1(DBG_IKE, "EAP method %N succeded, no MSK established", + eap_type_names, this->method->get_type(this->method)); + } + *out = eap_payload_create_code(EAP_SUCCESS); + return SUCCESS; case FAILED: default: DBG1(DBG_IKE, "EAP method %N failed for peer %D", @@ -290,11 +309,8 @@ static status_t process(private_eap_authenticator_t *this, eap_payload_t *in, if (this->method->get_msk(this->method, &this->msk) == SUCCESS) { this->msk = chunk_clone(this->msk); - return SUCCESS; } - DBG1(DBG_IKE, "EAP method %N has no MSK established", - eap_type_names, this->method->get_type(this->method)); - return FAILED; + return SUCCESS; } case EAP_FAILURE: default: diff --git a/src/charon/sa/authenticators/psk_authenticator.c b/src/charon/sa/authenticators/psk_authenticator.c index 43aec0971..37465d029 100644 --- a/src/charon/sa/authenticators/psk_authenticator.c +++ b/src/charon/sa/authenticators/psk_authenticator.c @@ -25,7 +25,6 @@ #include "psk_authenticator.h" -#include <config/policies/policy.h> #include <daemon.h> /** @@ -78,11 +77,12 @@ chunk_t build_tbs_octets(chunk_t ike_sa_init, chunk_t nonce, */ chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce, chunk_t secret, identification_t *id, - prf_t *prf_skp, prf_t *prf) + chunk_t skp, prf_t *prf) { chunk_t key_pad, key, auth_data, octets; - octets = build_tbs_octets(ike_sa_init, nonce, id, prf_skp); + prf->set_key(prf, skp); + octets = build_tbs_octets(ike_sa_init, nonce, id, prf); /* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */ key_pad.ptr = IKEV2_KEY_PAD; key_pad.len = IKEV2_KEY_PAD_LENGTH; @@ -122,7 +122,7 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init, } auth_data = build_shared_key_signature(ike_sa_init, my_nonce, shared_key, - other_id, this->ike_sa->get_auth_verify(this->ike_sa), + other_id, this->ike_sa->get_skp_verify(this->ike_sa), this->ike_sa->get_prf(this->ike_sa)); chunk_free(&shared_key); @@ -165,7 +165,7 @@ static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init, } auth_data = build_shared_key_signature(ike_sa_init, other_nonce, shared_key, - my_id, this->ike_sa->get_auth_build(this->ike_sa), + my_id, this->ike_sa->get_skp_build(this->ike_sa), this->ike_sa->get_prf(this->ike_sa)); DBG2(DBG_IKE, "successfully created shared key MAC"); chunk_free(&shared_key); diff --git a/src/charon/sa/authenticators/rsa_authenticator.c b/src/charon/sa/authenticators/rsa_authenticator.c index dfa01e332..e5c5cd60e 100644 --- a/src/charon/sa/authenticators/rsa_authenticator.c +++ b/src/charon/sa/authenticators/rsa_authenticator.c @@ -25,7 +25,6 @@ #include "rsa_authenticator.h" -#include <config/policies/policy.h> #include <daemon.h> @@ -61,8 +60,9 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init, { status_t status; chunk_t auth_data, octets; - rsa_public_key_t *public_key; identification_t *other_id; + ca_info_t *issuer; + prf_t *prf; other_id = this->ike_sa->get_other_id(this->ike_sa); @@ -71,27 +71,20 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init, return INVALID_ARG; } auth_data = auth_payload->get_data(auth_payload); - public_key = charon->credentials->get_trusted_public_key(charon->credentials, - other_id); - if (public_key == NULL) - { - DBG1(DBG_IKE, "no RSA public key found for '%D'", other_id); - return NOT_FOUND; - } - octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, - this->ike_sa->get_auth_verify(this->ike_sa)); - status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data); + prf = this->ike_sa->get_prf(this->ike_sa); + prf->set_key(prf, this->ike_sa->get_skp_verify(this->ike_sa)); + octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, prf); + status = charon->credentials->verify_signature(charon->credentials, + octets, auth_data, other_id, &issuer); chunk_free(&octets); - if (status != SUCCESS) + if (status == SUCCESS) { - DBG1(DBG_IKE, "RSA signature verification failed"); - return status; + this->ike_sa->set_other_ca(this->ike_sa, issuer); + DBG1(DBG_IKE, "authentication of '%D' with %N successful", + other_id, auth_method_names, AUTH_RSA); } - - DBG1(DBG_IKE, "authentication of '%D' with %N successful", - other_id, auth_method_names, AUTH_RSA); - return SUCCESS; + return status; } /** @@ -107,6 +100,7 @@ static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init, rsa_public_key_t *my_pubkey; rsa_private_key_t *my_key; identification_t *my_id; + prf_t *prf; my_id = this->ike_sa->get_my_id(this->ike_sa); DBG1(DBG_IKE, "authentication of '%D' (myself) with %N", @@ -131,8 +125,9 @@ static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init, } DBG2(DBG_IKE, "matching RSA private key found"); - octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, - this->ike_sa->get_auth_build(this->ike_sa)); + prf = this->ike_sa->get_prf(this->ike_sa); + prf->set_key(prf, this->ike_sa->get_skp_build(this->ike_sa)); + octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, prf); status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1, octets, &auth_data); chunk_free(&octets); |