[PATCH] refactor setup_esp_keys() to work for both Juniper and GP

Daniel Lenski dlenski at gmail.com
Tue Dec 27 11:02:48 PST 2016


Added a new oncp_setup_esp_keys() which handles the generation of new, random
keys for Juniper, and then calls the generic setup_esp_keys(), which just
initializes the cipher and MAC.

Mostly reverts my previous take on this from 8796139f9.

This was suggested by David Woodhouse:

> Just make an oncp_setup_esp_keys() function which creates the new keys and
> *then* calls the generic setup_esp_keys()? Note that the flip to the
> new incoming ESP setup has to be done *first*, or at least taken into
> account.

Signed-off-by: Daniel Lenski <dlenski at gmail.com>
---
 gnutls-esp.c           | 18 +++---------------
 gpst.c                 |  5 +++--
 oncp.c                 | 31 +++++++++++++++++++++++++++++--
 openconnect-internal.h |  2 +-
 openssl-esp.c          | 18 +++---------------
 5 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/gnutls-esp.c b/gnutls-esp.c
index 0b63e0f..7666f10 100644
--- a/gnutls-esp.c
+++ b/gnutls-esp.c
@@ -72,7 +72,7 @@ static int init_esp_ciphers(struct openconnect_info *vpninfo, struct esp *esp,
 	return 0;
 }
 
-int setup_esp_keys(struct openconnect_info *vpninfo, int new_keys)
+int setup_esp_keys(struct openconnect_info *vpninfo)
 {
 	struct esp *esp_in;
 	gnutls_mac_algorithm_t macalg;
@@ -106,23 +106,11 @@ int setup_esp_keys(struct openconnect_info *vpninfo, int new_keys)
 		return -EINVAL;
 	}
 
-	if (new_keys) {
-		vpninfo->old_esp_maxseq = vpninfo->esp_in[vpninfo->current_esp_in].seq + 32;
-		vpninfo->current_esp_in ^= 1;
-	}
+	vpninfo->old_esp_maxseq = vpninfo->esp_in[vpninfo->current_esp_in].seq + 32;
+	vpninfo->current_esp_in ^= 1;
 
 	esp_in = &vpninfo->esp_in[vpninfo->current_esp_in];
 
-	if (new_keys) {
-		if ((ret = gnutls_rnd(GNUTLS_RND_NONCE, &esp_in->spi, sizeof(esp_in->spi))) ||
-		    (ret = gnutls_rnd(GNUTLS_RND_RANDOM, &esp_in->secrets, sizeof(esp_in->secrets)))) {
-			vpn_progress(vpninfo, PRG_ERR,
-				     _("Failed to generate random keys for ESP: %s\n"),
-				     gnutls_strerror(ret));
-			return -EIO;
-		}
-	}
-
 	ret = init_esp_ciphers(vpninfo, &vpninfo->esp_out, macalg, encalg);
 	if (ret)
 		return ret;
