Commit e8c4187652 for strongswan.org
commit e8c4187652dda54c86fb8d86a57396b71713bb28
Author: Tobias Brunner <tobias@strongswan.org>
Date: Fri Aug 28 11:26:13 2026 +0200
charon-tkm: Use mapped signature scheme and pass AUTH payload without algorithm identifier
This makes the authentication creation and verification symmetric. Before,
it was necessary to parse/skip the identifier when verifying while already
none had to be added when creating a signature.
The changes also fix issues with potentially multiple calls to `sign()`
by storing the IKE_SA_INIT message directly in the misused auth octets.
So it doesn't have to be freed by `sign()` but is done automatically by
the caller.
diff --git a/src/charon-tkm/src/tkm/tkm_keymat.c b/src/charon-tkm/src/tkm/tkm_keymat.c
index 094007c73a..11bc62e97d 100644
--- a/src/charon-tkm/src/tkm/tkm_keymat.c
+++ b/src/charon-tkm/src/tkm/tkm_keymat.c
@@ -66,6 +66,11 @@ struct private_tkm_keymat_t {
*/
ae_id_type ae_ctx_id;
+ /**
+ * Authentication method from AUTH payload.
+ */
+ auth_method_t auth_method;
+
/**
* AUTH payload chunk.
*/
@@ -403,16 +408,15 @@ METHOD(keymat_v2_t, get_auth_octets, bool,
return TRUE;
}
- INIT(sign,
+ /* add IKE_SA_INIT at the end of the struct so it gets freed with it */
+ INIT_EXTRA(sign, ike_sa_init.len,
.isa_id = this->isa_ctx_id,
- .init_message = chunk_clone(ike_sa_init),
);
+ memcpy(sign->init_message_data, ike_sa_init.ptr, ike_sa_init.len);
- /*
- * store signature info in AUTH octets, which is passed to the private key
- * sign() operation
- */
- *octets = chunk_create((u_char *)sign, sizeof(sign_info_t));
+ /* store signature info in AUTH octets, which is passed to the private key
+ * sign() operation */
+ *octets = chunk_create((u_char*)sign, sizeof(sign_info_t) + ike_sa_init.len);
return TRUE;
}
@@ -498,15 +502,21 @@ METHOD(tkm_keymat_t, get_isa_id, isa_id_type,
}
METHOD(tkm_keymat_t, set_auth_payload, void,
- private_tkm_keymat_t *this, const chunk_t * const payload)
+ private_tkm_keymat_t *this, const auth_method_t method,
+ const chunk_t * const payload)
{
+ this->auth_method = method;
this->auth_payload = chunk_clone(*payload);
}
-METHOD(tkm_keymat_t, get_auth_payload, chunk_t*,
- private_tkm_keymat_t *this)
+METHOD(tkm_keymat_t, get_auth_payload, chunk_t,
+ private_tkm_keymat_t *this, auth_method_t *method)
{
- return &this->auth_payload;
+ if (method)
+ {
+ *method = this->auth_method;
+ }
+ return this->auth_payload;
}
METHOD(tkm_keymat_t, get_peer_init_msg, chunk_t*,
diff --git a/src/charon-tkm/src/tkm/tkm_keymat.h b/src/charon-tkm/src/tkm/tkm_keymat.h
index c9f787c0f5..6ca9035862 100644
--- a/src/charon-tkm/src/tkm/tkm_keymat.h
+++ b/src/charon-tkm/src/tkm/tkm_keymat.h
@@ -24,6 +24,7 @@
#ifndef TKM_KEYMAT_H_
#define TKM_KEYMAT_H_
+#include <sa/authenticator.h>
#include <sa/ikev2/keymat_v2.h>
typedef struct tkm_keymat_t tkm_keymat_t;
@@ -46,18 +47,22 @@ struct tkm_keymat_t {
isa_id_type (*get_isa_id)(tkm_keymat_t * const this);
/**
- * Set IKE AUTH payload.
+ * Set IKE AUTH payload method and data.
*
+ * @param method authentication method
* @param payload AUTH payload
*/
- void (*set_auth_payload)(tkm_keymat_t *this, const chunk_t * const payload);
+ void (*set_auth_payload)(tkm_keymat_t *this, const auth_method_t method,
+ const chunk_t * const payload);
/**
* Get IKE AUTH payload.
*
+ * @param[out] method authentication method
* @return AUTH payload if set, chunk_empty otherwise
*/
- chunk_t* (*get_auth_payload)(tkm_keymat_t * const this);
+ chunk_t (*get_auth_payload)(tkm_keymat_t * const this,
+ auth_method_t *method);
/**
* Get IKE init message of peer.
diff --git a/src/charon-tkm/src/tkm/tkm_listener.c b/src/charon-tkm/src/tkm/tkm_listener.c
index 7e4a0ecf0d..55989d508b 100644
--- a/src/charon-tkm/src/tkm/tkm_listener.c
+++ b/src/charon-tkm/src/tkm/tkm_listener.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2026 Tobias Brunner
* Copyright (C) 2012 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
*
@@ -22,6 +23,7 @@
#include <collections/array.h>
#include <collections/hashtable.h>
#include <encoding/payloads/auth_payload.h>
+#include <sa/ikev2/authenticators/pubkey_authenticator.h>
#include <utils/chunk.h>
#include <tkm/types.h>
#include <tkm/constants.h>
@@ -281,7 +283,10 @@ METHOD(listener_t, authorize, bool,
tkm_keymat_t *keymat;
isa_id_type isa_id;
cc_id_type cc_id;
- chunk_t *auth, *other_init_msg;
+ chunk_t auth, *other_init_msg;
+ auth_method_t method;
+ signature_params_t *params = NULL;
+ siga_id_type siga_id;
signature_type signature;
blob_id_type init_message_id = 0;
@@ -308,13 +313,28 @@ METHOD(listener_t, authorize, bool,
goto cc_reset;
}
- auth = keymat->get_auth_payload(keymat);
- if (!auth->ptr)
+ auth = keymat->get_auth_payload(keymat, &method);
+ if (!auth.ptr)
{
DBG1(DBG_IKE, "no AUTHENTICATION data available");
goto cc_reset;
}
+ params = pubkey_authenticator_parse_auth_data(method, NULL, &auth);
+ if (!params)
+ {
+ DBG1(DBG_IKE, "authentication method not supported or payload invalid");
+ goto cc_reset;
+ }
+
+ siga_id = siga_from_signature_scheme(params->scheme);
+ if (!siga_id)
+ {
+ DBG1(DBG_IKE, "unable to map signature scheme %N to SigA context id",
+ signature_scheme_names, params->scheme);
+ goto cc_reset;
+ }
+
other_init_msg = keymat->get_peer_init_msg(keymat);
if (!other_init_msg->ptr)
{
@@ -335,8 +355,9 @@ METHOD(listener_t, authorize, bool,
goto cc_reset;
}
- chunk_to_sequence(auth, &signature, sizeof(signature_type));
- if (ike_isa_auth(isa_id, cc_id, init_message_id, 1, signature) != TKM_OK)
+ chunk_to_sequence(&auth, &signature, sizeof(signature_type));
+ if (ike_isa_auth(isa_id, cc_id, init_message_id, siga_id,
+ signature) != TKM_OK)
{
DBG1(DBG_IKE, "TKM based authentication failed"
" for ISA context %llu", isa_id);
@@ -359,6 +380,7 @@ cc_reset:
{
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_BLOB, init_message_id);
}
+ signature_params_destroy(params);
return TRUE; /* stay registered */
}
@@ -384,10 +406,12 @@ METHOD(listener_t, message, bool,
PLV2_AUTH);
if (auth_payload)
{
+ auth_method_t method;
chunk_t auth_data;
+ method = auth_payload->get_auth_method(auth_payload);
auth_data = auth_payload->get_data(auth_payload);
- keymat->set_auth_payload(keymat, &auth_data);
+ keymat->set_auth_payload(keymat, method, &auth_data);
}
else
{
diff --git a/src/charon-tkm/src/tkm/tkm_private_key.c b/src/charon-tkm/src/tkm/tkm_private_key.c
index 78adc38ad3..11c61756d2 100644
--- a/src/charon-tkm/src/tkm/tkm_private_key.c
+++ b/src/charon-tkm/src/tkm/tkm_private_key.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2026 Tobias Brunner
* Copyright (C) 2012-2013 Reto Buerki
* Copyright (C) 2012-2013 Adrian-Ken Rueegsegger
*
@@ -23,6 +24,7 @@
#include "tkm.h"
#include "tkm_utils.h"
#include "tkm_types.h"
+#include "tkm_keymat.h"
#include "tkm_private_key.h"
typedef struct private_tkm_private_key_t private_tkm_private_key_t;
@@ -66,8 +68,9 @@ METHOD(private_key_t, sign, bool,
{
signature_type sig;
blob_id_type msg_id;
- sign_info_t sign;
- isa_id_type isa_id;
+ sign_info_t *sign;
+ siga_id_type siga_id;
+ chunk_t init;
bool success = FALSE;
if (data.ptr == NULL)
@@ -75,19 +78,26 @@ METHOD(private_key_t, sign, bool,
DBG1(DBG_LIB, "unable to get signature information");
return FALSE;
}
- sign = *(sign_info_t*)(data.ptr);
+ sign = (sign_info_t*)data.ptr;
+ init = chunk_skip(data, sizeof(sign_info_t));
+
+ siga_id = siga_from_signature_scheme(scheme);
+ if (!siga_id)
+ {
+ DBG1(DBG_LIB, "unable to map signature scheme %N to SigA context id",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
msg_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_BLOB);
if (!msg_id)
{
DBG1(DBG_LIB, "unable to acquire blob context id for init message");
- chunk_free(&sign.init_message);
return FALSE;
}
- isa_id = sign.isa_id;
- if (chunk_to_blob(msg_id, &sign.init_message) &&
- ike_isa_sign(isa_id, 1, msg_id, 1, &sig) == TKM_OK)
+ if (chunk_to_blob(msg_id, &init) &&
+ ike_isa_sign(sign->isa_id, 1, msg_id, siga_id, &sig) == TKM_OK)
{
sequence_to_chunk(sig.data, sig.size, signature);
success = TRUE;
@@ -98,7 +108,6 @@ METHOD(private_key_t, sign, bool,
}
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_BLOB, msg_id);
- chunk_free(&sign.init_message);
return success;
}
diff --git a/src/charon-tkm/src/tkm/tkm_types.h b/src/charon-tkm/src/tkm/tkm_types.h
index bca533cb25..b319a5a8fb 100644
--- a/src/charon-tkm/src/tkm/tkm_types.h
+++ b/src/charon-tkm/src/tkm/tkm_types.h
@@ -125,10 +125,9 @@ struct sign_info_t {
isa_id_type isa_id;
/**
- * Init message.
+ * Actual init message data.
*/
- chunk_t init_message;
-
+ u_char init_message_data[];
};
#endif /** TKM_TYPES_H_ @}*/