import OL

This commit is contained in:
eabdullin 2025-03-19 14:44:46 +03:00
parent 01b7ed9420
commit 60c36bc858
11 changed files with 916 additions and 352 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
SOURCES/ikev1_dsa.fax.bz2
SOURCES/ikev1_psk.fax.bz2
SOURCES/ikev2.fax.bz2
SOURCES/libreswan-4.12.tar.gz
SOURCES/libreswan-4.15.tar.gz

View File

@ -1,4 +1,4 @@
b35cd50b8bc0a08b9c07713bf19c72d53bfe66bb SOURCES/ikev1_dsa.fax.bz2
861d97bf488f9e296cad8c43ab72f111a5b1a848 SOURCES/ikev1_psk.fax.bz2
fcaf77f3deae3d8e99cdb3b1f8abea63167a0633 SOURCES/ikev2.fax.bz2
786c14a4755311ea3103683a3294e1536b1e44a6 SOURCES/libreswan-4.12.tar.gz
861eaeefff1c2f3862a8bfe0295b3e307f8e3055 SOURCES/libreswan-4.15.tar.gz

View File

@ -1,92 +0,0 @@
From 5101913b1e623121a9222f11eefa18f0a2708b00 Mon Sep 17 00:00:00 2001
From: Andrew Cagney <cagney@gnu.org>
Date: Wed, 27 Mar 2024 10:43:19 -0400
Subject: [PATCH] ikev1: in compute_proto_keymat() only allow explicitly
handled ESP algorithms
---
programs/pluto/ikev1_quick.c | 41 ++++++++++++++----------------------
1 file changed, 16 insertions(+), 25 deletions(-)
diff --git a/programs/pluto/ikev1_quick.c b/programs/pluto/ikev1_quick.c
index 81c522c148..22c346afb4 100644
--- a/programs/pluto/ikev1_quick.c
+++ b/programs/pluto/ikev1_quick.c
@@ -203,7 +203,7 @@ static bool emit_subnet_id(enum perspective perspective,
* RFC 2409 "IKE" section 5.5
* specifies how this is to be done.
*/
-static void compute_proto_keymat(struct state *st,
+static bool compute_proto_keymat(struct state *st,
uint8_t protoid,
struct ipsec_proto_info *pi,
const char *satypename)
@@ -297,27 +297,13 @@ static void compute_proto_keymat(struct state *st,
}
break;
- case ESP_CAST:
- case ESP_TWOFISH:
- case ESP_SERPENT:
- /* ESP_SEED is for IKEv1 only and not supported. Its number in IKEv2 has been re-used */
- bad_case(pi->attrs.transattrs.ta_ikev1_encrypt);
-
default:
- /* bytes */
- needed_len = encrypt_max_key_bit_length(pi->attrs.transattrs.ta_encrypt) / BITS_PER_BYTE;
- if (needed_len > 0) {
- /* XXX: check key_len coupling with kernel.c's */
- if (pi->attrs.transattrs.enckeylen) {
- needed_len =
- pi->attrs.transattrs.enckeylen
- / BITS_PER_BYTE;
- dbg("compute_proto_keymat: key_len=%d from peer",
- (int)needed_len);
- }
- break;
- }
- bad_case(pi->attrs.transattrs.ta_ikev1_encrypt);
+ {
+ enum_buf eb;
+ llog(RC_LOG, st->st_logger, "rejecting request for keymat for %s",
+ str_enum(&esp_transformid_names, protoid, &eb));
+ return false;
+ }
}
dbg("compute_proto_keymat: needed_len (after ESP enc)=%d", (int)needed_len);
needed_len += pi->attrs.transattrs.ta_integ->integ_keymat_size;
@@ -359,14 +345,17 @@ static void compute_proto_keymat(struct state *st,
DBG_dump_hunk(" inbound:", pi->inbound.keymat);
DBG_dump_hunk(" outbound:", pi->outbound.keymat);
}
+
+ return true;
}
-static void compute_keymats(struct state *st)
+static bool compute_keymats(struct state *st)
{
if (st->st_ah.present)
- compute_proto_keymat(st, PROTO_IPSEC_AH, &st->st_ah, "AH");
+ return compute_proto_keymat(st, PROTO_IPSEC_AH, &st->st_ah, "AH");
if (st->st_esp.present)
- compute_proto_keymat(st, PROTO_IPSEC_ESP, &st->st_esp, "ESP");
+ return compute_proto_keymat(st, PROTO_IPSEC_ESP, &st->st_esp, "ESP");
+ return false;
}
/*
@@ -1460,7 +1449,9 @@ static stf_status quick_inI1_outR1_continue12_tail(struct state *st, struct msg_
fixup_v1_HASH(st, &hash_fixup, st->st_v1_msgid.id, rbody.cur);
/* Derive new keying material */
- compute_keymats(st);
+ if (!compute_keymats(st)) {
+ return STF_FATAL;
+ }
/* Tell the kernel to establish the new inbound SA
* (unless the commit bit is set -- which we don't support).
--
2.45.0

View File

@ -1,54 +0,0 @@
From 2ec448884a7467743699803f8a36ee28d237666c Mon Sep 17 00:00:00 2001
From: Andrew Cagney <cagney@gnu.org>
Date: Wed, 28 Feb 2024 08:29:53 -0500
Subject: [PATCH] ikev2: return STF_FATAL when initiator fails to emit AUTH
packet
---
programs/pluto/ikev2_ike_auth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/pluto/ikev2_ike_auth.c b/programs/pluto/ikev2_ike_auth.c
index 192eb1b3b6..a54a109699 100644
--- a/programs/pluto/ikev2_ike_auth.c
+++ b/programs/pluto/ikev2_ike_auth.c
@@ -1267,7 +1267,7 @@ static stf_status process_v2_IKE_AUTH_request_auth_signature_continue(struct ike
/* now send AUTH payload */
if (!emit_local_v2AUTH(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, response.pbs)) {
- return STF_INTERNAL_ERROR;
+ return STF_FATAL;
}
ike->sa.st_v2_ike_intermediate.used = false;
--
2.44.0
From 16272f2475d25baab58fbed2af7c67cfb459137f Mon Sep 17 00:00:00 2001
From: Andrew Cagney <cagney@gnu.org>
Date: Thu, 29 Feb 2024 12:19:20 -0500
Subject: [PATCH] ikev2: always return STF_FATAL if emitting AUTH fails
Fix:
ikev2: return STF_FATAL when initiator fails to emit AUTH packet
which really fixed the responder.
---
programs/pluto/ikev2_ike_auth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/pluto/ikev2_ike_auth.c b/programs/pluto/ikev2_ike_auth.c
index a54a109699..491053fb10 100644
--- a/programs/pluto/ikev2_ike_auth.c
+++ b/programs/pluto/ikev2_ike_auth.c
@@ -397,7 +397,7 @@ stf_status initiate_v2_IKE_AUTH_request_signature_continue(struct ike_sa *ike,
/* send out the AUTH payload */
if (!emit_local_v2AUTH(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, request.pbs)) {
- return STF_INTERNAL_ERROR;
+ return STF_FATAL;
}
if (LIN(POLICY_MOBIKE, ike->sa.st_connection->policy)) {
--
2.44.0

View File

@ -1,198 +0,0 @@
From 474d75be074799efa9e38f346d3fdb76dec3eead Mon Sep 17 00:00:00 2001
From: Andrew Cagney <cagney@gnu.org>
Date: Tue, 5 Dec 2023 13:55:37 -0500
Subject: [PATCH] x509: unpack IPv6 general names based on length
fix #1321
---
programs/pluto/x509.c | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/programs/pluto/x509.c b/programs/pluto/x509.c
index fbbf5a553e..f7e97b9979 100644
--- a/programs/pluto/x509.c
+++ b/programs/pluto/x509.c
@@ -336,7 +336,7 @@ generalName_t *collect_rw_ca_candidates(struct msg_digest *md)
*/
static void gntoid(struct id *id, const generalName_t *gn, struct logger *logger)
{
- *id = empty_id;
+ *id = empty_id; /* aka ID_NONE */
switch (gn->kind) {
case GN_DNS_NAME: /* ID type: ID_FQDN */
@@ -345,18 +345,37 @@ static void gntoid(struct id *id, const generalName_t *gn, struct logger *logger
break;
case GN_IP_ADDRESS: /* ID type: ID_IPV4_ADDR */
{
+ const struct ip_info *afi = NULL;
+ for (enum ip_index i = 0; i < IP_INDEX_ROOF; i++) {
+ if (ip_families[i].ip_size == gn->name.len) {
+ afi = &ip_families[i];
+ break;
+ }
+ }
+ if (afi == NULL) {
+ llog(RC_LOG, logger,
+ "warning: invalid IP_ADDRESS general name: %zu byte length is not valid",
+ gn->name.len);
+ PEXPECT(logger, id->kind == ID_NONE);
+ return;
+ }
+
/*
* XXX: why could this fail; and what happens when it
* is ignored?
*/
- const struct ip_info *afi = &ipv4_info;
- id->kind = afi->id_ip_addr;
- err_t ugh = hunk_to_address(gn->name, afi, &id->ip_addr);
+ ip_address addr;
+ err_t ugh = hunk_to_address(gn->name, afi, &addr);
if (ugh != NULL) {
llog(RC_LOG, logger,
- "warning: gntoid() failed to initaddr(): %s",
- ugh);
+ "warning: invalid IP_ADDRESS general name: %s",
+ ugh);
+ PEXPECT(logger, id->kind == ID_NONE);
+ return;
}
+
+ id->kind = afi->id_ip_addr;
+ id->ip_addr = addr;
break;
}
case GN_RFC822_NAME: /* ID type: ID_USER_FQDN */
@@ -464,14 +483,18 @@ bool add_pubkey_from_nss_cert(struct pubkey_list **pubkey_db,
return false;
}
+ ldbg(logger, "adding cert using subject name");
replace_public_key(pubkey_db, &pk);
passert(pk == NULL); /*stolen*/
+ ldbg(logger, "adding cert using general names");
add_cert_san_pubkeys(pubkey_db, cert, logger);
if (keyid != NULL && keyid->kind != ID_DER_ASN1_DN &&
keyid->kind != ID_NONE &&
keyid->kind != ID_FROMCERT) {
+ id_buf idb;
+ ldbg(logger, "adding cert using keyid %s", str_id(keyid, &idb));
struct pubkey *pk2 = NULL;
diag_t d = create_pubkey_from_cert(keyid, cert, &pk2, logger);
if (d != NULL) {
--
2.44.0
From 1e27be95cd710a840681d1a51913e6a32ce75a2a Mon Sep 17 00:00:00 2001
From: Andrew Cagney <cagney@gnu.org>
Date: Mon, 11 Mar 2024 17:18:51 -0400
Subject: [PATCH] building: back-port ip_families[] and ip_index
---
include/ip_index.h | 27 +++++++++++++++++++++++++++
include/ip_info.h | 7 +++++--
lib/libswan/ip_info.c | 9 ++++++---
3 files changed, 38 insertions(+), 5 deletions(-)
create mode 100644 include/ip_index.h
diff --git a/include/ip_index.h b/include/ip_index.h
new file mode 100644
index 0000000000..508589b05e
--- /dev/null
+++ b/include/ip_index.h
@@ -0,0 +1,27 @@
+/* ip address type index, for libreswan
+ *
+ * Copyright (C) 2022 Andrew Cagney
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <https://www.gnu.org/licenses/lgpl-2.1.txt>.
+ *
+ * This library 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 Library General Public
+ * License for more details.
+ *
+ */
+
+#ifndef IP_INDEX_H
+#define IP_INDEX_H
+
+enum ip_index {
+ IPv4_INDEX,
+ IPv6_INDEX,
+};
+
+#define IP_INDEX_ROOF (IPv6_INDEX+1)
+
+#endif
diff --git a/include/ip_info.h b/include/ip_info.h
index 40e99ef687..c1329a8569 100644
--- a/include/ip_info.h
+++ b/include/ip_info.h
@@ -9,6 +9,7 @@
#include "ip_subnet.h"
#include "ip_selector.h"
#include "ip_sockaddr.h"
+#include "ip_index.h"
struct ip_info {
/*
@@ -113,8 +114,10 @@ struct ip_info {
};
-extern const struct ip_info ipv4_info;
-extern const struct ip_info ipv6_info;
+extern const struct ip_info ip_families[IP_INDEX_ROOF];
+
+#define ipv4_info ip_families[IPv4_INDEX]
+#define ipv6_info ip_families[IPv6_INDEX]
extern const struct ip_info *aftoinfo(int af);
diff --git a/lib/libswan/ip_info.c b/lib/libswan/ip_info.c
index 70cd6a368f..97296d3a11 100644
--- a/lib/libswan/ip_info.c
+++ b/lib/libswan/ip_info.c
@@ -158,7 +158,9 @@ static ip_port port_from_ipv6_sockaddr(const ip_sockaddr sa)
#define IPv4_FF { { 255, 255, 255, 255, }, }
-const struct ip_info ipv4_info = {
+const struct ip_info ip_families[IP_INDEX_ROOF] = {
+
+ [IPv4_INDEX] = {
.ip_version = IPv4,
.ip_size = sizeof(struct in_addr),
@@ -210,11 +212,11 @@ const struct ip_info ipv4_info = {
.id_ip_addr = ID_IPV4_ADDR,
.id_ip_addr_subnet = ID_IPV4_ADDR_SUBNET,
.id_ip_addr_range = ID_IPV4_ADDR_RANGE,
-};
+ },
#define IPv6_FF { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }, }
-const struct ip_info ipv6_info = {
+ [IPv6_INDEX] = {
.ip_version = IPv6,
.ip_size = sizeof(struct in6_addr),
@@ -266,6 +268,7 @@ const struct ip_info ipv6_info = {
.id_ip_addr = ID_IPV6_ADDR,
.id_ip_addr_subnet = ID_IPV6_ADDR_SUBNET,
.id_ip_addr_range = ID_IPV6_ADDR_RANGE,
+ }
};
const struct ip_info *aftoinfo(int af)
--
2.44.0

View File

@ -0,0 +1,57 @@
From d0a468bc4ca54b3aa941f522afd4ef8ed279e3cd Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno@gnu.org>
Date: Tue, 22 Oct 2024 07:53:20 +0900
Subject: [PATCH] pluto: ignore CREATE_CHILD_SA request if crypto is in
progress
Since commit 1f4cede653c865d84ea4dd045db05670d513d385, both initiator
and responder drive CREATE_CHILD_SA processing with the same shared
IKE SA, which may sometimes interleave. This adds a guard at the
entry to the responder code, to return STF_IGNORE in case any CRYPTO
continuation is already in place, so that the initiator could
retransmit after a timeout on their side.
Signed-off-by: Daiki Ueno <ueno@gnu.org>
---
programs/pluto/ikev2_create_child_sa.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/programs/pluto/ikev2_create_child_sa.c b/programs/pluto/ikev2_create_child_sa.c
index 951485d063..504fc58a6b 100644
--- a/programs/pluto/ikev2_create_child_sa.c
+++ b/programs/pluto/ikev2_create_child_sa.c
@@ -662,6 +662,15 @@ stf_status process_v2_CREATE_CHILD_SA_rekey_child_request(struct ike_sa *ike,
struct child_sa *larval_child,
struct msg_digest *md)
{
+ /*
+ * CRYPTO continuation is ongoing as the same IKE SA is shared
+ * between initiator and responder, ignore it for now and let
+ * the initiator retransmit.
+ */
+ if (verbose_state_busy(&ike->sa)) {
+ return STF_IGNORE;
+ }
+
struct child_sa *predecessor = NULL;
if (!find_v2N_REKEY_SA_child(ike, md, &predecessor)) {
record_v2N_response(ike->sa.st_logger, ike, md, v2N_INVALID_SYNTAX,
@@ -870,6 +879,15 @@ stf_status process_v2_CREATE_CHILD_SA_new_child_request(struct ike_sa *ike,
struct child_sa *larval_child,
struct msg_digest *md)
{
+ /*
+ * CRYPTO continuation is ongoing as the same IKE SA is shared
+ * between initiator and responder, ignore it for now and let
+ * the initiator retransmit.
+ */
+ if (verbose_state_busy(&ike->sa)) {
+ return STF_IGNORE;
+ }
+
pexpect(larval_child == NULL);
larval_child = new_v2_child_state(ike->sa.st_connection,
ike, IPSEC_SA, SA_RESPONDER,
--
2.47.0

View File

@ -0,0 +1,153 @@
From 4f2af7c8c3afaaa63e8e16467de3441622a5314d Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Tue, 21 May 2024 20:12:17 +0900
Subject: [PATCH] kernel_xfrm: record extended ack from netlink response
This enables pluto to log any error message reported through extended
ACK attributes[1] in a netlink response, to make diagnostic easier
when an error occurs. Suggested by Sabrina Dubroca.
1. https://docs.kernel.org/userspace-api/netlink/intro.html#ext-ack
Signed-off-by: Daiki Ueno <dueno@redhat.com>
Signed-off-by: Andrew Cagney <cagney@gnu.org>
---
include/netlink_attrib.h | 4 +++
lib/libswan/netlink_attrib.c | 29 +++++++++++++++++++++
programs/pluto/kernel_xfrm.c | 49 ++++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+)
diff --git a/include/netlink_attrib.h b/include/netlink_attrib.h
index 4c952ae3e9..fff35d83f1 100644
--- a/include/netlink_attrib.h
+++ b/include/netlink_attrib.h
@@ -46,4 +46,8 @@ void nl_addattrstrz(struct nlmsghdr *n, int maxlen, int type,
const char *str);
void nl_addattr32(struct nlmsghdr *n, int maxlen, int type, const uint32_t data);
+const struct nlattr *nl_getattr(const struct nlmsghdr *n, size_t *offset);
+const char *nl_getattrvalstrz(const struct nlmsghdr *n,
+ const struct nlattr *attr);
+
#endif
diff --git a/lib/libswan/netlink_attrib.c b/lib/libswan/netlink_attrib.c
index 34bb4bec83..ccc08cba8f 100644
--- a/lib/libswan/netlink_attrib.c
+++ b/lib/libswan/netlink_attrib.c
@@ -66,3 +66,32 @@ void nl_addattr32(struct nlmsghdr *n, int maxlen, int type, const uint32_t data)
{
nl_addattr_l(n, maxlen, type, &data, sizeof(uint32_t));
}
+
+const struct nlattr *nl_getattr(const struct nlmsghdr *n, size_t *offset)
+{
+ struct nlattr *attr = (void *)n + NLMSG_HDRLEN + NLMSG_ALIGN(*offset);
+ struct nlattr *tail = (void *)n + NLMSG_ALIGN(n->nlmsg_len);
+
+ if (attr == tail) {
+ return NULL;
+ }
+
+ *offset += NLA_ALIGN(attr->nla_len);
+ return attr;
+}
+
+const char *nl_getattrvalstrz(const struct nlmsghdr *n,
+ const struct nlattr *attr)
+{
+ struct nlattr *tail = (void *)n + NLMSG_ALIGN(n->nlmsg_len);
+
+ ptrdiff_t len = (void *)tail - (void *)attr;
+ if (len < (ptrdiff_t)sizeof(struct nlattr) ||
+ attr->nla_len <= sizeof(struct nlattr) ||
+ attr->nla_len > len ||
+ !memchr(attr + NLA_HDRLEN, '\0', attr->nla_len - NLA_HDRLEN)) {
+ return NULL;
+ }
+
+ return (void *)attr + NLA_HDRLEN;
+}
diff --git a/programs/pluto/kernel_xfrm.c b/programs/pluto/kernel_xfrm.c
index eed307f42b..25d1b16bc9 100644
--- a/programs/pluto/kernel_xfrm.c
+++ b/programs/pluto/kernel_xfrm.c
@@ -260,6 +260,22 @@ static void init_netlink(struct logger *logger)
"socket() in init_netlink()");
}
+#ifdef SOL_NETLINK
+ const int on = true;
+ if (setsockopt(nl_send_fd, SOL_NETLINK, NETLINK_CAP_ACK,
+ (const void *)&on, sizeof(on)) < 0) {
+ llog_errno(RC_LOG, logger, errno, "xfrm: setsockopt(NETLINK_CAP_ACK) failed: ");
+ } else {
+ ldbg(logger, "xfrm: setsockopt(NETLINK_CAP_ACK) ok");
+ }
+ if (setsockopt(nl_send_fd, SOL_NETLINK, NETLINK_EXT_ACK,
+ (const void *)&on, sizeof(on)) < 0) {
+ llog_errno(RC_LOG, logger, errno, "xfrm: setsockopt(NETLINK_EXT_ACK) failed: ");
+ } else {
+ ldbg(logger, "xfrm: setsockopt(NETLINK_EXT_ACK) ok");
+ }
+#endif
+
nl_xfrm_fd = cloexec_socket(AF_NETLINK, SOCK_DGRAM|SOCK_NONBLOCK, NETLINK_XFRM);
if (nl_xfrm_fd < 0) {
fatal_errno(PLUTO_EXIT_FAIL, logger, errno,
@@ -301,6 +317,37 @@ static void init_netlink(struct logger *logger)
}
}
+static void llog_ext_ack(lset_t rc_flags, struct logger *logger,
+ const struct nlmsghdr *n)
+{
+#ifdef SOL_NETLINK
+ if (n->nlmsg_type != NLMSG_ERROR ||
+ !(n->nlmsg_flags & NLM_F_ACK_TLVS)) {
+ return;
+ }
+
+ struct nlmsgerr *err = (void *)n + NLMSG_HDRLEN;
+ size_t offset = sizeof(*err);
+ if (!(n->nlmsg_flags & NLM_F_CAPPED)) {
+ offset += err->msg.nlmsg_len - NLMSG_HDRLEN;
+ }
+
+ for (const struct nlattr *attr = nl_getattr(n, &offset);
+ attr != NULL; attr = nl_getattr(n, &offset)) {
+ if ((attr->nla_type & NLA_TYPE_MASK) == NLMSGERR_ATTR_MSG) {
+ const char *msg = nl_getattrvalstrz(n, attr);
+ if (msg) {
+ llog(rc_flags, logger, "netlink ext_ack: %s",
+ msg);
+ }
+ }
+ }
+#else
+ /* use the arguments */
+ ldbg(logger, "ignoring "PRI_LSET" %p", rc_flags, n);
+#endif
+}
+
/*
* sendrecv_xfrm_msg()
*
@@ -403,6 +450,7 @@ static bool sendrecv_xfrm_msg(struct nlmsghdr *hdr,
if (rsp.u.e.error != 0) {
llog_error(logger, -rsp.u.e.error,
"netlink response for %s %s", description, story);
+ llog_ext_ack(RC_LOG, logger, &rsp.n);
return false;
}
/*
@@ -413,6 +461,7 @@ static bool sendrecv_xfrm_msg(struct nlmsghdr *hdr,
*/
dbg("netlink response for %s %s included non-error error",
description, story);
+ llog_ext_ack(DEBUG_STREAM, logger, &rsp.n);
/* ignore */
}
if (rbuf == NULL) {
--
2.45.2

View File

@ -0,0 +1,52 @@
From 0b91406427cf7292d61900991fd665f076b6d43f Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Tue, 2 Jul 2024 20:37:07 +0900
Subject: [PATCH] tcp: call kernel_ops->poke_ipsec_policy_hole before connect
This fixes ondemand initiation with TCP. Without the policy hole, a
TCP handshake will not complete, as it cannot receive SYN-ACK packet
in plaintext and thus connect blocks until timeout.
Signed-off-by: Daiki Ueno <dueno@redhat.com>
Signed-off-by: Andrew Cagney <cagney@gnu.org>
---
programs/pluto/iface_tcp.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/programs/pluto/iface_tcp.c b/programs/pluto/iface_tcp.c
index c63e8bfe4d..55fe639174 100644
--- a/programs/pluto/iface_tcp.c
+++ b/programs/pluto/iface_tcp.c
@@ -473,6 +473,15 @@ struct iface_endpoint *connect_to_tcp_endpoint(struct iface_dev *local_dev,
return NULL;
}
+ /* This needs to be called before connect, so TCP handshake
+ * (in plaintext) completes. */
+ if (kernel_ops->poke_ipsec_policy_hole != NULL &&
+ !kernel_ops->poke_ipsec_policy_hole(fd, afi, logger)) {
+ /* already logged */
+ close(fd);
+ return NULL;
+ }
+
/*
* Connect
*
@@ -551,13 +560,6 @@ struct iface_endpoint *connect_to_tcp_endpoint(struct iface_dev *local_dev,
}
}
- if (kernel_ops->poke_ipsec_policy_hole != NULL &&
- !kernel_ops->poke_ipsec_policy_hole(fd, afi, logger)) {
- /* already logged */
- close(fd);
- return NULL;
- }
-
struct iface_endpoint *ifp =
alloc_iface_endpoint(fd, local_dev, &iketcp_iface_io,
/*esp_encapsulation_enabled*/true,
--
2.45.2

View File

@ -0,0 +1,594 @@
From 5d20ce318199d3d525c8503ffc3242a90117a944 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Sat, 23 Nov 2024 10:18:03 +0900
Subject: [PATCH 1/2] secrets: allocate secret_pubkey_stuff separately from
heap
Signed-off-by: Daiki Ueno <dueno@redhat.com>
---
include/secrets.h | 2 +-
lib/libswan/pubkey_ecdsa.c | 12 +++----
lib/libswan/pubkey_rsa.c | 18 +++++------
.../secret_pubkey_stuff_to_pubkey_der.c | 2 +-
lib/libswan/secrets.c | 32 ++++++++++---------
programs/pluto/ikev2_eap.c | 2 +-
programs/pluto/keys.c | 6 ++--
programs/showhostkey/showhostkey.c | 32 +++++++++++--------
8 files changed, 56 insertions(+), 50 deletions(-)
diff --git a/include/secrets.h b/include/secrets.h
index 971f559da7..38906bf6ba 100644
--- a/include/secrets.h
+++ b/include/secrets.h
@@ -88,7 +88,7 @@ struct secret_stuff {
int line;
union {
chunk_t preshared_secret;
- struct secret_pubkey_stuff pubkey;
+ struct secret_pubkey_stuff *pubkey;
} u;
chunk_t ppk;
diff --git a/lib/libswan/pubkey_ecdsa.c b/lib/libswan/pubkey_ecdsa.c
index 29af07f380..17f39fbbc1 100644
--- a/lib/libswan/pubkey_ecdsa.c
+++ b/lib/libswan/pubkey_ecdsa.c
@@ -287,7 +287,7 @@ static struct hash_signature ECDSA_raw_sign_hash(const struct secret_stuff *pks,
{
DBGF(DBG_CRYPT, "%s: started using NSS", __func__);
- if (!pexpect(pks->u.pubkey.private_key != NULL)) {
+ if (!pexpect(pks->u.pubkey->private_key != NULL)) {
dbg("no private key!");
return (struct hash_signature) { .len = 0, };
}
@@ -304,14 +304,14 @@ static struct hash_signature ECDSA_raw_sign_hash(const struct secret_stuff *pks,
struct hash_signature signature = {0};
SECItem raw_signature = {
.type = siBuffer,
- .len = PK11_SignatureLen(pks->u.pubkey.private_key),
+ .len = PK11_SignatureLen(pks->u.pubkey->private_key),
.data = signature.ptr/*array*/,
};
passert(raw_signature.len <= sizeof(signature.ptr/*array*/));
dbg("ECDSA signature.len %d", raw_signature.len);
/* create the raw signature */
- SECStatus s = PK11_Sign(pks->u.pubkey.private_key, &raw_signature, &hash_to_sign);
+ SECStatus s = PK11_Sign(pks->u.pubkey->private_key, &raw_signature, &hash_to_sign);
if (DBGP(DBG_CRYPT)) {
DBG_dump("PK11_Sign()", raw_signature.data, raw_signature.len);
}
@@ -407,7 +407,7 @@ static struct hash_signature ECDSA_digsig_sign_hash(const struct secret_stuff *p
struct logger *logger)
{
- if (!pexpect(pks->u.pubkey.private_key != NULL)) {
+ if (!pexpect(pks->u.pubkey->private_key != NULL)) {
dbg("no private key!");
return (struct hash_signature) { .len = 0, };
}
@@ -425,14 +425,14 @@ static struct hash_signature ECDSA_digsig_sign_hash(const struct secret_stuff *p
uint8_t raw_signature_data[sizeof(struct hash_signature)];
SECItem raw_signature = {
.type = siBuffer,
- .len = PK11_SignatureLen(pks->u.pubkey.private_key),
+ .len = PK11_SignatureLen(pks->u.pubkey->private_key),
.data = raw_signature_data,
};
passert(raw_signature.len <= sizeof(raw_signature_data));
dbg("ECDSA signature.len %d", raw_signature.len);
/* create the raw signature */
- SECStatus s = PK11_Sign(pks->u.pubkey.private_key, &raw_signature, &hash_to_sign);
+ SECStatus s = PK11_Sign(pks->u.pubkey->private_key, &raw_signature, &hash_to_sign);
if (DBGP(DBG_CRYPT)) {
DBG_dump("sig_from_nss", raw_signature.data, raw_signature.len);
}
diff --git a/lib/libswan/pubkey_rsa.c b/lib/libswan/pubkey_rsa.c
index 38b44ab61d..be8935c38c 100644
--- a/lib/libswan/pubkey_rsa.c
+++ b/lib/libswan/pubkey_rsa.c
@@ -350,7 +350,7 @@ static struct hash_signature RSA_sign_hash_raw_rsa(const struct secret_stuff *pk
return (struct hash_signature) { .len = 0, };
}
- if (!pexpect(pks->u.pubkey.private_key != NULL)) {
+ if (!pexpect(pks->u.pubkey->private_key != NULL)) {
dbg("no private key!");
return (struct hash_signature) { .len = 0, };
}
@@ -361,7 +361,7 @@ static struct hash_signature RSA_sign_hash_raw_rsa(const struct secret_stuff *pk
.data = DISCARD_CONST(uint8_t *, hash_val),
};
- struct hash_signature sig = { .len = PK11_SignatureLen(pks->u.pubkey.private_key), };
+ struct hash_signature sig = { .len = PK11_SignatureLen(pks->u.pubkey->private_key), };
passert(sig.len <= sizeof(sig.ptr/*array*/));
SECItem signature = {
.type = siBuffer,
@@ -369,7 +369,7 @@ static struct hash_signature RSA_sign_hash_raw_rsa(const struct secret_stuff *pk
.data = sig.ptr,
};
- SECStatus s = PK11_Sign(pks->u.pubkey.private_key, &signature, &data);
+ SECStatus s = PK11_Sign(pks->u.pubkey->private_key, &signature, &data);
if (s != SECSuccess) {
/* PR_GetError() returns the thread-local error */
llog_nss_error(RC_LOG_SERIOUS, logger,
@@ -485,7 +485,7 @@ static struct hash_signature RSA_sign_hash_pkcs1_1_5_rsa(const struct secret_stu
{
dbg("%s: started using NSS", __func__);
- if (!pexpect(pks->u.pubkey.private_key != NULL)) {
+ if (!pexpect(pks->u.pubkey->private_key != NULL)) {
dbg("no private key!");
return (struct hash_signature) { .len = 0, };
}
@@ -501,7 +501,7 @@ static struct hash_signature RSA_sign_hash_pkcs1_1_5_rsa(const struct secret_stu
* used to generate the signature.
*/
SECItem signature_result = {0};
- SECStatus s = SGN_Digest(pks->u.pubkey.private_key,
+ SECStatus s = SGN_Digest(pks->u.pubkey->private_key,
hash_algo->nss.oid_tag,
&signature_result, &digest);
if (s != SECSuccess) {
@@ -516,7 +516,7 @@ static struct hash_signature RSA_sign_hash_pkcs1_1_5_rsa(const struct secret_stu
/* save the signature, free the returned pointer */
struct hash_signature signature = {
- .len = PK11_SignatureLen(pks->u.pubkey.private_key),
+ .len = PK11_SignatureLen(pks->u.pubkey->private_key),
};
passert(signature.len <= sizeof(signature.ptr/*array*/));
memcpy(signature.ptr, signature_result.data, signature.len);
@@ -629,7 +629,7 @@ static struct hash_signature RSA_sign_hash_rsassa_pss(const struct secret_stuff
{
dbg("%s: started using NSS", __func__);
- if (!pexpect(pks->u.pubkey.private_key != NULL)) {
+ if (!pexpect(pks->u.pubkey->private_key != NULL)) {
dbg("no private key!");
return (struct hash_signature) { .len = 0, };
}
@@ -640,7 +640,7 @@ static struct hash_signature RSA_sign_hash_rsassa_pss(const struct secret_stuff
.data = DISCARD_CONST(uint8_t *, hash_val),
};
- struct hash_signature sig = { .len = PK11_SignatureLen(pks->u.pubkey.private_key), };
+ struct hash_signature sig = { .len = PK11_SignatureLen(pks->u.pubkey->private_key), };
passert(sig.len <= sizeof(sig.ptr/*array*/));
SECItem signature = {
.type = siBuffer,
@@ -661,7 +661,7 @@ static struct hash_signature RSA_sign_hash_rsassa_pss(const struct secret_stuff
.data = (void*)mech, /* strip const */
.len = sizeof(*mech),
};
- SECStatus s = PK11_SignWithMechanism(pks->u.pubkey.private_key, CKM_RSA_PKCS_PSS,
+ SECStatus s = PK11_SignWithMechanism(pks->u.pubkey->private_key, CKM_RSA_PKCS_PSS,
&mech_item, &signature, &data);
if (s != SECSuccess) {
/* PR_GetError() returns the thread-local error */
diff --git a/lib/libswan/secret_pubkey_stuff_to_pubkey_der.c b/lib/libswan/secret_pubkey_stuff_to_pubkey_der.c
index 1b5de6917e..3f28cbd765 100644
--- a/lib/libswan/secret_pubkey_stuff_to_pubkey_der.c
+++ b/lib/libswan/secret_pubkey_stuff_to_pubkey_der.c
@@ -32,7 +32,7 @@ static diag_t seckey_pubkey_to_der(SECKEYPublicKey *seckey_pubkey, chunk_t *der)
diag_t secret_pubkey_stuff_to_pubkey_der(struct secret_stuff *pks, chunk_t *der)
{
- SECKEYPublicKey *seckey_pubkey = SECKEY_ConvertToPublicKey(pks->u.pubkey.private_key);
+ SECKEYPublicKey *seckey_pubkey = SECKEY_ConvertToPublicKey(pks->u.pubkey->private_key);
if (seckey_pubkey == NULL) {
return diag_nss_error("extracting Public Key from Private Key");
}
diff --git a/lib/libswan/secrets.c b/lib/libswan/secrets.c
index 44578efbe5..6becebe8e8 100644
--- a/lib/libswan/secrets.c
+++ b/lib/libswan/secrets.c
@@ -185,7 +185,7 @@ const ckaid_t *secret_ckaid(const struct secret *secret)
case SECRET_RSA:
case SECRET_ECDSA:
/* some sort of PKI */
- return &secret->stuff.u.pubkey.content.ckaid;
+ return &secret->stuff.u.pubkey->content.ckaid;
default:
return NULL;
}
@@ -197,7 +197,7 @@ const keyid_t *secret_keyid(const struct secret *secret)
case SECRET_RSA:
case SECRET_ECDSA:
/* some sort of PKI */
- return &secret->stuff.u.pubkey.content.keyid;
+ return &secret->stuff.u.pubkey->content.keyid;
default:
return NULL;
}
@@ -239,12 +239,12 @@ static struct secret *find_secret_by_pubkey_ckaid_1(struct secret *secrets,
dbg(" not PKI");
continue;
}
- if (type != NULL && pks->u.pubkey.content.type != type) {
+ if (type != NULL && pks->u.pubkey->content.type != type) {
/* need exact or wildcard */
dbg(" not %s", type->name);
continue;
}
- if (!ckaid_eq_nss(&pks->u.pubkey.content.ckaid, pubkey_ckaid)) {
+ if (!ckaid_eq_nss(&pks->u.pubkey->content.ckaid, pubkey_ckaid)) {
dbg(" wrong ckaid");
continue;
}
@@ -274,12 +274,12 @@ bool secret_pubkey_same(struct secret *lhs, struct secret *rhs)
return false;
}
- if (lhs->stuff.u.pubkey.content.type != rhs->stuff.u.pubkey.content.type) {
+ if (lhs->stuff.u.pubkey->content.type != rhs->stuff.u.pubkey->content.type) {
return false;
}
- return lhs->stuff.u.pubkey.content.type->pubkey_same(&lhs->stuff.u.pubkey.content,
- &rhs->stuff.u.pubkey.content);
+ return lhs->stuff.u.pubkey->content.type->pubkey_same(&lhs->stuff.u.pubkey->content,
+ &rhs->stuff.u.pubkey->content);
}
struct secret *lsw_find_secret_by_id(struct secret *secrets,
@@ -965,8 +965,9 @@ void lsw_free_preshared_secrets(struct secret **psecrets, struct logger *logger)
case SECRET_RSA:
case SECRET_ECDSA:
/* Note: pub is all there is */
- SECKEY_DestroyPrivateKey(s->stuff.u.pubkey.private_key);
- s->stuff.u.pubkey.content.type->free_pubkey_content(&s->stuff.u.pubkey.content);
+ SECKEY_DestroyPrivateKey(s->stuff.u.pubkey->private_key);
+ s->stuff.u.pubkey->content.type->free_pubkey_content(&s->stuff.u.pubkey->content);
+ pfree(s->stuff.u.pubkey);
break;
default:
bad_case(s->stuff.kind);
@@ -1193,19 +1194,20 @@ static err_t add_private_key(struct secret **secrets, const struct secret_stuff
s->stuff.kind = type->private_key_kind;
s->stuff.line = 0;
/* make an unpacked copy of the private key */
- s->stuff.u.pubkey.private_key = copy_private_key(private_key);
- err_t err = type->extract_pubkey_content(&s->stuff.u.pubkey.content,
+ s->stuff.u.pubkey = alloc_thing(struct secret_pubkey_stuff, "secret_pubkey_stuff");
+ s->stuff.u.pubkey->private_key = copy_private_key(private_key);
+ err_t err = type->extract_pubkey_content(&s->stuff.u.pubkey->content,
pubk, ckaid_nss);
if (err != NULL) {
/* extract should leave pubkey_content clean */
- SECKEY_DestroyPrivateKey(s->stuff.u.pubkey.private_key); /* allocated above */
+ SECKEY_DestroyPrivateKey(s->stuff.u.pubkey->private_key); /* allocated above */
pfree(s);
return err;
}
- passert(s->stuff.u.pubkey.content.type == type);
- pexpect(s->stuff.u.pubkey.content.ckaid.len > 0);
- pexpect(s->stuff.u.pubkey.content.keyid.keyid[0] != '\0');
+ passert(s->stuff.u.pubkey->content.type == type);
+ pexpect(s->stuff.u.pubkey->content.ckaid.len > 0);
+ pexpect(s->stuff.u.pubkey->content.keyid.keyid[0] != '\0');
add_secret(secrets, s, "lsw_add_rsa_secret");
*pks = &s->stuff;
diff --git a/programs/pluto/ikev2_eap.c b/programs/pluto/ikev2_eap.c
index d7f0b1d527..fe4c6e2e8c 100644
--- a/programs/pluto/ikev2_eap.c
+++ b/programs/pluto/ikev2_eap.c
@@ -264,7 +264,7 @@ static bool start_eap(struct ike_sa *ike, struct pbs_out *pbs)
SSL_OptionSet(pr, SSL_ENABLE_SSL3, PR_FALSE) != SECSuccess ||
SSL_BadCertHook(pr, eaptls_bad_cert_cb, eap) != SECSuccess ||
SSL_HandshakeCallback(pr, eaptls_handshake_cb, eap) != SECSuccess ||
- SSL_ConfigServerCert(pr, mycert->nss_cert, pks->u.pubkey.private_key, 0, 0) != SECSuccess) {
+ SSL_ConfigServerCert(pr, mycert->nss_cert, pks->u.pubkey->private_key, 0, 0) != SECSuccess) {
llog_nss_error(RC_LOG, logger, "Failed to start configure TLS options");
return false;
}
diff --git a/programs/pluto/keys.c b/programs/pluto/keys.c
index 81e506556a..37f2408ae3 100644
--- a/programs/pluto/keys.c
+++ b/programs/pluto/keys.c
@@ -609,7 +609,7 @@ const struct secret_stuff *get_local_private_key(const struct connection *c,
* etc) then best will end up as NULL
*/
pexpect(pks->kind == type->private_key_kind);
- pexpect(pks->u.pubkey.content.type == type);
+ pexpect(pks->u.pubkey->content.type == type);
dbg("connection %s's %s private key found in NSS DB using cert",
c->name, type->name);
return pks;
@@ -657,7 +657,7 @@ const struct secret_stuff *get_local_private_key(const struct connection *c,
* etc) then best will end up as NULL
*/
pexpect(pks->kind == type->private_key_kind);
- pexpect(pks->u.pubkey.content.type == type);
+ pexpect(pks->u.pubkey->content.type == type);
dbg("connection %s's %s private key found in NSS DB using CKAID",
c->name, type->name);
return pks;
@@ -676,7 +676,7 @@ const struct secret_stuff *get_local_private_key(const struct connection *c,
passert(pks != NULL);
pexpect(pks->kind == type->private_key_kind);
- pexpect(pks->u.pubkey.content.type == type);
+ pexpect(pks->u.pubkey->content.type == type);
dbg("connection %s's %s private key found",
c->name, type->name);
return pks;
diff --git a/programs/showhostkey/showhostkey.c b/programs/showhostkey/showhostkey.c
index 8f40b67a62..7b003365dd 100644
--- a/programs/showhostkey/showhostkey.c
+++ b/programs/showhostkey/showhostkey.c
@@ -172,14 +172,14 @@ static void print(struct secret_stuff *pks,
case SECRET_RSA:
case SECRET_ECDSA:
{
- printf("%s", pks->u.pubkey.content.type->name);
- keyid_t keyid = pks->u.pubkey.content.keyid;
+ printf("%s", pks->u.pubkey->content.type->name);
+ keyid_t keyid = pks->u.pubkey->content.keyid;
printf(" keyid: %s", str_keyid(keyid)[0] ? str_keyid(keyid) : "<missing-pubkey>");
if (id) {
printf(" id: %s", idb);
}
ckaid_buf cb;
- const ckaid_t *ckaid = &pks->u.pubkey.content.ckaid;
+ const ckaid_t *ckaid = &pks->u.pubkey->content.ckaid;
printf(" ckaid: %s\n", str_ckaid(ckaid, &cb));
break;
}
@@ -237,7 +237,7 @@ static int pick_by_rsaid(struct secret *secret UNUSED,
{
char *rsaid = (char *)uservoid;
- if (pks->kind == SECRET_RSA && streq(pks->u.pubkey.content.keyid.keyid, rsaid)) {
+ if (pks->kind == SECRET_RSA && streq(pks->u.pubkey->content.keyid.keyid, rsaid)) {
/* stop */
return 0;
} else {
@@ -254,7 +254,7 @@ static int pick_by_ckaid(struct secret *secret UNUSED,
switch (pks->kind) {
case SECRET_RSA:
case SECRET_ECDSA:
- if (ckaid_starts_with(&pks->u.pubkey.content.ckaid, start)) {
+ if (ckaid_starts_with(&pks->u.pubkey->content.ckaid, start)) {
/* stop */
return 0;
}
@@ -283,7 +283,7 @@ static char *base64_ipseckey_rdata_from_pubkey_secret(struct secret_stuff *pks,
enum ipseckey_algorithm_type *ipseckey_algorithm)
{
chunk_t ipseckey_pubkey = empty_chunk; /* must free */
- err_t e = pks->u.pubkey.content.type->pubkey_content_to_ipseckey_rdata(&pks->u.pubkey.content,
+ err_t e = pks->u.pubkey->content.type->pubkey_content_to_ipseckey_rdata(&pks->u.pubkey->content,
&ipseckey_pubkey,
ipseckey_algorithm);
if (e != NULL) {
@@ -390,7 +390,7 @@ static int show_leftright(struct secret_stuff *pks,
}
}
- passert(pks->u.pubkey.content.type != NULL);
+ passert(pks->u.pubkey->content.type != NULL);
char *base64 = NULL;
if (pubkey_flg) {
@@ -408,11 +408,11 @@ static int show_leftright(struct secret_stuff *pks,
} else {
switch (pks->kind) {
case SECRET_RSA:
- printf("\t# rsakey %s\n", pks->u.pubkey.content.keyid.keyid);
+ printf("\t# rsakey %s\n", pks->u.pubkey->content.keyid.keyid);
printf("\t%srsasigkey=0s", side);
break;
case SECRET_ECDSA:
- printf("\t# ecdsakey %s\n", pks->u.pubkey.content.keyid.keyid);
+ printf("\t# ecdsakey %s\n", pks->u.pubkey->content.keyid.keyid);
printf("\t%secdsakey=0s", side);
break;
default:
@@ -481,14 +481,17 @@ static struct secret_stuff *foreach_nss_private_key(secret_eval func,
continue;
}
+ struct secret_pubkey_stuff pubkey = {
+ .private_key = SECKEY_CopyPrivateKey(private_key), /* add reference */
+ };
+ type->extract_pubkey_content(&pubkey.content, pubk, ckaid_nss);
+
struct secret_stuff pks = {
.kind = type->private_key_kind,
.line = 0,
- .u.pubkey.private_key = SECKEY_CopyPrivateKey(private_key), /* add reference */
+ .u.pubkey = clone_thing(pubkey, "pubkey"),
};
- type->extract_pubkey_content(&pks.u.pubkey.content, pubk, ckaid_nss);
-
/*
* Only count private keys that get processed.
*/
@@ -513,8 +516,9 @@ static struct secret_stuff *foreach_nss_private_key(secret_eval func,
break;
}
- SECKEY_DestroyPrivateKey(pks.u.pubkey.private_key); /* destory reference */
- type->free_pubkey_content(&pks.u.pubkey.content);
+ SECKEY_DestroyPrivateKey(pks.u.pubkey->private_key); /* destory reference */
+ type->free_pubkey_content(&pks.u.pubkey->content);
+ pfreeany(pks.u.pubkey);
if (ret < 0) {
break;
--
2.47.1
From b4102e2243a6513897502113dfbf90fc4ff36323 Mon Sep 17 00:00:00 2001
From: Andrew Cagney <cagney@gnu.org>
Date: Fri, 8 Nov 2024 17:45:53 -0500
Subject: [PATCH 2/2] crypto: refcnt struct secret_pubkey_stuff when passing to
helper thread
fix problem where a thread was trying to use a key when which
was being deleted by reloadsecrets.
close #1894 Segmentation fault in PK11_SignatureLen (key=0xa5a5a5a5a5a5a5a5)
Modified-by: Daiki Ueno <dueno@redhat.com>
---
include/secrets.h | 4 ++++
lib/libswan/secrets.c | 26 +++++++++++++++++++++-----
programs/pluto/ikev2_auth_helper.c | 27 ++++++++++++++++++---------
3 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/include/secrets.h b/include/secrets.h
index 38906bf6ba..b64e9091ca 100644
--- a/include/secrets.h
+++ b/include/secrets.h
@@ -74,10 +74,14 @@ enum secret_kind {
};
struct secret_pubkey_stuff {
+ struct refcnt refcnt;
SECKEYPrivateKey *private_key;
struct pubkey_content content;
};
+struct secret_pubkey_stuff *secret_pubkey_stuff_addref(struct secret_pubkey_stuff *, where_t where);
+void secret_pubkey_stuff_delref(struct secret_pubkey_stuff **, where_t where);
+
struct secret_stuff {
enum secret_kind kind;
/*
diff --git a/lib/libswan/secrets.c b/lib/libswan/secrets.c
index 6becebe8e8..5c725c5734 100644
--- a/lib/libswan/secrets.c
+++ b/lib/libswan/secrets.c
@@ -964,10 +964,7 @@ void lsw_free_preshared_secrets(struct secret **psecrets, struct logger *logger)
break;
case SECRET_RSA:
case SECRET_ECDSA:
- /* Note: pub is all there is */
- SECKEY_DestroyPrivateKey(s->stuff.u.pubkey->private_key);
- s->stuff.u.pubkey->content.type->free_pubkey_content(&s->stuff.u.pubkey->content);
- pfree(s->stuff.u.pubkey);
+ secret_pubkey_stuff_delref(&s->stuff.u.pubkey, HERE);
break;
default:
bad_case(s->stuff.kind);
@@ -1186,6 +1183,25 @@ static const struct pubkey_type *private_key_type_nss(SECKEYPrivateKey *private_
}
}
+struct secret_pubkey_stuff *secret_pubkey_stuff_addref(struct secret_pubkey_stuff *pks,
+ where_t where)
+{
+ return addref_where(pks, where);
+}
+
+static void free_secret_pubkey_stuff(void *obj, where_t where UNUSED)
+{
+ struct secret_pubkey_stuff *pks = obj;
+ SECKEY_DestroyPrivateKey(pks->private_key);
+ pks->content.type->free_pubkey_content(&pks->content);
+ pfree(pks);
+}
+
+void secret_pubkey_stuff_delref(struct secret_pubkey_stuff **pks, where_t where)
+{
+ delref_where(pks, where)
+}
+
static err_t add_private_key(struct secret **secrets, const struct secret_stuff **pks,
SECKEYPublicKey *pubk, SECItem *ckaid_nss,
const struct pubkey_type *type, SECKEYPrivateKey *private_key)
@@ -1194,7 +1210,7 @@ static err_t add_private_key(struct secret **secrets, const struct secret_stuff
s->stuff.kind = type->private_key_kind;
s->stuff.line = 0;
/* make an unpacked copy of the private key */
- s->stuff.u.pubkey = alloc_thing(struct secret_pubkey_stuff, "secret_pubkey_stuff");
+ s->stuff.u.pubkey = refcnt_alloc(struct secret_pubkey_stuff, free_secret_pubkey_stuff, HERE);
s->stuff.u.pubkey->private_key = copy_private_key(private_key);
err_t err = type->extract_pubkey_content(&s->stuff.u.pubkey->content,
pubk, ckaid_nss);
diff --git a/programs/pluto/ikev2_auth_helper.c b/programs/pluto/ikev2_auth_helper.c
index 388f57c611..08edf412ee 100644
--- a/programs/pluto/ikev2_auth_helper.c
+++ b/programs/pluto/ikev2_auth_helper.c
@@ -38,7 +38,7 @@ struct task {
const struct crypt_mac hash_to_sign;
const struct hash_desc *hash_algo;
v2_auth_signature_cb *cb;
- const struct secret_stuff *pks;
+ struct secret_pubkey_stuff *pks;
const struct pubkey_signer *signer;
/* out */
struct hash_signature signature;
@@ -63,19 +63,21 @@ bool submit_v2_auth_signature(struct ike_sa *ike,
where_t where)
{
const struct connection *c = ike->sa.st_connection;
+ const struct secret_stuff *s = get_local_private_key(c, signer->type,
+ ike->sa.st_logger);
+ if (s == NULL) {
+ /* failure: no key to use */
+ return false;
+ }
+
struct task task = {
.cb = cb,
.hash_algo = hash_algo,
.hash_to_sign = *hash_to_sign,
.signer = signer,
- .pks = get_local_private_key(c, signer->type,
- ike->sa.st_logger),
+ .pks = secret_pubkey_stuff_addref(s->u.pubkey, HERE),
};
- if (task.pks == NULL)
- /* failure: no key to use */
- return false;
-
submit_task(ike->sa.st_logger, &ike->sa /*state to resume*/,
clone_thing(task, "signature task"),
&v2_auth_signature_handler, where);
@@ -85,7 +87,7 @@ bool submit_v2_auth_signature(struct ike_sa *ike,
static struct hash_signature v2_auth_signature(struct logger *logger,
const struct crypt_mac *hash_to_sign,
const struct hash_desc *hash_algo,
- const struct secret_stuff *pks,
+ const struct secret_pubkey_stuff *pks,
const struct pubkey_signer *signer)
{
passert(hash_to_sign->len <= sizeof(hash_to_sign->ptr/*array*/)); /*hint to coverity*/
@@ -95,8 +97,14 @@ static struct hash_signature v2_auth_signature(struct logger *logger,
DBG_dump_hunk("hash to sign", *hash_to_sign);
}
+ struct secret_stuff s = {
+ .kind = pks->content.type->private_key_kind,
+ .line = 0,
+ .u.pubkey = (struct secret_pubkey_stuff *)pks,
+ };
+
logtime_t sign_time = logtime_start(logger);
- struct hash_signature sig = signer->sign_hash(pks,
+ struct hash_signature sig = signer->sign_hash(&s,
hash_to_sign->ptr,
hash_to_sign->len,
hash_algo,
@@ -124,5 +132,6 @@ static stf_status v2_auth_signature_completed(struct state *st,
static void v2_auth_signature_cleanup(struct task **task)
{
+ secret_pubkey_stuff_delref(&(*task)->pks, HERE);
pfreeany(*task);
}
--
2.47.1

View File

@ -0,0 +1,24 @@
From d2b6309933caaee42804eadd687a3a1f2db9833f Mon Sep 17 00:00:00 2001
From: Edward Leung <edward.leung@oracle.com>
Date: Wed, 9 Jan 2019 15:55:37 -0800
Subject: [PATCH] Add libreswan-oracle.patch to detect Oracle Linux distro
Signed-off-by: David Sloboda <david.x.sloboda@oracle.com>
diff --git a/libreswan-oracle.patch b/libreswan-oracle.patch
new file mode 100644
index 0000000..89a6e6f
--- /dev/null
+++ b/libreswan-oracle.patch
@@ -0,0 +1,12 @@
+diff -Nur libreswan-3.27.orig/programs/barf/barf.in libreswan-3.27/programs/barf/barf.in
+--- libreswan-3.27.orig/programs/barf/barf.in 2013-10-31 06:46:36.000000000 +0400
++++ libreswan-3.27/programs/barf/barf.in 2014-03-24 18:18:25.256273674 +0400
+@@ -272,7 +272,7 @@
+ cat /proc/config_built_with
+ fi
+ _________________________ distro-release
+-for distro in /etc/redhat-release /etc/debian-release /etc/SuSE-release /etc/mandrake-release /etc/mandriva-release /etc/gentoo-release
++for distro in /etc/redhat-release /etc/oracle-release /etc/debian-release /etc/SuSE-release /etc/mandrake-release /etc/mandriva-release /etc/gentoo-release
+ do
+ if [ -f ${distro} ]; then
+ cat ${distro}

View File

@ -30,8 +30,8 @@
Name: libreswan
Summary: Internet Key Exchange (IKEv1 and IKEv2) implementation for IPsec
# version is generated in the release script
Version: 4.12
Release: %{?prever:0.}2%{?prever:.%{prever}}%{?dist}.1
Version: 4.15
Release: %{?prever:0.}3%{?prever:.%{prever}}.0.1%{?dist}.3
License: GPLv2
Url: https://libreswan.org/
Source0: https://download.libreswan.org/%{?prever:development/}%{name}-%{version}%{?prever}.tar.gz
@ -41,9 +41,12 @@ Source2: https://download.libreswan.org/cavs/ikev1_psk.fax.bz2
Source3: https://download.libreswan.org/cavs/ikev2.fax.bz2
%endif
Patch: libreswan-4.6-ikev1-policy-defaults-to-drop.patch
Patch: libreswan-4.12-ikev2-auth-delete-state.patch
Patch: libreswan-4.12-ipv6-san.patch
Patch: libreswan-4.12-ikev1-compute-keymat-default.patch
Patch: libreswan-4.15-ondemand-tcp.patch
Patch: libreswan-4.15-netlink-extack.patch
Patch: libreswan-4.15-create-child-sa-race-condition.patch
Patch: libreswan-4.15-rereadsecrets.patch
Patch100: libreswan-oracle.patch
BuildRequires: audit-libs-devel
BuildRequires: bison
@ -199,7 +202,32 @@ certutil -N -d sql:$tmpdir --empty-password
%doc %{_mandir}/*/*
%changelog
* Wed Jun 5 2024 Daiki Ueno <dueno@redhat.com> - 4.12-2.1
* Tue Mar 18 2025 Craig Guiller <craig.guiller@oracle.com> - 4.15-3.0.1.3
- Add libreswan-oracle.patch to detect Oracle Linux distro
* Fri Jan 24 2025 Daiki Ueno <dueno@redhat.com> - 4.15-3.3
- showhostkey: fix regression after RHEL-68755 (RHEL-75967)
* Fri Nov 22 2024 Daiki Ueno <dueno@redhat.com> - 4.15-3.2
- crypto: refcnt struct secret_pubkey_stuff when passing to helper thread (RHEL-68755)
* Tue Nov 12 2024 Daiki Ueno <dueno@redhat.com> - 4.15-3.1
- pluto: ignore CREATE_CHILD_SA request if crypto is in progress (RHEL-71496)
* Tue Aug 6 2024 Daiki Ueno <dueno@redhat.com> - 4.15-3
- Fix release number
* Tue Aug 6 2024 Daiki Ueno <dueno@redhat.com> - 4.15-2
- Fix auto=ondemand connection initialization with TCP (RHEL-51879)
- Make use of Netlink extack for additional error reporting (RHEL-51881)
* Tue Jul 30 2024 Daiki Ueno <dueno@redhat.com> - 4.15-1
- Update to 4.15 (RHEL-50006)
* Thu Jul 11 2024 Daiki Ueno <dueno@redhat.com> - 4.12-4
- Bump release to synchronize with el9_5 package
* Wed Jun 5 2024 Daiki Ueno <dueno@redhat.com> - 4.12-3
- Fix CVE-2024-3652 (RHEL-32483)
* Thu Apr 11 2024 Daiki Ueno <dueno@redhat.com> - 4.12-2