added support for EAP methods not establishing an MSK
authorMartin Willi <martin@strongswan.org>
Thu, 19 Apr 2007 12:37:48 +0000 (12:37 -0000)
committerMartin Willi <martin@strongswan.org>
Thu, 19 Apr 2007 12:37:48 +0000 (12:37 -0000)
src/charon/sa/authenticators/eap_authenticator.c
src/charon/sa/authenticators/psk_authenticator.c
src/charon/sa/authenticators/rsa_authenticator.c
src/charon/sa/ike_sa.c
src/charon/sa/ike_sa.h

index 08edd80..6e2f73a 100644 (file)
@@ -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:
index 1831b2d..37465d0 100644 (file)
@@ -77,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;
@@ -121,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);
        
@@ -164,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);
index 42d861e..19aad06 100644 (file)
@@ -62,6 +62,7 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
        chunk_t auth_data, octets;
        rsa_public_key_t *public_key;
        identification_t *other_id;
+       prf_t *prf;
        
        other_id = this->ike_sa->get_other_id(this->ike_sa);
        
@@ -77,8 +78,9 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
                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));
+       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 = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data);
        chunk_free(&octets);
        
@@ -106,6 +108,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",
@@ -130,8 +133,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);
 
index 3b23ff6..858cef3 100644 (file)
@@ -176,14 +176,14 @@ struct private_ike_sa_t {
        prf_t *child_prf;
        
        /**
-        * PRF to build outging authentication data
+        * Key to build outging authentication data (SKp)
         */
-       prf_t *auth_build;
+       chunk_t skp_build;
 
        /**
-        * PRF to verify incoming authentication data
+        * Key to verify incoming authentication data (SKp)
         */
-       prf_t *auth_verify;
+       chunk_t skp_verify;
        
        /**
         * NAT status of local host.
@@ -1112,19 +1112,19 @@ static prf_t *get_child_prf(private_ike_sa_t *this)
 }
 
 /**
- * Implementation of ike_sa_t.get_auth_bild
+ * Implementation of ike_sa_t.get_skp_bild
  */
-static prf_t *get_auth_build(private_ike_sa_t *this)
+static chunk_t get_skp_build(private_ike_sa_t *this)
 {
-       return this->auth_build;
+       return this->skp_build;
 }
 
 /**
- * Implementation of ike_sa_t.get_auth_verify
+ * Implementation of ike_sa_t.get_skp_verify
  */
-static prf_t *get_auth_verify(private_ike_sa_t *this)
+static chunk_t get_skp_verify(private_ike_sa_t *this)
 {
-       return this->auth_verify;
+       return this->skp_verify;
 }
 
 /**
@@ -1232,7 +1232,6 @@ static status_t derive_keys(private_ike_sa_t *this,
        size_t key_size;
        crypter_t *crypter_i, *crypter_r;
        signer_t *signer_i, *signer_r;
-       prf_t *prf_i, *prf_r;
        u_int8_t spi_i_buf[sizeof(u_int64_t)], spi_r_buf[sizeof(u_int64_t)];
        chunk_t spi_i = chunk_from_buf(spi_i_buf);
        chunk_t spi_r = chunk_from_buf(spi_r_buf);
@@ -1373,31 +1372,27 @@ static status_t derive_keys(private_ike_sa_t *this,
                this->crypter_out = crypter_r;
        }
        
-       /* SK_pi/SK_pr used for authentication => prf_auth_i, prf_auth_r */     
-       proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo);
-       prf_i = prf_create(algo->algorithm);
-       prf_r = prf_create(algo->algorithm);
-       
-       key_size = prf_i->get_key_size(prf_i);
+       /* SK_pi/SK_pr used for authentication => stored for later */   
+       key_size = this->prf->get_key_size(this->prf);
        prf_plus->allocate_bytes(prf_plus, key_size, &key);
        DBG4(DBG_IKE, "Sk_pi secret %B", &key);
