ike-sa-manager: Extract IKE SPI labeling feature from charon-tkm

Might be useful for users of other daemons too. Note that compared to the
previous implementation in charon-tkm, the mask/label are applied in
network order.

Closes strongswan/strongswan#134.
This commit is contained in:
Tobias Brunner
2019-04-11 09:51:02 +02:00
parent f5ad3cf491
commit 62d43ea694
5 changed files with 37 additions and 138 deletions
+7
View File
@@ -370,6 +370,13 @@ charon.signature_authentication_constraints = yes
certificate chain, are also used as constraints against the signature scheme certificate chain, are also used as constraints against the signature scheme
used by peers during IKEv2. used by peers during IKEv2.
charon.spi_label = 0x0000000000000000
Value mixed into the local IKE SPIs after applying _spi_mask_.
charon.spi_mask = 0x0000000000000000
Mask applied to local IKE SPIs before mixing in _spi_label_ (bits set will
be replaced with _spi_label_).
charon.spi_min = 0xc0000000 charon.spi_min = 0xc0000000
The lower limit for SPIs requested from the kernel for IPsec SAs. The lower limit for SPIs requested from the kernel for IPsec SAs.
-4
View File
@@ -43,7 +43,6 @@
#include "tkm_public_key.h" #include "tkm_public_key.h"
#include "tkm_cred.h" #include "tkm_cred.h"
#include "tkm_encoder.h" #include "tkm_encoder.h"
#include "tkm_spi_generator.h"
/** /**
* TKM bus listener for IKE authorize events. * TKM bus listener for IKE authorize events.
@@ -316,9 +315,6 @@ int main(int argc, char *argv[])
PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256), PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256),
PLUGIN_CALLBACK(kernel_ipsec_register, tkm_kernel_ipsec_create), PLUGIN_CALLBACK(kernel_ipsec_register, tkm_kernel_ipsec_create),
PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"), PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
PLUGIN_CALLBACK(tkm_spi_generator_register, NULL),
PLUGIN_PROVIDE(CUSTOM, "tkm-spi-generator"),
PLUGIN_DEPENDS(CUSTOM, "libcharon-sa-managers"),
}; };
lib->plugins->add_static_features(lib->plugins, "tkm-backend", features, lib->plugins->add_static_features(lib->plugins, "tkm-backend", features,
countof(features), TRUE, NULL, NULL); countof(features), TRUE, NULL, NULL);
@@ -1,98 +0,0 @@
/*
* Copyright (C) 2015 Reto Buerki
* Copyright (C) 2015 Adrian-Ken Rueegsegger
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <inttypes.h>
#include <library.h>
#include <daemon.h>
#include "tkm_spi_generator.h"
/**
* Get SPI callback arguments
*/
typedef struct {
rng_t *rng;
uint64_t spi_mask;
uint64_t spi_label;
} get_spi_args_t;
static get_spi_args_t *spi_args;
/**
* Callback called to generate an IKE SPI.
*
* @param this Callback args containing rng_t and spi mask & label
* @return labeled SPI
*/
CALLBACK(tkm_get_spi, uint64_t,
const get_spi_args_t const *this)
{
uint64_t spi;
if (!this->rng->get_bytes(this->rng, sizeof(spi), (uint8_t*)&spi))
{
return 0;
}
return (spi & ~this->spi_mask) | this->spi_label;
}
bool tkm_spi_generator_register(plugin_t *plugin,
plugin_feature_t *feature,
bool reg, void *cb_data)
{
uint64_t spi_mask, spi_label;
char *spi_val;
rng_t *rng;
if (reg)
{
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
if (!rng)
{
return FALSE;
}
spi_val = lib->settings->get_str(lib->settings, "%s.spi_mask", NULL,
lib->ns);
spi_mask = settings_value_as_uint64(spi_val, 0);
spi_val = lib->settings->get_str(lib->settings, "%s.spi_label", NULL,
lib->ns);
spi_label = settings_value_as_uint64(spi_val, 0);
INIT(spi_args,
.rng = rng,
.spi_mask = spi_mask,
.spi_label = spi_label,
);
charon->ike_sa_manager->set_spi_cb(charon->ike_sa_manager,
tkm_get_spi, spi_args);
DBG1(DBG_IKE, "using SPI label 0x%.16"PRIx64" and mask 0x%.16"PRIx64,
spi_label, spi_mask);
}
else
{
if (spi_args)
{
DESTROY_IF(spi_args->rng);
free(spi_args);
}
}
return TRUE;
}
@@ -1,36 +0,0 @@
/*
* Copyright (C) 2015 Reto Buerki
* Copyright (C) 2015 Adrian-Ken Rueegsegger
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup tkm-spi-generator spi generator
* @{ @ingroup tkm
*/
#ifndef TKM_SPI_GENERATOR_H_
#define TKM_SPI_GENERATOR_H_
#include <plugins/plugin.h>
/**
* Register the TKM SPI generator callback.
*
* @return TRUE on success
*/
bool tkm_spi_generator_register(plugin_t *plugin,
plugin_feature_t *feature,
bool reg, void *cb_data);
#endif /** TKM_SPI_GENERATOR_H_ @}*/
+30
View File
@@ -413,6 +413,16 @@ struct private_ike_sa_manager_t {
*/ */
rwlock_t *spi_lock; rwlock_t *spi_lock;
/**
* Mask applied to local SPIs before mixing in the label
*/
uint64_t spi_mask;
/**
* Label applied to local SPIs
*/
uint64_t spi_label;
/** /**
* reuse existing IKE_SAs in checkout_by_config * reuse existing IKE_SAs in checkout_by_config
*/ */
@@ -1010,6 +1020,11 @@ static uint64_t get_spi(private_ike_sa_manager_t *this)
spi = 0; spi = 0;
} }
this->spi_lock->unlock(this->spi_lock); this->spi_lock->unlock(this->spi_lock);
if (spi)
{
spi = (spi & ~this->spi_mask) | this->spi_label;
}
return spi; return spi;
} }
@@ -2339,6 +2354,7 @@ static u_int get_nearest_powerof2(u_int n)
ike_sa_manager_t *ike_sa_manager_create() ike_sa_manager_t *ike_sa_manager_create()
{ {
private_ike_sa_manager_t *this; private_ike_sa_manager_t *this;
char *spi_val;
u_int i; u_int i;
INIT(this, INIT(this,
@@ -2372,6 +2388,20 @@ ike_sa_manager_t *ike_sa_manager_create()
return NULL; return NULL;
} }
this->spi_lock = rwlock_create(RWLOCK_TYPE_DEFAULT); this->spi_lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
spi_val = lib->settings->get_str(lib->settings, "%s.spi_mask", NULL,
lib->ns);
this->spi_mask = settings_value_as_uint64(spi_val, 0);
spi_val = lib->settings->get_str(lib->settings, "%s.spi_label", NULL,
lib->ns);
this->spi_label = settings_value_as_uint64(spi_val, 0);
if (this->spi_mask || this->spi_label)
{
DBG1(DBG_IKE, "using SPI label 0x%.16"PRIx64" and mask 0x%.16"PRIx64,
this->spi_label, this->spi_mask);
/* the allocated SPI is assumed to be in network order */
this->spi_mask = htobe64(this->spi_mask);
this->spi_label = htobe64(this->spi_label);
}
this->ikesa_limit = lib->settings->get_int(lib->settings, this->ikesa_limit = lib->settings->get_int(lib->settings,
"%s.ikesa_limit", 0, lib->ns); "%s.ikesa_limit", 0, lib->ns);