[PATCH 6/8] add new_keys argument to esp_setup_keys() in preparation for supporting GlobalProtect ESP
Daniel Lenski
dlenski at gmail.com
Sat May 20 15:43:27 PDT 2017
The existing ESP key setup code can be almost entirely reused for
GlobalProtect ESP, except for the fact that esp_setup_keys() always
overwrites the secret keys with new random keys.
Since GlobalProtect ESP always uses keys provided by the server, a new
argument is added to esp_setup_keys() to make this behavior optional.
The Juniper-specific code in oncp.c calls it with new_keys=1 in order
to explicitly request it.
Signed-off-by: Daniel Lenski <dlenski at gmail.com>
---
gnutls-esp.c | 23 ++++++++++++++---------
oncp.c | 4 ++--
openconnect-internal.h | 2 +-
openssl-esp.c | 23 ++++++++++++++---------
4 files changed, 31 insertions(+), 21 deletions(-)
diff --git a/gnutls-esp.c b/gnutls-esp.c
index f3fd499..916cbc7 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,17 +106,22 @@ 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))) ||
+ 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->enc_key, vpninfo->enc_key_len)) ||
(ret = gnutls_rnd(GNUTLS_RND_RANDOM, &esp_in->hmac_key, vpninfo->hmac_key_len)) ) {
- vpn_progress(vpninfo, PRG_ERR,
- _("Failed to generate random keys for ESP: %s\n"),
- gnutls_strerror(ret));
- return -EIO;
+ 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);
@@ -197,7 +202,7 @@ int encrypt_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt)
pkt->data[pkt->len + i] = i + 1;
pkt->data[pkt->len + padlen] = padlen;
pkt->data[pkt->len + padlen + 1] = 0x04; /* Legacy IP */
-
+
gnutls_cipher_set_iv(vpninfo->esp_out.cipher, pkt->esp.iv, sizeof(pkt->esp.iv));
err = gnutls_cipher_encrypt(vpninfo->esp_out.cipher, pkt->data, pkt->len + padlen + 2);
if (err) {
diff --git a/oncp.c b/oncp.c
index 59cfa4b..f7d3d68 100644
--- a/oncp.c
+++ b/oncp.c
@@ -777,7 +777,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, 1)) {
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
@@ -831,7 +831,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, 1)) {
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 a9e2750..a16b05f 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -930,7 +930,7 @@ int esp_send_probes(struct openconnect_info *vpninfo);
int esp_catch_probe(struct openconnect_info *vpninfo, struct pkt *pkt);
/* {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 faba1ff..ec60dfc 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,17 +146,22 @@ 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)) ||
+ if (new_keys) {
+ if (!RAND_bytes((void *)&esp_in->spi, sizeof(esp_in->spi)) ||
!RAND_bytes((void *)&esp_in->enc_key, vpninfo->enc_key_len)) ||
!RAND_bytes((void *)&esp_in->hmac_key, vpninfo->hmac_key_len)) ) {
- vpn_progress(vpninfo, PRG_ERR,
- _("Failed to generate random keys for ESP:\n"));
- openconnect_report_ssl_errors(vpninfo);
- return -EIO;
+ 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);
@@ -242,7 +247,7 @@ int encrypt_esp_packet(struct openconnect_info *vpninfo, struct pkt *pkt)
pkt->data[pkt->len + i] = i + 1;
pkt->data[pkt->len + padlen] = padlen;
pkt->data[pkt->len + padlen + 1] = 0x04; /* Legacy IP */
-
+
if (!EVP_EncryptInit_ex(vpninfo->esp_out.cipher, NULL, NULL, NULL,
pkt->esp.iv)) {
vpn_progress(vpninfo, PRG_ERR,
--
2.7.4
More information about the openconnect-devel
mailing list