[PATCH 4/6] Added --pfs option to force perfect forward secrecy
Nikos Mavrogiannopoulos
nmav at gnutls.org
Sat Nov 23 12:58:28 EST 2013
The PFS option will prevent a leakage of the server long-term key from causing
decryption of all previously exchanged data.
Signed-off-by: Nikos Mavrogiannopoulos <nmav at gnutls.org>
---
gnutls.c | 18 +++++++++++++-----
main.c | 6 ++++++
openconnect-internal.h | 1 +
openssl.c | 3 +++
4 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/gnutls.c b/gnutls.c
index 52e632b..d25ec23 100644
--- a/gnutls.c
+++ b/gnutls.c
@@ -1801,11 +1801,14 @@ static int verify_peer(gnutls_session_t session)
return err;
}
+#define DEFAULT_PRIO "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:" \
+ "%COMPAT:%DISABLE_SAFE_RENEGOTIATION:%LATEST_RECORD_VERSION"
int openconnect_open_https(struct openconnect_info *vpninfo)
{
int ssl_sock = -1;
int err;
+ const char * prio;
if (vpninfo->https_sess)
return 0;
@@ -1912,13 +1915,18 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
gnutls_sign_callback_set(vpninfo->https_sess, gtls2_tpm_sign_cb, vpninfo);
#endif
- err = gnutls_priority_set_direct(vpninfo->https_sess,
- "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:"
+ if (vpninfo->pfs) {
+ prio = DEFAULT_PRIO":-RSA";
+ } else {
+ prio = DEFAULT_PRIO
#if GNUTLS_VERSION_MAJOR >= 3
- "-CURVE-ALL:"
+ ":-CURVE-ALL"
#endif
- "%COMPAT:%DISABLE_SAFE_RENEGOTIATION:%LATEST_RECORD_VERSION",
- NULL);
+ ;
+ }
+
+ err = gnutls_priority_set_direct(vpninfo->https_sess,
+ prio, NULL);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to set TLS priority string: %s\n"),
diff --git a/main.c b/main.c
index 5ddd9b8..afaedf2 100644
--- a/main.c
+++ b/main.c
@@ -116,6 +116,7 @@ enum {
OPT_TOKEN_MODE,
OPT_TOKEN_SECRET,
OPT_OS,
+ OPT_PFS,
};
#ifdef __sun__
@@ -130,6 +131,7 @@ enum {
static struct option long_options[] = {
OPTION("background", 0, 'b'),
+ OPTION("pfs", 0, OPT_PFS),
OPTION("pid-file", 1, OPT_PIDFILE),
OPTION("certificate", 1, 'c'),
OPTION("sslkey", 1, 'k'),
@@ -270,6 +272,7 @@ static void usage(void)
#ifndef LIBPROXY_HDR
printf(" %s\n", _("(NOTE: libproxy disabled in this build)"));
#endif
+ printf(" --pfs %s\n", _("Require perfect forward secrecy"));
printf(" -q, --quiet %s\n", _("Less output"));
printf(" -Q, --queue-len=LEN %s\n", _("Set packet queue limit to LEN pkts"));
printf(" -s, --script=SCRIPT %s\n", _("Shell command line for using a vpnc-compatible config script"));
@@ -541,6 +544,9 @@ int main(int argc, char **argv)
case OPT_PIDFILE:
pidfile = keep_config_arg();
break;
+ case OPT_PFS:
+ vpninfo->pfs = 1;
+ break;
case OPT_SERVERCERT:
vpninfo->servercert = keep_config_arg();
break;
diff --git a/openconnect-internal.h b/openconnect-internal.h
index 4dc9ed4..b480847 100644
--- a/openconnect-internal.h
+++ b/openconnect-internal.h
@@ -203,6 +203,7 @@ struct openconnect_info {
struct vpn_option *cstp_options;
struct vpn_option *dtls_options;
+ unsigned pfs;
#if defined(OPENCONNECT_OPENSSL)
X509 *cert_x509;
SSL_CTX *https_ctx;
diff --git a/openssl.c b/openssl.c
index a395bc5..43a2093 100644
--- a/openssl.c
+++ b/openssl.c
@@ -1319,6 +1319,9 @@ int openconnect_open_https(struct openconnect_info *vpninfo)
ssl_app_verify_callback, NULL);
#endif
SSL_CTX_set_default_verify_paths(vpninfo->https_ctx);
+
+ if (vpninfo->pfs)
+ SSL_CTX_set_cipher_list(vpninfo->https_ctx, "HIGH:!aNULL:!eNULL:-RSA");
#ifdef ANDROID_KEYSTORE
if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) {
More information about the openconnect-devel
mailing list