summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEthan Rahn <erahn@arista.com>2016-10-06 16:21:33 -0700
committerBen Pfaff <blp@ovn.org>2016-11-10 10:36:42 -0800
commite18a1d0861338058f591e09b30415d758bdbac9b (patch)
treed94eaf8163bcbac6a5490c2644260dca549fbb66 /lib
parent60230e06ce89ac7bb4e2cba85a4e037a5ffbd224 (diff)
downloadopenvswitch-e18a1d0861338058f591e09b30415d758bdbac9b.tar.gz
Add support for specifying SSL connection parameters to ovsdb
Signed-off-by: Ethan Rahn <erahn@arista.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/automake.mk2
-rw-r--r--lib/ssl-connect-syn.man5
-rw-r--r--lib/ssl-connect.man12
-rw-r--r--lib/stream-nossl.c16
-rw-r--r--lib/stream-ssl.c65
-rw-r--r--lib/stream-ssl.h20
6 files changed, 117 insertions, 3 deletions
diff --git a/lib/automake.mk b/lib/automake.mk
index 81d5097be..9345cee7d 100644
--- a/lib/automake.mk
+++ b/lib/automake.mk
@@ -461,6 +461,8 @@ MAN_FRAGMENTS += \
lib/ssl-peer-ca-cert-syn.man \
lib/ssl.man \
lib/ssl-syn.man \
+ lib/ssl-connect.man \
+ lib/ssl-connect-syn.man \
lib/table.man \
lib/unixctl.man \
lib/unixctl-syn.man \
diff --git a/lib/ssl-connect-syn.man b/lib/ssl-connect-syn.man
new file mode 100644
index 000000000..ed77f7868
--- /dev/null
+++ b/lib/ssl-connect-syn.man
@@ -0,0 +1,5 @@
+.IP "SSL connection options:"
+[\fB\-\-ssl\-protocols=\fIprotocols\fR]
+.br
+[\fB\-\-ssl\-ciphers=\fIciphers\fR]
+.br
diff --git a/lib/ssl-connect.man b/lib/ssl-connect.man
new file mode 100644
index 000000000..6e54f77ef
--- /dev/null
+++ b/lib/ssl-connect.man
@@ -0,0 +1,12 @@
+.IP "\fB\-\-ssl\-protocols=\fIprotocols\fR"
+Specifies, in a comma- or space-delimited list, the SSL protocols
+\fB\*(PN\fR will enable for SSL connections. Supported
+\fIprotocols\fR include \fBTLSv1\fR, \fBTLSv1.1\fR, and \fBTLSv1.2\fR.
+Regardless of order, the highest protocol supported by both sides will
+be chosen when making the connection. The default when this option is
+omitted is \fBTLSv1,TLSv1.1,TLSv1.2\fR.
+.
+.IP "\fB\-\-ssl\-ciphers=\fIciphers\fR"
+Specifies, in OpenSSL cipher string format, the ciphers \fB\*(PN\fR will
+support for SSL connections. The default when this option is omitted is
+\fBHIGH:!aNULL:!MD5\fR.
diff --git a/lib/stream-nossl.c b/lib/stream-nossl.c
index 26fcc978e..6ea622b7c 100644
--- a/lib/stream-nossl.c
+++ b/lib/stream-nossl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Nicira, Inc.
+ * Copyright (c) 2011, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -74,3 +74,17 @@ stream_ssl_set_key_and_cert(const char *private_key_file,
stream_ssl_set_private_key_file(private_key_file);
stream_ssl_set_certificate_file(certificate_file);
}
+
+void
+stream_ssl_set_protocols(const char *arg OVS_UNUSED)
+{
+ /* Ignore this option since it seems harmless to set SSL protocols if SSL
+ * won't be used. */
+}
+
+void
+stream_ssl_set_ciphers(const char *arg OVS_UNUSED)
+{
+ /* Ignore this option since it seems harmless to set SSL ciphers if SSL
+ * won't be used. */
+}
diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c
index dcafc2d48..5d88b52a2 100644
--- a/lib/stream-ssl.c
+++ b/lib/stream-ssl.c
@@ -162,6 +162,8 @@ struct ssl_config_file {
static struct ssl_config_file private_key;
static struct ssl_config_file certificate;
static struct ssl_config_file ca_cert;
+static char *ssl_protocols = "TLSv1,TLSv1.1,TLSv1.2";
+static char *ssl_ciphers = "HIGH:!aNULL:!MD5";
/* Ordinarily, the SSL client and server verify each other's certificates using
* a CA certificate. Setting this to false disables this behavior. (This is a
@@ -966,6 +968,7 @@ do_ssl_init(void)
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
NULL);
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
+ SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL:!MD5");
return 0;
}
@@ -1114,6 +1117,68 @@ stream_ssl_set_key_and_cert(const char *private_key_file,
}
}
+/* Sets SSL ciphers based on string input. Aborts with an error message
+ * if 'arg' is invalid. */
+void
+stream_ssl_set_ciphers(const char *arg)
+{
+ if (ssl_init() || !arg || !strcmp(ssl_ciphers, arg)) {
+ return;
+ }
+ if (SSL_CTX_set_cipher_list(ctx,arg) == 0) {
+ VLOG_ERR("SSL_CTX_set_cipher_list: %s",
+ ERR_error_string(ERR_get_error(), NULL));
+ }
+ ssl_ciphers = xstrdup(arg);
+}
+
+/* Set SSL protocols based on the string input. Aborts with an error message
+ * if 'arg' is invalid. */
+void
+stream_ssl_set_protocols(const char *arg)
+{
+ if (ssl_init() || !arg || !strcmp(arg, ssl_protocols)){
+ return;
+ }
+
+ /* Start with all the flags off and turn them on as requested. */
+ long protocol_flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
+ protocol_flags |= SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
+
+ char *s = xstrdup(arg);
+ char *save_ptr = NULL;
+ char *word = strtok_r(s, " ,\t", &save_ptr);
+ if (word == NULL) {
+ VLOG_ERR("SSL protocol settings invalid");
+ goto exit;
+ }
+ while (word != NULL) {
+ long on_flag;
+ if (!strcasecmp(word, "TLSv1.2")){
+ on_flag = SSL_OP_NO_TLSv1_2;
+ } else if (!strcasecmp(word, "TLSv1.1")){
+ on_flag = SSL_OP_NO_TLSv1_1;
+ } else if (!strcasecmp(word, "TLSv1")){
+ on_flag = SSL_OP_NO_TLSv1;
+ } else {
+ VLOG_ERR("%s: SSL protocol not recognized", word);
+ goto exit;
+ }
+ /* Reverse the no flag and mask it out in the flags
+ * to turn on that protocol. */
+ protocol_flags &= ~on_flag;
+ word = strtok_r(NULL, " ,\t", &save_ptr);
+ };
+
+ /* Set the actual options. */
+ SSL_CTX_set_options(ctx, protocol_flags);
+
+ ssl_protocols = xstrdup(arg);
+
+exit:
+ free(s);
+}
+
/* Reads the X509 certificate or certificates in file 'file_name'. On success,
* stores the address of the first element in an array of pointers to
* certificates in '*certs' and the number of certificates in the array in
diff --git a/lib/stream-ssl.h b/lib/stream-ssl.h
index 030f66225..4bfe09b00 100644
--- a/lib/stream-ssl.h
+++ b/lib/stream-ssl.h
@@ -25,11 +25,19 @@ void stream_ssl_set_ca_cert_file(const char *file_name, bool bootstrap);
void stream_ssl_set_peer_ca_cert_file(const char *file_name);
void stream_ssl_set_key_and_cert(const char *private_key_file,
const char *certificate_file);
+void stream_ssl_set_protocols(const char *arg);
+void stream_ssl_set_ciphers(const char *arg);
+
+#define SSL_OPTION_ENUMS \
+ OPT_SSL_PROTOCOLS, \
+ OPT_SSL_CIPHERS
#define STREAM_SSL_LONG_OPTIONS \
{"private-key", required_argument, NULL, 'p'}, \
{"certificate", required_argument, NULL, 'c'}, \
- {"ca-cert", required_argument, NULL, 'C'}
+ {"ca-cert", required_argument, NULL, 'C'}, \
+ {"ssl-protocols", required_argument, NULL, OPT_SSL_PROTOCOLS}, \
+ {"ssl-ciphers", required_argument, NULL, OPT_SSL_CIPHERS}
#define STREAM_SSL_OPTION_HANDLERS \
case 'p': \
@@ -42,6 +50,14 @@ void stream_ssl_set_key_and_cert(const char *private_key_file,
\
case 'C': \
stream_ssl_set_ca_cert_file(optarg, false); \
- break;
+ break; \
+ \
+ case OPT_SSL_PROTOCOLS: \
+ stream_ssl_set_protocols(optarg); \
+ break; \
+ \
+ case OPT_SSL_CIPHERS: \
+ stream_ssl_set_ciphers(optarg); \
+ break;
#endif /* stream-ssl.h */