tls: support specifying accepted TLS ciphers
authorJo-Philipp Wich <jo@mein.io>
Sat, 15 Feb 2020 20:35:40 +0000 (21:35 +0100)
committerJo-Philipp Wich <jo@mein.io>
Sat, 15 Feb 2020 22:47:00 +0000 (23:47 +0100)
Introduce a new `-P` option which allows specifying a colon separated list
of accepted TLS ciphers.

Depending on the underlying ustream-ssl provider, the list either follows
OpenSSL's cipher string format or, in case of mbedTLS, is a simple colon
separated cipher whitelist.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
main.c
tls.c
tls.h

diff --git a/main.c b/main.c
index 6c29afe0d06facf7d885921250fc09e48b131afa..26e74ece57e77d1fb6810025073f53473891751c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -139,6 +139,7 @@ static int usage(const char *name)
                "       -s [addr:]port  Like -p but provide HTTPS on this port\n"
                "       -C file         ASN.1 server certificate file\n"
                "       -K file         ASN.1 server private key file\n"
                "       -s [addr:]port  Like -p but provide HTTPS on this port\n"
                "       -C file         ASN.1 server certificate file\n"
                "       -K file         ASN.1 server private key file\n"
+               "       -P ciphers      Colon separated list of allowed TLS ciphers\n"
                "       -q              Redirect all HTTP requests to HTTPS\n"
 #endif
                "       -h directory    Specify the document root, default is '.'\n"
                "       -q              Redirect all HTTP requests to HTTPS\n"
 #endif
                "       -h directory    Specify the document root, default is '.'\n"
@@ -249,7 +250,7 @@ int main(int argc, char **argv)
        int bound = 0;
 #ifdef HAVE_TLS
        int n_tls = 0;
        int bound = 0;
 #ifdef HAVE_TLS
        int n_tls = 0;
-       const char *tls_key = NULL, *tls_crt = NULL;
+       const char *tls_key = NULL, *tls_crt = NULL, *tls_ciphers = NULL;
 #endif
 #ifdef HAVE_LUA
        const char *lua_prefix = NULL, *lua_handler = NULL;
 #endif
 #ifdef HAVE_LUA
        const char *lua_prefix = NULL, *lua_handler = NULL;
@@ -261,7 +262,7 @@ int main(int argc, char **argv)
        init_defaults_pre();
        signal(SIGPIPE, SIG_IGN);
 
        init_defaults_pre();
        signal(SIGPIPE, SIG_IGN);
 
-       while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:fh:H:I:i:K:k:L:l:m:N:n:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
+       while ((ch = getopt(argc, argv, "A:aC:c:Dd:E:fh:H:I:i:K:k:L:l:m:N:n:P:p:qRr:Ss:T:t:U:u:Xx:y:")) != -1) {
                switch(ch) {
 #ifdef HAVE_TLS
                case 'C':
                switch(ch) {
 #ifdef HAVE_TLS
                case 'C':
@@ -272,6 +273,10 @@ int main(int argc, char **argv)
                        tls_key = optarg;
                        break;
 
                        tls_key = optarg;
                        break;
 
+               case 'P':
+                       tls_ciphers = optarg;
+                       break;
+
                case 'q':
                        conf.tls_redirect = 1;
                        break;
                case 'q':
                        conf.tls_redirect = 1;
                        break;
@@ -282,6 +287,7 @@ int main(int argc, char **argv)
 #else
                case 'C':
                case 'K':
 #else
                case 'C':
                case 'K':
+               case 'P':
                case 'q':
                case 's':
                        fprintf(stderr, "uhttpd: TLS support not compiled, "
                case 'q':
                case 's':
                        fprintf(stderr, "uhttpd: TLS support not compiled, "
@@ -523,7 +529,7 @@ int main(int argc, char **argv)
                        return 1;
                }
 
                        return 1;
                }
 
-               if (uh_tls_init(tls_key, tls_crt))
+               if (uh_tls_init(tls_key, tls_crt, tls_ciphers))
                    return 1;
        }
 #endif
                    return 1;
        }
 #endif
diff --git a/tls.c b/tls.c
index d969b8287064c608c0fd3acb8558010103f6702a..1da08812f12e37a9afda89963982f520cfe3be33 100644 (file)
--- a/tls.c
+++ b/tls.c
@@ -31,7 +31,7 @@ static struct ustream_ssl_ops *ops;
 static void *dlh;
 static void *ctx;
 
 static void *dlh;
 static void *ctx;
 
-int uh_tls_init(const char *key, const char *crt)
+int uh_tls_init(const char *key, const char *crt, const char *ciphers)
 {
        static bool _init = false;
 
 {
        static bool _init = false;
 
@@ -63,6 +63,11 @@ int uh_tls_init(const char *key, const char *crt)
                return -EINVAL;
        }
 
                return -EINVAL;
        }
 
+       if (ciphers && ops->context_set_ciphers(ctx, ciphers)) {
+               fprintf(stderr, "No recognized ciphers in cipher list\n");
+               return -EINVAL;
+       }
+
        return 0;
 }
 
        return 0;
 }
 
diff --git a/tls.h b/tls.h
index 9be74ba85d7007460b19f1a6071b3cb04d33761a..f457cb76f343fbf6aa6e13a3c42e9cd8280422fe 100644 (file)
--- a/tls.h
+++ b/tls.h
 
 #ifdef HAVE_TLS
 
 
 #ifdef HAVE_TLS
 
-int uh_tls_init(const char *key, const char *crt);
+int uh_tls_init(const char *key, const char *crt, const char *ciphers);
 void uh_tls_client_attach(struct client *cl);
 void uh_tls_client_detach(struct client *cl);
 
 #else
 
 void uh_tls_client_attach(struct client *cl);
 void uh_tls_client_detach(struct client *cl);
 
 #else
 
-static inline int uh_tls_init(const char *key, const char *crt)
+static inline int uh_tls_init(const char *key, const char *crt, const char *ciphers)
 {
        return -1;
 }
 {
        return -1;
 }