[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