0
0
mirror of https://github.com/OpenVPN/openvpn.git synced 2024-09-20 03:52:28 +02:00

Refactor tls-auth/tls-crypt wrapping into into own function

This allows the the wrapping to be easier reused by a function that
does not have access to a full TLS session.
Acked-by: Frank Lichtenheld <frank@lichtenheld.com>
Message-Id: <20220422142953.3805364-2-arne@rfc2549.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24150.html

Signed-off-by: Gert Doering <gert@greenie.muc.de>
This commit is contained in:
Arne Schwabe 2022-04-22 16:29:36 +02:00 committed by Gert Doering
parent 33abca0415
commit 9bbebf100a

View File

@ -110,6 +110,61 @@ swap_hmac(struct buffer *buf, const struct crypto_options *co, bool incoming)
#undef SWAP_BUF_SIZE
/**
* Wraps a TLS control packet by adding tls-auth HMAC or tls-crypt(-v2)
* encryption and opcode header including session id.
*
* @param ctx tls wrapping context
* @param header first byte of the packet (opcode and key id)
* @param buf buffer to write the resulting packet to
* @param session_id session id to use as our session id
*/
static void
tls_wrap_control(struct tls_wrap_ctx *ctx, uint8_t header, struct buffer *buf,
struct session_id *session_id)
{
if (ctx->mode == TLS_WRAP_AUTH
|| ctx->mode == TLS_WRAP_NONE)
{
ASSERT(session_id_write_prepend(session_id, buf));
ASSERT(buf_write_prepend(buf, &header, sizeof(header)));
}
if (ctx->mode == TLS_WRAP_AUTH)
{
struct buffer null = clear_buf();
/* no encryption, only write hmac */
openvpn_encrypt(buf, null, &ctx->opt);
ASSERT(swap_hmac(buf, &ctx->opt, false));
}
else if (ctx->mode == TLS_WRAP_CRYPT)
{
ASSERT(buf_init(&ctx->work, buf->offset));
ASSERT(buf_write(&ctx->work, &header, sizeof(header)));
ASSERT(session_id_write(session_id, &ctx->work));
if (!tls_crypt_wrap(buf, &ctx->work, &ctx->opt))
{
buf->len = 0;
return;
}
if ((header >> P_OPCODE_SHIFT) == P_CONTROL_HARD_RESET_CLIENT_V3)
{
if (!buf_copy(&ctx->work,
ctx->tls_crypt_v2_wkc))
{
msg(D_TLS_ERRORS, "Could not append tls-crypt-v2 client key");
buf->len = 0;
return;
}
}
/* Don't change the original data in buf, it's used by the reliability
* layer to resend on failure. */
*buf = ctx->work;
}
}
void
write_control_auth(struct tls_session *session,
struct key_state *ks,
@ -120,7 +175,6 @@ write_control_auth(struct tls_session *session,
bool prepend_ack)
{
uint8_t header = ks->key_id | (opcode << P_OPCODE_SHIFT);
struct buffer null = clear_buf();
ASSERT(link_socket_actual_defined(&ks->remote_addr));
ASSERT(reliable_ack_write
@ -128,44 +182,8 @@ write_control_auth(struct tls_session *session,
msg(D_TLS_DEBUG, "%s(): %s", __func__, packet_opcode_name(opcode));
if (session->tls_wrap.mode == TLS_WRAP_AUTH
|| session->tls_wrap.mode == TLS_WRAP_NONE)
{
ASSERT(session_id_write_prepend(&session->session_id, buf));
ASSERT(buf_write_prepend(buf, &header, sizeof(header)));
}
if (session->tls_wrap.mode == TLS_WRAP_AUTH)
{
/* no encryption, only write hmac */
openvpn_encrypt(buf, null, &session->tls_wrap.opt);
ASSERT(swap_hmac(buf, &session->tls_wrap.opt, false));
}
else if (session->tls_wrap.mode == TLS_WRAP_CRYPT)
{
ASSERT(buf_init(&session->tls_wrap.work, buf->offset));
ASSERT(buf_write(&session->tls_wrap.work, &header, sizeof(header)));
ASSERT(session_id_write(&session->session_id, &session->tls_wrap.work));
if (!tls_crypt_wrap(buf, &session->tls_wrap.work, &session->tls_wrap.opt))
{
buf->len = 0;
return;
}
tls_wrap_control(&session->tls_wrap, header, buf, &session->session_id);
if (opcode == P_CONTROL_HARD_RESET_CLIENT_V3)
{
if (!buf_copy(&session->tls_wrap.work,
session->tls_wrap.tls_crypt_v2_wkc))
{
msg(D_TLS_ERRORS, "Could not append tls-crypt-v2 client key");
buf->len = 0;
return;
}
}
/* Don't change the original data in buf, it's used by the reliability
* layer to resend on failure. */
*buf = session->tls_wrap.work;
}
*to_link_addr = &ks->remote_addr;
}