Pass SIM/AKA crypto helper to constructor of message
authorMartin Willi <martin@strongswan.org>
Fri, 23 Oct 2009 11:57:13 +0000 (13:57 +0200)
committerMartin Willi <martin@strongswan.org>
Thu, 12 Nov 2009 09:34:00 +0000 (10:34 +0100)
src/charon/plugins/eap_aka/eap_aka_peer.c
src/charon/plugins/eap_aka/eap_aka_server.c
src/charon/plugins/eap_sim/eap_sim_peer.c
src/charon/plugins/eap_sim/eap_sim_server.c
src/libsimaka/simaka_message.c
src/libsimaka/simaka_message.h

index 079ab13..b83833b 100644 (file)
@@ -62,12 +62,12 @@ static eap_payload_t* create_client_error(private_eap_aka_peer_t *this,
        DBG1(DBG_IKE, "sending client error '%N'",
                 simaka_client_error_names, AKA_UNABLE_TO_PROCESS);
 
-       message = simaka_message_create(FALSE, identifier,
-                                                                       EAP_AKA, AKA_CLIENT_ERROR);
+       message = simaka_message_create(FALSE, identifier, EAP_AKA,
+                                                                       AKA_CLIENT_ERROR, this->crypto);
        encoded = htons(AKA_UNABLE_TO_PROCESS);
        message->add_attribute(message, AT_CLIENT_ERROR_CODE,
                                                   chunk_create((char*)&encoded, sizeof(encoded)));
-       out = message->generate(message, this->crypto, chunk_empty);
+       out = message->generate(message, chunk_empty);
        message->destroy(message);
        return out;
 }
@@ -133,11 +133,11 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
        {
                DBG1(DBG_IKE, "received SQN invalid, sending %N",
                         simaka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
-               message = simaka_message_create(FALSE, in->get_identifier(in),
-                                                                               EAP_AKA, AKA_SYNCHRONIZATION_FAILURE);
+               message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
+                                                                       AKA_SYNCHRONIZATION_FAILURE, this->crypto);
                message->add_attribute(message, AT_AUTS,
                                                           chunk_create(auts, AKA_AUTS_LEN));
-               *out = message->generate(message, this->crypto, chunk_empty);
+               *out = message->generate(message, chunk_empty);
                message->destroy(message);
                return NEED_MORE;
        }
@@ -145,9 +145,9 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
        {
                DBG1(DBG_IKE, "no USIM found with quintuplets for '%Y', sending %N",
                         this->peer, simaka_subtype_names, AKA_AUTHENTICATION_REJECT);
-               message = simaka_message_create(FALSE, in->get_identifier(in),
-                                                                               EAP_AKA, AKA_AUTHENTICATION_REJECT);
-               *out = message->generate(message, this->crypto, chunk_empty);
+               message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
+                                                                               AKA_AUTHENTICATION_REJECT, this->crypto);
+               *out = message->generate(message, chunk_empty);
                message->destroy(message);
                return NEED_MORE;
        }
@@ -158,17 +158,17 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
        this->msk = this->crypto->derive_keys_full(this->crypto, this->peer, data);
 
        /* verify EAP message MAC AT_MAC */
-       if (!in->verify(in, this->crypto, chunk_empty))
+       if (!in->verify(in, chunk_empty))
        {
                DBG1(DBG_IKE, "AT_MAC verification failed ");
                *out = create_client_error(this, in->get_identifier(in));
                return NEED_MORE;
        }
 
-       message = simaka_message_create(FALSE, in->get_identifier(in),
-                                                                       EAP_AKA, AKA_CHALLENGE);
+       message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
+                                                                       AKA_CHALLENGE, this->crypto);
        message->add_attribute(message, AT_RES, chunk_create(res, AKA_RES_LEN));
-       *out = message->generate(message, this->crypto, chunk_empty);
+       *out = message->generate(message, chunk_empty);
        message->destroy(message);
        return NEED_MORE;
 }
@@ -208,11 +208,11 @@ static status_t process_identity(private_eap_aka_peer_t *this,
        }
        enumerator->destroy(enumerator);
 
-       message = simaka_message_create(FALSE, in->get_identifier(in),
-                                                                       EAP_AKA, AKA_IDENTITY);
+       message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
+                                                                       AKA_IDENTITY, this->crypto);
        message->add_attribute(message, AT_IDENTITY,
                                                   this->peer->get_encoding(this->peer));
