diff options
author | Ethan Rahn <erahn@arista.com> | 2016-10-06 16:21:33 -0700 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-11-10 10:36:42 -0800 |
commit | e18a1d0861338058f591e09b30415d758bdbac9b (patch) | |
tree | d94eaf8163bcbac6a5490c2644260dca549fbb66 /lib | |
parent | 60230e06ce89ac7bb4e2cba85a4e037a5ffbd224 (diff) | |
download | openvswitch-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.mk | 2 | ||||
-rw-r--r-- | lib/ssl-connect-syn.man | 5 | ||||
-rw-r--r-- | lib/ssl-connect.man | 12 | ||||
-rw-r--r-- | lib/stream-nossl.c | 16 | ||||
-rw-r--r-- | lib/stream-ssl.c | 65 | ||||
-rw-r--r-- | lib/stream-ssl.h | 20 |
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 */ |