]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
charon-tkm: Reset stale nonce contexts
authorReto Buerki <reet@codelabs.ch>
Thu, 23 Apr 2015 07:41:12 +0000 (09:41 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 4 May 2015 16:07:51 +0000 (18:07 +0200)
If the nonce generator detects a stale nonce upon destroy(), it resets
the context in the TKM and releases associated resources in the ID
manager and chunk map.

Also, do not acquire the nonce context ID in tkm_nonceg_create function
but rather when the nonce is actually created by get_nonce().

The nonces created with get_nonce must also be registered in the chunk map.

src/charon-tkm/src/tkm/tkm_nonceg.c
src/charon-tkm/tests/keymat_tests.c

index 89baab7ce1e91131a49664eaf0457a6b0f5b3b10..336f16ecd5fe04ff0183a83d1144d01e8c6ddfc3 100644 (file)
@@ -33,23 +33,32 @@ struct private_tkm_nonceg_t {
        tkm_nonceg_t public;
 
        /**
-        * Context id.
+        * Nonce chunk.
         */
-       nc_id_type context_id;
-
+       chunk_t nonce;
 };
 
 METHOD(nonce_gen_t, get_nonce, bool,
        private_tkm_nonceg_t *this, size_t size, u_int8_t *buffer)
 {
        nonce_type nonce;
+       uint64_t nc_id;
 
-       if (ike_nc_create(this->context_id, size, &nonce) != TKM_OK)
+       nc_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_NONCE);
+       if (!nc_id)
        {
                return FALSE;
        }
 
+       if (ike_nc_create(nc_id, size, &nonce) != TKM_OK)
+       {
+               tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nc_id);
+               return FALSE;
+       }
+
        memcpy(buffer, &nonce.data, size);
+       this->nonce = chunk_clone(chunk_create(buffer, size));
+       tkm->chunk_map->insert(tkm->chunk_map, &this->nonce, nc_id);
        return TRUE;
 }
 
@@ -57,17 +66,27 @@ METHOD(nonce_gen_t, allocate_nonce, bool,
        private_tkm_nonceg_t *this, size_t size, chunk_t *chunk)
 {
        *chunk = chunk_alloc(size);
-       if (get_nonce(this, chunk->len, chunk->ptr))
-       {
-               tkm->chunk_map->insert(tkm->chunk_map, chunk, this->context_id);
-               return TRUE;
-       }
-       return FALSE;
+       return get_nonce(this, chunk->len, chunk->ptr);
 }
 
 METHOD(nonce_gen_t, destroy, void,
        private_tkm_nonceg_t *this)
 {
+       uint64_t nc_id;
+
+       nc_id = tkm->chunk_map->get_id(tkm->chunk_map, &this->nonce);
+       if (nc_id)
+       {
+               DBG1(DBG_IKE, "resetting stale nonce context %llu", nc_id);
+
+               if (ike_nc_reset(nc_id) != TKM_OK)
+               {
+                       DBG1(DBG_IKE, "failed to reset nonce context %llu", nc_id);
+               }
+               tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nc_id);
+               tkm->chunk_map->remove(tkm->chunk_map, &this->nonce);
+       }
+       chunk_free(&this->nonce);
        free(this);
 }
 
@@ -86,14 +105,7 @@ tkm_nonceg_t *tkm_nonceg_create()
                                .destroy = _destroy,
                        },
                },
-               .context_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_NONCE),
        );
 
-       if (!this->context_id)
-       {
-               free(this);
-               return NULL;
-       }
-
        return &this->public;
 }
index 889965a78415a97ad78b2ee35869646ebf678101..d087bee3f69439d7a70c70e13ed1ae2fbf43be65 100644 (file)
@@ -46,7 +46,6 @@ START_TEST(test_derive_ike_keys)
        fail_if(!ng, "Unable to create nonce generator");
        fail_unless(ng->nonce_gen.allocate_nonce(&ng->nonce_gen, 32, &nonce),
                        "Unable to allocate nonce");
-       ng->nonce_gen.destroy(&ng->nonce_gen);
 
        tkm_diffie_hellman_t *dh = tkm_diffie_hellman_create(MODP_4096_BIT);
        fail_if(!dh, "Unable to create DH");
@@ -69,6 +68,7 @@ START_TEST(test_derive_ike_keys)
        fail_if(aead->get_block_size(aead) != 16, "Block size mismatch %d",
                        aead->get_block_size(aead));
 
+       ng->nonce_gen.destroy(&ng->nonce_gen);
        proposal->destroy(proposal);
        dh->dh.destroy(&dh->dh);
        ike_sa_id->destroy(ike_sa_id);