-       *out = message->generate(message, this->crypto, chunk_empty);
+       *out = message->generate(message, chunk_empty);
        message->destroy(message);
        return NEED_MORE;
 }
@@ -262,9 +262,9 @@ static status_t process_notification(private_eap_aka_peer_t *this,
 
        if (success)
        {       /* empty notification reply */
-               message = simaka_message_create(FALSE, in->get_identifier(in),
-                                                                               EAP_AKA, AKA_NOTIFICATION);
-               *out = message->generate(message, this->crypto, chunk_empty);
+               message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
+                                                                               AKA_NOTIFICATION, this->crypto);
+               *out = message->generate(message, chunk_empty);
                message->destroy(message);
        }
        else
@@ -284,13 +284,13 @@ static status_t process(private_eap_aka_peer_t *this,
        simaka_message_t *message;
        status_t status;
 
-       message = simaka_message_create_from_payload(in);
+       message = simaka_message_create_from_payload(in, this->crypto);
        if (!message)
        {
                *out = create_client_error(this, in->get_identifier(in));
                return NEED_MORE;
        }
-       if (!message->parse(message, this->crypto))
+       if (!message->parse(message))
        {
                message->destroy(message);
                *out = create_client_error(this, in->get_identifier(in));
index db0c532..0431feb 100644 (file)
@@ -126,11 +126,11 @@ static status_t initiate(private_eap_aka_server_t *this, eap_payload_t **out)
        this->rand = chunk_clone(chunk_create(rand, AKA_RAND_LEN));
        this->xres = chunk_clone(chunk_create(xres, AKA_RES_LEN));
 
-       message = simaka_message_create(TRUE, this->identifier++,
-                                                                       EAP_AKA, AKA_CHALLENGE);
+       message = simaka_message_create(TRUE, this->identifier++, EAP_AKA,
+                                                                       AKA_CHALLENGE, this->crypto);
        message->add_attribute(message, AT_RAND, this->rand);
        message->add_attribute(message, AT_AUTN, chunk_create(autn, AKA_AUTN_LEN));
-       *out = message->generate(message, this->crypto, chunk_empty);
+       *out = message->generate(message, chunk_empty);
        message->destroy(message);
 
        this->pending = AKA_CHALLENGE;
@@ -175,7 +175,7 @@ static status_t process_challenge(private_eap_aka_server_t *this,
        enumerator->destroy(enumerator);
 
        /* verify MAC of EAP message, AT_MAC */
-       if (!in->verify(in, this->crypto, chunk_empty))
+       if (!in->verify(in, chunk_empty))
        {
                DBG1(DBG_IKE, "AT_MAC verification failed");
                return FAILED;
@@ -308,12 +308,12 @@ static status_t process(private_eap_aka_server_t *this,
        simaka_message_t *message;
        status_t status;
 
-       message = simaka_message_create_from_payload(in);
+       message = simaka_message_create_from_payload(in, this->crypto);
        if (!message)
        {
                return FAILED;
        }
-       if (!message->parse(message, this->crypto))
+       if (!message->parse(message))
        {
                message->destroy(message);
                return FAILED;
index c394106..843aa53 100644 (file)
@@ -113,12 +113,12 @@ static eap_payload_t* create_client_error(private_eap_sim_peer_t *this,
 
        DBG1(DBG_IKE, "sending client error '%N'", simaka_client_error_names, code);
 
-       message = simaka_message_create(FALSE, identifier,
-                                                                       EAP_SIM, SIM_CLIENT_ERROR);
+       message = simaka_message_create(FALSE, identifier, EAP_SIM,
+                                                                       SIM_CLIENT_ERROR, this->crypto);
        encoded = htons(code);
        message->add_attribute(message, AT_CLIENT_ERROR_CODE,
                                                   chunk_create((char*)&encoded, sizeof(encoded)));
-       out = message->generate(message, this->crypto, chunk_empty);
+       out = message->generate(message, chunk_empty);
        message->destroy(message);
        return out;
 }
@@ -181,11 +181,11 @@ static status_t process_start(private_eap_sim_peer_t *this,
        free(this->nonce.ptr);
        rng->allocate_bytes(rng, NONCE_LEN, &this->nonce);
 
-       message = simaka_message_create(FALSE, in->get_identifier(in),
-                                                                       EAP_SIM, SIM_START);
+       message = simaka_message_create(FALSE, in->get_identifier(in), EAP_SIM,
+                                                                       SIM_START, this->crypto);
        message->add_attribute(message, AT_SELECTED_VERSION, version);
        message->add_attribute(message, AT_NONCE_MT, this->nonce);
-       *out = message->generate(message, this->crypto, chunk_empty);
+       *out = message->generate(message, chunk_empty);
        message->destroy(message);
 
        return NEED_MORE;
@@ -264,7 +264,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
        this->msk = this->crypto->derive_keys_full(this->crypto, this->peer, data);
 
        /* verify AT_MAC attribute, signature is over "EAP packet | NONCE_MT"  */
-       if (!in->verify(in, this->crypto, this->nonce))
+       if (!in->verify(in, this->nonce))
        {
                DBG1(DBG_IKE, "AT_MAC verification failed");
                *out = create_client_error(this, in->get_identifier(in),
@@ -273,9 +273,9 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
        }
 
        /* build response with AT_MAC, built over "EAP packet | n*SRES" */
-       message = simaka_message_create(FALSE, in->get_identifier(in),
-                                                                       EAP_SIM, SIM_CHALLENGE);
-       *out = message->generate(message, this->crypto, sreses);
+       message = simaka_message_create(FALSE, in->get_identifier(in), EAP_SIM,
+                                                                       SIM_CHALLENGE, this->crypto);
+       *out = message->generate(message, sreses);
        message->destroy(message);
        return NEED_MORE;
 }
@@ -325,9 +325,9 @@ static status_t process_notification(private_eap_sim_peer_t *this,
 
        if (success)
        {       /* empty notification reply */
-               message = simaka_message_create(FALSE, in->get_identifier(in),
-                                                                               EAP_SIM, SIM_NOTIFICATION);
-               *out = message->generate(message, this->crypto, chunk_empty);
+               message = simaka_message_create(FALSE, in->get_identifier(in), EAP_SIM,
+                                                                               SIM_NOTIFICATION, this->crypto);
+               *out = message->generate(message, chunk_empty);
                message->destroy(message);
        }
        else
@@ -347,14 +347,14 @@ static status_t process(private_eap_sim_peer_t *this,
        simaka_message_t *message;
        status_t status;
 
-       message = simaka_message_create_from_payload(in);
+       message = simaka_message_create_from_payload(in, this->crypto);
        if (!message)
        {
                *out = create_client_error(this, in->get_identifier(in),
                                                                   SIM_UNABLE_TO_PROCESS);
                return NEED_MORE;
        }
-       if (!message->parse(message, this->crypto))
+       if (!message->parse(message))
        {
                message->destroy(message);
                *out = create_client_error(this, in->get_identifier(in),
index 5e4d115..d3f438e 100644 (file)
@@ -173,10 +173,10 @@ static status_t process_start(private_eap_sim_server_t *this,
        this->msk = this->crypto->derive_keys_full(this->crypto, this->peer, data);
 
        /* build response with AT_MAC, built over "EAP packet | NONCE_MT" */
-       message = simaka_message_create(TRUE, this->identifier++,
-                                                                       EAP_SIM, SIM_CHALLENGE);
+       message = simaka_message_create(TRUE, this->identifier++, EAP_SIM,
+                                                                       SIM_CHALLENGE, this->crypto);
        message->add_attribute(message, AT_RAND, rands);
-       *out = message->generate(message, this->crypto, nonce);
+       *out = message->generate(message, nonce);
        message->destroy(message);
 
        this->pending = SIM_CHALLENGE;
@@ -212,7 +212,7 @@ static status_t process_challenge(private_eap_sim_server_t *this,
        enumerator->destroy(enumerator);
 
        /* verify AT_MAC attribute, signature is over "EAP packet | n*SRES"  */
-       if (!in->verify(in, this->crypto, this->sreses))
+       if (!in->verify(in, this->sreses))
        {
                DBG1(DBG_IKE, "AT_MAC verification failed");
                return FAILED;
@@ -259,12 +259,12 @@ static status_t process(private_eap_sim_server_t *this,
        simaka_message_t *message;
        status_t status;
 
-       message = simaka_message_create_from_payload(in);
+       message = simaka_message_create_from_payload(in, this->crypto);
        if (!message)
        {
                return FAILED;
        }
-       if (!message->parse(message, this->crypto))
+       if (!message->parse(message))
        {
                message->destroy(message);
                return FAILED;
@@ -297,10 +297,10 @@ static status_t initiate(private_eap_sim_server_t *this, eap_payload_t **out)
 {
        simaka_message_t *message;
 
-       message = simaka_message_create(TRUE, this->identifier++,
-                                                                       EAP_SIM, SIM_START);
+       message = simaka_message_create(TRUE, this->identifier++, EAP_SIM,
+                                                                       SIM_START, this->crypto);
        message->add_attribute(message, AT_VERSION_LIST, version);
-       *out = message->generate(message, this->crypto, chunk_empty);
+       *out = message->generate(message, chunk_empty);
        message->destroy(message);
 
        this->pending = SIM_START;
index fc2380e..689e8c0 100644 (file)
@@ -168,7 +168,13 @@ struct private_simaka_message_t {
        bool encrypted;
 
        /**
-        * Phase a NOTIFICATION is sent within */
+        * crypto helper
+        */
+       simaka_crypto_t *crypto;
+
+       /**
+        * Phase a NOTIFICATION is sent within
+        */
        bool p_bit;
 
        /**
@@ -251,8 +257,7 @@ static void add_attribute(private_simaka_message_t *this,
 /**
  * Implementation of simaka_message_t.parse
  */
-static bool parse(private_simaka_message_t *this, simaka_crypto_t *crypto,
-                                 chunk_t sigdata)
+static bool parse(private_simaka_message_t *this, chunk_t sigdata)
 {
        chunk_t in, iv = chunk_empty, encr = chunk_empty;
 
@@ -443,7 +448,7 @@ static bool parse(private_simaka_message_t *this, simaka_crypto_t *crypto,
                                 eap_type_names, this->hdr->type);
                        return FALSE;
                }
-               crypter = crypto->get_crypter(crypto);
+               crypter = this->crypto->get_crypter(this->crypto);
                if (!crypter)
                {
                        DBG1(DBG_IKE, "%N message contains unexpected encrypted data",
@@ -461,7 +466,7 @@ static bool parse(private_simaka_message_t *this, simaka_crypto_t *crypto,
                crypter->decrypt(crypter, encr, iv, NULL);
 
                this->encrypted = TRUE;
-               success = parse(this, crypto, chunk_empty);
+               success = parse(this, chunk_empty);
                this->encrypted = FALSE;
                return success;
        }
@@ -471,13 +476,12 @@ static bool parse(private_simaka_message_t *this, simaka_crypto_t *crypto,
 /**
  * Implementation of simaka_message_t.verify
  */
-static bool verify(private_simaka_message_t *this,
-                                  simaka_crypto_t *crypto, chunk_t sigdata)
+static bool verify(private_simaka_message_t *this, chunk_t sigdata)
 {
        chunk_t data, backup;
        signer_t *signer;
 
-       signer = crypto->get_signer(crypto);
+       signer = this->crypto->get_signer(this->crypto);
 
        switch (this->hdr->subtype)
        {
@@ -545,8 +549,7 @@ static bool verify(private_simaka_message_t *this,
 /**
  * Implementation of simaka_message_t.generate
  */
-static eap_payload_t* generate(private_simaka_message_t *this,
-                                                          simaka_crypto_t *crypto, chunk_t sigdata)
+static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
 {
        /* buffers large enough for messages we generate */
        char out_buf[1024], encr_buf[512];
@@ -691,7 +694,7 @@ static eap_payload_t* generate(private_simaka_message_t *this,
                crypter_t *crypter;
                rng_t *rng;
 
-               crypter = crypto->get_crypter(crypto);
+               crypter = this->crypto->get_crypter(this->crypto);
                encr = chunk_create(encr_buf, sizeof(encr_buf) - encr.len);
                bs = crypter->get_block_size(crypter);
 
@@ -702,7 +705,7 @@ static eap_payload_t* generate(private_simaka_message_t *this,
                memset(out.ptr + 2, 0, 2);
                out = chunk_skip(out, 4);
 
-               rng = crypto->get_rng(crypto);
+               rng = this->crypto->get_rng(this->crypto);
                rng->get_bytes(rng, bs, out.ptr);
 
                iv = chunk_clonea(chunk_create(out.ptr, bs));
@@ -721,7 +724,7 @@ static eap_payload_t* generate(private_simaka_message_t *this,
        }
 
        /* include MAC ? */
-       signer = crypto->get_signer(crypto);
+       signer = this->crypto->get_signer(this->crypto);
        switch (this->hdr->subtype)
        {
                case SIM_CHALLENGE:
@@ -772,7 +775,8 @@ static void destroy(private_simaka_message_t *this)
 /**
  * Generic constructor.
  */
-static simaka_message_t *simaka_message_create_data(chunk_t data)
+static simaka_message_t *simaka_message_create_data(chunk_t data,
+                                                                                                       simaka_crypto_t *crypto)
 {
        private_simaka_message_t *this;
        hdr_t *hdr = (hdr_t*)data.ptr;
@@ -810,6 +814,7 @@ static simaka_message_t *simaka_message_create_data(chunk_t data)
 
        this->attributes = linked_list_create();
        this->encrypted = FALSE;
+       this->crypto = crypto;
        this->p_bit = TRUE;
        this->mac = chunk_empty;
        this->hdr = malloc(data.len);
@@ -821,16 +826,18 @@ static simaka_message_t *simaka_message_create_data(chunk_t data)
 /**
  * See header.
  */
-simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload)
+simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload,
+                                                                                                        simaka_crypto_t *crypto)
 {
-       return simaka_message_create_data(payload->get_data(payload));
+       return simaka_message_create_data(payload->get_data(payload), crypto);
 }
 
 /**
  * See header.
  */
 simaka_message_t *simaka_message_create(bool request, u_int8_t identifier,
-                                                                       eap_type_t type, simaka_subtype_t subtype)
+                                                                       eap_type_t type, simaka_subtype_t subtype,
+                                                                       simaka_crypto_t *crypto)
 {
        hdr_t hdr = {
                .code = request ? EAP_REQUEST : EAP_RESPONSE,
@@ -839,6 +846,7 @@ simaka_message_t *simaka_message_create(bool request, u_int8_t identifier,
                .type = type,
                .subtype = subtype,
        };
-       return simaka_message_create_data(chunk_create((char*)&hdr, sizeof(hdr)));
+       return simaka_message_create_data(chunk_create((char*)&hdr, sizeof(hdr)),
+                                                                         crypto);
 }
 
index 0fd21ad..c31df7f 100644 (file)
@@ -219,7 +219,7 @@ struct simaka_message_t {
         * @param crypto        EAP-SIM/AKA crypto helper
         * @return                      TRUE if message parsed successfully
         */
-       bool (*parse)(simaka_message_t *this, simaka_crypto_t *crypto);
+       bool (*parse)(simaka_message_t *this);
 
        /**
         * Verify the message integrity of a parsed message.
@@ -228,18 +228,15 @@ struct simaka_message_t {
         * @param sigdata       additional data to include in signature, if any
         * @return                      TRUE if message integrity check successful
         */
-       bool (*verify)(simaka_message_t *this, simaka_crypto_t *crypto,
-                                  chunk_t sigdata);
+       bool (*verify)(simaka_message_t *this, chunk_t sigdata);
 
        /**
         * Generate a message, optionally encrypt attributes and create a MAC.
         *
-        * @param crypto        EAP-SIM/AKA crypto helper
         * @param sigdata       additional data to include in signature, if any
         * @return                      generated eap payload, NULL if failed
         */
-       eap_payload_t* (*generate)(simaka_message_t *this, simaka_crypto_t *crypto,
-                                                          chunk_t sigdata);
+       eap_payload_t* (*generate)(simaka_message_t *this, chunk_t sigdata);
 
        /**
         * Destroy a simaka_message_t.
@@ -254,17 +251,21 @@ struct simaka_message_t {
  * @param identifier   EAP message identifier
  * @param type                 EAP type: EAP-SIM or EAP-AKA
  * @param subtype              subtype of the EAP message
+ * @param crypto               EAP-SIM/AKA crypto helper
  * @return                             empty message of requested kind, NULL on error
  */
 simaka_message_t *simaka_message_create(bool request, u_int8_t identifier,
-                                                               eap_type_t type, simaka_subtype_t subtype);
+                                                                       eap_type_t type, simaka_subtype_t subtype,
+                                                                       simaka_crypto_t *crypto);
 
 /**
  * Create an simaka_message from a chunk of data.
  *
  * @param payload              payload to create message from
+ * @param crypto               EAP-SIM/AKA crypto helper
  * @return                             EAP message, NULL on error
  */
-simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload);
+simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload,
+                                                                                                        simaka_crypto_t *crypto);
 
 #endif /** SIMAKA_MESSAGE_H_ @}*/