]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
add new_keys argument to esp_setup_keys() in preparation for supporting GlobalProtect ESP
authorDaniel Lenski <dlenski@gmail.com>
Sat, 20 May 2017 22:43:27 +0000 (15:43 -0700)
committerDavid Woodhouse <dwmw2@infradead.org>
Mon, 14 Aug 2017 16:26:46 +0000 (17:26 +0100)
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@gmail.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
gnutls-esp.c
oncp.c
openconnect-internal.h
openssl-esp.c

index f3fd499c2b1f8865da475acb68b5034e78777b68..916cbc7c93327d40b727b0f5a8ed99a5b86d2c34 100644 (file)
@@ -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 38673c7c541b3fba63ba8042b1daff9ebd04aac1..17853af923677497888c129ec078202b58ceb2ef 100644 (file)
--- a/oncp.c
+++ b/oncp.c
@@ -789,7 +789,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
@@ -843,7 +843,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;
 
index 933f78c29d001dc80f77dc6b408f5491a418db6c..b70085d2189bed16f1fb645681aafa8945cb73bb 100644 (file)
@@ -905,7 +905,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);
index 14228ef0b77bd5ab0e357d56d9915c3135247a6c..c3dff510e2338ccaafc12bf1ef199f500eaa3c79 100644 (file)
@@ -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)) ||
-           !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;
+       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;
+               }
        }
 
        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,