added --with-sim-reader option to configure script
some cleanups in eap_sim
This commit is contained in:
@@ -80,6 +80,12 @@ AC_ARG_WITH(
|
|||||||
[AC_SUBST(eapdir, "${ipsecdir}/eap")]
|
[AC_SUBST(eapdir, "${ipsecdir}/eap")]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
AC_ARG_WITH(
|
||||||
|
[sim-reader],
|
||||||
|
AS_HELP_STRING([--with-sim-reader=library.so],[library containing the sim_run_alg() function for EAP-SIM]),
|
||||||
|
[AC_DEFINE_UNQUOTED(SIM_READER_LIB, "$withval")]
|
||||||
|
)
|
||||||
|
|
||||||
AC_ARG_ENABLE(
|
AC_ARG_ENABLE(
|
||||||
[http],
|
[http],
|
||||||
AS_HELP_STRING([--enable-http],[enable OCSP and fetching of Certificates and CRLs over HTTP (default is NO). Requires libcurl.]),
|
AS_HELP_STRING([--enable-http],[enable OCSP and fetching of Certificates and CRLs over HTTP (default is NO). Requires libcurl.]),
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ struct private_eap_sim_t {
|
|||||||
#define RAND_LEN 16
|
#define RAND_LEN 16
|
||||||
/** length of the k_encr key */
|
/** length of the k_encr key */
|
||||||
#define KENCR_LEN 16
|
#define KENCR_LEN 16
|
||||||
/** length of the k_Auth value */
|
/** length of the k_auth key */
|
||||||
#define KAUTH_LEN 16
|
#define KAUTH_LEN 16
|
||||||
/** length of the MSK */
|
/** length of the MSK */
|
||||||
#define MSK_LEN 64
|
#define MSK_LEN 64
|
||||||
@@ -257,6 +257,14 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier
|
|||||||
}
|
}
|
||||||
case AT_IDENTITY:
|
case AT_IDENTITY:
|
||||||
{
|
{
|
||||||
|
/* align up to four byte */
|
||||||
|
if (data.len % 4)
|
||||||
|
{
|
||||||
|
chunk_t tmp = chunk_alloca((data.len/4)*4 + 4);
|
||||||
|
memset(tmp.ptr, 0, tmp.len);
|
||||||
|
memcpy(tmp.ptr, data.ptr, data.len);
|
||||||
|
data = tmp;
|
||||||
|
}
|
||||||
*pos.ptr = data.len/4 + 1;
|
*pos.ptr = data.len/4 + 1;
|
||||||
pos = chunk_skip(pos, 1);
|
pos = chunk_skip(pos, 1);
|
||||||
/* actual length in bytes */
|
/* actual length in bytes */
|
||||||
@@ -315,10 +323,9 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier
|
|||||||
signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
|
signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
|
||||||
signer->set_key(signer, this->k_auth);
|
signer->set_key(signer, this->k_auth);
|
||||||
mac_data = chunk_cata("cc", message, mac_data);
|
mac_data = chunk_cata("cc", message, mac_data);
|
||||||
DBG3(DBG_IKE, "AT_MAC signature of %B", &mac_data);
|
|
||||||
DBG3(DBG_IKE, "using k_auth %B", &this->k_auth);
|
|
||||||
signer->get_signature(signer, mac_data, mac_pos);
|
signer->get_signature(signer, mac_data, mac_pos);
|
||||||
DBG3(DBG_IKE, "is %b", mac_pos, MAC_LEN);
|
DBG3(DBG_IKE, "AT_MAC signature of %B\n is %b",
|
||||||
|
&mac_data, mac_pos, MAC_LEN);
|
||||||
signer->destroy(signer);
|
signer->destroy(signer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +357,6 @@ static status_t process_start(private_eap_sim_t *this, eap_payload_t *in,
|
|||||||
{
|
{
|
||||||
/* check if server supports our implementation */
|
/* check if server supports our implementation */
|
||||||
bool found = FALSE;
|
bool found = FALSE;
|
||||||
|
|
||||||
if (data.len > 2)
|
if (data.len > 2)
|
||||||
{
|
{
|
||||||
/* read actual length first */
|
/* read actual length first */
|
||||||
@@ -409,7 +415,7 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
|
|||||||
{
|
{
|
||||||
chunk_t message, data, tmp, kcs, kc, sreses, sres, mk;
|
chunk_t message, data, tmp, kcs, kc, sreses, sres, mk;
|
||||||
sim_attribute_t attribute;
|
sim_attribute_t attribute;
|
||||||
u_int8_t identifier;
|
u_int8_t identifier, i;
|
||||||
chunk_t mac = chunk_empty, rands = chunk_empty;
|
chunk_t mac = chunk_empty, rands = chunk_empty;
|
||||||
signer_t *signer;
|
signer_t *signer;
|
||||||
hasher_t *hasher;
|
hasher_t *hasher;
|
||||||
@@ -431,7 +437,8 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
|
|||||||
case AT_MAC:
|
case AT_MAC:
|
||||||
{
|
{
|
||||||
/* backup MAC, zero it inline for later verification */
|
/* backup MAC, zero it inline for later verification */
|
||||||
mac = chunk_clonea(chunk_skip(data, 2));
|
data = chunk_skip(data, 2);
|
||||||
|
mac = chunk_clonea(data);
|
||||||
memset(data.ptr, 0, data.len);
|
memset(data.ptr, 0, data.len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -443,7 +450,7 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* excepting two or three RAND, each 16 bytes. We require two valid
|
/* excepting two or three RAND, each 16 bytes. We require two valid
|
||||||
* and different (!) RANDs */
|
* and different RANDs */
|
||||||
if ((rands.len != 2 * RAND_LEN && rands.len != 3 * RAND_LEN) ||
|
if ((rands.len != 2 * RAND_LEN && rands.len != 3 * RAND_LEN) ||
|
||||||
memeq(rands.ptr, rands.ptr + RAND_LEN, RAND_LEN))
|
memeq(rands.ptr, rands.ptr + RAND_LEN, RAND_LEN))
|
||||||
{
|
{
|
||||||
@@ -469,7 +476,7 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
|
|||||||
{
|
{
|
||||||
int kc_len = kc.len, sres_len = sres.len;
|
int kc_len = kc.len, sres_len = sres.len;
|
||||||
|
|
||||||
if (this->alg(rands.ptr, RAND_LEN, kc.ptr, &kc_len, sres.ptr, &sres_len))
|
if (this->alg(rands.ptr, RAND_LEN, sres.ptr, &sres_len, kc.ptr, &kc_len))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "unable to get triplets from SIM");
|
DBG1(DBG_IKE, "unable to get triplets from SIM");
|
||||||
*out = build_payload(this, identifier, SIM_CLIENT_ERROR,
|
*out = build_payload(this, identifier, SIM_CLIENT_ERROR,
|
||||||
@@ -477,18 +484,21 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
|
|||||||
AT_END);
|
AT_END);
|
||||||
return NEED_MORE;
|
return NEED_MORE;
|
||||||
}
|
}
|
||||||
|
DBG3(DBG_IKE, "got triplet for RAND %b\n Kc %b\n SRES %b",
|
||||||
|
rands.ptr, RAND_LEN, sres.ptr, sres_len, kc.ptr, kc_len);
|
||||||
kc = chunk_skip(kc, kc_len);
|
kc = chunk_skip(kc, kc_len);
|
||||||
sres = chunk_skip(sres, sres_len);
|
sres = chunk_skip(sres, sres_len);
|
||||||
rands = chunk_skip(rands, RAND_LEN);
|
rands = chunk_skip(rands, RAND_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build MK */
|
/* build MK = SHA1(Identity|n*Kc|NONCE_MT|Version List|Selected Version) */
|
||||||
tmp = chunk_cata("ccccc", this->peer->get_encoding(this->peer), kcs,
|
tmp = chunk_cata("ccccc", this->peer->get_encoding(this->peer), kcs,
|
||||||
this->nonce, this->version_list, this->version);
|
this->nonce, this->version_list, this->version);
|
||||||
hasher = hasher_create(HASH_SHA1);
|
hasher = hasher_create(HASH_SHA1);
|
||||||
mk = chunk_alloca(hasher->get_hash_size(hasher));
|
mk = chunk_alloca(hasher->get_hash_size(hasher));
|
||||||
hasher->get_hash(hasher, tmp, mk.ptr);
|
hasher->get_hash(hasher, tmp, mk.ptr);
|
||||||
hasher->destroy(hasher);
|
hasher->destroy(hasher);
|
||||||
|
DBG3(DBG_IKE, "MK = SHA1(%B\n) = %B", &tmp, &mk);
|
||||||
|
|
||||||
/* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf()
|
/* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf()
|
||||||
* FIPS PRF has 320 bit block size, we need 160 byte for keys
|
* FIPS PRF has 320 bit block size, we need 160 byte for keys
|
||||||
@@ -496,10 +506,10 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
|
|||||||
prf = prf_create(PRF_FIPS_SHA1_160);
|
prf = prf_create(PRF_FIPS_SHA1_160);
|
||||||
prf->set_key(prf, mk);
|
prf->set_key(prf, mk);
|
||||||
tmp = chunk_alloca(prf->get_block_size(prf) * 4);
|
tmp = chunk_alloca(prf->get_block_size(prf) * 4);
|
||||||
prf->get_bytes(prf, chunk_empty, tmp.ptr);
|
for (i = 0; i < 4; i++)
|
||||||
prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
|
{
|
||||||
prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
|
prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * i);
|
||||||
prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
|
}
|
||||||
prf->destroy(prf);
|
prf->destroy(prf);
|
||||||
chunk_free(&this->k_encr);
|
chunk_free(&this->k_encr);
|
||||||
chunk_free(&this->k_auth);
|
chunk_free(&this->k_auth);
|
||||||
@@ -507,23 +517,17 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
|
|||||||
chunk_free(&this->emsk);
|
chunk_free(&this->emsk);
|
||||||
chunk_split(tmp, "aaaa", KENCR_LEN, &this->k_encr, KAUTH_LEN, &this->k_auth,
|
chunk_split(tmp, "aaaa", KENCR_LEN, &this->k_encr, KAUTH_LEN, &this->k_auth,
|
||||||
MSK_LEN, &this->msk, EMSK_LEN, &this->emsk);
|
MSK_LEN, &this->msk, EMSK_LEN, &this->emsk);
|
||||||
DBG3(DBG_IKE, "MK %B", &mk);
|
DBG3(DBG_IKE, "K_encr %B\nK_auth %B\nMSK %B\nEMSK %B",
|
||||||
DBG3(DBG_IKE, "K_encr %B", &this->k_encr);
|
&this->k_encr, &this->k_auth, &this->msk, &this->emsk);
|
||||||
DBG3(DBG_IKE, "K_auth %B", &this->k_auth);
|
|
||||||
DBG3(DBG_IKE, "MSK %B", &this->msk);
|
|
||||||
DBG3(DBG_IKE, "EMSK %B", &this->emsk);
|
|
||||||
|
|
||||||
/* verify AT_MAC attribute, signature is over "EAP packet | NONCE_MT" */
|
/* verify AT_MAC attribute, signature is over "EAP packet | NONCE_MT" */
|
||||||
signer = signer_create(AUTH_HMAC_SHA1_128);
|
signer = signer_create(AUTH_HMAC_SHA1_128);
|
||||||
signer->set_key(signer, this->k_auth);
|
signer->set_key(signer, this->k_auth);
|
||||||
tmp = chunk_cata("cc", message, this->nonce);
|
tmp = chunk_cata("cc", in->get_data(in), this->nonce);
|
||||||
DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &tmp);
|
|
||||||
DBG3(DBG_IKE, "using k_auth %B", &this->k_auth);
|
|
||||||
if (!signer->verify_signature(signer, tmp, mac))
|
if (!signer->verify_signature(signer, tmp, mac))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "MAC in AT_MAC attribute verification failed");
|
DBG1(DBG_IKE, "AT_MAC verification failed");
|
||||||
signer->destroy(signer);
|
signer->destroy(signer);
|
||||||
chunk_free(&this->msk);
|
|
||||||
*out = build_payload(this, identifier, SIM_CLIENT_ERROR,
|
*out = build_payload(this, identifier, SIM_CLIENT_ERROR,
|
||||||
AT_CLIENT_ERROR_CODE, client_error_general,
|
AT_CLIENT_ERROR_CODE, client_error_general,
|
||||||
AT_END);
|
AT_END);
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ typedef int (*sim_algo_t)(const unsigned char *rand, int rand_length,
|
|||||||
|
|
||||||
#ifndef SIM_READER_LIB
|
#ifndef SIM_READER_LIB
|
||||||
/** the library containing the cardreader with the SIM function */
|
/** the library containing the cardreader with the SIM function */
|
||||||
#define SIM_READER_LIB "/root/strongswan-shared/trunk/src/charon/sa/authenticators/eap/sim_reader/sim_api.so"
|
#define SIM_READER_LIB "(unspecified)"
|
||||||
#endif /* SIM_READER_LIB */
|
#endif /* SIM_READER_LIB */
|
||||||
|
|
||||||
#ifndef SIM_READER_ALG
|
#ifndef SIM_READER_ALG
|
||||||
@@ -104,7 +104,6 @@ typedef int (*sim_algo_t)(const unsigned char *rand, int rand_length,
|
|||||||
#endif /* SIM_READER_ALG */
|
#endif /* SIM_READER_ALG */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Implementation of the eap_method_t interface using EAP-SIM.
|
* @brief Implementation of the eap_method_t interface using EAP-SIM.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user