diff --git a/gpst.c b/gpst.c
index 7179ecb..3346194 100644
--- a/gpst.c
+++ b/gpst.c
@@ -286,7 +286,8 @@ static int gpst_parse_config_xml(struct openconnect_info *vpninfo, xmlNode *xml_
 			}
 		} else if (xmlnode_is_named(xml_node, "ipsec")) {
 #ifdef HAVE_ESP
-			int c = (vpninfo->current_esp_in ^= 1);
+			/* setup_esp_keys() will swap the active incoming key-set */
+			int c = (vpninfo->current_esp_in ^ 1);
 			int enclen=0, maclen=0;
 			for (member = xml_node->children; member; member=member->next) {
 				s = NULL;
@@ -303,7 +304,7 @@ static int gpst_parse_config_xml(struct openconnect_info *vpninfo, xmlNode *xml_
 				free((void *)s);
 			}
 			if (vpninfo->dtls_state != DTLS_DISABLED) {
-				if (setup_esp_keys(vpninfo, 0))
+				if (setup_esp_keys(vpninfo))
 					vpn_progress(vpninfo, PRG_ERR, "Failed to setup ESP keys.\n");
 				else
 					vpninfo->dtls_times.last_rekey = time(NULL);
diff --git a/oncp.c b/oncp.c
index 61ff9cf..f58c389 100644
--- a/oncp.c
+++ b/oncp.c
@@ -523,6 +523,33 @@ static int parse_conf_pkt(struct openconnect_info *vpninfo, unsigned char *bytes
 	return 0;
 }
 
+static int oncp_setup_esp_keys(struct openconnect_info *vpninfo)
+{
+	int ret;
+	/* setup_esp_keys() will swap the active incoming key-set */
+	struct esp *esp_in = &vpninfo->esp_in[vpninfo->current_esp_in ^ 1];
+
+#if defined(OPENCONNECT_GNUTLS)
+	if ((ret = gnutls_rnd(GNUTLS_RND_NONCE, &esp_in->spi, sizeof(esp_in->spi))) ||
+	    (ret = gnutls_rnd(GNUTLS_RND_RANDOM, &esp_in->secrets, sizeof(esp_in->secrets)))) {
+		vpn_progress(vpninfo, PRG_ERR,
+			     _("Failed to generate random keys for ESP: %s\n"),
+			     gnutls_strerror(ret));
+		return -EIO;
+	}
+#elif defined(OPENCONNECT_OPENSSL)
+	if (!RAND_bytes((void *)&esp_in->spi, sizeof(esp_in->spi)) ||
+	    !RAND_bytes((void *)&esp_in->secrets, sizeof(esp_in->secrets))) {
+		vpn_progress(vpninfo, PRG_ERR,
+			     _("Failed to generate random keys for ESP:\n"));
+		openconnect_report_ssl_errors(vpninfo);
+		return -EIO;
+	}
+#endif
+
+	return setup_esp_keys(vpninfo);
+}
+
 int oncp_connect(struct openconnect_info *vpninfo)
 {
 	int ret, len, kmp, kmplen, group;
@@ -762,7 +789,7 @@ int oncp_connect(struct openconnect_info *vpninfo)
 	put_len16(reqbuf, kmp);
 
 #ifdef HAVE_ESP
-	if (!setup_esp_keys(vpninfo, 1)) {
+	if (!oncp_setup_esp_keys(vpninfo)) {
 		struct esp *esp = &vpninfo->esp_in[vpninfo->current_esp_in];
 		/* Since we'll want to do this in the oncp_mainloop too, where it's easier
 		 * *not* to have an oc_text_buf and build it up manually, and since it's
@@ -814,7 +841,7 @@ static int oncp_receive_espkeys(struct openconnect_info *vpninfo, int len)
 	int ret;
 
 	ret = parse_conf_pkt(vpninfo, vpninfo->cstp_pkt->oncp.kmp, len + 20, 301);
-	if (!ret && !setup_esp_keys(vpninfo, 1)) {
+	if (!ret && !oncp_setup_esp_keys(vpninfo)) {
 		struct esp *esp = &vpninfo->esp_in[vpninfo->current_esp_in];
 		unsigned char *p = vpninfo->cstp_pkt->oncp.kmp;
 
diff --git a/openconnect-internal.h b/openconnect-internal.h
index 466828d..c9f7b08 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -922,7 +922,7 @@ int esp_catch_probe(struct openconnect_info *vpninfo, struct pkt *pkt);
 int esp_catch_probe_gp(struct openconnect_info *vpninfo, struct pkt *pkt);
 
 /* {gnutls,openssl}-esp.c */
-int setup_esp_keys(struct openconnect_info *vpninfo, int new_keys);
+int setup_esp_keys(struct openconnect_info *vpninfo);
 void destroy_esp_ciphers(struct esp *esp);
 int decrypt_esp_packet(struct openconnect_info *vpninfo, struct esp *esp, struct pkt *pkt);
 int encrypt_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt);
diff --git a/openssl-esp.c b/openssl-esp.c
index f58d32f..9224388 100644
--- a/openssl-esp.c
+++ b/openssl-esp.c
@@ -112,7 +112,7 @@ static int init_esp_ciphers(struct openconnect_info *vpninfo, struct esp *esp,
 	return 0;
 }
 
-int setup_esp_keys(struct openconnect_info *vpninfo, int new_keys)
+int setup_esp_keys(struct openconnect_info *vpninfo)
 {
 	struct esp *esp_in;
 	const EVP_CIPHER *encalg;
@@ -146,23 +146,11 @@ int setup_esp_keys(struct openconnect_info *vpninfo, int new_keys)
 		return -EINVAL;
 	}
 
-	if (new_keys) {
-		vpninfo->old_esp_maxseq = vpninfo->esp_in[vpninfo->current_esp_in].seq + 32;
-		vpninfo->current_esp_in ^= 1;
-	}
+	vpninfo->old_esp_maxseq = vpninfo->esp_in[vpninfo->current_esp_in].seq + 32;
+	vpninfo->current_esp_in ^= 1;
 
 	esp_in = &vpninfo->esp_in[vpninfo->current_esp_in];
 
-	if (new_keys) {
-		if (!RAND_bytes((void *)&esp_in->spi, sizeof(esp_in->spi)) ||
-		    !RAND_bytes((void *)&esp_in->secrets, sizeof(esp_in->secrets))) {
-			vpn_progress(vpninfo, PRG_ERR,
-				     _("Failed to generate random keys for ESP:\n"));
-			openconnect_report_ssl_errors(vpninfo);
-			return -EIO;
-		}
-	}
-
 	ret = init_esp_ciphers(vpninfo, &vpninfo->esp_out, macalg, encalg, 0);
 	if (ret)
 		return ret;
-- 
2.7.4




More information about the openconnect-devel mailing list