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