[PATCH] add new_keys argument to esp_setup_keys() and comment clarifying esp.secrets format
Daniel Lenski
dlenski at gmail.com
Wed Oct 19 08:39:11 PDT 2016
This is to make esp_setup_keys() usable for both Juniper and GlobalProtect.
Juniper generates a new set of keys on the client side, while GlobalProtect
just needs to set up the keys provided by the server.
Signed-off-by: Daniel Lenski <dlenski at gmail.com>
---
gnutls-esp.c | 23 ++++++++++++++---------
oncp.c | 4 ++--
openconnect-internal.h | 4 ++--
openssl-esp.c | 23 ++++++++++++++---------
4 files changed, 32 insertions(+), 22 deletions(-)
diff --git a/gnutls-esp.c b/gnutls-esp.c
index 1ad4e60..ac58dcd 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 setup_esp_keys(struct openconnect_info *vpninfo, int new_keys)
{
struct esp *esp_in;
gnutls_mac_algorithm_t macalg;
@@ -106,16 +106,21 @@ int setup_esp_keys(struct openconnect_info *vpninfo)
return -EINVAL;
}
- vpninfo->old_esp_maxseq = vpninfo->esp_in[vpninfo->current_esp_in].seq + 32;
- vpninfo->current_esp_in ^= 1;
+ if (new_keys) {
+ 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 ((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;
+ 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);
diff --git a/oncp.c b/oncp.c
index b0f6d12..dd79c5a 100644
--- a/oncp.c
+++ b/oncp.c
@@ -778,7 +778,7 @@ int oncp_connect(struct openconnect_info *vpninfo)
put_len16(reqbuf, kmp);
#ifdef HAVE_ESP
- if (!setup_esp_keys(vpninfo)) {
+ if (!setup_esp_keys(vpninfo, TRUE)) {
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
@@ -830,7 +830,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)) {
+ if (!ret && !setup_esp_keys(vpninfo, TRUE)) {
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 c8612dd..379156f 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -337,7 +337,7 @@ struct esp {
uint64_t seq_backlog;
uint64_t seq;
uint32_t spi; /* Stored network-endian */
- unsigned char secrets[0x40];
+ unsigned char secrets[0x40]; /* Encryption key bytes, then HMAC key bytes */
};
struct openconnect_info {
@@ -889,7 +889,7 @@ void esp_shutdown(struct openconnect_info *vpninfo);
int print_esp_keys(struct openconnect_info *vpninfo, const char *name, struct esp *esp);
/* {gnutls,openssl}-esp.c */
-int setup_esp_keys(struct openconnect_info *vpninfo);
+int setup_esp_keys(struct openconnect_info *vpninfo, int new_keys);
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 e20bde0..e4d5e0c 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 setup_esp_keys(struct openconnect_info *vpninfo, int new_keys)
{
struct esp *esp_in;
const EVP_CIPHER *encalg;
@@ -146,16 +146,21 @@ int setup_esp_keys(struct openconnect_info *vpninfo)
return -EINVAL;
}
- vpninfo->old_esp_maxseq = vpninfo->esp_in[vpninfo->current_esp_in].seq + 32;
- vpninfo->current_esp_in ^= 1;
+ if (new_keys) {
+ 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 (!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;
+ 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);
--
2.7.4
More information about the openconnect-devel
mailing list