added --with-sim-reader option to configure script

some cleanups in eap_sim
This commit is contained in:
Martin Willi
2007-03-14 15:39:45 +00:00
parent c105696d1c
commit d560c849e3
3 changed files with 36 additions and 27 deletions
+6
View File
@@ -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.]),
+29 -25
View File
@@ -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))
{ {
@@ -468,8 +475,8 @@ static status_t process_challenge(private_eap_sim_t *this, eap_payload_t *in,
while (rands.len > 0) while (rands.len > 0)
{ {
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);
+1 -2
View File
@@ -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.
* *