-       prf_i->set_key(prf_i, key);
-       chunk_free(&key);
-       
+       if (initiator)
+       {
+               this->skp_build = key;
+       }
+       else
+       {
+               this->skp_verify = key;
+       }
        prf_plus->allocate_bytes(prf_plus, key_size, &key);
        DBG4(DBG_IKE, "Sk_pr secret %B", &key);
-       prf_r->set_key(prf_r, key);
-       chunk_free(&key);
-       
        if (initiator)
        {
-               this->auth_verify = prf_r;
-               this->auth_build = prf_i;
+               this->skp_verify = key;
        }
        else
        {
-               this->auth_verify = prf_i;
-               this->auth_build = prf_r;
+               this->skp_build = key;
        }
        
        /* all done, prf_plus not needed anymore */
@@ -1837,8 +1832,8 @@ static void destroy(private_ike_sa_t *this)
        DESTROY_IF(this->signer_out);
        DESTROY_IF(this->prf);
        DESTROY_IF(this->child_prf);
-       DESTROY_IF(this->auth_verify);
-       DESTROY_IF(this->auth_build);
+       chunk_free(&this->skp_verify);
+       chunk_free(&this->skp_build);
        
        if (this->my_virtual_ip)
        {
@@ -1902,8 +1897,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->public.send_keepalive = (void (*)(ike_sa_t*)) send_keepalive;
        this->public.get_prf = (prf_t *(*) (ike_sa_t *)) get_prf;
        this->public.get_child_prf = (prf_t *(*) (ike_sa_t *)) get_child_prf;
-       this->public.get_auth_verify = (prf_t *(*) (ike_sa_t *)) get_auth_verify;
-       this->public.get_auth_build = (prf_t *(*) (ike_sa_t *)) get_auth_build;
+       this->public.get_skp_verify = (chunk_t(*) (ike_sa_t *)) get_skp_verify;
+       this->public.get_skp_build = (chunk_t(*) (ike_sa_t *)) get_skp_build;
        this->public.derive_keys = (status_t (*) (ike_sa_t *,proposal_t*,chunk_t,chunk_t,chunk_t,bool,prf_t*,prf_t*)) derive_keys;
        this->public.add_child_sa = (void (*) (ike_sa_t*,child_sa_t*)) add_child_sa;
        this->public.get_child_sa = (child_sa_t* (*)(ike_sa_t*,protocol_id_t,u_int32_t,bool)) get_child_sa;
@@ -1935,8 +1930,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->signer_in = NULL;
        this->signer_out = NULL;
        this->prf = NULL;
-       this->auth_verify = NULL;
-       this->auth_build = NULL;
+       this->skp_verify = chunk_empty;
+       this->skp_build = chunk_empty;
        this->child_prf = NULL;
        this->nat_here = FALSE;
        this->nat_there = FALSE;
index c26457e..0f977c7 100644 (file)
@@ -486,7 +486,7 @@ struct ike_sa_t {
                                                        bool initiator, prf_t *child_prf, prf_t *old_prf);
        
        /**
-        * @brief Get the multi purpose prf.
+        * @brief Get a multi purpose prf for the negotiated PRF function.
         * 
         * @param this                  calling object
         * @return                              pointer to prf_t object
@@ -502,20 +502,20 @@ struct ike_sa_t {
        prf_t *(*get_child_prf) (ike_sa_t *this);
        
        /**
-        * @brief Get the prf to build outgoing authentication data.
+        * @brief Get the key to build outgoing authentication data.
         * 
         * @param this                  calling object
         * @return                              pointer to prf_t object
         */
-       prf_t *(*get_auth_build) (ike_sa_t *this);
+       chunk_t (*get_skp_build) (ike_sa_t *this);
        
        /**
-        * @brief Get the prf to verify incoming authentication data.
+        * @brief Get the key to verify incoming authentication data.
         * 
         * @param this                  calling object
         * @return                              pointer to prf_t object
         */
-       prf_t *(*get_auth_verify) (ike_sa_t *this);
+       chunk_t (*get_skp_verify) (ike_sa_t *this);
        
        /**
         * @brief Associates a child SA to this IKE SA