blob: 8d38f285957b093f9409cfb60da8b79056dd2f16 [file] [log] [blame]
yanbzhu08ce6ab2015-12-02 13:01:29 -05001
Emeric Brun46591952012-05-18 15:47:34 +02002/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02004 *
5 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
Willy Tarreau69845df2012-09-10 09:43:09 +020012 * Acknowledgement:
13 * We'd like to specially thank the Stud project authors for a very clean
14 * and well documented code which helped us understand how the OpenSSL API
15 * ought to be used in non-blocking mode. This is one difficult part which
16 * is not easy to get from the OpenSSL doc, and reading the Stud code made
17 * it much more obvious than the examples in the OpenSSL package. Keep up
18 * the good works, guys !
19 *
20 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
21 * particularly well with haproxy. For more info about this project, visit :
22 * https://github.com/bumptech/stud
23 *
Emeric Brun46591952012-05-18 15:47:34 +020024 */
25
26#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020027#include <ctype.h>
28#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020029#include <errno.h>
30#include <fcntl.h>
31#include <stdio.h>
32#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020033#include <string.h>
34#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020035
36#include <sys/socket.h>
37#include <sys/stat.h>
38#include <sys/types.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020039#include <netdb.h>
Emeric Brun46591952012-05-18 15:47:34 +020040#include <netinet/tcp.h>
41
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020042#include <openssl/crypto.h>
Emeric Brun46591952012-05-18 15:47:34 +020043#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020044#include <openssl/x509.h>
45#include <openssl/x509v3.h>
46#include <openssl/x509.h>
47#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010048#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010049#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020050#include <openssl/ocsp.h>
51#endif
Remi Gacogne4f902b82015-05-28 16:23:00 +020052#ifndef OPENSSL_NO_DH
53#include <openssl/dh.h>
54#endif
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +020055#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +000056#include <openssl/engine.h>
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +020057#endif
Emeric Brun46591952012-05-18 15:47:34 +020058
Grant Zhangfa6c7ee2017-01-14 01:42:15 +000059#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
60#include <openssl/async.h>
61#endif
62
Christopher Faulet31af49d2015-06-09 17:29:50 +020063#include <import/lru.h>
64#include <import/xxhash.h>
65
Emeric Brun46591952012-05-18 15:47:34 +020066#include <common/buffer.h>
67#include <common/compat.h>
68#include <common/config.h>
69#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020070#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020071#include <common/standard.h>
72#include <common/ticks.h>
73#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010074#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010075#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020076
Emeric Brunfc0421f2012-09-07 17:30:07 +020077#include <ebsttree.h>
78
William Lallemand32af2032016-10-29 18:09:35 +020079#include <types/applet.h>
80#include <types/cli.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020081#include <types/global.h>
82#include <types/ssl_sock.h>
William Lallemand32af2032016-10-29 18:09:35 +020083#include <types/stats.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020084
Willy Tarreau7875d092012-09-10 08:20:03 +020085#include <proto/acl.h>
86#include <proto/arg.h>
William Lallemand32af2032016-10-29 18:09:35 +020087#include <proto/channel.h>
Emeric Brun46591952012-05-18 15:47:34 +020088#include <proto/connection.h>
William Lallemand32af2032016-10-29 18:09:35 +020089#include <proto/cli.h>
Emeric Brun46591952012-05-18 15:47:34 +020090#include <proto/fd.h>
91#include <proto/freq_ctr.h>
92#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020093#include <proto/listener.h>
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020094#include <proto/openssl-compat.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010095#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020096#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020097#include <proto/server.h>
William Lallemand32af2032016-10-29 18:09:35 +020098#include <proto/stream_interface.h>
Emeric Brun46591952012-05-18 15:47:34 +020099#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +0200100#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +0200101#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +0200102#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +0200103#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +0200104#include <proto/task.h>
105
Willy Tarreau518cedd2014-02-17 15:43:01 +0100106/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +0200107#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +0100108#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +0100109#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +0200110#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
111
Emeric Brunf282a812012-09-21 15:27:54 +0200112/* bits 0xFFFF0000 are reserved to store verify errors */
113
114/* Verify errors macros */
115#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
116#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
117#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
118
119#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
120#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
121#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200122
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100123/* Supported hash function for TLS tickets */
124#ifdef OPENSSL_NO_SHA256
125#define HASH_FUNCT EVP_sha1
126#else
127#define HASH_FUNCT EVP_sha256
128#endif /* OPENSSL_NO_SHA256 */
129
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200130/* ssl_methods flags for ssl options */
131#define MC_SSL_O_ALL 0x0000
132#define MC_SSL_O_NO_SSLV3 0x0001 /* disable SSLv3 */
133#define MC_SSL_O_NO_TLSV10 0x0002 /* disable TLSv10 */
134#define MC_SSL_O_NO_TLSV11 0x0004 /* disable TLSv11 */
135#define MC_SSL_O_NO_TLSV12 0x0008 /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +0200136#define MC_SSL_O_NO_TLSV13 0x0010 /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200137
138/* ssl_methods versions */
139enum {
140 CONF_TLSV_NONE = 0,
141 CONF_TLSV_MIN = 1,
142 CONF_SSLV3 = 1,
143 CONF_TLSV10 = 2,
144 CONF_TLSV11 = 3,
145 CONF_TLSV12 = 4,
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +0200146 CONF_TLSV13 = 5,
147 CONF_TLSV_MAX = 5,
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200148};
149
Emeric Brun850efd52014-01-29 12:24:34 +0100150/* server and bind verify method, it uses a global value as default */
151enum {
152 SSL_SOCK_VERIFY_DEFAULT = 0,
153 SSL_SOCK_VERIFY_REQUIRED = 1,
154 SSL_SOCK_VERIFY_OPTIONAL = 2,
155 SSL_SOCK_VERIFY_NONE = 3,
156};
157
Willy Tarreau71b734c2014-01-28 15:19:44 +0100158int sslconns = 0;
159int totalsslconns = 0;
Willy Tarreaud9f5cca2016-12-22 21:08:52 +0100160static struct xprt_ops ssl_sock;
Emeric Brune1f38db2012-09-03 20:36:47 +0200161
Willy Tarreauef934602016-12-22 23:12:01 +0100162static struct {
163 char *crt_base; /* base directory path for certificates */
164 char *ca_base; /* base directory path for CAs and CRLs */
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000165 int async; /* whether we use ssl async mode */
Willy Tarreauef934602016-12-22 23:12:01 +0100166
167 char *listen_default_ciphers;
168 char *connect_default_ciphers;
169 int listen_default_ssloptions;
170 int connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200171 struct tls_version_filter listen_default_sslmethods;
172 struct tls_version_filter connect_default_sslmethods;
Willy Tarreauef934602016-12-22 23:12:01 +0100173
174 int private_cache; /* Force to use a private session cache even if nbproc > 1 */
175 unsigned int life_time; /* SSL session lifetime in seconds */
176 unsigned int max_record; /* SSL max record size */
177 unsigned int default_dh_param; /* SSL maximum DH parameter size */
178 int ctx_cache; /* max number of entries in the ssl_ctx cache. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100179 int capture_cipherlist; /* Size of the cipherlist buffer. */
Willy Tarreauef934602016-12-22 23:12:01 +0100180} global_ssl = {
181#ifdef LISTEN_DEFAULT_CIPHERS
182 .listen_default_ciphers = LISTEN_DEFAULT_CIPHERS,
183#endif
184#ifdef CONNECT_DEFAULT_CIPHERS
185 .connect_default_ciphers = CONNECT_DEFAULT_CIPHERS,
186#endif
187 .listen_default_ssloptions = BC_SSL_O_NONE,
188 .connect_default_ssloptions = SRV_SSL_O_NONE,
189
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200190 .listen_default_sslmethods.flags = MC_SSL_O_ALL,
191 .listen_default_sslmethods.min = CONF_TLSV_NONE,
192 .listen_default_sslmethods.max = CONF_TLSV_NONE,
193 .connect_default_sslmethods.flags = MC_SSL_O_ALL,
194 .connect_default_sslmethods.min = CONF_TLSV_NONE,
195 .connect_default_sslmethods.max = CONF_TLSV_NONE,
196
Willy Tarreauef934602016-12-22 23:12:01 +0100197#ifdef DEFAULT_SSL_MAX_RECORD
198 .max_record = DEFAULT_SSL_MAX_RECORD,
199#endif
200 .default_dh_param = SSL_DEFAULT_DH_PARAM,
201 .ctx_cache = DEFAULT_SSL_CTX_CACHE,
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100202 .capture_cipherlist = 0,
Willy Tarreauef934602016-12-22 23:12:01 +0100203};
204
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100205/* This memory pool is used for capturing clienthello parameters. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100206struct ssl_capture {
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100207 unsigned long long int xxh64;
208 unsigned char ciphersuite_len;
209 char ciphersuite[0];
210};
211struct pool_head *pool2_ssl_capture = NULL;
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100212static int ssl_capture_ptr_index = -1;
Willy Tarreauef934602016-12-22 23:12:01 +0100213
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200214#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
215struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
216#endif
217
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +0200218#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +0000219static unsigned int openssl_engines_initialized;
220struct list openssl_engines = LIST_HEAD_INIT(openssl_engines);
221struct ssl_engine_list {
222 struct list list;
223 ENGINE *e;
224};
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +0200225#endif
Grant Zhang872f9c22017-01-21 01:10:18 +0000226
Remi Gacogne8de54152014-07-15 11:36:40 +0200227#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200228static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200229static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200230static DH *local_dh_1024 = NULL;
231static DH *local_dh_2048 = NULL;
232static DH *local_dh_4096 = NULL;
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +0100233static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
Remi Gacogne8de54152014-07-15 11:36:40 +0200234#endif /* OPENSSL_NO_DH */
235
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100236#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +0200237/* X509V3 Extensions that will be added on generated certificates */
238#define X509V3_EXT_SIZE 5
239static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
240 "basicConstraints",
241 "nsComment",
242 "subjectKeyIdentifier",
243 "authorityKeyIdentifier",
244 "keyUsage",
245};
246static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
247 "CA:FALSE",
248 "\"OpenSSL Generated Certificate\"",
249 "hash",
250 "keyid,issuer:always",
251 "nonRepudiation,digitalSignature,keyEncipherment"
252};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200253/* LRU cache to store generated certificate */
254static struct lru64_head *ssl_ctx_lru_tree = NULL;
255static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200256#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
257
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100258static struct ssl_bind_kw ssl_bind_kws[];
259
yanbzhube2774d2015-12-10 15:07:30 -0500260#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
261/* The order here matters for picking a default context,
262 * keep the most common keytype at the bottom of the list
263 */
264const char *SSL_SOCK_KEYTYPE_NAMES[] = {
265 "dsa",
266 "ecdsa",
267 "rsa"
268};
269#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100270#else
271#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500272#endif
273
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100274/*
275 * This function gives the detail of the SSL error. It is used only
276 * if the debug mode and the verbose mode are activated. It dump all
277 * the SSL error until the stack was empty.
278 */
279static forceinline void ssl_sock_dump_errors(struct connection *conn)
280{
281 unsigned long ret;
282
283 if (unlikely(global.mode & MODE_DEBUG)) {
284 while(1) {
285 ret = ERR_get_error();
286 if (ret == 0)
287 return;
288 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
289 (unsigned short)conn->t.sock.fd, ret,
290 ERR_func_error_string(ret), ERR_reason_error_string(ret));
291 }
292 }
293}
294
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200295#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500296/*
297 * struct alignment works here such that the key.key is the same as key_data
298 * Do not change the placement of key_data
299 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200300struct certificate_ocsp {
301 struct ebmb_node key;
302 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
303 struct chunk response;
304 long expire;
305};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200306
yanbzhube2774d2015-12-10 15:07:30 -0500307struct ocsp_cbk_arg {
308 int is_single;
309 int single_kt;
310 union {
311 struct certificate_ocsp *s_ocsp;
312 /*
313 * m_ocsp will have multiple entries dependent on key type
314 * Entry 0 - DSA
315 * Entry 1 - ECDSA
316 * Entry 2 - RSA
317 */
318 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
319 };
320};
321
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +0200322#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +0000323static int ssl_init_single_engine(const char *engine_id, const char *def_algorithms)
324{
325 int err_code = ERR_ABORT;
326 ENGINE *engine;
327 struct ssl_engine_list *el;
328
329 /* grab the structural reference to the engine */
330 engine = ENGINE_by_id(engine_id);
331 if (engine == NULL) {
332 Alert("ssl-engine %s: failed to get structural reference\n", engine_id);
333 goto fail_get;
334 }
335
336 if (!ENGINE_init(engine)) {
337 /* the engine couldn't initialise, release it */
338 Alert("ssl-engine %s: failed to initialize\n", engine_id);
339 goto fail_init;
340 }
341
342 if (ENGINE_set_default_string(engine, def_algorithms) == 0) {
343 Alert("ssl-engine %s: failed on ENGINE_set_default_string\n", engine_id);
344 goto fail_set_method;
345 }
346
347 el = calloc(1, sizeof(*el));
348 el->e = engine;
349 LIST_ADD(&openssl_engines, &el->list);
350 return 0;
351
352fail_set_method:
353 /* release the functional reference from ENGINE_init() */
354 ENGINE_finish(engine);
355
356fail_init:
357 /* release the structural reference from ENGINE_by_id() */
358 ENGINE_free(engine);
359
360fail_get:
361 return err_code;
362}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +0200363#endif
Grant Zhang872f9c22017-01-21 01:10:18 +0000364
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000365#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brun3854e012017-05-17 20:42:48 +0200366/*
367 * openssl async fd handler
368 */
369static void ssl_async_fd_handler(int fd)
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000370{
371 struct connection *conn = fdtab[fd].owner;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000372
Emeric Brun3854e012017-05-17 20:42:48 +0200373 /* fd is an async enfine fd, we must stop
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000374 * to poll this fd until it is requested
375 */
Emeric Brunbbc16542017-06-02 15:54:06 +0000376 fd_stop_recv(fd);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000377 fd_cant_recv(fd);
378
379 /* crypto engine is available, let's notify the associated
380 * connection that it can pursue its processing.
381 */
Emeric Brunbbc16542017-06-02 15:54:06 +0000382 __conn_sock_want_recv(conn);
383 __conn_sock_want_send(conn);
384 conn_update_sock_polling(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000385}
386
Emeric Brun3854e012017-05-17 20:42:48 +0200387/*
388 * openssl async delayed SSL_free handler
389 */
390static void ssl_async_fd_free(int fd)
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000391{
392 SSL *ssl = fdtab[fd].owner;
Emeric Brun3854e012017-05-17 20:42:48 +0200393 OSSL_ASYNC_FD all_fd[32];
394 size_t num_all_fds = 0;
395 int i;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000396
Emeric Brun3854e012017-05-17 20:42:48 +0200397 /* We suppose that the async job for a same SSL *
398 * are serialized. So if we are awake it is
399 * because the running job has just finished
400 * and we can remove all async fds safely
401 */
402 SSL_get_all_async_fds(ssl, NULL, &num_all_fds);
403 if (num_all_fds > 32) {
404 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
405 return;
406 }
407
408 SSL_get_all_async_fds(ssl, all_fd, &num_all_fds);
409 for (i=0 ; i < num_all_fds ; i++)
410 fd_remove(all_fd[i]);
411
412 /* Now we can safely call SSL_free, no more pending job in engines */
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000413 SSL_free(ssl);
414 sslconns--;
415 jobs--;
416}
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000417/*
Emeric Brun3854e012017-05-17 20:42:48 +0200418 * function used to manage a returned SSL_ERROR_WANT_ASYNC
419 * and enable/disable polling for async fds
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000420 */
Emeric Brun3854e012017-05-17 20:42:48 +0200421static void inline ssl_async_process_fds(struct connection *conn, SSL *ssl)
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000422{
Emeric Brun3854e012017-05-17 20:42:48 +0200423 OSSL_ASYNC_FD add_fd[32], afd;
424 OSSL_ASYNC_FD del_fd[32];
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000425 size_t num_add_fds = 0;
426 size_t num_del_fds = 0;
Emeric Brun3854e012017-05-17 20:42:48 +0200427 int i;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000428
429 SSL_get_changed_async_fds(ssl, NULL, &num_add_fds, NULL,
430 &num_del_fds);
Emeric Brun3854e012017-05-17 20:42:48 +0200431 if (num_add_fds > 32 || num_del_fds > 32) {
432 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000433 return;
434 }
435
Emeric Brun3854e012017-05-17 20:42:48 +0200436 SSL_get_changed_async_fds(ssl, add_fd, &num_add_fds, del_fd, &num_del_fds);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000437
Emeric Brun3854e012017-05-17 20:42:48 +0200438 /* We remove unused fds from the fdtab */
439 for (i=0 ; i < num_del_fds ; i++)
440 fd_remove(del_fd[i]);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000441
Emeric Brun3854e012017-05-17 20:42:48 +0200442 /* We add new fds to the fdtab */
443 for (i=0 ; i < num_add_fds ; i++) {
444 afd = add_fd[i];
445 fdtab[afd].owner = conn;
446 fdtab[afd].iocb = ssl_async_fd_handler;
447 fd_insert(afd);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000448 }
449
Emeric Brun3854e012017-05-17 20:42:48 +0200450 num_add_fds = 0;
451 SSL_get_all_async_fds(ssl, NULL, &num_add_fds);
452 if (num_add_fds > 32) {
453 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
454 return;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000455 }
Emeric Brun3854e012017-05-17 20:42:48 +0200456
457 /* We activate the polling for all known async fds */
458 SSL_get_all_async_fds(ssl, add_fd, &num_add_fds);
Emeric Brunce9e01c2017-05-31 10:02:53 +0000459 for (i=0 ; i < num_add_fds ; i++) {
Emeric Brun3854e012017-05-17 20:42:48 +0200460 fd_want_recv(add_fd[i]);
Emeric Brunce9e01c2017-05-31 10:02:53 +0000461 /* To ensure that the fd cache won't be used
462 * We'll prefer to catch a real RD event
463 * because handling an EAGAIN on this fd will
464 * result in a context switch and also
465 * some engines uses a fd in blocking mode.
466 */
467 fd_cant_recv(add_fd[i]);
468 }
Emeric Brun3854e012017-05-17 20:42:48 +0200469
470 /* We must also prevent the conn_handler
471 * to be called until a read event was
472 * polled on an async fd
473 */
474 __conn_sock_stop_both(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000475}
476#endif
477
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200478/*
479 * This function returns the number of seconds elapsed
480 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
481 * date presented un ASN1_GENERALIZEDTIME.
482 *
483 * In parsing error case, it returns -1.
484 */
485static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
486{
487 long epoch;
488 char *p, *end;
489 const unsigned short month_offset[12] = {
490 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
491 };
492 int year, month;
493
494 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
495
496 p = (char *)d->data;
497 end = p + d->length;
498
499 if (end - p < 4) return -1;
500 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
501 p += 4;
502 if (end - p < 2) return -1;
503 month = 10 * (p[0] - '0') + p[1] - '0';
504 if (month < 1 || month > 12) return -1;
505 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
506 We consider leap years and the current month (<marsh or not) */
507 epoch = ( ((year - 1970) * 365)
508 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
509 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
510 + month_offset[month-1]
511 ) * 24 * 60 * 60;
512 p += 2;
513 if (end - p < 2) return -1;
514 /* Add the number of seconds of completed days of current month */
515 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
516 p += 2;
517 if (end - p < 2) return -1;
518 /* Add the completed hours of the current day */
519 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
520 p += 2;
521 if (end - p < 2) return -1;
522 /* Add the completed minutes of the current hour */
523 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
524 p += 2;
525 if (p == end) return -1;
526 /* Test if there is available seconds */
527 if (p[0] < '0' || p[0] > '9')
528 goto nosec;
529 if (end - p < 2) return -1;
530 /* Add the seconds of the current minute */
531 epoch += 10 * (p[0] - '0') + p[1] - '0';
532 p += 2;
533 if (p == end) return -1;
534 /* Ignore seconds float part if present */
535 if (p[0] == '.') {
536 do {
537 if (++p == end) return -1;
538 } while (p[0] >= '0' && p[0] <= '9');
539 }
540
541nosec:
542 if (p[0] == 'Z') {
543 if (end - p != 1) return -1;
544 return epoch;
545 }
546 else if (p[0] == '+') {
547 if (end - p != 5) return -1;
548 /* Apply timezone offset */
549 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
550 }
551 else if (p[0] == '-') {
552 if (end - p != 5) return -1;
553 /* Apply timezone offset */
554 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
555 }
556
557 return -1;
558}
559
Emeric Brun1d3865b2014-06-20 15:37:32 +0200560static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200561
562/* This function starts to check if the OCSP response (in DER format) contained
563 * in chunk 'ocsp_response' is valid (else exits on error).
564 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
565 * contained in the OCSP Response and exits on error if no match.
566 * If it's a valid OCSP Response:
567 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
568 * pointed by 'ocsp'.
569 * If 'ocsp' is NULL, the function looks up into the OCSP response's
570 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
571 * from the response) and exits on error if not found. Finally, If an OCSP response is
572 * already present in the container, it will be overwritten.
573 *
574 * Note: OCSP response containing more than one OCSP Single response is not
575 * considered valid.
576 *
577 * Returns 0 on success, 1 in error case.
578 */
579static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
580{
581 OCSP_RESPONSE *resp;
582 OCSP_BASICRESP *bs = NULL;
583 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200584 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200585 unsigned char *p = (unsigned char *)ocsp_response->str;
586 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200587 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200588 int reason;
589 int ret = 1;
590
591 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
592 if (!resp) {
593 memprintf(err, "Unable to parse OCSP response");
594 goto out;
595 }
596
597 rc = OCSP_response_status(resp);
598 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
599 memprintf(err, "OCSP response status not successful");
600 goto out;
601 }
602
603 bs = OCSP_response_get1_basic(resp);
604 if (!bs) {
605 memprintf(err, "Failed to get basic response from OCSP Response");
606 goto out;
607 }
608
609 count_sr = OCSP_resp_count(bs);
610 if (count_sr > 1) {
611 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
612 goto out;
613 }
614
615 sr = OCSP_resp_get0(bs, 0);
616 if (!sr) {
617 memprintf(err, "Failed to get OCSP single response");
618 goto out;
619 }
620
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200621 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
622
Emeric Brun4147b2e2014-06-16 18:36:30 +0200623 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
624 if (rc != V_OCSP_CERTSTATUS_GOOD) {
625 memprintf(err, "OCSP single response: certificate status not good");
626 goto out;
627 }
628
Emeric Brun13a6b482014-06-20 15:44:34 +0200629 if (!nextupd) {
630 memprintf(err, "OCSP single response: missing nextupdate");
631 goto out;
632 }
633
Emeric Brunc8b27b62014-06-19 14:16:17 +0200634 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200635 if (!rc) {
636 memprintf(err, "OCSP single response: no longer valid.");
637 goto out;
638 }
639
640 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200641 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200642 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
643 goto out;
644 }
645 }
646
647 if (!ocsp) {
648 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
649 unsigned char *p;
650
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200651 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200652 if (!rc) {
653 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
654 goto out;
655 }
656
657 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
658 memprintf(err, "OCSP single response: Certificate ID too long");
659 goto out;
660 }
661
662 p = key;
663 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200664 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200665 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
666 if (!ocsp) {
667 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
668 goto out;
669 }
670 }
671
672 /* According to comments on "chunk_dup", the
673 previous chunk buffer will be freed */
674 if (!chunk_dup(&ocsp->response, ocsp_response)) {
675 memprintf(err, "OCSP response: Memory allocation error");
676 goto out;
677 }
678
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200679 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
680
Emeric Brun4147b2e2014-06-16 18:36:30 +0200681 ret = 0;
682out:
Janusz Dziemidowicz8d710492017-03-08 16:59:41 +0100683 ERR_clear_error();
684
Emeric Brun4147b2e2014-06-16 18:36:30 +0200685 if (bs)
686 OCSP_BASICRESP_free(bs);
687
688 if (resp)
689 OCSP_RESPONSE_free(resp);
690
691 return ret;
692}
693/*
694 * External function use to update the OCSP response in the OCSP response's
695 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
696 * to update in DER format.
697 *
698 * Returns 0 on success, 1 in error case.
699 */
700int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
701{
702 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
703}
704
705/*
706 * This function load the OCSP Resonse in DER format contained in file at
707 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
708 *
709 * Returns 0 on success, 1 in error case.
710 */
711static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
712{
713 int fd = -1;
714 int r = 0;
715 int ret = 1;
716
717 fd = open(ocsp_path, O_RDONLY);
718 if (fd == -1) {
719 memprintf(err, "Error opening OCSP response file");
720 goto end;
721 }
722
723 trash.len = 0;
724 while (trash.len < trash.size) {
725 r = read(fd, trash.str + trash.len, trash.size - trash.len);
726 if (r < 0) {
727 if (errno == EINTR)
728 continue;
729
730 memprintf(err, "Error reading OCSP response from file");
731 goto end;
732 }
733 else if (r == 0) {
734 break;
735 }
736 trash.len += r;
737 }
738
739 close(fd);
740 fd = -1;
741
742 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
743end:
744 if (fd != -1)
745 close(fd);
746
747 return ret;
748}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100749#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200750
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100751#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
752static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
753{
754 struct tls_sess_key *keys;
755 struct connection *conn;
756 int head;
757 int i;
758
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200759 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200760 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
761 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100762
763 if (enc) {
764 memcpy(key_name, keys[head].name, 16);
765
766 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
767 return -1;
768
769 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
770 return -1;
771
772 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
773
774 return 1;
775 } else {
776 for (i = 0; i < TLS_TICKETS_NO; i++) {
777 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
778 goto found;
779 }
780 return 0;
781
782 found:
783 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
784 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
785 return -1;
786 /* 2 for key renewal, 1 if current key is still valid */
787 return i ? 2 : 1;
788 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200789}
790
791struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
792{
793 struct tls_keys_ref *ref;
794
795 list_for_each_entry(ref, &tlskeys_reference, list)
796 if (ref->filename && strcmp(filename, ref->filename) == 0)
797 return ref;
798 return NULL;
799}
800
801struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
802{
803 struct tls_keys_ref *ref;
804
805 list_for_each_entry(ref, &tlskeys_reference, list)
806 if (ref->unique_id == unique_id)
807 return ref;
808 return NULL;
809}
810
811int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
812 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
813
814 if(!ref) {
815 memprintf(err, "Unable to locate the referenced filename: %s", filename);
816 return 1;
817 }
818
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530819 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
820 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200821
822 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100823}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200824
825/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100826 * automatic ids. It's called just after the basic checks. It returns
827 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200828 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100829static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200830{
831 int i = 0;
832 struct tls_keys_ref *ref, *ref2, *ref3;
833 struct list tkr = LIST_HEAD_INIT(tkr);
834
835 list_for_each_entry(ref, &tlskeys_reference, list) {
836 if (ref->unique_id == -1) {
837 /* Look for the first free id. */
838 while (1) {
839 list_for_each_entry(ref2, &tlskeys_reference, list) {
840 if (ref2->unique_id == i) {
841 i++;
842 break;
843 }
844 }
845 if (&ref2->list == &tlskeys_reference)
846 break;
847 }
848
849 /* Uses the unique id and increment it for the next entry. */
850 ref->unique_id = i;
851 i++;
852 }
853 }
854
855 /* This sort the reference list by id. */
856 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
857 LIST_DEL(&ref->list);
858 list_for_each_entry(ref3, &tkr, list) {
859 if (ref->unique_id < ref3->unique_id) {
860 LIST_ADDQ(&ref3->list, &ref->list);
861 break;
862 }
863 }
864 if (&ref3->list == &tkr)
865 LIST_ADDQ(&tkr, &ref->list);
866 }
867
868 /* swap root */
869 LIST_ADD(&tkr, &tlskeys_reference);
870 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100871 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200872}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100873#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
874
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100875#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500876int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
877{
878 switch (evp_keytype) {
879 case EVP_PKEY_RSA:
880 return 2;
881 case EVP_PKEY_DSA:
882 return 0;
883 case EVP_PKEY_EC:
884 return 1;
885 }
886
887 return -1;
888}
889
Emeric Brun4147b2e2014-06-16 18:36:30 +0200890/*
891 * Callback used to set OCSP status extension content in server hello.
892 */
893int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
894{
yanbzhube2774d2015-12-10 15:07:30 -0500895 struct certificate_ocsp *ocsp;
896 struct ocsp_cbk_arg *ocsp_arg;
897 char *ssl_buf;
898 EVP_PKEY *ssl_pkey;
899 int key_type;
900 int index;
901
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200902 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500903
904 ssl_pkey = SSL_get_privatekey(ssl);
905 if (!ssl_pkey)
906 return SSL_TLSEXT_ERR_NOACK;
907
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200908 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500909
910 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
911 ocsp = ocsp_arg->s_ocsp;
912 else {
913 /* For multiple certs per context, we have to find the correct OCSP response based on
914 * the certificate type
915 */
916 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
917
918 if (index < 0)
919 return SSL_TLSEXT_ERR_NOACK;
920
921 ocsp = ocsp_arg->m_ocsp[index];
922
923 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200924
925 if (!ocsp ||
926 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200927 !ocsp->response.len ||
928 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200929 return SSL_TLSEXT_ERR_NOACK;
930
931 ssl_buf = OPENSSL_malloc(ocsp->response.len);
932 if (!ssl_buf)
933 return SSL_TLSEXT_ERR_NOACK;
934
935 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
936 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
937
938 return SSL_TLSEXT_ERR_OK;
939}
940
941/*
942 * This function enables the handling of OCSP status extension on 'ctx' if a
943 * file name 'cert_path' suffixed using ".ocsp" is present.
944 * To enable OCSP status extension, the issuer's certificate is mandatory.
945 * It should be present in the certificate's extra chain builded from file
946 * 'cert_path'. If not found, the issuer certificate is loaded from a file
947 * named 'cert_path' suffixed using '.issuer'.
948 *
949 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
950 * response. If file is empty or content is not a valid OCSP response,
951 * OCSP status extension is enabled but OCSP response is ignored (a warning
952 * is displayed).
953 *
954 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
955 * succesfully enabled, or -1 in other error case.
956 */
957static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
958{
959
960 BIO *in = NULL;
961 X509 *x, *xi = NULL, *issuer = NULL;
962 STACK_OF(X509) *chain = NULL;
963 OCSP_CERTID *cid = NULL;
964 SSL *ssl;
965 char ocsp_path[MAXPATHLEN+1];
966 int i, ret = -1;
967 struct stat st;
968 struct certificate_ocsp *ocsp = NULL, *iocsp;
969 char *warn = NULL;
970 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200971 pem_password_cb *passwd_cb;
972 void *passwd_cb_userdata;
973 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200974
975 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
976
977 if (stat(ocsp_path, &st))
978 return 1;
979
980 ssl = SSL_new(ctx);
981 if (!ssl)
982 goto out;
983
984 x = SSL_get_certificate(ssl);
985 if (!x)
986 goto out;
987
988 /* Try to lookup for issuer in certificate extra chain */
989#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
990 SSL_CTX_get_extra_chain_certs(ctx, &chain);
991#else
992 chain = ctx->extra_certs;
993#endif
994 for (i = 0; i < sk_X509_num(chain); i++) {
995 issuer = sk_X509_value(chain, i);
996 if (X509_check_issued(issuer, x) == X509_V_OK)
997 break;
998 else
999 issuer = NULL;
1000 }
1001
1002 /* If not found try to load issuer from a suffixed file */
1003 if (!issuer) {
1004 char issuer_path[MAXPATHLEN+1];
1005
1006 in = BIO_new(BIO_s_file());
1007 if (!in)
1008 goto out;
1009
1010 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
1011 if (BIO_read_filename(in, issuer_path) <= 0)
1012 goto out;
1013
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001014 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
1015 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
1016
1017 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +02001018 if (!xi)
1019 goto out;
1020
1021 if (X509_check_issued(xi, x) != X509_V_OK)
1022 goto out;
1023
1024 issuer = xi;
1025 }
1026
1027 cid = OCSP_cert_to_id(0, x, issuer);
1028 if (!cid)
1029 goto out;
1030
1031 i = i2d_OCSP_CERTID(cid, NULL);
1032 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
1033 goto out;
1034
Vincent Bernat02779b62016-04-03 13:48:43 +02001035 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +02001036 if (!ocsp)
1037 goto out;
1038
1039 p = ocsp->key_data;
1040 i2d_OCSP_CERTID(cid, &p);
1041
1042 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
1043 if (iocsp == ocsp)
1044 ocsp = NULL;
1045
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001046#ifndef SSL_CTX_get_tlsext_status_cb
1047# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
1048 *cb = (void (*) (void))ctx->tlsext_status_cb;
1049#endif
1050 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
1051
1052 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +02001053 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001054 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -05001055
1056 cb_arg->is_single = 1;
1057 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001058
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001059 pkey = X509_get_pubkey(x);
1060 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
1061 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -05001062
1063 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
1064 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
1065 } else {
1066 /*
1067 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
1068 * Update that cb_arg with the new cert's staple
1069 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001070 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -05001071 struct certificate_ocsp *tmp_ocsp;
1072 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001073 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001074 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001075
1076#ifdef SSL_CTX_get_tlsext_status_arg
1077 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
1078#else
1079 cb_arg = ctx->tlsext_status_arg;
1080#endif
yanbzhube2774d2015-12-10 15:07:30 -05001081
1082 /*
1083 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
1084 * the order of operations below matter, take care when changing it
1085 */
1086 tmp_ocsp = cb_arg->s_ocsp;
1087 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
1088 cb_arg->s_ocsp = NULL;
1089 cb_arg->m_ocsp[index] = tmp_ocsp;
1090 cb_arg->is_single = 0;
1091 cb_arg->single_kt = 0;
1092
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001093 pkey = X509_get_pubkey(x);
1094 key_type = EVP_PKEY_base_id(pkey);
1095 EVP_PKEY_free(pkey);
1096
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001097 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -05001098 if (index >= 0 && !cb_arg->m_ocsp[index])
1099 cb_arg->m_ocsp[index] = iocsp;
1100
1101 }
Emeric Brun4147b2e2014-06-16 18:36:30 +02001102
1103 ret = 0;
1104
1105 warn = NULL;
1106 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
1107 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
1108 Warning("%s.\n", warn);
1109 }
1110
1111out:
1112 if (ssl)
1113 SSL_free(ssl);
1114
1115 if (in)
1116 BIO_free(in);
1117
1118 if (xi)
1119 X509_free(xi);
1120
1121 if (cid)
1122 OCSP_CERTID_free(cid);
1123
1124 if (ocsp)
1125 free(ocsp);
1126
1127 if (warn)
1128 free(warn);
1129
1130
1131 return ret;
1132}
1133
1134#endif
1135
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02001136#ifdef OPENSSL_IS_BORINGSSL
1137static int ssl_sock_set_ocsp_response_from_file(SSL_CTX *ctx, const char *cert_path)
1138{
1139 char ocsp_path[MAXPATHLEN+1];
1140 struct stat st;
1141 int fd = -1, r = 0;
1142
1143 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
1144 if (stat(ocsp_path, &st))
1145 return 0;
1146
1147 fd = open(ocsp_path, O_RDONLY);
1148 if (fd == -1) {
1149 Warning("Error opening OCSP response file %s.\n", ocsp_path);
1150 return -1;
1151 }
1152
1153 trash.len = 0;
1154 while (trash.len < trash.size) {
1155 r = read(fd, trash.str + trash.len, trash.size - trash.len);
1156 if (r < 0) {
1157 if (errno == EINTR)
1158 continue;
1159 Warning("Error reading OCSP response from file %s.\n", ocsp_path);
1160 close(fd);
1161 return -1;
1162 }
1163 else if (r == 0) {
1164 break;
1165 }
1166 trash.len += r;
1167 }
1168 close(fd);
1169 return SSL_CTX_set_ocsp_response(ctx, (const uint8_t *)trash.str, trash.len);
1170}
1171#endif
1172
Daniel Jakots54ffb912015-11-06 20:02:41 +01001173#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001174
1175#define CT_EXTENSION_TYPE 18
1176
1177static int sctl_ex_index = -1;
1178
1179/*
1180 * Try to parse Signed Certificate Timestamp List structure. This function
1181 * makes only basic test if the data seems like SCTL. No signature validation
1182 * is performed.
1183 */
1184static int ssl_sock_parse_sctl(struct chunk *sctl)
1185{
1186 int ret = 1;
1187 int len, pos, sct_len;
1188 unsigned char *data;
1189
1190 if (sctl->len < 2)
1191 goto out;
1192
1193 data = (unsigned char *)sctl->str;
1194 len = (data[0] << 8) | data[1];
1195
1196 if (len + 2 != sctl->len)
1197 goto out;
1198
1199 data = data + 2;
1200 pos = 0;
1201 while (pos < len) {
1202 if (len - pos < 2)
1203 goto out;
1204
1205 sct_len = (data[pos] << 8) | data[pos + 1];
1206 if (pos + sct_len + 2 > len)
1207 goto out;
1208
1209 pos += sct_len + 2;
1210 }
1211
1212 ret = 0;
1213
1214out:
1215 return ret;
1216}
1217
1218static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
1219{
1220 int fd = -1;
1221 int r = 0;
1222 int ret = 1;
1223
1224 *sctl = NULL;
1225
1226 fd = open(sctl_path, O_RDONLY);
1227 if (fd == -1)
1228 goto end;
1229
1230 trash.len = 0;
1231 while (trash.len < trash.size) {
1232 r = read(fd, trash.str + trash.len, trash.size - trash.len);
1233 if (r < 0) {
1234 if (errno == EINTR)
1235 continue;
1236
1237 goto end;
1238 }
1239 else if (r == 0) {
1240 break;
1241 }
1242 trash.len += r;
1243 }
1244
1245 ret = ssl_sock_parse_sctl(&trash);
1246 if (ret)
1247 goto end;
1248
Vincent Bernat02779b62016-04-03 13:48:43 +02001249 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001250 if (!chunk_dup(*sctl, &trash)) {
1251 free(*sctl);
1252 *sctl = NULL;
1253 goto end;
1254 }
1255
1256end:
1257 if (fd != -1)
1258 close(fd);
1259
1260 return ret;
1261}
1262
1263int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1264{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001265 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001266
1267 *out = (unsigned char *)sctl->str;
1268 *outlen = sctl->len;
1269
1270 return 1;
1271}
1272
1273int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1274{
1275 return 1;
1276}
1277
1278static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1279{
1280 char sctl_path[MAXPATHLEN+1];
1281 int ret = -1;
1282 struct stat st;
1283 struct chunk *sctl = NULL;
1284
1285 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1286
1287 if (stat(sctl_path, &st))
1288 return 1;
1289
1290 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1291 goto out;
1292
1293 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1294 free(sctl);
1295 goto out;
1296 }
1297
1298 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1299
1300 ret = 0;
1301
1302out:
1303 return ret;
1304}
1305
1306#endif
1307
Emeric Brune1f38db2012-09-03 20:36:47 +02001308void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1309{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001310 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001311 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001312 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001313
1314 if (where & SSL_CB_HANDSHAKE_START) {
1315 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001316 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001317 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001318 conn->err_code = CO_ER_SSL_RENEG;
1319 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001320 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001321
1322 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1323 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1324 /* Long certificate chains optimz
1325 If write and read bios are differents, we
1326 consider that the buffering was activated,
1327 so we rise the output buffer size from 4k
1328 to 16k */
1329 write_bio = SSL_get_wbio(ssl);
1330 if (write_bio != SSL_get_rbio(ssl)) {
1331 BIO_set_write_buffer_size(write_bio, 16384);
1332 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1333 }
1334 }
1335 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001336}
1337
Emeric Brune64aef12012-09-21 13:15:06 +02001338/* Callback is called for each certificate of the chain during a verify
1339 ok is set to 1 if preverify detect no error on current certificate.
1340 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001341int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001342{
1343 SSL *ssl;
1344 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001345 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001346
1347 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001348 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001349
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001350 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001351
Emeric Brun81c00f02012-09-21 14:31:21 +02001352 if (ok) /* no errors */
1353 return ok;
1354
1355 depth = X509_STORE_CTX_get_error_depth(x_store);
1356 err = X509_STORE_CTX_get_error(x_store);
1357
1358 /* check if CA error needs to be ignored */
1359 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001360 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1361 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1362 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001363 }
1364
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001365 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001366 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001367 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001368 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001369 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001370
Willy Tarreau20879a02012-12-03 16:32:10 +01001371 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001372 return 0;
1373 }
1374
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001375 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1376 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001377
Emeric Brun81c00f02012-09-21 14:31:21 +02001378 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001379 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001380 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001381 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001382 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001383 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001384
Willy Tarreau20879a02012-12-03 16:32:10 +01001385 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001386 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001387}
1388
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001389static inline
1390void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001391 const void *buf, size_t len, SSL *ssl)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001392{
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001393 struct ssl_capture *capture;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001394 unsigned char *msg;
1395 unsigned char *end;
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001396 size_t rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001397
1398 /* This function is called for "from client" and "to server"
1399 * connections. The combination of write_p == 0 and content_type == 22
1400 * is only avalaible during "from client" connection.
1401 */
1402
1403 /* "write_p" is set to 0 is the bytes are received messages,
1404 * otherwise it is set to 1.
1405 */
1406 if (write_p != 0)
1407 return;
1408
1409 /* content_type contains the type of message received or sent
1410 * according with the SSL/TLS protocol spec. This message is
1411 * encoded with one byte. The value 256 (two bytes) is used
1412 * for designing the SSL/TLS record layer. According with the
1413 * rfc6101, the expected message (other than 256) are:
1414 * - change_cipher_spec(20)
1415 * - alert(21)
1416 * - handshake(22)
1417 * - application_data(23)
1418 * - (255)
1419 * We are interessed by the handshake and specially the client
1420 * hello.
1421 */
1422 if (content_type != 22)
1423 return;
1424
1425 /* The message length is at least 4 bytes, containing the
1426 * message type and the message length.
1427 */
1428 if (len < 4)
1429 return;
1430
1431 /* First byte of the handshake message id the type of
1432 * message. The konwn types are:
1433 * - hello_request(0)
1434 * - client_hello(1)
1435 * - server_hello(2)
1436 * - certificate(11)
1437 * - server_key_exchange (12)
1438 * - certificate_request(13)
1439 * - server_hello_done(14)
1440 * We are interested by the client hello.
1441 */
1442 msg = (unsigned char *)buf;
1443 if (msg[0] != 1)
1444 return;
1445
1446 /* Next three bytes are the length of the message. The total length
1447 * must be this decoded length + 4. If the length given as argument
1448 * is not the same, we abort the protocol dissector.
1449 */
1450 rec_len = (msg[1] << 16) + (msg[2] << 8) + msg[3];
1451 if (len < rec_len + 4)
1452 return;
1453 msg += 4;
1454 end = msg + rec_len;
1455 if (end < msg)
1456 return;
1457
1458 /* Expect 2 bytes for protocol version (1 byte for major and 1 byte
1459 * for minor, the random, composed by 4 bytes for the unix time and
1460 * 28 bytes for unix payload, and them 1 byte for the session id. So
1461 * we jump 1 + 1 + 4 + 28 + 1 bytes.
1462 */
1463 msg += 1 + 1 + 4 + 28 + 1;
1464 if (msg > end)
1465 return;
1466
1467 /* Next two bytes are the ciphersuite length. */
1468 if (msg + 2 > end)
1469 return;
1470 rec_len = (msg[0] << 8) + msg[1];
1471 msg += 2;
1472 if (msg + rec_len > end || msg + rec_len < msg)
1473 return;
1474
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001475 capture = pool_alloc_dirty(pool2_ssl_capture);
1476 if (!capture)
1477 return;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001478 /* Compute the xxh64 of the ciphersuite. */
1479 capture->xxh64 = XXH64(msg, rec_len, 0);
1480
1481 /* Capture the ciphersuite. */
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001482 capture->ciphersuite_len = (global_ssl.capture_cipherlist < rec_len) ?
1483 global_ssl.capture_cipherlist : rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001484 memcpy(capture->ciphersuite, msg, capture->ciphersuite_len);
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001485
1486 SSL_set_ex_data(ssl, ssl_capture_ptr_index, capture);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001487}
1488
Emeric Brun29f037d2014-04-25 19:05:36 +02001489/* Callback is called for ssl protocol analyse */
1490void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1491{
Emeric Brun29f037d2014-04-25 19:05:36 +02001492#ifdef TLS1_RT_HEARTBEAT
1493 /* test heartbeat received (write_p is set to 0
1494 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001495 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001496 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001497 const unsigned char *p = buf;
1498 unsigned int payload;
1499
Emeric Brun29f037d2014-04-25 19:05:36 +02001500 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001501
1502 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1503 if (*p != TLS1_HB_REQUEST)
1504 return;
1505
Willy Tarreauaeed6722014-04-25 23:59:58 +02001506 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001507 goto kill_it;
1508
1509 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001510 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001511 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001512 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001513 /* We have a clear heartbleed attack (CVE-2014-0160), the
1514 * advertised payload is larger than the advertised packet
1515 * length, so we have garbage in the buffer between the
1516 * payload and the end of the buffer (p+len). We can't know
1517 * if the SSL stack is patched, and we don't know if we can
1518 * safely wipe out the area between p+3+len and payload.
1519 * So instead, we prevent the response from being sent by
1520 * setting the max_send_fragment to 0 and we report an SSL
1521 * error, which will kill this connection. It will be reported
1522 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001523 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1524 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001525 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001526 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1527 return;
1528 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001529#endif
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001530 if (global_ssl.capture_cipherlist > 0)
1531 ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
Emeric Brun29f037d2014-04-25 19:05:36 +02001532}
1533
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001534#ifdef OPENSSL_NPN_NEGOTIATED
1535/* This callback is used so that the server advertises the list of
1536 * negociable protocols for NPN.
1537 */
1538static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1539 unsigned int *len, void *arg)
1540{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001541 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001542
1543 *data = (const unsigned char *)conf->npn_str;
1544 *len = conf->npn_len;
1545 return SSL_TLSEXT_ERR_OK;
1546}
1547#endif
1548
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001549#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001550/* This callback is used so that the server advertises the list of
1551 * negociable protocols for ALPN.
1552 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001553static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1554 unsigned char *outlen,
1555 const unsigned char *server,
1556 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001557{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001558 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001559
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001560 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1561 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1562 return SSL_TLSEXT_ERR_NOACK;
1563 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001564 return SSL_TLSEXT_ERR_OK;
1565}
1566#endif
1567
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001568#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001569#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001570
Christopher Faulet30548802015-06-11 13:39:32 +02001571/* Create a X509 certificate with the specified servername and serial. This
1572 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001573static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001574ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001575{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001576 static unsigned int serial = 0;
1577
Christopher Faulet7969a332015-10-09 11:15:03 +02001578 X509 *cacert = bind_conf->ca_sign_cert;
1579 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001580 SSL_CTX *ssl_ctx = NULL;
1581 X509 *newcrt = NULL;
1582 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001583 X509_NAME *name;
1584 const EVP_MD *digest;
1585 X509V3_CTX ctx;
1586 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001587 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001588
Christopher Faulet48a83322017-07-28 16:56:09 +02001589 /* Get the private key of the default certificate and use it */
1590 if (!(pkey = SSL_CTX_get0_privatekey(bind_conf->default_ctx)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001591 goto mkcert_error;
1592
1593 /* Create the certificate */
1594 if (!(newcrt = X509_new()))
1595 goto mkcert_error;
1596
1597 /* Set version number for the certificate (X509v3) and the serial
1598 * number */
1599 if (X509_set_version(newcrt, 2L) != 1)
1600 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001601 if (!serial)
1602 serial = now_ms;
1603 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001604
1605 /* Set duration for the certificate */
1606 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1607 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1608 goto mkcert_error;
1609
1610 /* set public key in the certificate */
1611 if (X509_set_pubkey(newcrt, pkey) != 1)
1612 goto mkcert_error;
1613
1614 /* Set issuer name from the CA */
1615 if (!(name = X509_get_subject_name(cacert)))
1616 goto mkcert_error;
1617 if (X509_set_issuer_name(newcrt, name) != 1)
1618 goto mkcert_error;
1619
1620 /* Set the subject name using the same, but the CN */
1621 name = X509_NAME_dup(name);
1622 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1623 (const unsigned char *)servername,
1624 -1, -1, 0) != 1) {
1625 X509_NAME_free(name);
1626 goto mkcert_error;
1627 }
1628 if (X509_set_subject_name(newcrt, name) != 1) {
1629 X509_NAME_free(name);
1630 goto mkcert_error;
1631 }
1632 X509_NAME_free(name);
1633
1634 /* Add x509v3 extensions as specified */
1635 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1636 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1637 X509_EXTENSION *ext;
1638
1639 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1640 goto mkcert_error;
1641 if (!X509_add_ext(newcrt, ext, -1)) {
1642 X509_EXTENSION_free(ext);
1643 goto mkcert_error;
1644 }
1645 X509_EXTENSION_free(ext);
1646 }
1647
1648 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001649
1650 key_type = EVP_PKEY_base_id(capkey);
1651
1652 if (key_type == EVP_PKEY_DSA)
1653 digest = EVP_sha1();
1654 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001655 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001656 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001657 digest = EVP_sha256();
1658 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001659#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001660 int nid;
1661
1662 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1663 goto mkcert_error;
1664 if (!(digest = EVP_get_digestbynid(nid)))
1665 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001666#else
1667 goto mkcert_error;
1668#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001669 }
1670
Christopher Faulet31af49d2015-06-09 17:29:50 +02001671 if (!(X509_sign(newcrt, capkey, digest)))
1672 goto mkcert_error;
1673
1674 /* Create and set the new SSL_CTX */
1675 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1676 goto mkcert_error;
1677 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1678 goto mkcert_error;
1679 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1680 goto mkcert_error;
1681 if (!SSL_CTX_check_private_key(ssl_ctx))
1682 goto mkcert_error;
1683
1684 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001685
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001686#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001687 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001688#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001689#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1690 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001691 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001692 EC_KEY *ecc;
1693 int nid;
1694
1695 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1696 goto end;
1697 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1698 goto end;
1699 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1700 EC_KEY_free(ecc);
1701 }
1702#endif
1703 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001704 return ssl_ctx;
1705
1706 mkcert_error:
1707 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1708 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001709 return NULL;
1710}
1711
Christopher Faulet7969a332015-10-09 11:15:03 +02001712SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001713ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001714{
1715 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001716
1717 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001718}
1719
Christopher Faulet30548802015-06-11 13:39:32 +02001720/* Do a lookup for a certificate in the LRU cache used to store generated
1721 * certificates. */
1722SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001723ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001724{
1725 struct lru64 *lru = NULL;
1726
1727 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001728 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001729 if (lru && lru->domain)
1730 return (SSL_CTX *)lru->data;
1731 }
1732 return NULL;
1733}
1734
Christopher Fauletd2cab922015-07-28 16:03:47 +02001735/* Set a certificate int the LRU cache used to store generated
1736 * certificate. Return 0 on success, otherwise -1 */
1737int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001738ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001739{
1740 struct lru64 *lru = NULL;
1741
1742 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001743 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001744 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001745 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001746 if (lru->domain && lru->data)
1747 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001748 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001749 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001750 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001751 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001752}
1753
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001754/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001755unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001756ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001757{
1758 return XXH32(data, len, ssl_ctx_lru_seed);
1759}
1760
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001761/* Generate a cert and immediately assign it to the SSL session so that the cert's
1762 * refcount is maintained regardless of the cert's presence in the LRU cache.
1763 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001764static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001765ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001766{
1767 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001768 SSL_CTX *ssl_ctx = NULL;
1769 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001770 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001771
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001772 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001773 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001774 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001775 if (lru && lru->domain)
1776 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001777 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001778 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001779 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001780 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001781 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001782 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001783 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001784 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001785 SSL_set_SSL_CTX(ssl, ssl_ctx);
1786 /* No LRU cache, this CTX will be released as soon as the session dies */
1787 SSL_CTX_free(ssl_ctx);
1788 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001789 return ssl_ctx;
1790}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001791#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001792
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001793
1794#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1795#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1796#endif
1797
1798#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1799#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
1800#define SSL_renegotiate_pending(arg) 0
1801#endif
1802#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1803#define SSL_OP_SINGLE_ECDH_USE 0
1804#endif
1805#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1806#define SSL_OP_NO_TICKET 0
1807#endif
1808#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1809#define SSL_OP_NO_COMPRESSION 0
1810#endif
Emmanuel Hocdet23877ab2017-07-12 12:53:02 +02001811#ifdef OPENSSL_NO_SSL3 /* SSLv3 support removed */
1812#undef SSL_OP_NO_SSLv3
1813#define SSL_OP_NO_SSLv3 0
1814#endif
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001815#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1816#define SSL_OP_NO_TLSv1_1 0
1817#endif
1818#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1819#define SSL_OP_NO_TLSv1_2 0
1820#endif
1821#ifndef SSL_OP_NO_TLSv1_3 /* dev */
1822#define SSL_OP_NO_TLSv1_3 0
1823#endif
1824#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1825#define SSL_OP_SINGLE_DH_USE 0
1826#endif
1827#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1828#define SSL_OP_SINGLE_ECDH_USE 0
1829#endif
1830#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1831#define SSL_MODE_RELEASE_BUFFERS 0
1832#endif
1833#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1834#define SSL_MODE_SMALL_BUFFERS 0
1835#endif
1836
1837#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001838typedef enum { SET_CLIENT, SET_SERVER } set_context_func;
1839
1840static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001841{
Emmanuel Hocdet23877ab2017-07-12 12:53:02 +02001842#if SSL_OP_NO_SSLv3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001843 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, SSLv3_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001844 : SSL_CTX_set_ssl_version(ctx, SSLv3_client_method());
1845#endif
1846}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001847static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1848 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001849 : SSL_CTX_set_ssl_version(ctx, TLSv1_client_method());
1850}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001851static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001852#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001853 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001854 : SSL_CTX_set_ssl_version(ctx, TLSv1_1_client_method());
1855#endif
1856}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001857static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001858#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001859 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001860 : SSL_CTX_set_ssl_version(ctx, TLSv1_2_client_method());
1861#endif
1862}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001863/* TLS 1.2 is the last supported version in this context. */
1864static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {}
1865/* Unusable in this context. */
1866static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {}
1867static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {}
1868static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {}
1869static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {}
1870static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {}
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001871#else /* openssl >= 1.1.0 */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001872typedef enum { SET_MIN, SET_MAX } set_context_func;
1873
1874static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c) {
1875 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001876 : SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
1877}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001878static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {
1879 c == SET_MAX ? SSL_set_max_proto_version(ssl, SSL3_VERSION)
1880 : SSL_set_min_proto_version(ssl, SSL3_VERSION);
1881}
1882static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1883 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001884 : SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1885}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001886static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {
1887 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_VERSION)
1888 : SSL_set_min_proto_version(ssl, TLS1_VERSION);
1889}
1890static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
1891 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001892 : SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
1893}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001894static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {
1895 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_1_VERSION)
1896 : SSL_set_min_proto_version(ssl, TLS1_1_VERSION);
1897}
1898static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
1899 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001900 : SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
1901}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001902static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {
1903 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_2_VERSION)
1904 : SSL_set_min_proto_version(ssl, TLS1_2_VERSION);
1905}
1906static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001907#if SSL_OP_NO_TLSv1_3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001908 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001909 : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
1910#endif
1911}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001912static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {
1913#if SSL_OP_NO_TLSv1_3
1914 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_3_VERSION)
1915 : SSL_set_min_proto_version(ssl, TLS1_3_VERSION);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001916#endif
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001917}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001918#endif
1919static void ctx_set_None_func(SSL_CTX *ctx, set_context_func c) { }
1920static void ssl_set_None_func(SSL *ssl, set_context_func c) { }
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001921
1922static struct {
1923 int option;
1924 uint16_t flag;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001925 void (*ctx_set_version)(SSL_CTX *, set_context_func);
1926 void (*ssl_set_version)(SSL *, set_context_func);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001927 const char *name;
1928} methodVersions[] = {
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001929 {0, 0, ctx_set_None_func, ssl_set_None_func, "NONE"}, /* CONF_TLSV_NONE */
1930 {SSL_OP_NO_SSLv3, MC_SSL_O_NO_SSLV3, ctx_set_SSLv3_func, ssl_set_SSLv3_func, "SSLv3"}, /* CONF_SSLV3 */
1931 {SSL_OP_NO_TLSv1, MC_SSL_O_NO_TLSV10, ctx_set_TLSv10_func, ssl_set_TLSv10_func, "TLSv1.0"}, /* CONF_TLSV10 */
1932 {SSL_OP_NO_TLSv1_1, MC_SSL_O_NO_TLSV11, ctx_set_TLSv11_func, ssl_set_TLSv11_func, "TLSv1.1"}, /* CONF_TLSV11 */
1933 {SSL_OP_NO_TLSv1_2, MC_SSL_O_NO_TLSV12, ctx_set_TLSv12_func, ssl_set_TLSv12_func, "TLSv1.2"}, /* CONF_TLSV12 */
1934 {SSL_OP_NO_TLSv1_3, MC_SSL_O_NO_TLSV13, ctx_set_TLSv13_func, ssl_set_TLSv13_func, "TLSv1.3"}, /* CONF_TLSV13 */
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001935};
1936
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001937static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1938{
1939 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1940 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1941 SSL_set_SSL_CTX(ssl, ctx);
1942}
1943
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001944#ifdef OPENSSL_IS_BORINGSSL
1945
1946static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1947{
1948 (void)al; /* shut gcc stupid warning */
1949 (void)priv;
1950
1951 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1952 return SSL_TLSEXT_ERR_NOACK;
1953 return SSL_TLSEXT_ERR_OK;
1954}
1955
1956static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1957{
1958 struct connection *conn;
1959 struct bind_conf *s;
1960 const uint8_t *extension_data;
1961 size_t extension_len;
1962 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1963 const SSL_CIPHER *cipher;
1964 uint16_t cipher_suite;
1965 uint8_t name_type, hash, sign;
1966 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1967
1968 char *wildp = NULL;
1969 const uint8_t *servername;
1970 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1971 int i;
1972
1973 conn = SSL_get_app_data(ctx->ssl);
1974 s = objt_listener(conn->target)->bind_conf;
1975
1976 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1977 &extension_data, &extension_len)) {
1978 CBS_init(&extension, extension_data, extension_len);
1979
1980 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1981 || !CBS_get_u8(&server_name_list, &name_type)
1982 /* Although the server_name extension was intended to be extensible to
1983 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1984 * different name types will cause an error. Further, RFC 4366 originally
1985 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1986 * adding new name types is no longer feasible.
1987 *
1988 * Act as if the extensibility does not exist to simplify parsing. */
1989 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1990 || CBS_len(&server_name_list) != 0
1991 || CBS_len(&extension) != 0
1992 || name_type != TLSEXT_NAMETYPE_host_name
1993 || CBS_len(&host_name) == 0
1994 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1995 || CBS_contains_zero_byte(&host_name)) {
1996 goto abort;
1997 }
1998 } else {
1999 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002000 if (!s->strict_sni) {
2001 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002002 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002003 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002004 goto abort;
2005 }
2006
2007 /* extract/check clientHello informations */
2008 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
2009 CBS_init(&extension, extension_data, extension_len);
2010
2011 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
2012 || CBS_len(&sig_algs) == 0
2013 || CBS_len(&extension) != 0) {
2014 goto abort;
2015 }
2016 if (CBS_len(&sig_algs) % 2 != 0) {
2017 goto abort;
2018 }
2019 while (CBS_len(&sig_algs) != 0) {
2020 if (!CBS_get_u8(&sig_algs, &hash)
2021 || !CBS_get_u8(&sig_algs, &sign)) {
2022 goto abort;
2023 }
2024 switch (sign) {
2025 case TLSEXT_signature_rsa:
2026 has_rsa = 1;
2027 break;
2028 case TLSEXT_signature_ecdsa:
2029 has_ecdsa_sig = 1;
2030 break;
2031 default:
2032 continue;
2033 }
2034 if (has_ecdsa_sig && has_rsa)
2035 break;
2036 }
2037 } else {
2038 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
2039 has_rsa = 1;
2040 }
2041 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
2042 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
2043
2044 while (CBS_len(&cipher_suites) != 0) {
2045 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
2046 goto abort;
2047 }
2048 cipher = SSL_get_cipher_by_value(cipher_suite);
2049 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
2050 has_ecdsa = 1;
2051 break;
2052 }
2053 }
2054 }
2055
2056 servername = CBS_data(&host_name);
2057 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
2058 trash.str[i] = tolower(servername[i]);
2059 if (!wildp && (trash.str[i] == '.'))
2060 wildp = &trash.str[i];
2061 }
2062 trash.str[i] = 0;
2063
2064 /* lookup in full qualified names */
2065 node = ebst_lookup(&s->sni_ctx, trash.str);
2066
2067 /* lookup a not neg filter */
2068 for (n = node; n; n = ebmb_next_dup(n)) {
2069 if (!container_of(n, struct sni_ctx, name)->neg) {
2070 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2071 case TLSEXT_signature_ecdsa:
2072 if (has_ecdsa) {
2073 node_ecdsa = n;
2074 goto find_one;
2075 }
2076 break;
2077 case TLSEXT_signature_rsa:
2078 if (has_rsa && !node_rsa) {
2079 node_rsa = n;
2080 if (!has_ecdsa)
2081 goto find_one;
2082 }
2083 break;
2084 default: /* TLSEXT_signature_anonymous */
2085 if (!node_anonymous)
2086 node_anonymous = n;
2087 break;
2088 }
2089 }
2090 }
2091 if (wildp) {
2092 /* lookup in wildcards names */
2093 node = ebst_lookup(&s->sni_w_ctx, wildp);
2094 for (n = node; n; n = ebmb_next_dup(n)) {
2095 if (!container_of(n, struct sni_ctx, name)->neg) {
2096 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2097 case TLSEXT_signature_ecdsa:
2098 if (has_ecdsa) {
2099 node_ecdsa = n;
2100 goto find_one;
2101 }
2102 break;
2103 case TLSEXT_signature_rsa:
2104 if (has_rsa && !node_rsa) {
2105 node_rsa = n;
2106 if (!has_ecdsa)
2107 goto find_one;
2108 }
2109 break;
2110 default: /* TLSEXT_signature_anonymous */
2111 if (!node_anonymous)
2112 node_anonymous = n;
2113 break;
2114 }
2115 }
2116 }
2117 }
2118 find_one:
2119 /* select by key_signature priority order */
2120 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
2121
2122 if (node) {
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02002123 int min, max;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002124 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002125 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02002126 min = container_of(node, struct sni_ctx, name)->conf->ssl_methods.min;
2127 if (min != s->ssl_methods.min)
2128 methodVersions[min].ssl_set_version(ctx->ssl, SET_MIN);
2129 max = container_of(node, struct sni_ctx, name)->conf->ssl_methods.max;
2130 if (max != s->ssl_methods.max)
2131 methodVersions[max].ssl_set_version(ctx->ssl, SET_MAX);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002132 return 1;
2133 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002134 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002135 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002136 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002137 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002138 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002139 abort:
2140 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
2141 conn->err_code = CO_ER_SSL_HANDSHAKE;
2142 return -1;
2143}
2144
2145#else /* OPENSSL_IS_BORINGSSL */
2146
Emeric Brunfc0421f2012-09-07 17:30:07 +02002147/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
2148 * warning when no match is found, which implies the default (first) cert
2149 * will keep being used.
2150 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002151static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002152{
2153 const char *servername;
2154 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002155 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002156 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002157 int i;
2158 (void)al; /* shut gcc stupid warning */
2159
2160 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002161 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002162#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02002163 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002164 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002165 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02002166 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02002167
Willy Tarreauf6721452015-07-07 18:04:38 +02002168 conn_get_to_addr(conn);
2169 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002170 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
2171 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02002172 if (ctx) {
2173 /* switch ctx */
2174 SSL_set_SSL_CTX(ssl, ctx);
2175 return SSL_TLSEXT_ERR_OK;
2176 }
Christopher Faulet30548802015-06-11 13:39:32 +02002177 }
2178 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002179#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002180 if (s->strict_sni)
2181 return SSL_TLSEXT_ERR_ALERT_FATAL;
2182 ssl_sock_switchctx_set(ssl, s->default_ctx);
2183 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002184 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002185
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002186 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002187 if (!servername[i])
2188 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002189 trash.str[i] = tolower(servername[i]);
2190 if (!wildp && (trash.str[i] == '.'))
2191 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002192 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002193 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002194
2195 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002196 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002197
2198 /* lookup a not neg filter */
2199 for (n = node; n; n = ebmb_next_dup(n)) {
2200 if (!container_of(n, struct sni_ctx, name)->neg) {
2201 node = n;
2202 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002203 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002204 }
2205 if (!node && wildp) {
2206 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002207 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002208 }
2209 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002210#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02002211 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002212 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02002213 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02002214 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02002215 return SSL_TLSEXT_ERR_OK;
2216 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002217#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002218 if (s->strict_sni)
2219 return SSL_TLSEXT_ERR_ALERT_FATAL;
2220 ssl_sock_switchctx_set(ssl, s->default_ctx);
2221 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002222 }
2223
2224 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002225 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002226 return SSL_TLSEXT_ERR_OK;
2227}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002228#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002229#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2230
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002231#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002232
2233static DH * ssl_get_dh_1024(void)
2234{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002235 static unsigned char dh1024_p[]={
2236 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
2237 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
2238 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
2239 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
2240 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
2241 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
2242 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
2243 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
2244 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
2245 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
2246 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
2247 };
2248 static unsigned char dh1024_g[]={
2249 0x02,
2250 };
2251
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002252 BIGNUM *p;
2253 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002254 DH *dh = DH_new();
2255 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002256 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
2257 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002258
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002259 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002260 DH_free(dh);
2261 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002262 } else {
2263 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002264 }
2265 }
2266 return dh;
2267}
2268
2269static DH *ssl_get_dh_2048(void)
2270{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002271 static unsigned char dh2048_p[]={
2272 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
2273 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
2274 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
2275 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
2276 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
2277 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
2278 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
2279 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
2280 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
2281 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
2282 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
2283 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
2284 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
2285 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
2286 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
2287 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
2288 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
2289 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
2290 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
2291 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
2292 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
2293 0xB7,0x1F,0x77,0xF3,
2294 };
2295 static unsigned char dh2048_g[]={
2296 0x02,
2297 };
2298
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002299 BIGNUM *p;
2300 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002301 DH *dh = DH_new();
2302 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002303 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
2304 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002305
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002306 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002307 DH_free(dh);
2308 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002309 } else {
2310 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002311 }
2312 }
2313 return dh;
2314}
2315
2316static DH *ssl_get_dh_4096(void)
2317{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002318 static unsigned char dh4096_p[]={
2319 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
2320 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
2321 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
2322 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
2323 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
2324 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
2325 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
2326 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
2327 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
2328 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
2329 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
2330 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
2331 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
2332 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
2333 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
2334 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
2335 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
2336 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
2337 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
2338 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
2339 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
2340 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
2341 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
2342 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
2343 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
2344 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
2345 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
2346 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
2347 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
2348 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
2349 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
2350 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
2351 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
2352 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
2353 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
2354 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
2355 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
2356 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
2357 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
2358 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
2359 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
2360 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
2361 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002362 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02002363 static unsigned char dh4096_g[]={
2364 0x02,
2365 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002366
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002367 BIGNUM *p;
2368 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002369 DH *dh = DH_new();
2370 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002371 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
2372 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002373
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002374 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002375 DH_free(dh);
2376 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002377 } else {
2378 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002379 }
2380 }
2381 return dh;
2382}
2383
2384/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01002385 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002386static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
2387{
2388 DH *dh = NULL;
2389 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002390 int type;
2391
2392 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002393
2394 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2395 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2396 */
2397 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2398 keylen = EVP_PKEY_bits(pkey);
2399 }
2400
Willy Tarreauef934602016-12-22 23:12:01 +01002401 if (keylen > global_ssl.default_dh_param) {
2402 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002403 }
2404
Remi Gacogned3a341a2015-05-29 16:26:17 +02002405 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002406 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002407 }
2408 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002409 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002410 }
2411 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002412 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002413 }
2414
2415 return dh;
2416}
2417
Remi Gacogne47783ef2015-05-29 15:53:22 +02002418static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002419{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002420 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002421 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002422
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002423 if (in == NULL)
2424 goto end;
2425
Remi Gacogne47783ef2015-05-29 15:53:22 +02002426 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002427 goto end;
2428
Remi Gacogne47783ef2015-05-29 15:53:22 +02002429 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2430
2431end:
2432 if (in)
2433 BIO_free(in);
2434
2435 return dh;
2436}
2437
2438int ssl_sock_load_global_dh_param_from_file(const char *filename)
2439{
2440 global_dh = ssl_sock_get_dh_from_file(filename);
2441
2442 if (global_dh) {
2443 return 0;
2444 }
2445
2446 return -1;
2447}
2448
2449/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2450 if an error occured, and 0 if parameter not found. */
2451int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2452{
2453 int ret = -1;
2454 DH *dh = ssl_sock_get_dh_from_file(file);
2455
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002456 if (dh) {
2457 ret = 1;
2458 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002459
2460 if (ssl_dh_ptr_index >= 0) {
2461 /* store a pointer to the DH params to avoid complaining about
2462 ssl-default-dh-param not being set for this SSL_CTX */
2463 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2464 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002465 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002466 else if (global_dh) {
2467 SSL_CTX_set_tmp_dh(ctx, global_dh);
2468 ret = 0; /* DH params not found */
2469 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002470 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002471 /* Clear openssl global errors stack */
2472 ERR_clear_error();
2473
Willy Tarreauef934602016-12-22 23:12:01 +01002474 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002475 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002476 if (local_dh_1024 == NULL)
2477 local_dh_1024 = ssl_get_dh_1024();
2478
Remi Gacogne8de54152014-07-15 11:36:40 +02002479 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002480 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002481
Remi Gacogne8de54152014-07-15 11:36:40 +02002482 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002483 }
2484 else {
2485 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2486 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002487
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002488 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002489 }
Emeric Brun644cde02012-12-14 11:21:13 +01002490
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002491end:
2492 if (dh)
2493 DH_free(dh);
2494
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002495 return ret;
2496}
2497#endif
2498
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002499static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2500 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002501{
2502 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002503 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002504 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002505
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002506 if (*name == '!') {
2507 neg = 1;
2508 name++;
2509 }
2510 if (*name == '*') {
2511 wild = 1;
2512 name++;
2513 }
2514 /* !* filter is a nop */
2515 if (neg && wild)
2516 return order;
2517 if (*name) {
2518 int j, len;
2519 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002520 for (j = 0; j < len && j < trash.size; j++)
2521 trash.str[j] = tolower(name[j]);
2522 if (j >= trash.size)
2523 return order;
2524 trash.str[j] = 0;
2525
2526 /* Check for duplicates. */
2527 if (wild)
2528 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2529 else
2530 node = ebst_lookup(&s->sni_ctx, trash.str);
2531 for (; node; node = ebmb_next_dup(node)) {
2532 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002533 if (sc->ctx == ctx && sc->conf == conf &&
2534 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002535 return order;
2536 }
2537
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002538 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002539 if (!sc)
2540 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002541 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002542 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002543 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002544 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002545 sc->order = order++;
2546 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002547 if (wild)
2548 ebst_insert(&s->sni_w_ctx, &sc->name);
2549 else
2550 ebst_insert(&s->sni_ctx, &sc->name);
2551 }
2552 return order;
2553}
2554
yanbzhu488a4d22015-12-01 15:16:07 -05002555
2556/* The following code is used for loading multiple crt files into
2557 * SSL_CTX's based on CN/SAN
2558 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002559#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002560/* This is used to preload the certifcate, private key
2561 * and Cert Chain of a file passed in via the crt
2562 * argument
2563 *
2564 * This way, we do not have to read the file multiple times
2565 */
2566struct cert_key_and_chain {
2567 X509 *cert;
2568 EVP_PKEY *key;
2569 unsigned int num_chain_certs;
2570 /* This is an array of X509 pointers */
2571 X509 **chain_certs;
2572};
2573
yanbzhu08ce6ab2015-12-02 13:01:29 -05002574#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2575
2576struct key_combo_ctx {
2577 SSL_CTX *ctx;
2578 int order;
2579};
2580
2581/* Map used for processing multiple keypairs for a single purpose
2582 *
2583 * This maps CN/SNI name to certificate type
2584 */
2585struct sni_keytype {
2586 int keytypes; /* BITMASK for keytypes */
2587 struct ebmb_node name; /* node holding the servername value */
2588};
2589
2590
yanbzhu488a4d22015-12-01 15:16:07 -05002591/* Frees the contents of a cert_key_and_chain
2592 */
2593static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2594{
2595 int i;
2596
2597 if (!ckch)
2598 return;
2599
2600 /* Free the certificate and set pointer to NULL */
2601 if (ckch->cert)
2602 X509_free(ckch->cert);
2603 ckch->cert = NULL;
2604
2605 /* Free the key and set pointer to NULL */
2606 if (ckch->key)
2607 EVP_PKEY_free(ckch->key);
2608 ckch->key = NULL;
2609
2610 /* Free each certificate in the chain */
2611 for (i = 0; i < ckch->num_chain_certs; i++) {
2612 if (ckch->chain_certs[i])
2613 X509_free(ckch->chain_certs[i]);
2614 }
2615
2616 /* Free the chain obj itself and set to NULL */
2617 if (ckch->num_chain_certs > 0) {
2618 free(ckch->chain_certs);
2619 ckch->num_chain_certs = 0;
2620 ckch->chain_certs = NULL;
2621 }
2622
2623}
2624
2625/* checks if a key and cert exists in the ckch
2626 */
2627static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2628{
2629 return (ckch->cert != NULL && ckch->key != NULL);
2630}
2631
2632
2633/* Loads the contents of a crt file (path) into a cert_key_and_chain
2634 * This allows us to carry the contents of the file without having to
2635 * read the file multiple times.
2636 *
2637 * returns:
2638 * 0 on Success
2639 * 1 on SSL Failure
2640 * 2 on file not found
2641 */
2642static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2643{
2644
2645 BIO *in;
2646 X509 *ca = NULL;
2647 int ret = 1;
2648
2649 ssl_sock_free_cert_key_and_chain_contents(ckch);
2650
2651 in = BIO_new(BIO_s_file());
2652 if (in == NULL)
2653 goto end;
2654
2655 if (BIO_read_filename(in, path) <= 0)
2656 goto end;
2657
yanbzhu488a4d22015-12-01 15:16:07 -05002658 /* Read Private Key */
2659 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2660 if (ckch->key == NULL) {
2661 memprintf(err, "%sunable to load private key from file '%s'.\n",
2662 err && *err ? *err : "", path);
2663 goto end;
2664 }
2665
Willy Tarreaubb137a82016-04-06 19:02:38 +02002666 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002667 if (BIO_reset(in) == -1) {
2668 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2669 err && *err ? *err : "", path);
2670 goto end;
2671 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002672
2673 /* Read Certificate */
2674 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2675 if (ckch->cert == NULL) {
2676 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2677 err && *err ? *err : "", path);
2678 goto end;
2679 }
2680
yanbzhu488a4d22015-12-01 15:16:07 -05002681 /* Read Certificate Chain */
2682 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2683 /* Grow the chain certs */
2684 ckch->num_chain_certs++;
2685 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2686
2687 /* use - 1 here since we just incremented it above */
2688 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2689 }
2690 ret = ERR_get_error();
2691 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2692 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2693 err && *err ? *err : "", path);
2694 ret = 1;
2695 goto end;
2696 }
2697
2698 ret = 0;
2699
2700end:
2701
2702 ERR_clear_error();
2703 if (in)
2704 BIO_free(in);
2705
2706 /* Something went wrong in one of the reads */
2707 if (ret != 0)
2708 ssl_sock_free_cert_key_and_chain_contents(ckch);
2709
2710 return ret;
2711}
2712
2713/* Loads the info in ckch into ctx
2714 * Currently, this does not process any information about ocsp, dhparams or
2715 * sctl
2716 * Returns
2717 * 0 on success
2718 * 1 on failure
2719 */
2720static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2721{
2722 int i = 0;
2723
2724 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2725 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2726 err && *err ? *err : "", path);
2727 return 1;
2728 }
2729
2730 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2731 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2732 err && *err ? *err : "", path);
2733 return 1;
2734 }
2735
yanbzhu488a4d22015-12-01 15:16:07 -05002736 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2737 for (i = 0; i < ckch->num_chain_certs; i++) {
2738 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002739 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2740 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002741 return 1;
2742 }
2743 }
2744
2745 if (SSL_CTX_check_private_key(ctx) <= 0) {
2746 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2747 err && *err ? *err : "", path);
2748 return 1;
2749 }
2750
2751 return 0;
2752}
2753
yanbzhu08ce6ab2015-12-02 13:01:29 -05002754
2755static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2756{
2757 struct sni_keytype *s_kt = NULL;
2758 struct ebmb_node *node;
2759 int i;
2760
2761 for (i = 0; i < trash.size; i++) {
2762 if (!str[i])
2763 break;
2764 trash.str[i] = tolower(str[i]);
2765 }
2766 trash.str[i] = 0;
2767 node = ebst_lookup(sni_keytypes, trash.str);
2768 if (!node) {
2769 /* CN not found in tree */
2770 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2771 /* Using memcpy here instead of strncpy.
2772 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2773 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2774 */
2775 memcpy(s_kt->name.key, trash.str, i+1);
2776 s_kt->keytypes = 0;
2777 ebst_insert(sni_keytypes, &s_kt->name);
2778 } else {
2779 /* CN found in tree */
2780 s_kt = container_of(node, struct sni_keytype, name);
2781 }
2782
2783 /* Mark that this CN has the keytype of key_index via keytypes mask */
2784 s_kt->keytypes |= 1<<key_index;
2785
2786}
2787
2788
2789/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2790 * If any are found, group these files into a set of SSL_CTX*
2791 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2792 *
2793 * This will allow the user to explictly group multiple cert/keys for a single purpose
2794 *
2795 * Returns
2796 * 0 on success
2797 * 1 on failure
2798 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002799static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2800 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002801{
2802 char fp[MAXPATHLEN+1] = {0};
2803 int n = 0;
2804 int i = 0;
2805 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2806 struct eb_root sni_keytypes_map = { {0} };
2807 struct ebmb_node *node;
2808 struct ebmb_node *next;
2809 /* Array of SSL_CTX pointers corresponding to each possible combo
2810 * of keytypes
2811 */
2812 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2813 int rv = 0;
2814 X509_NAME *xname = NULL;
2815 char *str = NULL;
2816#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2817 STACK_OF(GENERAL_NAME) *names = NULL;
2818#endif
2819
2820 /* Load all possible certs and keys */
2821 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2822 struct stat buf;
2823
2824 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2825 if (stat(fp, &buf) == 0) {
2826 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2827 rv = 1;
2828 goto end;
2829 }
2830 }
2831 }
2832
2833 /* Process each ckch and update keytypes for each CN/SAN
2834 * for example, if CN/SAN www.a.com is associated with
2835 * certs with keytype 0 and 2, then at the end of the loop,
2836 * www.a.com will have:
2837 * keyindex = 0 | 1 | 4 = 5
2838 */
2839 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2840
2841 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2842 continue;
2843
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002844 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002845 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002846 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2847 } else {
2848 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2849 * so the line that contains logic is marked via comments
2850 */
2851 xname = X509_get_subject_name(certs_and_keys[n].cert);
2852 i = -1;
2853 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2854 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002855 ASN1_STRING *value;
2856 value = X509_NAME_ENTRY_get_data(entry);
2857 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002858 /* Important line is here */
2859 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002860
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002861 OPENSSL_free(str);
2862 str = NULL;
2863 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002864 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002865
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002866 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002867#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002868 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2869 if (names) {
2870 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2871 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002872
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002873 if (name->type == GEN_DNS) {
2874 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2875 /* Important line is here */
2876 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002877
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002878 OPENSSL_free(str);
2879 str = NULL;
2880 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002881 }
2882 }
2883 }
2884 }
2885#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2886 }
2887
2888 /* If no files found, return error */
2889 if (eb_is_empty(&sni_keytypes_map)) {
2890 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2891 err && *err ? *err : "", path);
2892 rv = 1;
2893 goto end;
2894 }
2895
2896 /* We now have a map of CN/SAN to keytypes that are loaded in
2897 * Iterate through the map to create the SSL_CTX's (if needed)
2898 * and add each CTX to the SNI tree
2899 *
2900 * Some math here:
2901 * There are 2^n - 1 possibile combinations, each unique
2902 * combination is denoted by the key in the map. Each key
2903 * has a value between 1 and 2^n - 1. Conveniently, the array
2904 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2905 * entry in the array to correspond to the unique combo (key)
2906 * associated with i. This unique key combo (i) will be associated
2907 * with combos[i-1]
2908 */
2909
2910 node = ebmb_first(&sni_keytypes_map);
2911 while (node) {
2912 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002913 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002914
2915 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2916 i = container_of(node, struct sni_keytype, name)->keytypes;
2917 cur_ctx = key_combos[i-1].ctx;
2918
2919 if (cur_ctx == NULL) {
2920 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002921 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002922 if (cur_ctx == NULL) {
2923 memprintf(err, "%sunable to allocate SSL context.\n",
2924 err && *err ? *err : "");
2925 rv = 1;
2926 goto end;
2927 }
2928
yanbzhube2774d2015-12-10 15:07:30 -05002929 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002930 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2931 if (i & (1<<n)) {
2932 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002933 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2934 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002935 SSL_CTX_free(cur_ctx);
2936 rv = 1;
2937 goto end;
2938 }
yanbzhube2774d2015-12-10 15:07:30 -05002939
2940#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2941 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002942 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002943 if (err)
2944 memprintf(err, "%s '%s.ocsp' is present and activates OCSP but it is impossible to compute the OCSP certificate ID (maybe the issuer could not be found)'.\n",
Bertrand Jacquin5424ee02016-11-13 16:37:14 +00002945 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002946 SSL_CTX_free(cur_ctx);
2947 rv = 1;
2948 goto end;
2949 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02002950#elif (defined OPENSSL_IS_BORINGSSL)
2951 ssl_sock_set_ocsp_response_from_file(cur_ctx, cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002952#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002953 }
2954 }
2955
2956 /* Load DH params into the ctx to support DHE keys */
2957#ifndef OPENSSL_NO_DH
2958 if (ssl_dh_ptr_index >= 0)
2959 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2960
2961 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2962 if (rv < 0) {
2963 if (err)
2964 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2965 *err ? *err : "", path);
2966 rv = 1;
2967 goto end;
2968 }
2969#endif
2970
2971 /* Update key_combos */
2972 key_combos[i-1].ctx = cur_ctx;
2973 }
2974
2975 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002976 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2977 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002978 node = ebmb_next(node);
2979 }
2980
2981
2982 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2983 if (!bind_conf->default_ctx) {
2984 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2985 if (key_combos[i].ctx) {
2986 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002987 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002988 break;
2989 }
2990 }
2991 }
2992
2993end:
2994
2995 if (names)
2996 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2997
2998 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2999 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
3000
3001 node = ebmb_first(&sni_keytypes_map);
3002 while (node) {
3003 next = ebmb_next(node);
3004 ebmb_delete(node);
3005 node = next;
3006 }
3007
3008 return rv;
3009}
3010#else
3011/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003012static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3013 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05003014{
3015 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3016 err && *err ? *err : "", path, strerror(errno));
3017 return 1;
3018}
3019
yanbzhu488a4d22015-12-01 15:16:07 -05003020#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
3021
Emeric Brunfc0421f2012-09-07 17:30:07 +02003022/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
3023 * an early error happens and the caller must call SSL_CTX_free() by itelf.
3024 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003025static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
3026 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003027{
3028 BIO *in;
3029 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003030 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003031 int ret = -1;
3032 int order = 0;
3033 X509_NAME *xname;
3034 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003035 pem_password_cb *passwd_cb;
3036 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003037 EVP_PKEY *pkey;
3038 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003039
Emeric Brunfc0421f2012-09-07 17:30:07 +02003040#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3041 STACK_OF(GENERAL_NAME) *names;
3042#endif
3043
3044 in = BIO_new(BIO_s_file());
3045 if (in == NULL)
3046 goto end;
3047
3048 if (BIO_read_filename(in, file) <= 0)
3049 goto end;
3050
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003051
3052 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
3053 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
3054
3055 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003056 if (x == NULL)
3057 goto end;
3058
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003059 pkey = X509_get_pubkey(x);
3060 if (pkey) {
3061 switch(EVP_PKEY_base_id(pkey)) {
3062 case EVP_PKEY_RSA:
3063 key_sig = TLSEXT_signature_rsa;
3064 break;
3065 case EVP_PKEY_EC:
3066 key_sig = TLSEXT_signature_ecdsa;
3067 break;
3068 }
3069 EVP_PKEY_free(pkey);
3070 }
3071
Emeric Brun50bcecc2013-04-22 13:05:23 +02003072 if (fcount) {
3073 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003074 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003075 }
3076 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003077#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003078 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
3079 if (names) {
3080 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
3081 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
3082 if (name->type == GEN_DNS) {
3083 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003084 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003085 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003086 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003087 }
3088 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003089 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003090 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003091#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003092 xname = X509_get_subject_name(x);
3093 i = -1;
3094 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
3095 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003096 ASN1_STRING *value;
3097
3098 value = X509_NAME_ENTRY_get_data(entry);
3099 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003100 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003101 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003102 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003103 }
3104 }
3105
3106 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
3107 if (!SSL_CTX_use_certificate(ctx, x))
3108 goto end;
3109
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003110#ifdef SSL_CTX_clear_extra_chain_certs
3111 SSL_CTX_clear_extra_chain_certs(ctx);
3112#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02003113 if (ctx->extra_certs != NULL) {
3114 sk_X509_pop_free(ctx->extra_certs, X509_free);
3115 ctx->extra_certs = NULL;
3116 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003117#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003118
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003119 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003120 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
3121 X509_free(ca);
3122 goto end;
3123 }
3124 }
3125
3126 err = ERR_get_error();
3127 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
3128 /* we successfully reached the last cert in the file */
3129 ret = 1;
3130 }
3131 ERR_clear_error();
3132
3133end:
3134 if (x)
3135 X509_free(x);
3136
3137 if (in)
3138 BIO_free(in);
3139
3140 return ret;
3141}
3142
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003143static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3144 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003145{
3146 int ret;
3147 SSL_CTX *ctx;
3148
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003149 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02003150 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003151 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
3152 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003153 return 1;
3154 }
3155
3156 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003157 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
3158 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003159 SSL_CTX_free(ctx);
3160 return 1;
3161 }
3162
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003163 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003164 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003165 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
3166 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003167 if (ret < 0) /* serious error, must do that ourselves */
3168 SSL_CTX_free(ctx);
3169 return 1;
3170 }
Emeric Brun61694ab2012-10-26 13:35:33 +02003171
3172 if (SSL_CTX_check_private_key(ctx) <= 0) {
3173 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3174 err && *err ? *err : "", path);
3175 return 1;
3176 }
3177
Emeric Brunfc0421f2012-09-07 17:30:07 +02003178 /* we must not free the SSL_CTX anymore below, since it's already in
3179 * the tree, so it will be discovered and cleaned in time.
3180 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003181#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02003182 /* store a NULL pointer to indicate we have not yet loaded
3183 a custom DH param file */
3184 if (ssl_dh_ptr_index >= 0) {
3185 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
3186 }
3187
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003188 ret = ssl_sock_load_dh_params(ctx, path);
3189 if (ret < 0) {
3190 if (err)
3191 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
3192 *err ? *err : "", path);
3193 return 1;
3194 }
3195#endif
3196
Lukas Tribuse4e30f72014-12-09 16:32:51 +01003197#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02003198 ret = ssl_sock_load_ocsp(ctx, path);
3199 if (ret < 0) {
3200 if (err)
3201 memprintf(err, "%s '%s.ocsp' is present and activates OCSP but it is impossible to compute the OCSP certificate ID (maybe the issuer could not be found)'.\n",
3202 *err ? *err : "", path);
3203 return 1;
3204 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02003205#elif (defined OPENSSL_IS_BORINGSSL)
3206 ssl_sock_set_ocsp_response_from_file(ctx, path);
Emeric Brun4147b2e2014-06-16 18:36:30 +02003207#endif
3208
Daniel Jakots54ffb912015-11-06 20:02:41 +01003209#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01003210 if (sctl_ex_index >= 0) {
3211 ret = ssl_sock_load_sctl(ctx, path);
3212 if (ret < 0) {
3213 if (err)
3214 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
3215 *err ? *err : "", path);
3216 return 1;
3217 }
3218 }
3219#endif
3220
Emeric Brunfc0421f2012-09-07 17:30:07 +02003221#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003222 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003223 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
3224 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02003225 return 1;
3226 }
3227#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003228 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003229 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003230 bind_conf->default_ssl_conf = ssl_conf;
3231 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003232
3233 return 0;
3234}
3235
Willy Tarreau03209342016-12-22 17:08:28 +01003236int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003237{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003238 struct dirent **de_list;
3239 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003240 DIR *dir;
3241 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01003242 char *end;
3243 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02003244 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05003245#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3246 int is_bundle;
3247 int j;
3248#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003249
yanbzhu08ce6ab2015-12-02 13:01:29 -05003250 if (stat(path, &buf) == 0) {
3251 dir = opendir(path);
3252 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003253 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003254
yanbzhu08ce6ab2015-12-02 13:01:29 -05003255 /* strip trailing slashes, including first one */
3256 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
3257 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003258
yanbzhu08ce6ab2015-12-02 13:01:29 -05003259 n = scandir(path, &de_list, 0, alphasort);
3260 if (n < 0) {
3261 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
3262 err && *err ? *err : "", path, strerror(errno));
3263 cfgerr++;
3264 }
3265 else {
3266 for (i = 0; i < n; i++) {
3267 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02003268
yanbzhu08ce6ab2015-12-02 13:01:29 -05003269 end = strrchr(de->d_name, '.');
3270 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
3271 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003272
yanbzhu08ce6ab2015-12-02 13:01:29 -05003273 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
3274 if (stat(fp, &buf) != 0) {
3275 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3276 err && *err ? *err : "", fp, strerror(errno));
3277 cfgerr++;
3278 goto ignore_entry;
3279 }
3280 if (!S_ISREG(buf.st_mode))
3281 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05003282
3283#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3284 is_bundle = 0;
3285 /* Check if current entry in directory is part of a multi-cert bundle */
3286
3287 if (end) {
3288 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
3289 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
3290 is_bundle = 1;
3291 break;
3292 }
3293 }
3294
3295 if (is_bundle) {
3296 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
3297 int dp_len;
3298
3299 dp_len = end - de->d_name;
3300 snprintf(dp, dp_len + 1, "%s", de->d_name);
3301
3302 /* increment i and free de until we get to a non-bundle cert
3303 * Note here that we look at de_list[i + 1] before freeing de
3304 * this is important since ignore_entry will free de
3305 */
3306 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
3307 free(de);
3308 i++;
3309 de = de_list[i];
3310 }
3311
3312 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003313 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05003314
3315 /* Successfully processed the bundle */
3316 goto ignore_entry;
3317 }
3318 }
3319
3320#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003321 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003322ignore_entry:
3323 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003324 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003325 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003326 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003327 closedir(dir);
3328 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003329 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003330
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003331 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003332
Emeric Brunfc0421f2012-09-07 17:30:07 +02003333 return cfgerr;
3334}
3335
Thierry Fournier383085f2013-01-24 14:15:43 +01003336/* Make sure openssl opens /dev/urandom before the chroot. The work is only
3337 * done once. Zero is returned if the operation fails. No error is returned
3338 * if the random is said as not implemented, because we expect that openssl
3339 * will use another method once needed.
3340 */
3341static int ssl_initialize_random()
3342{
3343 unsigned char random;
3344 static int random_initialized = 0;
3345
3346 if (!random_initialized && RAND_bytes(&random, 1) != 0)
3347 random_initialized = 1;
3348
3349 return random_initialized;
3350}
3351
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003352/* release ssl bind conf */
3353void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003354{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003355 if (conf) {
3356#ifdef OPENSSL_NPN_NEGOTIATED
3357 free(conf->npn_str);
3358 conf->npn_str = NULL;
3359#endif
3360#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
3361 free(conf->alpn_str);
3362 conf->alpn_str = NULL;
3363#endif
3364 free(conf->ca_file);
3365 conf->ca_file = NULL;
3366 free(conf->crl_file);
3367 conf->crl_file = NULL;
3368 free(conf->ciphers);
3369 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003370 free(conf->curves);
3371 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003372 free(conf->ecdhe);
3373 conf->ecdhe = NULL;
3374 }
3375}
3376
3377int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
3378{
3379 char thisline[CRT_LINESIZE];
3380 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003381 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05003382 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003383 int linenum = 0;
3384 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003385
Willy Tarreauad1731d2013-04-02 17:35:58 +02003386 if ((f = fopen(file, "r")) == NULL) {
3387 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003388 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003389 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003390
3391 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003392 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003393 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003394 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003395 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003396 char *crt_path;
3397 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003398
3399 linenum++;
3400 end = line + strlen(line);
3401 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3402 /* Check if we reached the limit and the last char is not \n.
3403 * Watch out for the last line without the terminating '\n'!
3404 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003405 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3406 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003407 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003408 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003409 }
3410
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003411 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003412 newarg = 1;
3413 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003414 if (*line == '#' || *line == '\n' || *line == '\r') {
3415 /* end of string, end of loop */
3416 *line = 0;
3417 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003418 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003419 newarg = 1;
3420 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003421 } else if (*line == '[') {
3422 if (ssl_b) {
3423 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3424 cfgerr = 1;
3425 break;
3426 }
3427 if (!arg) {
3428 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3429 cfgerr = 1;
3430 break;
3431 }
3432 ssl_b = arg;
3433 newarg = 1;
3434 *line = 0;
3435 } else if (*line == ']') {
3436 if (ssl_e) {
3437 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003438 cfgerr = 1;
3439 break;
3440 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003441 if (!ssl_b) {
3442 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3443 cfgerr = 1;
3444 break;
3445 }
3446 ssl_e = arg;
3447 newarg = 1;
3448 *line = 0;
3449 } else if (newarg) {
3450 if (arg == MAX_CRT_ARGS) {
3451 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3452 cfgerr = 1;
3453 break;
3454 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003455 newarg = 0;
3456 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003457 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003458 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003459 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003460 if (cfgerr)
3461 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003462 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003463
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003464 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003465 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003466 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003467
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003468 crt_path = args[0];
3469 if (*crt_path != '/' && global_ssl.crt_base) {
3470 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3471 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3472 crt_path, linenum, file);
3473 cfgerr = 1;
3474 break;
3475 }
3476 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3477 crt_path = path;
3478 }
3479
3480 ssl_conf = calloc(1, sizeof *ssl_conf);
3481 cur_arg = ssl_b ? ssl_b : 1;
3482 while (cur_arg < ssl_e) {
3483 newarg = 0;
3484 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3485 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3486 newarg = 1;
3487 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3488 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3489 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3490 args[cur_arg], linenum, file);
3491 cfgerr = 1;
3492 }
3493 cur_arg += 1 + ssl_bind_kws[i].skip;
3494 break;
3495 }
3496 }
3497 if (!cfgerr && !newarg) {
3498 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3499 args[cur_arg], linenum, file);
3500 cfgerr = 1;
3501 break;
3502 }
3503 }
3504 if (cfgerr) {
3505 ssl_sock_free_ssl_conf(ssl_conf);
3506 free(ssl_conf);
3507 ssl_conf = NULL;
3508 break;
3509 }
3510
3511 if (stat(crt_path, &buf) == 0) {
3512 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3513 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003514 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003515 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3516 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003517 }
3518
Willy Tarreauad1731d2013-04-02 17:35:58 +02003519 if (cfgerr) {
3520 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003521 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003522 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003523 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003524 fclose(f);
3525 return cfgerr;
3526}
3527
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003528/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003529static int
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003530ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003531{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003532 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003533 long options =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003534 SSL_OP_ALL | /* all known workarounds for bugs */
3535 SSL_OP_NO_SSLv2 |
3536 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003537 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003538 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003539 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3540 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003541 long mode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003542 SSL_MODE_ENABLE_PARTIAL_WRITE |
3543 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003544 SSL_MODE_RELEASE_BUFFERS |
3545 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003546 struct tls_version_filter *conf_ssl_methods = &bind_conf->ssl_methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003547 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003548 int flags = MC_SSL_O_ALL;
3549 int cfgerr = 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003550
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003551 ctx = SSL_CTX_new(SSLv23_server_method());
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003552 bind_conf->initial_ctx = ctx;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003553
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003554 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
3555 Warning("Proxy '%s': no-sslv3/no-tlsv1x are ignored for bind '%s' at [%s:%d]. "
3556 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
3557 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3558 else
3559 flags = conf_ssl_methods->flags;
3560
Emmanuel Hocdetbd695fe2017-05-15 15:53:41 +02003561 min = conf_ssl_methods->min;
3562 max = conf_ssl_methods->max;
3563 /* start with TLSv10 to remove SSLv3 per default */
3564 if (!min && (!max || max >= CONF_TLSV10))
3565 min = CONF_TLSV10;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003566 /* Real min and max should be determinate with configuration and openssl's capabilities */
Emmanuel Hocdetbd695fe2017-05-15 15:53:41 +02003567 if (min)
3568 flags |= (methodVersions[min].flag - 1);
3569 if (max)
3570 flags |= ~((methodVersions[max].flag << 1) - 1);
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003571 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003572 min = max = CONF_TLSV_NONE;
3573 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003574 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003575 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003576 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003577 if (min) {
3578 if (hole) {
3579 Warning("Proxy '%s': SSL/TLS versions range not contiguous for bind '%s' at [%s:%d]. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003580 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003581 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line,
3582 methodVersions[hole].name);
3583 hole = 0;
3584 }
3585 max = i;
3586 }
3587 else {
3588 min = max = i;
3589 }
3590 }
3591 else {
3592 if (min)
3593 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003594 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003595 if (!min) {
3596 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003597 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003598 cfgerr += 1;
3599 }
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003600 /* save real min/max in bind_conf */
3601 conf_ssl_methods->min = min;
3602 conf_ssl_methods->max = max;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003603
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003604#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3605 /* Keep force-xxx implementation as it is in older haproxy. It's a
3606 precautionary measure to avoid any suprise with older openssl version. */
3607 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003608 methodVersions[min].ctx_set_version(ctx, SET_SERVER);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003609 else
3610 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3611 if (flags & methodVersions[i].flag)
3612 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003613#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003614 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003615 methodVersions[min].ctx_set_version(ctx, SET_MIN);
3616 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003617#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003618
3619 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3620 options |= SSL_OP_NO_TICKET;
3621 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
3622 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
3623 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00003624
3625#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
3626 if (global_ssl.async)
3627 mode |= SSL_MODE_ASYNC;
3628#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003629 SSL_CTX_set_mode(ctx, mode);
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003630 if (global_ssl.life_time)
3631 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003632
3633#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3634#ifdef OPENSSL_IS_BORINGSSL
3635 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3636 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3637#else
3638 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3639 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3640#endif
3641#endif
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003642 return cfgerr;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003643}
3644
3645int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3646{
3647 struct proxy *curproxy = bind_conf->frontend;
3648 int cfgerr = 0;
3649 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003650 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003651 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003652 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003653
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003654 if (ssl_conf) {
3655 struct tls_version_filter *conf_ssl_methods = &ssl_conf->ssl_methods;
3656 int i, min, max;
3657 int flags = MC_SSL_O_ALL;
3658
3659 /* Real min and max should be determinate with configuration and openssl's capabilities */
3660 min = conf_ssl_methods->min ? conf_ssl_methods->min : bind_conf->ssl_methods.min;
3661 max = conf_ssl_methods->max ? conf_ssl_methods->max : bind_conf->ssl_methods.max;
3662 if (min)
3663 flags |= (methodVersions[min].flag - 1);
3664 if (max)
3665 flags |= ~((methodVersions[max].flag << 1) - 1);
3666 min = max = CONF_TLSV_NONE;
3667 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3668 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
3669 if (min)
3670 max = i;
3671 else
3672 min = max = i;
3673 }
3674 /* save real min/max */
3675 conf_ssl_methods->min = min;
3676 conf_ssl_methods->max = max;
3677 if (!min) {
3678 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
3679 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3680 cfgerr += 1;
3681 }
3682 }
3683
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003684 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003685 case SSL_SOCK_VERIFY_NONE:
3686 verify = SSL_VERIFY_NONE;
3687 break;
3688 case SSL_SOCK_VERIFY_OPTIONAL:
3689 verify = SSL_VERIFY_PEER;
3690 break;
3691 case SSL_SOCK_VERIFY_REQUIRED:
3692 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3693 break;
3694 }
3695 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3696 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003697 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3698 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3699 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003700 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003701 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003702 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003703 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003704 cfgerr++;
3705 }
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02003706 if (!((ssl_conf && ssl_conf->no_ca_names) || bind_conf->ssl_conf.no_ca_names)) {
3707 /* set CA names for client cert request, function returns void */
3708 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
3709 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003710 }
Emeric Brun850efd52014-01-29 12:24:34 +01003711 else {
3712 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3713 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3714 cfgerr++;
3715 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003716#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003717 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003718 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3719
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003720 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003721 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003722 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003723 cfgerr++;
3724 }
Emeric Brun561e5742012-10-02 15:20:55 +02003725 else {
3726 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3727 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003728 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003729#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003730 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003731 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003732#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003733 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003734 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3735 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3736 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3737 cfgerr++;
3738 }
3739 }
3740#endif
3741
Emeric Brunfc0421f2012-09-07 17:30:07 +02003742 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003743 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3744 if (conf_ciphers &&
3745 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003746 Alert("Proxy '%s': unable to set SSL cipher list to '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003747 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003748 cfgerr++;
3749 }
3750
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003751#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003752 /* If tune.ssl.default-dh-param has not been set,
3753 neither has ssl-default-dh-file and no static DH
3754 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003755 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003756 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003757 (ssl_dh_ptr_index == -1 ||
3758 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003759 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3760 const SSL_CIPHER * cipher = NULL;
3761 char cipher_description[128];
3762 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3763 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3764 which is not ephemeral DH. */
3765 const char dhe_description[] = " Kx=DH ";
3766 const char dhe_export_description[] = " Kx=DH(";
3767 int idx = 0;
3768 int dhe_found = 0;
3769 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003770
Remi Gacogne23d5d372014-10-10 17:04:26 +02003771 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003772
Remi Gacogne23d5d372014-10-10 17:04:26 +02003773 if (ssl) {
3774 ciphers = SSL_get_ciphers(ssl);
3775
3776 if (ciphers) {
3777 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3778 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3779 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3780 if (strstr(cipher_description, dhe_description) != NULL ||
3781 strstr(cipher_description, dhe_export_description) != NULL) {
3782 dhe_found = 1;
3783 break;
3784 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003785 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003786 }
3787 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003788 SSL_free(ssl);
3789 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003790 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003791
Lukas Tribus90132722014-08-18 00:56:33 +02003792 if (dhe_found) {
3793 Warning("Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.\n");
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003794 }
3795
Willy Tarreauef934602016-12-22 23:12:01 +01003796 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003797 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003798
Willy Tarreauef934602016-12-22 23:12:01 +01003799 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003800 if (local_dh_1024 == NULL) {
3801 local_dh_1024 = ssl_get_dh_1024();
3802 }
Willy Tarreauef934602016-12-22 23:12:01 +01003803 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003804 if (local_dh_2048 == NULL) {
3805 local_dh_2048 = ssl_get_dh_2048();
3806 }
Willy Tarreauef934602016-12-22 23:12:01 +01003807 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003808 if (local_dh_4096 == NULL) {
3809 local_dh_4096 = ssl_get_dh_4096();
3810 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003811 }
3812 }
3813 }
3814#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003815
Emeric Brunfc0421f2012-09-07 17:30:07 +02003816 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003817#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003818 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003819#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003820
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003821#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003822 ssl_conf_cur = NULL;
3823 if (ssl_conf && ssl_conf->npn_str)
3824 ssl_conf_cur = ssl_conf;
3825 else if (bind_conf->ssl_conf.npn_str)
3826 ssl_conf_cur = &bind_conf->ssl_conf;
3827 if (ssl_conf_cur)
3828 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003829#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003830#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003831 ssl_conf_cur = NULL;
3832 if (ssl_conf && ssl_conf->alpn_str)
3833 ssl_conf_cur = ssl_conf;
3834 else if (bind_conf->ssl_conf.alpn_str)
3835 ssl_conf_cur = &bind_conf->ssl_conf;
3836 if (ssl_conf_cur)
3837 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003838#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003839#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3840 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3841 if (conf_curves) {
3842 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3843 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3844 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3845 cfgerr++;
3846 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003847#if defined(SSL_CTX_set_ecdh_auto)
3848 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3849#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003850 }
3851#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003852#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003853 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003854 int i;
3855 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003856 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3857 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003858
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003859 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003860 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3861 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003862 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003863 cfgerr++;
3864 }
3865 else {
3866 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3867 EC_KEY_free(ecdh);
3868 }
3869 }
3870#endif
3871
Emeric Brunfc0421f2012-09-07 17:30:07 +02003872 return cfgerr;
3873}
3874
Evan Broderbe554312013-06-27 00:05:25 -07003875static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3876{
3877 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3878 size_t prefixlen, suffixlen;
3879
3880 /* Trivial case */
3881 if (strcmp(pattern, hostname) == 0)
3882 return 1;
3883
Evan Broderbe554312013-06-27 00:05:25 -07003884 /* The rest of this logic is based on RFC 6125, section 6.4.3
3885 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3886
Emeric Bruna848dae2013-10-08 11:27:28 +02003887 pattern_wildcard = NULL;
3888 pattern_left_label_end = pattern;
3889 while (*pattern_left_label_end != '.') {
3890 switch (*pattern_left_label_end) {
3891 case 0:
3892 /* End of label not found */
3893 return 0;
3894 case '*':
3895 /* If there is more than one wildcards */
3896 if (pattern_wildcard)
3897 return 0;
3898 pattern_wildcard = pattern_left_label_end;
3899 break;
3900 }
3901 pattern_left_label_end++;
3902 }
3903
3904 /* If it's not trivial and there is no wildcard, it can't
3905 * match */
3906 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003907 return 0;
3908
3909 /* Make sure all labels match except the leftmost */
3910 hostname_left_label_end = strchr(hostname, '.');
3911 if (!hostname_left_label_end
3912 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3913 return 0;
3914
3915 /* Make sure the leftmost label of the hostname is long enough
3916 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003917 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003918 return 0;
3919
3920 /* Finally compare the string on either side of the
3921 * wildcard */
3922 prefixlen = pattern_wildcard - pattern;
3923 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003924 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3925 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003926 return 0;
3927
3928 return 1;
3929}
3930
3931static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3932{
3933 SSL *ssl;
3934 struct connection *conn;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003935 const char *servername;
Willy Tarreau71d058c2017-07-26 20:09:56 +02003936 const char *sni;
Evan Broderbe554312013-06-27 00:05:25 -07003937
3938 int depth;
3939 X509 *cert;
3940 STACK_OF(GENERAL_NAME) *alt_names;
3941 int i;
3942 X509_NAME *cert_subject;
3943 char *str;
3944
3945 if (ok == 0)
3946 return ok;
3947
3948 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003949 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003950
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003951 /* We're checking if the provided hostnames match the desired one. The
3952 * desired hostname comes from the SNI we presented if any, or if not
3953 * provided then it may have been explicitly stated using a "verifyhost"
3954 * directive. If neither is set, we don't care about the name so the
3955 * verification is OK.
Willy Tarreau2ab88672017-07-05 18:23:03 +02003956 */
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003957 servername = SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau71d058c2017-07-26 20:09:56 +02003958 sni = servername;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003959 if (!servername) {
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003960 servername = objt_server(conn->target)->ssl_ctx.verify_host;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003961 if (!servername)
3962 return ok;
3963 }
Evan Broderbe554312013-06-27 00:05:25 -07003964
3965 /* We only need to verify the CN on the actual server cert,
3966 * not the indirect CAs */
3967 depth = X509_STORE_CTX_get_error_depth(ctx);
3968 if (depth != 0)
3969 return ok;
3970
3971 /* At this point, the cert is *not* OK unless we can find a
3972 * hostname match */
3973 ok = 0;
3974
3975 cert = X509_STORE_CTX_get_current_cert(ctx);
3976 /* It seems like this might happen if verify peer isn't set */
3977 if (!cert)
3978 return ok;
3979
3980 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3981 if (alt_names) {
3982 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3983 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3984 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003985#if OPENSSL_VERSION_NUMBER < 0x00907000L
3986 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3987#else
Evan Broderbe554312013-06-27 00:05:25 -07003988 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003989#endif
Evan Broderbe554312013-06-27 00:05:25 -07003990 ok = ssl_sock_srv_hostcheck(str, servername);
3991 OPENSSL_free(str);
3992 }
3993 }
3994 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003995 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003996 }
3997
3998 cert_subject = X509_get_subject_name(cert);
3999 i = -1;
4000 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
4001 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004002 ASN1_STRING *value;
4003 value = X509_NAME_ENTRY_get_data(entry);
4004 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07004005 ok = ssl_sock_srv_hostcheck(str, servername);
4006 OPENSSL_free(str);
4007 }
4008 }
4009
Willy Tarreau71d058c2017-07-26 20:09:56 +02004010 /* report the mismatch and indicate if SNI was used or not */
4011 if (!ok && !conn->err_code)
4012 conn->err_code = sni ? CO_ER_SSL_MISMATCH_SNI : CO_ER_SSL_MISMATCH;
Evan Broderbe554312013-06-27 00:05:25 -07004013 return ok;
4014}
4015
Emeric Brun94324a42012-10-11 14:00:19 +02004016/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01004017int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02004018{
Willy Tarreau03209342016-12-22 17:08:28 +01004019 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02004020 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02004021 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02004022 SSL_OP_ALL | /* all known workarounds for bugs */
4023 SSL_OP_NO_SSLv2 |
4024 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02004025 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02004026 SSL_MODE_ENABLE_PARTIAL_WRITE |
4027 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01004028 SSL_MODE_RELEASE_BUFFERS |
4029 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01004030 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004031 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004032 struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004033 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004034 int flags = MC_SSL_O_ALL;
Emeric Brun94324a42012-10-11 14:00:19 +02004035
Thierry Fournier383085f2013-01-24 14:15:43 +01004036 /* Make sure openssl opens /dev/urandom before the chroot */
4037 if (!ssl_initialize_random()) {
4038 Alert("OpenSSL random data generator initialization failed.\n");
4039 cfgerr++;
4040 }
4041
Willy Tarreaufce03112015-01-15 21:32:40 +01004042 /* Automatic memory computations need to know we use SSL there */
4043 global.ssl_used_backend = 1;
4044
4045 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02004046 srv->ssl_ctx.reused_sess = NULL;
4047 if (srv->use_ssl)
4048 srv->xprt = &ssl_sock;
4049 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01004050 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02004051
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004052 ctx = SSL_CTX_new(SSLv23_client_method());
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004053 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02004054 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
4055 proxy_type_str(curproxy), curproxy->id,
4056 srv->id);
4057 cfgerr++;
4058 return cfgerr;
4059 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004060
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004061 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
4062 Warning("config : %s '%s': no-sslv3/no-tlsv1x are ignored for server '%s'. "
4063 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
4064 proxy_type_str(curproxy), curproxy->id, srv->id);
4065 else
4066 flags = conf_ssl_methods->flags;
4067
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004068 /* Real min and max should be determinate with configuration and openssl's capabilities */
4069 if (conf_ssl_methods->min)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004070 flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004071 if (conf_ssl_methods->max)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004072 flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004073
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004074 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004075 min = max = CONF_TLSV_NONE;
4076 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004077 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004078 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004079 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004080 if (min) {
4081 if (hole) {
4082 Warning("config : %s '%s': SSL/TLS versions range not contiguous for server '%s'. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02004083 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004084 proxy_type_str(curproxy), curproxy->id, srv->id,
4085 methodVersions[hole].name);
4086 hole = 0;
4087 }
4088 max = i;
4089 }
4090 else {
4091 min = max = i;
4092 }
4093 }
4094 else {
4095 if (min)
4096 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004097 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004098 if (!min) {
4099 Alert("config : %s '%s': all SSL/TLS versions are disabled for server '%s'.\n",
4100 proxy_type_str(curproxy), curproxy->id, srv->id);
4101 cfgerr += 1;
4102 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004103
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004104#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
4105 /* Keep force-xxx implementation as it is in older haproxy. It's a
4106 precautionary measure to avoid any suprise with older openssl version. */
4107 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004108 methodVersions[min].ctx_set_version(ctx, SET_CLIENT);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004109 else
4110 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
4111 if (flags & methodVersions[i].flag)
4112 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004113#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004114 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004115 methodVersions[min].ctx_set_version(ctx, SET_MIN);
4116 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004117#endif
4118
4119 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
4120 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004121 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004122
4123#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4124 if (global_ssl.async)
4125 mode |= SSL_MODE_ASYNC;
4126#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004127 SSL_CTX_set_mode(ctx, mode);
4128 srv->ssl_ctx.ctx = ctx;
4129
Emeric Bruna7aa3092012-10-26 12:58:00 +02004130 if (srv->ssl_ctx.client_crt) {
4131 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
4132 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
4133 proxy_type_str(curproxy), curproxy->id,
4134 srv->id, srv->ssl_ctx.client_crt);
4135 cfgerr++;
4136 }
4137 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
4138 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
4139 proxy_type_str(curproxy), curproxy->id,
4140 srv->id, srv->ssl_ctx.client_crt);
4141 cfgerr++;
4142 }
4143 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
4144 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
4145 proxy_type_str(curproxy), curproxy->id,
4146 srv->id, srv->ssl_ctx.client_crt);
4147 cfgerr++;
4148 }
4149 }
Emeric Brun94324a42012-10-11 14:00:19 +02004150
Emeric Brun850efd52014-01-29 12:24:34 +01004151 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
4152 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01004153 switch (srv->ssl_ctx.verify) {
4154 case SSL_SOCK_VERIFY_NONE:
4155 verify = SSL_VERIFY_NONE;
4156 break;
4157 case SSL_SOCK_VERIFY_REQUIRED:
4158 verify = SSL_VERIFY_PEER;
4159 break;
4160 }
Evan Broderbe554312013-06-27 00:05:25 -07004161 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01004162 verify,
Willy Tarreau2ab88672017-07-05 18:23:03 +02004163 (srv->ssl_ctx.verify_host || (verify & SSL_VERIFY_PEER)) ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01004164 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02004165 if (srv->ssl_ctx.ca_file) {
4166 /* load CAfile to verify */
4167 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004168 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004169 curproxy->id, srv->id,
4170 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
4171 cfgerr++;
4172 }
4173 }
Emeric Brun850efd52014-01-29 12:24:34 +01004174 else {
4175 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004176 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled by default but no CA file specified. If you're running on a LAN where you're certain to trust the server's certificate, please set an explicit 'verify none' statement on the 'server' line, or use 'ssl-server-verify none' in the global section to disable server-side verifications by default.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01004177 curproxy->id, srv->id,
4178 srv->conf.file, srv->conf.line);
4179 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004180 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01004181 curproxy->id, srv->id,
4182 srv->conf.file, srv->conf.line);
4183 cfgerr++;
4184 }
Emeric Brunef42d922012-10-11 16:11:36 +02004185#ifdef X509_V_FLAG_CRL_CHECK
4186 if (srv->ssl_ctx.crl_file) {
4187 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
4188
4189 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004190 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004191 curproxy->id, srv->id,
4192 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
4193 cfgerr++;
4194 }
4195 else {
4196 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
4197 }
4198 }
4199#endif
4200 }
4201
Emeric Brun94324a42012-10-11 14:00:19 +02004202 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
4203 if (srv->ssl_ctx.ciphers &&
4204 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
4205 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
4206 curproxy->id, srv->id,
4207 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
4208 cfgerr++;
4209 }
4210
4211 return cfgerr;
4212}
4213
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004214/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004215 * be NULL, in which case nothing is done. Returns the number of errors
4216 * encountered.
4217 */
Willy Tarreau03209342016-12-22 17:08:28 +01004218int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004219{
4220 struct ebmb_node *node;
4221 struct sni_ctx *sni;
4222 int err = 0;
4223
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004224 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004225 return 0;
4226
Willy Tarreaufce03112015-01-15 21:32:40 +01004227 /* Automatic memory computations need to know we use SSL there */
4228 global.ssl_used_frontend = 1;
4229
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004230 /* Make sure openssl opens /dev/urandom before the chroot */
4231 if (!ssl_initialize_random()) {
4232 Alert("OpenSSL random data generator initialization failed.\n");
4233 err++;
4234 }
4235 /* Create initial_ctx used to start the ssl connection before do switchctx */
4236 if (!bind_conf->initial_ctx) {
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004237 err += ssl_sock_initial_ctx(bind_conf);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004238 /* It should not be necessary to call this function, but it's
4239 necessary first to check and move all initialisation related
4240 to initial_ctx in ssl_sock_initial_ctx. */
4241 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
4242 }
Emeric Brun0bed9942014-10-30 19:25:24 +01004243 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004244 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01004245
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004246 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004247 while (node) {
4248 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004249 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4250 /* only initialize the CTX on its first occurrence and
4251 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004252 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004253 node = ebmb_next(node);
4254 }
4255
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004256 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004257 while (node) {
4258 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004259 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4260 /* only initialize the CTX on its first occurrence and
4261 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004262 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004263 node = ebmb_next(node);
4264 }
4265 return err;
4266}
4267
Willy Tarreau55d37912016-12-21 23:38:39 +01004268/* Prepares all the contexts for a bind_conf and allocates the shared SSL
4269 * context if needed. Returns < 0 on error, 0 on success. The warnings and
4270 * alerts are directly emitted since the rest of the stack does it below.
4271 */
4272int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
4273{
4274 struct proxy *px = bind_conf->frontend;
4275 int alloc_ctx;
4276 int err;
4277
4278 if (!bind_conf->is_ssl) {
4279 if (bind_conf->default_ctx) {
4280 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
4281 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4282 }
4283 return 0;
4284 }
4285 if (!bind_conf->default_ctx) {
Emmanuel Hocdetaa0d6372017-08-09 11:24:25 +02004286 if (bind_conf->strict_sni && !bind_conf->generate_certs) {
4287 Warning("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d], ssl connections will fail (use 'crt').\n",
4288 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4289 }
4290 else {
4291 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
4292 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4293 return -1;
4294 }
Willy Tarreau55d37912016-12-21 23:38:39 +01004295 }
4296
Willy Tarreauef934602016-12-22 23:12:01 +01004297 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01004298 if (alloc_ctx < 0) {
4299 if (alloc_ctx == SHCTX_E_INIT_LOCK)
4300 Alert("Unable to initialize the lock for the shared SSL session cache. You can retry using the global statement 'tune.ssl.force-private-cache' but it could increase CPU usage due to renegotiations if nbproc > 1.\n");
4301 else
4302 Alert("Unable to allocate SSL session cache.\n");
4303 return -1;
4304 }
4305
4306 err = 0;
4307 /* initialize all certificate contexts */
4308 err += ssl_sock_prepare_all_ctx(bind_conf);
4309
4310 /* initialize CA variables if the certificates generation is enabled */
4311 err += ssl_sock_load_ca(bind_conf);
4312
4313 return -err;
4314}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02004315
4316/* release ssl context allocated for servers. */
4317void ssl_sock_free_srv_ctx(struct server *srv)
4318{
4319 if (srv->ssl_ctx.ctx)
4320 SSL_CTX_free(srv->ssl_ctx.ctx);
4321}
4322
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004323/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004324 * be NULL, in which case nothing is done. The default_ctx is nullified too.
4325 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004326void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004327{
4328 struct ebmb_node *node, *back;
4329 struct sni_ctx *sni;
4330
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004331 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004332 return;
4333
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004334 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004335 while (node) {
4336 sni = ebmb_entry(node, struct sni_ctx, name);
4337 back = ebmb_next(node);
4338 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004339 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004340 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004341 ssl_sock_free_ssl_conf(sni->conf);
4342 free(sni->conf);
4343 sni->conf = NULL;
4344 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004345 free(sni);
4346 node = back;
4347 }
4348
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004349 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004350 while (node) {
4351 sni = ebmb_entry(node, struct sni_ctx, name);
4352 back = ebmb_next(node);
4353 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004354 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004355 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004356 ssl_sock_free_ssl_conf(sni->conf);
4357 free(sni->conf);
4358 sni->conf = NULL;
4359 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004360 free(sni);
4361 node = back;
4362 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004363 SSL_CTX_free(bind_conf->initial_ctx);
4364 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004365 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004366 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02004367}
4368
Willy Tarreau795cdab2016-12-22 17:30:54 +01004369/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
4370void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
4371{
4372 ssl_sock_free_ca(bind_conf);
4373 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004374 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004375 free(bind_conf->ca_sign_file);
4376 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004377 if (bind_conf->keys_ref) {
4378 free(bind_conf->keys_ref->filename);
4379 free(bind_conf->keys_ref->tlskeys);
4380 LIST_DEL(&bind_conf->keys_ref->list);
4381 free(bind_conf->keys_ref);
4382 }
4383 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004384 bind_conf->ca_sign_pass = NULL;
4385 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004386}
4387
Christopher Faulet31af49d2015-06-09 17:29:50 +02004388/* Load CA cert file and private key used to generate certificates */
4389int
Willy Tarreau03209342016-12-22 17:08:28 +01004390ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02004391{
Willy Tarreau03209342016-12-22 17:08:28 +01004392 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004393 FILE *fp;
4394 X509 *cacert = NULL;
4395 EVP_PKEY *capkey = NULL;
4396 int err = 0;
4397
4398 if (!bind_conf || !bind_conf->generate_certs)
4399 return err;
4400
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004401#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01004402 if (global_ssl.ctx_cache)
4403 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02004404 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02004405#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02004406
Christopher Faulet31af49d2015-06-09 17:29:50 +02004407 if (!bind_conf->ca_sign_file) {
4408 Alert("Proxy '%s': cannot enable certificate generation, "
4409 "no CA certificate File configured at [%s:%d].\n",
4410 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004411 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004412 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004413
4414 /* read in the CA certificate */
4415 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
4416 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4417 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004418 goto load_error;
4419 }
4420 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
4421 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4422 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004423 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004424 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004425 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004426 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
4427 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
4428 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004429 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004430 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004431
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004432 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004433 bind_conf->ca_sign_cert = cacert;
4434 bind_conf->ca_sign_pkey = capkey;
4435 return err;
4436
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004437 read_error:
4438 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004439 if (capkey) EVP_PKEY_free(capkey);
4440 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004441 load_error:
4442 bind_conf->generate_certs = 0;
4443 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004444 return err;
4445}
4446
4447/* Release CA cert and private key used to generate certificated */
4448void
4449ssl_sock_free_ca(struct bind_conf *bind_conf)
4450{
4451 if (!bind_conf)
4452 return;
4453
4454 if (bind_conf->ca_sign_pkey)
4455 EVP_PKEY_free(bind_conf->ca_sign_pkey);
4456 if (bind_conf->ca_sign_cert)
4457 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01004458 bind_conf->ca_sign_pkey = NULL;
4459 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004460}
4461
Emeric Brun46591952012-05-18 15:47:34 +02004462/*
4463 * This function is called if SSL * context is not yet allocated. The function
4464 * is designed to be called before any other data-layer operation and sets the
4465 * handshake flag on the connection. It is safe to call it multiple times.
4466 * It returns 0 on success and -1 in error case.
4467 */
4468static int ssl_sock_init(struct connection *conn)
4469{
4470 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004471 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004472 return 0;
4473
Willy Tarreau3c728722014-01-23 13:50:42 +01004474 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004475 return 0;
4476
Willy Tarreau20879a02012-12-03 16:32:10 +01004477 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4478 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004479 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004480 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004481
Emeric Brun46591952012-05-18 15:47:34 +02004482 /* If it is in client mode initiate SSL session
4483 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004484 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004485 int may_retry = 1;
4486
4487 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004488 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004489 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004490 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004491 if (may_retry--) {
4492 pool_gc2();
4493 goto retry_connect;
4494 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004495 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004496 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004497 }
Emeric Brun46591952012-05-18 15:47:34 +02004498
Emeric Brun46591952012-05-18 15:47:34 +02004499 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004500 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4501 SSL_free(conn->xprt_ctx);
4502 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004503 if (may_retry--) {
4504 pool_gc2();
4505 goto retry_connect;
4506 }
Emeric Brun55476152014-11-12 17:35:37 +01004507 conn->err_code = CO_ER_SSL_NO_MEM;
4508 return -1;
4509 }
Emeric Brun46591952012-05-18 15:47:34 +02004510
Evan Broderbe554312013-06-27 00:05:25 -07004511 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004512 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4513 SSL_free(conn->xprt_ctx);
4514 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004515 if (may_retry--) {
4516 pool_gc2();
4517 goto retry_connect;
4518 }
Emeric Brun55476152014-11-12 17:35:37 +01004519 conn->err_code = CO_ER_SSL_NO_MEM;
4520 return -1;
4521 }
4522
4523 SSL_set_connect_state(conn->xprt_ctx);
4524 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4525 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4526 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4527 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4528 }
4529 }
Evan Broderbe554312013-06-27 00:05:25 -07004530
Emeric Brun46591952012-05-18 15:47:34 +02004531 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004532 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004533
4534 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004535 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004536 return 0;
4537 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004538 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004539 int may_retry = 1;
4540
4541 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004542 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004543 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004544 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004545 if (may_retry--) {
4546 pool_gc2();
4547 goto retry_accept;
4548 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004549 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004550 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004551 }
Emeric Brun46591952012-05-18 15:47:34 +02004552
Emeric Brun46591952012-05-18 15:47:34 +02004553 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004554 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4555 SSL_free(conn->xprt_ctx);
4556 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004557 if (may_retry--) {
4558 pool_gc2();
4559 goto retry_accept;
4560 }
Emeric Brun55476152014-11-12 17:35:37 +01004561 conn->err_code = CO_ER_SSL_NO_MEM;
4562 return -1;
4563 }
Emeric Brun46591952012-05-18 15:47:34 +02004564
Emeric Brune1f38db2012-09-03 20:36:47 +02004565 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004566 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4567 SSL_free(conn->xprt_ctx);
4568 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004569 if (may_retry--) {
4570 pool_gc2();
4571 goto retry_accept;
4572 }
Emeric Brun55476152014-11-12 17:35:37 +01004573 conn->err_code = CO_ER_SSL_NO_MEM;
4574 return -1;
4575 }
4576
4577 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004578
Emeric Brun46591952012-05-18 15:47:34 +02004579 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004580 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004581
4582 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004583 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004584 return 0;
4585 }
4586 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004587 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004588 return -1;
4589}
4590
4591
4592/* This is the callback which is used when an SSL handshake is pending. It
4593 * updates the FD status if it wants some polling before being called again.
4594 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4595 * otherwise it returns non-zero and removes itself from the connection's
4596 * flags (the bit is provided in <flag> by the caller).
4597 */
4598int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4599{
4600 int ret;
4601
Willy Tarreau3c728722014-01-23 13:50:42 +01004602 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004603 return 0;
4604
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004605 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004606 goto out_error;
4607
Emeric Brun674b7432012-11-08 19:21:55 +01004608 /* If we use SSL_do_handshake to process a reneg initiated by
4609 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4610 * Usually SSL_write and SSL_read are used and process implicitly
4611 * the reneg handshake.
4612 * Here we use SSL_peek as a workaround for reneg.
4613 */
4614 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4615 char c;
4616
4617 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4618 if (ret <= 0) {
4619 /* handshake may have not been completed, let's find why */
4620 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004621
Emeric Brun674b7432012-11-08 19:21:55 +01004622 if (ret == SSL_ERROR_WANT_WRITE) {
4623 /* SSL handshake needs to write, L4 connection may not be ready */
4624 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004625 __conn_sock_want_send(conn);
4626 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004627 return 0;
4628 }
4629 else if (ret == SSL_ERROR_WANT_READ) {
4630 /* handshake may have been completed but we have
4631 * no more data to read.
4632 */
4633 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4634 ret = 1;
4635 goto reneg_ok;
4636 }
4637 /* SSL handshake needs to read, L4 connection is ready */
4638 if (conn->flags & CO_FL_WAIT_L4_CONN)
4639 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4640 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004641 __conn_sock_want_recv(conn);
4642 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004643 return 0;
4644 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004645#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4646 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004647 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004648 return 0;
4649 }
4650#endif
Emeric Brun674b7432012-11-08 19:21:55 +01004651 else if (ret == SSL_ERROR_SYSCALL) {
4652 /* if errno is null, then connection was successfully established */
4653 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4654 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004655 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004656#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4657 conn->err_code = CO_ER_SSL_HANDSHAKE;
4658#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004659 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004660#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004661 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4662 empty_handshake = state == TLS_ST_BEFORE;
4663#else
4664 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4665#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004666 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004667 if (!errno) {
4668 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4669 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4670 else
4671 conn->err_code = CO_ER_SSL_EMPTY;
4672 }
4673 else {
4674 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4675 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4676 else
4677 conn->err_code = CO_ER_SSL_ABORT;
4678 }
4679 }
4680 else {
4681 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4682 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004683 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004684 conn->err_code = CO_ER_SSL_HANDSHAKE;
4685 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004686#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004687 }
Emeric Brun674b7432012-11-08 19:21:55 +01004688 goto out_error;
4689 }
4690 else {
4691 /* Fail on all other handshake errors */
4692 /* Note: OpenSSL may leave unread bytes in the socket's
4693 * buffer, causing an RST to be emitted upon close() on
4694 * TCP sockets. We first try to drain possibly pending
4695 * data to avoid this as much as possible.
4696 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004697 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004698 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004699 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4700 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004701 goto out_error;
4702 }
4703 }
4704 /* read some data: consider handshake completed */
4705 goto reneg_ok;
4706 }
4707
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004708 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004709 if (ret != 1) {
4710 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004711 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004712
4713 if (ret == SSL_ERROR_WANT_WRITE) {
4714 /* SSL handshake needs to write, L4 connection may not be ready */
4715 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004716 __conn_sock_want_send(conn);
4717 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004718 return 0;
4719 }
4720 else if (ret == SSL_ERROR_WANT_READ) {
4721 /* SSL handshake needs to read, L4 connection is ready */
4722 if (conn->flags & CO_FL_WAIT_L4_CONN)
4723 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4724 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004725 __conn_sock_want_recv(conn);
4726 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004727 return 0;
4728 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004729#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4730 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004731 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004732 return 0;
4733 }
4734#endif
Willy Tarreau89230192012-09-28 20:22:13 +02004735 else if (ret == SSL_ERROR_SYSCALL) {
4736 /* if errno is null, then connection was successfully established */
4737 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4738 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004739 if (!conn->err_code) {
4740#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4741 conn->err_code = CO_ER_SSL_HANDSHAKE;
4742#else
4743 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004744#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004745 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4746 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004747#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004748 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004749#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004750 if (empty_handshake) {
4751 if (!errno) {
4752 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4753 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4754 else
4755 conn->err_code = CO_ER_SSL_EMPTY;
4756 }
4757 else {
4758 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4759 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4760 else
4761 conn->err_code = CO_ER_SSL_ABORT;
4762 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004763 }
4764 else {
4765 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4766 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4767 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004768 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004769 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004770#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004771 }
Willy Tarreau89230192012-09-28 20:22:13 +02004772 goto out_error;
4773 }
Emeric Brun46591952012-05-18 15:47:34 +02004774 else {
4775 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004776 /* Note: OpenSSL may leave unread bytes in the socket's
4777 * buffer, causing an RST to be emitted upon close() on
4778 * TCP sockets. We first try to drain possibly pending
4779 * data to avoid this as much as possible.
4780 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004781 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004782 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004783 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4784 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004785 goto out_error;
4786 }
4787 }
4788
Emeric Brun674b7432012-11-08 19:21:55 +01004789reneg_ok:
Emeric Brunb5e42a82017-06-06 12:35:14 +00004790
4791#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4792 /* ASYNC engine API doesn't support moving read/write
4793 * buffers. So we disable ASYNC mode right after
4794 * the handshake to avoid buffer oveflows.
4795 */
4796 if (global_ssl.async)
4797 SSL_clear_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4798#endif
Emeric Brun46591952012-05-18 15:47:34 +02004799 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004800 if (!SSL_session_reused(conn->xprt_ctx)) {
4801 if (objt_server(conn->target)) {
4802 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4803 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4804 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4805
Emeric Brun46591952012-05-18 15:47:34 +02004806 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004807 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004808 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004809 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4810 }
Emeric Brun46591952012-05-18 15:47:34 +02004811
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004812 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4813 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004814 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004815 else {
4816 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4817 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4818 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4819 }
Emeric Brun46591952012-05-18 15:47:34 +02004820 }
4821
4822 /* The connection is now established at both layers, it's time to leave */
4823 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4824 return 1;
4825
4826 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004827 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004828 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004829 ERR_clear_error();
4830
Emeric Brun9fa89732012-10-04 17:09:56 +02004831 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004832 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4833 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4834 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004835 }
4836
Emeric Brun46591952012-05-18 15:47:34 +02004837 /* Fail on all other handshake errors */
4838 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004839 if (!conn->err_code)
4840 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004841 return 0;
4842}
4843
4844/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004845 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004846 * buffer wraps, in which case a second call may be performed. The connection's
4847 * flags are updated with whatever special event is detected (error, read0,
4848 * empty). The caller is responsible for taking care of those events and
4849 * avoiding the call if inappropriate. The function does not call the
4850 * connection's polling update function, so the caller is responsible for this.
4851 */
4852static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4853{
4854 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004855 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004856
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004857 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004858 goto out_error;
4859
4860 if (conn->flags & CO_FL_HANDSHAKE)
4861 /* a handshake was requested */
4862 return 0;
4863
Willy Tarreauabf08d92014-01-14 11:31:27 +01004864 /* let's realign the buffer to optimize I/O */
4865 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004866 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004867
4868 /* read the largest possible block. For this, we perform only one call
4869 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4870 * in which case we accept to do it once again. A new attempt is made on
4871 * EINTR too.
4872 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004873 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004874 /* first check if we have some room after p+i */
4875 try = buf->data + buf->size - (buf->p + buf->i);
4876 /* otherwise continue between data and p-o */
4877 if (try <= 0) {
4878 try = buf->p - (buf->data + buf->o);
4879 if (try <= 0)
4880 break;
4881 }
4882 if (try > count)
4883 try = count;
4884
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004885 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004886 if (conn->flags & CO_FL_ERROR) {
4887 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004888 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004889 }
Emeric Brun46591952012-05-18 15:47:34 +02004890 if (ret > 0) {
4891 buf->i += ret;
4892 done += ret;
Emeric Brun46591952012-05-18 15:47:34 +02004893 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004894 }
4895 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004896 ret = SSL_get_error(conn->xprt_ctx, ret);
4897 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004898 /* error on protocol or underlying transport */
4899 if ((ret != SSL_ERROR_SYSCALL)
4900 || (errno && (errno != EAGAIN)))
4901 conn->flags |= CO_FL_ERROR;
4902
Emeric Brun644cde02012-12-14 11:21:13 +01004903 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004904 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004905 ERR_clear_error();
4906 }
Emeric Brun46591952012-05-18 15:47:34 +02004907 goto read0;
4908 }
4909 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004910 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004911 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004912 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004913 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004914 __conn_sock_want_send(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00004915#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4916 /* Async mode can be re-enabled, because we're leaving data state.*/
4917 if (global_ssl.async)
4918 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4919#endif
Emeric Brun46591952012-05-18 15:47:34 +02004920 break;
4921 }
4922 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004923 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4924 /* handshake is running, and it may need to re-enable read */
4925 conn->flags |= CO_FL_SSL_WAIT_HS;
4926 __conn_sock_want_recv(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00004927#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4928 /* Async mode can be re-enabled, because we're leaving data state.*/
4929 if (global_ssl.async)
4930 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4931#endif
Emeric Brun282a76a2012-11-08 18:02:56 +01004932 break;
4933 }
Emeric Brun46591952012-05-18 15:47:34 +02004934 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004935 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004936 break;
4937 }
4938 /* otherwise it's a real error */
4939 goto out_error;
4940 }
4941 }
4942 return done;
4943
4944 read0:
4945 conn_sock_read0(conn);
4946 return done;
4947 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004948 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004949 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004950 ERR_clear_error();
4951
Emeric Brun46591952012-05-18 15:47:34 +02004952 conn->flags |= CO_FL_ERROR;
4953 return done;
4954}
4955
4956
4957/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004958 * <flags> may contain some CO_SFL_* flags to hint the system about other
4959 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004960 * Only one call to send() is performed, unless the buffer wraps, in which case
4961 * a second call may be performed. The connection's flags are updated with
4962 * whatever special event is detected (error, empty). The caller is responsible
4963 * for taking care of those events and avoiding the call if inappropriate. The
4964 * function does not call the connection's polling update function, so the caller
4965 * is responsible for this.
4966 */
4967static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4968{
4969 int ret, try, done;
4970
4971 done = 0;
4972
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004973 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004974 goto out_error;
4975
4976 if (conn->flags & CO_FL_HANDSHAKE)
4977 /* a handshake was requested */
4978 return 0;
4979
4980 /* send the largest possible block. For this we perform only one call
4981 * to send() unless the buffer wraps and we exactly fill the first hunk,
4982 * in which case we accept to do it once again.
4983 */
4984 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004985 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004986
Willy Tarreau7bed9452014-02-02 02:00:24 +01004987 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004988 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004989 global_ssl.max_record && try > global_ssl.max_record) {
4990 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004991 }
4992 else {
4993 /* we need to keep the information about the fact that
4994 * we're not limiting the upcoming send(), because if it
4995 * fails, we'll have to retry with at least as many data.
4996 */
4997 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4998 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004999
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005000 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01005001
Emeric Brune1f38db2012-09-03 20:36:47 +02005002 if (conn->flags & CO_FL_ERROR) {
5003 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01005004 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02005005 }
Emeric Brun46591952012-05-18 15:47:34 +02005006 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01005007 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
5008
Emeric Brun46591952012-05-18 15:47:34 +02005009 buf->o -= ret;
5010 done += ret;
5011
Willy Tarreau5fb38032012-12-16 19:39:09 +01005012 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02005013 /* optimize data alignment in the buffer */
5014 buf->p = buf->data;
5015
5016 /* if the system buffer is full, don't insist */
5017 if (ret < try)
5018 break;
5019 }
5020 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005021 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005022
Emeric Brun46591952012-05-18 15:47:34 +02005023 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01005024 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
5025 /* handshake is running, and it may need to re-enable write */
5026 conn->flags |= CO_FL_SSL_WAIT_HS;
5027 __conn_sock_want_send(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00005028#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
5029 /* Async mode can be re-enabled, because we're leaving data state.*/
5030 if (global_ssl.async)
5031 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
5032#endif
Emeric Brun282a76a2012-11-08 18:02:56 +01005033 break;
5034 }
Emeric Brun46591952012-05-18 15:47:34 +02005035 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01005036 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02005037 break;
5038 }
5039 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01005040 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02005041 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01005042 __conn_sock_want_recv(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005043#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brunb5e42a82017-06-06 12:35:14 +00005044 /* Async mode can be re-enabled, because we're leaving data state.*/
5045 if (global_ssl.async)
5046 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
5047#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005048 break;
5049 }
Emeric Brun46591952012-05-18 15:47:34 +02005050 goto out_error;
5051 }
5052 }
5053 return done;
5054
5055 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01005056 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005057 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005058 ERR_clear_error();
5059
Emeric Brun46591952012-05-18 15:47:34 +02005060 conn->flags |= CO_FL_ERROR;
5061 return done;
5062}
5063
Emeric Brun46591952012-05-18 15:47:34 +02005064static void ssl_sock_close(struct connection *conn) {
5065
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005066 if (conn->xprt_ctx) {
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005067#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brun3854e012017-05-17 20:42:48 +02005068 if (global_ssl.async) {
5069 OSSL_ASYNC_FD all_fd[32], afd;
5070 size_t num_all_fds = 0;
5071 int i;
5072
5073 SSL_get_all_async_fds(conn->xprt_ctx, NULL, &num_all_fds);
5074 if (num_all_fds > 32) {
5075 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
5076 return;
5077 }
5078
5079 SSL_get_all_async_fds(conn->xprt_ctx, all_fd, &num_all_fds);
5080
5081 /* If an async job is pending, we must try to
5082 to catch the end using polling before calling
5083 SSL_free */
5084 if (num_all_fds && SSL_waiting_for_async(conn->xprt_ctx)) {
5085 for (i=0 ; i < num_all_fds ; i++) {
5086 /* switch on an handler designed to
5087 * handle the SSL_free
5088 */
5089 afd = all_fd[i];
5090 fdtab[afd].iocb = ssl_async_fd_free;
5091 fdtab[afd].owner = conn->xprt_ctx;
5092 fd_want_recv(afd);
Emeric Brunce9e01c2017-05-31 10:02:53 +00005093 /* To ensure that the fd cache won't be used
5094 * and we'll catch a real RD event.
5095 */
5096 fd_cant_recv(afd);
Emeric Brun3854e012017-05-17 20:42:48 +02005097 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005098 conn->xprt_ctx = NULL;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005099 jobs++;
5100 return;
5101 }
Emeric Brun3854e012017-05-17 20:42:48 +02005102 /* Else we can remove the fds from the fdtab
5103 * and call SSL_free.
5104 * note: we do a fd_remove and not a delete
5105 * because the fd is owned by the engine.
5106 * the engine is responsible to close
5107 */
5108 for (i=0 ; i < num_all_fds ; i++)
5109 fd_remove(all_fd[i]);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005110 }
5111#endif
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005112 SSL_free(conn->xprt_ctx);
5113 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02005114 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02005115 }
Emeric Brun46591952012-05-18 15:47:34 +02005116}
5117
5118/* This function tries to perform a clean shutdown on an SSL connection, and in
5119 * any case, flags the connection as reusable if no handshake was in progress.
5120 */
5121static void ssl_sock_shutw(struct connection *conn, int clean)
5122{
5123 if (conn->flags & CO_FL_HANDSHAKE)
5124 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005125 if (!clean)
5126 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01005127 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02005128 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005129 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01005130 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005131 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005132 ERR_clear_error();
5133 }
Emeric Brun46591952012-05-18 15:47:34 +02005134}
5135
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02005136/* used for logging, may be changed for a sample fetch later */
5137const char *ssl_sock_get_cipher_name(struct connection *conn)
5138{
5139 if (!conn->xprt && !conn->xprt_ctx)
5140 return NULL;
5141 return SSL_get_cipher_name(conn->xprt_ctx);
5142}
5143
5144/* used for logging, may be changed for a sample fetch later */
5145const char *ssl_sock_get_proto_version(struct connection *conn)
5146{
5147 if (!conn->xprt && !conn->xprt_ctx)
5148 return NULL;
5149 return SSL_get_version(conn->xprt_ctx);
5150}
5151
Willy Tarreau8d598402012-10-22 17:58:39 +02005152/* Extract a serial from a cert, and copy it to a chunk.
5153 * Returns 1 if serial is found and copied, 0 if no serial found and
5154 * -1 if output is not large enough.
5155 */
5156static int
5157ssl_sock_get_serial(X509 *crt, struct chunk *out)
5158{
5159 ASN1_INTEGER *serial;
5160
5161 serial = X509_get_serialNumber(crt);
5162 if (!serial)
5163 return 0;
5164
5165 if (out->size < serial->length)
5166 return -1;
5167
5168 memcpy(out->str, serial->data, serial->length);
5169 out->len = serial->length;
5170 return 1;
5171}
5172
Emeric Brun43e79582014-10-29 19:03:26 +01005173/* Extract a cert to der, and copy it to a chunk.
5174 * Returns 1 if cert is found and copied, 0 on der convertion failure and
5175 * -1 if output is not large enough.
5176 */
5177static int
5178ssl_sock_crt2der(X509 *crt, struct chunk *out)
5179{
5180 int len;
5181 unsigned char *p = (unsigned char *)out->str;;
5182
5183 len =i2d_X509(crt, NULL);
5184 if (len <= 0)
5185 return 1;
5186
5187 if (out->size < len)
5188 return -1;
5189
5190 i2d_X509(crt,&p);
5191 out->len = len;
5192 return 1;
5193}
5194
Emeric Brunce5ad802012-10-22 14:11:22 +02005195
5196/* Copy Date in ASN1_UTCTIME format in struct chunk out.
5197 * Returns 1 if serial is found and copied, 0 if no valid time found
5198 * and -1 if output is not large enough.
5199 */
5200static int
5201ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
5202{
5203 if (tm->type == V_ASN1_GENERALIZEDTIME) {
5204 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
5205
5206 if (gentm->length < 12)
5207 return 0;
5208 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
5209 return 0;
5210 if (out->size < gentm->length-2)
5211 return -1;
5212
5213 memcpy(out->str, gentm->data+2, gentm->length-2);
5214 out->len = gentm->length-2;
5215 return 1;
5216 }
5217 else if (tm->type == V_ASN1_UTCTIME) {
5218 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
5219
5220 if (utctm->length < 10)
5221 return 0;
5222 if (utctm->data[0] >= 0x35)
5223 return 0;
5224 if (out->size < utctm->length)
5225 return -1;
5226
5227 memcpy(out->str, utctm->data, utctm->length);
5228 out->len = utctm->length;
5229 return 1;
5230 }
5231
5232 return 0;
5233}
5234
Emeric Brun87855892012-10-17 17:39:35 +02005235/* Extract an entry from a X509_NAME and copy its value to an output chunk.
5236 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
5237 */
5238static int
5239ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
5240{
5241 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005242 ASN1_OBJECT *obj;
5243 ASN1_STRING *data;
5244 const unsigned char *data_ptr;
5245 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005246 int i, j, n;
5247 int cur = 0;
5248 const char *s;
5249 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005250 int name_count;
5251
5252 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005253
5254 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005255 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02005256 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005257 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02005258 else
5259 j = i;
5260
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005261 ne = X509_NAME_get_entry(a, j);
5262 obj = X509_NAME_ENTRY_get_object(ne);
5263 data = X509_NAME_ENTRY_get_data(ne);
5264 data_ptr = ASN1_STRING_get0_data(data);
5265 data_len = ASN1_STRING_length(data);
5266 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005267 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005268 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005269 s = tmp;
5270 }
5271
5272 if (chunk_strcasecmp(entry, s) != 0)
5273 continue;
5274
5275 if (pos < 0)
5276 cur--;
5277 else
5278 cur++;
5279
5280 if (cur != pos)
5281 continue;
5282
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005283 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02005284 return -1;
5285
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005286 memcpy(out->str, data_ptr, data_len);
5287 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005288 return 1;
5289 }
5290
5291 return 0;
5292
5293}
5294
5295/* Extract and format full DN from a X509_NAME and copy result into a chunk
5296 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
5297 */
5298static int
5299ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
5300{
5301 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005302 ASN1_OBJECT *obj;
5303 ASN1_STRING *data;
5304 const unsigned char *data_ptr;
5305 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005306 int i, n, ln;
5307 int l = 0;
5308 const char *s;
5309 char *p;
5310 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005311 int name_count;
5312
5313
5314 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005315
5316 out->len = 0;
5317 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005318 for (i = 0; i < name_count; i++) {
5319 ne = X509_NAME_get_entry(a, i);
5320 obj = X509_NAME_ENTRY_get_object(ne);
5321 data = X509_NAME_ENTRY_get_data(ne);
5322 data_ptr = ASN1_STRING_get0_data(data);
5323 data_len = ASN1_STRING_length(data);
5324 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005325 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005326 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005327 s = tmp;
5328 }
5329 ln = strlen(s);
5330
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005331 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005332 if (l > out->size)
5333 return -1;
5334 out->len = l;
5335
5336 *(p++)='/';
5337 memcpy(p, s, ln);
5338 p += ln;
5339 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005340 memcpy(p, data_ptr, data_len);
5341 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005342 }
5343
5344 if (!out->len)
5345 return 0;
5346
5347 return 1;
5348}
5349
David Safb76832014-05-08 23:42:08 -04005350char *ssl_sock_get_version(struct connection *conn)
5351{
5352 if (!ssl_sock_is_ssl(conn))
5353 return NULL;
5354
5355 return (char *)SSL_get_version(conn->xprt_ctx);
5356}
5357
Willy Tarreau119a4082016-12-22 21:58:38 +01005358/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
5359 * to disable SNI.
5360 */
Willy Tarreau63076412015-07-10 11:33:32 +02005361void ssl_sock_set_servername(struct connection *conn, const char *hostname)
5362{
5363#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01005364 char *prev_name;
5365
Willy Tarreau63076412015-07-10 11:33:32 +02005366 if (!ssl_sock_is_ssl(conn))
5367 return;
5368
Willy Tarreau119a4082016-12-22 21:58:38 +01005369 /* if the SNI changes, we must destroy the reusable context so that a
5370 * new connection will present a new SNI. As an optimization we could
5371 * later imagine having a small cache of ssl_ctx to hold a few SNI per
5372 * server.
5373 */
5374 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5375 if ((!prev_name && hostname) ||
5376 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
5377 SSL_set_session(conn->xprt_ctx, NULL);
5378
Willy Tarreau63076412015-07-10 11:33:32 +02005379 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
5380#endif
5381}
5382
Emeric Brun0abf8362014-06-24 18:26:41 +02005383/* Extract peer certificate's common name into the chunk dest
5384 * Returns
5385 * the len of the extracted common name
5386 * or 0 if no CN found in DN
5387 * or -1 on error case (i.e. no peer certificate)
5388 */
5389int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04005390{
5391 X509 *crt = NULL;
5392 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04005393 const char find_cn[] = "CN";
5394 const struct chunk find_cn_chunk = {
5395 .str = (char *)&find_cn,
5396 .len = sizeof(find_cn)-1
5397 };
Emeric Brun0abf8362014-06-24 18:26:41 +02005398 int result = -1;
David Safb76832014-05-08 23:42:08 -04005399
5400 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02005401 goto out;
David Safb76832014-05-08 23:42:08 -04005402
5403 /* SSL_get_peer_certificate, it increase X509 * ref count */
5404 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5405 if (!crt)
5406 goto out;
5407
5408 name = X509_get_subject_name(crt);
5409 if (!name)
5410 goto out;
David Safb76832014-05-08 23:42:08 -04005411
Emeric Brun0abf8362014-06-24 18:26:41 +02005412 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
5413out:
David Safb76832014-05-08 23:42:08 -04005414 if (crt)
5415 X509_free(crt);
5416
5417 return result;
5418}
5419
Dave McCowan328fb582014-07-30 10:39:13 -04005420/* returns 1 if client passed a certificate for this session, 0 if not */
5421int ssl_sock_get_cert_used_sess(struct connection *conn)
5422{
5423 X509 *crt = NULL;
5424
5425 if (!ssl_sock_is_ssl(conn))
5426 return 0;
5427
5428 /* SSL_get_peer_certificate, it increase X509 * ref count */
5429 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5430 if (!crt)
5431 return 0;
5432
5433 X509_free(crt);
5434 return 1;
5435}
5436
5437/* returns 1 if client passed a certificate for this connection, 0 if not */
5438int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04005439{
5440 if (!ssl_sock_is_ssl(conn))
5441 return 0;
5442
5443 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
5444}
5445
5446/* returns result from SSL verify */
5447unsigned int ssl_sock_get_verify_result(struct connection *conn)
5448{
5449 if (!ssl_sock_is_ssl(conn))
5450 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
5451
5452 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
5453}
5454
Willy Tarreau8743f7e2016-12-04 18:44:29 +01005455/* Returns the application layer protocol name in <str> and <len> when known.
5456 * Zero is returned if the protocol name was not found, otherwise non-zero is
5457 * returned. The string is allocated in the SSL context and doesn't have to be
5458 * freed by the caller. NPN is also checked if available since older versions
5459 * of openssl (1.0.1) which are more common in field only support this one.
5460 */
5461static int ssl_sock_get_alpn(const struct connection *conn, const char **str, int *len)
5462{
5463 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5464 return 0;
5465
5466 *str = NULL;
5467
5468#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
5469 SSL_get0_alpn_selected(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
5470 if (*str)
5471 return 1;
5472#endif
5473#ifdef OPENSSL_NPN_NEGOTIATED
5474 SSL_get0_next_proto_negotiated(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
5475 if (*str)
5476 return 1;
5477#endif
5478 return 0;
5479}
5480
Willy Tarreau7875d092012-09-10 08:20:03 +02005481/***** Below are some sample fetching functions for ACL/patterns *****/
5482
Emeric Brune64aef12012-09-21 13:15:06 +02005483/* boolean, returns true if client cert was present */
5484static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005485smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02005486{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005487 struct connection *conn;
5488
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005489 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005490 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02005491 return 0;
5492
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005493 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02005494 smp->flags |= SMP_F_MAY_CHANGE;
5495 return 0;
5496 }
5497
5498 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005499 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005500 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02005501
5502 return 1;
5503}
5504
Emeric Brun43e79582014-10-29 19:03:26 +01005505/* binary, returns a certificate in a binary chunk (der/raw).
5506 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5507 * should be use.
5508 */
5509static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005510smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01005511{
5512 int cert_peer = (kw[4] == 'c') ? 1 : 0;
5513 X509 *crt = NULL;
5514 int ret = 0;
5515 struct chunk *smp_trash;
5516 struct connection *conn;
5517
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005518 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01005519 if (!conn || conn->xprt != &ssl_sock)
5520 return 0;
5521
5522 if (!(conn->flags & CO_FL_CONNECTED)) {
5523 smp->flags |= SMP_F_MAY_CHANGE;
5524 return 0;
5525 }
5526
5527 if (cert_peer)
5528 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5529 else
5530 crt = SSL_get_certificate(conn->xprt_ctx);
5531
5532 if (!crt)
5533 goto out;
5534
5535 smp_trash = get_trash_chunk();
5536 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
5537 goto out;
5538
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005539 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005540 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01005541 ret = 1;
5542out:
5543 /* SSL_get_peer_certificate, it increase X509 * ref count */
5544 if (cert_peer && crt)
5545 X509_free(crt);
5546 return ret;
5547}
5548
Emeric Brunba841a12014-04-30 17:05:08 +02005549/* binary, returns serial of certificate in a binary chunk.
5550 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5551 * should be use.
5552 */
Willy Tarreau8d598402012-10-22 17:58:39 +02005553static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005554smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02005555{
Emeric Brunba841a12014-04-30 17:05:08 +02005556 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02005557 X509 *crt = NULL;
5558 int ret = 0;
5559 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005560 struct connection *conn;
5561
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005562 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005563 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02005564 return 0;
5565
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005566 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02005567 smp->flags |= SMP_F_MAY_CHANGE;
5568 return 0;
5569 }
5570
Emeric Brunba841a12014-04-30 17:05:08 +02005571 if (cert_peer)
5572 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5573 else
5574 crt = SSL_get_certificate(conn->xprt_ctx);
5575
Willy Tarreau8d598402012-10-22 17:58:39 +02005576 if (!crt)
5577 goto out;
5578
Willy Tarreau47ca5452012-12-23 20:22:19 +01005579 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005580 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5581 goto out;
5582
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005583 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005584 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005585 ret = 1;
5586out:
Emeric Brunba841a12014-04-30 17:05:08 +02005587 /* SSL_get_peer_certificate, it increase X509 * ref count */
5588 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005589 X509_free(crt);
5590 return ret;
5591}
Emeric Brune64aef12012-09-21 13:15:06 +02005592
Emeric Brunba841a12014-04-30 17:05:08 +02005593/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5594 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5595 * should be use.
5596 */
James Votha051b4a2013-05-14 20:37:59 +02005597static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005598smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005599{
Emeric Brunba841a12014-04-30 17:05:08 +02005600 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005601 X509 *crt = NULL;
5602 const EVP_MD *digest;
5603 int ret = 0;
5604 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005605 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005606
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005607 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005608 if (!conn || conn->xprt != &ssl_sock)
5609 return 0;
5610
5611 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005612 smp->flags |= SMP_F_MAY_CHANGE;
5613 return 0;
5614 }
5615
Emeric Brunba841a12014-04-30 17:05:08 +02005616 if (cert_peer)
5617 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5618 else
5619 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005620 if (!crt)
5621 goto out;
5622
5623 smp_trash = get_trash_chunk();
5624 digest = EVP_sha1();
5625 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5626
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005627 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005628 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005629 ret = 1;
5630out:
Emeric Brunba841a12014-04-30 17:05:08 +02005631 /* SSL_get_peer_certificate, it increase X509 * ref count */
5632 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005633 X509_free(crt);
5634 return ret;
5635}
5636
Emeric Brunba841a12014-04-30 17:05:08 +02005637/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5638 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5639 * should be use.
5640 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005641static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005642smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005643{
Emeric Brunba841a12014-04-30 17:05:08 +02005644 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005645 X509 *crt = NULL;
5646 int ret = 0;
5647 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005648 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005649
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005650 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005651 if (!conn || conn->xprt != &ssl_sock)
5652 return 0;
5653
5654 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005655 smp->flags |= SMP_F_MAY_CHANGE;
5656 return 0;
5657 }
5658
Emeric Brunba841a12014-04-30 17:05:08 +02005659 if (cert_peer)
5660 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5661 else
5662 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005663 if (!crt)
5664 goto out;
5665
Willy Tarreau47ca5452012-12-23 20:22:19 +01005666 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005667 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5668 goto out;
5669
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005670 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005671 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005672 ret = 1;
5673out:
Emeric Brunba841a12014-04-30 17:05:08 +02005674 /* SSL_get_peer_certificate, it increase X509 * ref count */
5675 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005676 X509_free(crt);
5677 return ret;
5678}
5679
Emeric Brunba841a12014-04-30 17:05:08 +02005680/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5681 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5682 * should be use.
5683 */
Emeric Brun87855892012-10-17 17:39:35 +02005684static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005685smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005686{
Emeric Brunba841a12014-04-30 17:05:08 +02005687 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005688 X509 *crt = NULL;
5689 X509_NAME *name;
5690 int ret = 0;
5691 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005692 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005693
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005694 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005695 if (!conn || conn->xprt != &ssl_sock)
5696 return 0;
5697
5698 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005699 smp->flags |= SMP_F_MAY_CHANGE;
5700 return 0;
5701 }
5702
Emeric Brunba841a12014-04-30 17:05:08 +02005703 if (cert_peer)
5704 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5705 else
5706 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005707 if (!crt)
5708 goto out;
5709
5710 name = X509_get_issuer_name(crt);
5711 if (!name)
5712 goto out;
5713
Willy Tarreau47ca5452012-12-23 20:22:19 +01005714 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005715 if (args && args[0].type == ARGT_STR) {
5716 int pos = 1;
5717
5718 if (args[1].type == ARGT_SINT)
5719 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005720
5721 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5722 goto out;
5723 }
5724 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5725 goto out;
5726
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005727 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005728 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005729 ret = 1;
5730out:
Emeric Brunba841a12014-04-30 17:05:08 +02005731 /* SSL_get_peer_certificate, it increase X509 * ref count */
5732 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005733 X509_free(crt);
5734 return ret;
5735}
5736
Emeric Brunba841a12014-04-30 17:05:08 +02005737/* string, returns notbefore date in ASN1_UTCTIME format.
5738 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5739 * should be use.
5740 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005741static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005742smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005743{
Emeric Brunba841a12014-04-30 17:05:08 +02005744 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005745 X509 *crt = NULL;
5746 int ret = 0;
5747 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005748 struct connection *conn;
5749
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005750 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005751 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005752 return 0;
5753
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005754 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005755 smp->flags |= SMP_F_MAY_CHANGE;
5756 return 0;
5757 }
5758
Emeric Brunba841a12014-04-30 17:05:08 +02005759 if (cert_peer)
5760 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5761 else
5762 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005763 if (!crt)
5764 goto out;
5765
Willy Tarreau47ca5452012-12-23 20:22:19 +01005766 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005767 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5768 goto out;
5769
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005770 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005771 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005772 ret = 1;
5773out:
Emeric Brunba841a12014-04-30 17:05:08 +02005774 /* SSL_get_peer_certificate, it increase X509 * ref count */
5775 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005776 X509_free(crt);
5777 return ret;
5778}
5779
Emeric Brunba841a12014-04-30 17:05:08 +02005780/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5781 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5782 * should be use.
5783 */
Emeric Brun87855892012-10-17 17:39:35 +02005784static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005785smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005786{
Emeric Brunba841a12014-04-30 17:05:08 +02005787 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005788 X509 *crt = NULL;
5789 X509_NAME *name;
5790 int ret = 0;
5791 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005792 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005793
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005794 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005795 if (!conn || conn->xprt != &ssl_sock)
5796 return 0;
5797
5798 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005799 smp->flags |= SMP_F_MAY_CHANGE;
5800 return 0;
5801 }
5802
Emeric Brunba841a12014-04-30 17:05:08 +02005803 if (cert_peer)
5804 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5805 else
5806 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005807 if (!crt)
5808 goto out;
5809
5810 name = X509_get_subject_name(crt);
5811 if (!name)
5812 goto out;
5813
Willy Tarreau47ca5452012-12-23 20:22:19 +01005814 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005815 if (args && args[0].type == ARGT_STR) {
5816 int pos = 1;
5817
5818 if (args[1].type == ARGT_SINT)
5819 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005820
5821 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5822 goto out;
5823 }
5824 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5825 goto out;
5826
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005827 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005828 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005829 ret = 1;
5830out:
Emeric Brunba841a12014-04-30 17:05:08 +02005831 /* SSL_get_peer_certificate, it increase X509 * ref count */
5832 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005833 X509_free(crt);
5834 return ret;
5835}
Emeric Brun9143d372012-12-20 15:44:16 +01005836
5837/* integer, returns true if current session use a client certificate */
5838static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005839smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005840{
5841 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005842 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005843
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005844 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005845 if (!conn || conn->xprt != &ssl_sock)
5846 return 0;
5847
5848 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005849 smp->flags |= SMP_F_MAY_CHANGE;
5850 return 0;
5851 }
5852
5853 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005854 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005855 if (crt) {
5856 X509_free(crt);
5857 }
5858
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005859 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005860 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005861 return 1;
5862}
5863
Emeric Brunba841a12014-04-30 17:05:08 +02005864/* integer, returns the certificate version
5865 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5866 * should be use.
5867 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005868static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005869smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005870{
Emeric Brunba841a12014-04-30 17:05:08 +02005871 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005872 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005873 struct connection *conn;
5874
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005875 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005876 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005877 return 0;
5878
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005879 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005880 smp->flags |= SMP_F_MAY_CHANGE;
5881 return 0;
5882 }
5883
Emeric Brunba841a12014-04-30 17:05:08 +02005884 if (cert_peer)
5885 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5886 else
5887 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005888 if (!crt)
5889 return 0;
5890
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005891 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005892 /* SSL_get_peer_certificate increase X509 * ref count */
5893 if (cert_peer)
5894 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005895 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005896
5897 return 1;
5898}
5899
Emeric Brunba841a12014-04-30 17:05:08 +02005900/* string, returns the certificate's signature algorithm.
5901 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5902 * should be use.
5903 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005904static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005905smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005906{
Emeric Brunba841a12014-04-30 17:05:08 +02005907 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005908 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005909 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005910 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005911 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005912
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005913 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005914 if (!conn || conn->xprt != &ssl_sock)
5915 return 0;
5916
5917 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005918 smp->flags |= SMP_F_MAY_CHANGE;
5919 return 0;
5920 }
5921
Emeric Brunba841a12014-04-30 17:05:08 +02005922 if (cert_peer)
5923 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5924 else
5925 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005926 if (!crt)
5927 return 0;
5928
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005929 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5930 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005931
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005932 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5933 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005934 /* SSL_get_peer_certificate increase X509 * ref count */
5935 if (cert_peer)
5936 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005937 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005938 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005939
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005940 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005941 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005942 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005943 /* SSL_get_peer_certificate increase X509 * ref count */
5944 if (cert_peer)
5945 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005946
5947 return 1;
5948}
5949
Emeric Brunba841a12014-04-30 17:05:08 +02005950/* string, returns the certificate's key algorithm.
5951 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5952 * should be use.
5953 */
Emeric Brun521a0112012-10-22 12:22:55 +02005954static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005955smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005956{
Emeric Brunba841a12014-04-30 17:05:08 +02005957 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005958 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005959 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005960 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005961 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005962
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005963 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005964 if (!conn || conn->xprt != &ssl_sock)
5965 return 0;
5966
5967 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005968 smp->flags |= SMP_F_MAY_CHANGE;
5969 return 0;
5970 }
5971
Emeric Brunba841a12014-04-30 17:05:08 +02005972 if (cert_peer)
5973 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5974 else
5975 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005976 if (!crt)
5977 return 0;
5978
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005979 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5980 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005981
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005982 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5983 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005984 /* SSL_get_peer_certificate increase X509 * ref count */
5985 if (cert_peer)
5986 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005987 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005988 }
Emeric Brun521a0112012-10-22 12:22:55 +02005989
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005990 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005991 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005992 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005993 if (cert_peer)
5994 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005995
5996 return 1;
5997}
5998
Emeric Brun645ae792014-04-30 14:21:06 +02005999/* boolean, returns true if front conn. transport layer is SSL.
6000 * This function is also usable on backend conn if the fetch keyword 5th
6001 * char is 'b'.
6002 */
Willy Tarreau7875d092012-09-10 08:20:03 +02006003static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006004smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006005{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006006 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6007 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006008
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006009 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006010 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02006011 return 1;
6012}
6013
Emeric Brun2525b6b2012-10-18 15:59:43 +02006014/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02006015static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006016smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006017{
6018#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006019 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006020
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006021 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006022 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006023 conn->xprt_ctx &&
6024 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02006025 return 1;
6026#else
6027 return 0;
6028#endif
6029}
6030
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02006031/* boolean, returns true if client session has been resumed */
6032static int
6033smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
6034{
6035 struct connection *conn = objt_conn(smp->sess->origin);
6036
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006037 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006038 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02006039 conn->xprt_ctx &&
6040 SSL_session_reused(conn->xprt_ctx);
6041 return 1;
6042}
6043
Emeric Brun645ae792014-04-30 14:21:06 +02006044/* string, returns the used cipher if front conn. transport layer is SSL.
6045 * This function is also usable on backend conn if the fetch keyword 5th
6046 * char is 'b'.
6047 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006048static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006049smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006050{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006051 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6052 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02006053
Willy Tarreaube508f12016-03-10 11:47:01 +01006054 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006055 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02006056 return 0;
6057
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006058 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
6059 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006060 return 0;
6061
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006062 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006063 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006064 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006065
6066 return 1;
6067}
6068
Emeric Brun645ae792014-04-30 14:21:06 +02006069/* integer, returns the algoritm's keysize if front conn. transport layer
6070 * is SSL.
6071 * This function is also usable on backend conn if the fetch keyword 5th
6072 * char is 'b'.
6073 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006074static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006075smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006076{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006077 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6078 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006079
Willy Tarreaue237fe12016-03-10 17:05:28 +01006080 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01006081
Emeric Brun589fcad2012-10-16 14:13:26 +02006082 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006083 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02006084 return 0;
6085
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006086 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006087 return 0;
6088
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006089 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006090 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02006091
6092 return 1;
6093}
6094
Emeric Brun645ae792014-04-30 14:21:06 +02006095/* integer, returns the used keysize if front conn. transport layer is SSL.
6096 * This function is also usable on backend conn if the fetch keyword 5th
6097 * char is 'b'.
6098 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006099static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006100smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006101{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006102 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6103 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006104
Emeric Brun589fcad2012-10-16 14:13:26 +02006105 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006106 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6107 return 0;
6108
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006109 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
6110 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02006111 return 0;
6112
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006113 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02006114
6115 return 1;
6116}
6117
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006118#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02006119static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006120smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02006121{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006122 struct connection *conn;
6123
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006124 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006125 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02006126
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006127 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006128 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6129 return 0;
6130
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006131 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006132 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006133 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02006134
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006135 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02006136 return 0;
6137
6138 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02006139}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006140#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02006141
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006142#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006143static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006144smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02006145{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006146 struct connection *conn;
6147
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006148 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006149 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02006150
Willy Tarreaue26bf052015-05-12 10:30:12 +02006151 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006152 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02006153 return 0;
6154
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006155 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006156 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006157 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02006158
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006159 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02006160 return 0;
6161
6162 return 1;
6163}
6164#endif
6165
Emeric Brun645ae792014-04-30 14:21:06 +02006166/* string, returns the used protocol if front conn. transport layer is SSL.
6167 * This function is also usable on backend conn if the fetch keyword 5th
6168 * char is 'b'.
6169 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02006170static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006171smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006172{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006173 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6174 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006175
Emeric Brun589fcad2012-10-16 14:13:26 +02006176 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006177 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6178 return 0;
6179
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006180 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
6181 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006182 return 0;
6183
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006184 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006185 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006186 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006187
6188 return 1;
6189}
6190
Willy Tarreau87b09662015-04-03 00:22:06 +02006191/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02006192 * This function is also usable on backend conn if the fetch keyword 5th
6193 * char is 'b'.
6194 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006195static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006196smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02006197{
6198#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006199 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6200 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02006201
Willy Tarreaue237fe12016-03-10 17:05:28 +01006202 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01006203
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006204 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006205 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02006206
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006207 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6208 return 0;
6209
Willy Tarreau192252e2015-04-04 01:47:55 +02006210 ssl_sess = SSL_get_session(conn->xprt_ctx);
6211 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02006212 return 0;
6213
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006214 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
6215 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02006216 return 0;
6217
6218 return 1;
6219#else
6220 return 0;
6221#endif
6222}
6223
6224static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006225smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006226{
6227#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006228 struct connection *conn;
6229
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006230 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006231 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02006232
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006233 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006234 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6235 return 0;
6236
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006237 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
6238 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02006239 return 0;
6240
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006241 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02006242 return 1;
6243#else
6244 return 0;
6245#endif
6246}
6247
David Sc1ad52e2014-04-08 18:48:47 -04006248static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006249smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
6250{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006251 struct connection *conn;
6252 struct ssl_capture *capture;
6253
6254 conn = objt_conn(smp->sess->origin);
6255 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6256 return 0;
6257
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006258 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006259 if (!capture)
6260 return 0;
6261
6262 smp->flags = SMP_F_CONST;
6263 smp->data.type = SMP_T_BIN;
6264 smp->data.u.str.str = capture->ciphersuite;
6265 smp->data.u.str.len = capture->ciphersuite_len;
6266 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006267}
6268
6269static int
6270smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
6271{
6272 struct chunk *data;
6273
6274 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6275 return 0;
6276
6277 data = get_trash_chunk();
6278 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
6279 smp->data.type = SMP_T_BIN;
6280 smp->data.u.str = *data;
6281 return 1;
6282}
6283
6284static int
6285smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
6286{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006287 struct connection *conn;
6288 struct ssl_capture *capture;
6289
6290 conn = objt_conn(smp->sess->origin);
6291 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6292 return 0;
6293
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006294 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006295 if (!capture)
6296 return 0;
6297
6298 smp->data.type = SMP_T_SINT;
6299 smp->data.u.sint = capture->xxh64;
6300 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006301}
6302
6303static int
6304smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
6305{
6306#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
6307 struct chunk *data;
6308 SSL_CIPHER cipher;
6309 int i;
6310 const char *str;
6311 unsigned char *bin;
6312
6313 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6314 return 0;
6315
6316 /* The cipher algorith must not be SSL_SSLV2, because this
6317 * SSL version seems to not have the same cipher encoding,
6318 * and it is not supported by OpenSSL. Unfortunately, the
6319 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
6320 * with standard defines. We just set the variable to 0,
6321 * ensure that the match with SSL_SSLV2 fails.
6322 */
6323 cipher.algorithm_ssl = 0;
6324
6325 data = get_trash_chunk();
6326 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
6327 bin = (unsigned char *)smp->data.u.str.str + i;
6328 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
6329 str = SSL_CIPHER_standard_name(&cipher);
6330 if (!str || strcmp(str, "UNKNOWN") == 0)
6331 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
6332 else
6333 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
6334 }
6335 smp->data.type = SMP_T_STR;
6336 smp->data.u.str = *data;
6337 return 1;
6338#else
6339 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
6340#endif
6341}
6342
6343static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006344smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04006345{
6346#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006347 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6348 smp->strm ? smp->strm->si[1].end : NULL);
6349
David Sc1ad52e2014-04-08 18:48:47 -04006350 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04006351 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04006352
6353 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04006354 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6355 return 0;
6356
6357 if (!(conn->flags & CO_FL_CONNECTED)) {
6358 smp->flags |= SMP_F_MAY_CHANGE;
6359 return 0;
6360 }
6361
6362 finished_trash = get_trash_chunk();
6363 if (!SSL_session_reused(conn->xprt_ctx))
6364 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6365 else
6366 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6367
6368 if (!finished_len)
6369 return 0;
6370
Emeric Brunb73a9b02014-04-30 18:49:19 +02006371 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006372 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006373 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04006374
6375 return 1;
6376#else
6377 return 0;
6378#endif
6379}
6380
Emeric Brun2525b6b2012-10-18 15:59:43 +02006381/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006382static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006383smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006384{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006385 struct connection *conn;
6386
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006387 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006388 if (!conn || conn->xprt != &ssl_sock)
6389 return 0;
6390
6391 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006392 smp->flags = SMP_F_MAY_CHANGE;
6393 return 0;
6394 }
6395
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006396 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006397 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006398 smp->flags = 0;
6399
6400 return 1;
6401}
6402
Emeric Brun2525b6b2012-10-18 15:59:43 +02006403/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006404static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006405smp_fetch_ssl_c_ca_err_depth(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006406{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006407 struct connection *conn;
6408
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006409 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006410 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02006411 return 0;
6412
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006413 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006414 smp->flags = SMP_F_MAY_CHANGE;
6415 return 0;
6416 }
6417
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006418 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006419 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006420 smp->flags = 0;
6421
6422 return 1;
6423}
6424
Emeric Brun2525b6b2012-10-18 15:59:43 +02006425/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02006426static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006427smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006428{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006429 struct connection *conn;
6430
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006431 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006432 if (!conn || conn->xprt != &ssl_sock)
6433 return 0;
6434
6435 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006436 smp->flags = SMP_F_MAY_CHANGE;
6437 return 0;
6438 }
6439
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006440 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006441 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006442 smp->flags = 0;
6443
6444 return 1;
6445}
6446
Emeric Brun2525b6b2012-10-18 15:59:43 +02006447/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006448static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006449smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006450{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006451 struct connection *conn;
6452
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006453 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006454 if (!conn || conn->xprt != &ssl_sock)
6455 return 0;
6456
6457 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006458 smp->flags = SMP_F_MAY_CHANGE;
6459 return 0;
6460 }
6461
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006462 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006463 return 0;
6464
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006465 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006466 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006467 smp->flags = 0;
6468
6469 return 1;
6470}
6471
Emeric Brunfb510ea2012-10-05 12:00:26 +02006472/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006473static int ssl_bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02006474{
6475 if (!*args[cur_arg + 1]) {
6476 if (err)
6477 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6478 return ERR_ALERT | ERR_FATAL;
6479 }
6480
Willy Tarreauef934602016-12-22 23:12:01 +01006481 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6482 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006483 else
6484 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006485
Emeric Brund94b3fe2012-09-20 18:23:56 +02006486 return 0;
6487}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006488static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6489{
6490 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
6491}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006492
Christopher Faulet31af49d2015-06-09 17:29:50 +02006493/* parse the "ca-sign-file" bind keyword */
6494static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6495{
6496 if (!*args[cur_arg + 1]) {
6497 if (err)
6498 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6499 return ERR_ALERT | ERR_FATAL;
6500 }
6501
Willy Tarreauef934602016-12-22 23:12:01 +01006502 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6503 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02006504 else
6505 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
6506
6507 return 0;
6508}
6509
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006510/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006511static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6512{
6513 if (!*args[cur_arg + 1]) {
6514 if (err)
6515 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
6516 return ERR_ALERT | ERR_FATAL;
6517 }
6518 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
6519 return 0;
6520}
6521
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006522/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006523static int ssl_bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006524{
6525 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006526 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006527 return ERR_ALERT | ERR_FATAL;
6528 }
6529
Emeric Brun76d88952012-10-05 15:47:31 +02006530 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02006531 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006532 return 0;
6533}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006534static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6535{
6536 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
6537}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006538/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006539static int bind_parse_crt(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006540{
Willy Tarreau38011032013-08-13 16:59:39 +02006541 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02006542
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006543 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006544 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006545 return ERR_ALERT | ERR_FATAL;
6546 }
6547
Willy Tarreauef934602016-12-22 23:12:01 +01006548 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
6549 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02006550 memprintf(err, "'%s' : path too long", args[cur_arg]);
6551 return ERR_ALERT | ERR_FATAL;
6552 }
Willy Tarreauef934602016-12-22 23:12:01 +01006553 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01006554 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02006555 return ERR_ALERT | ERR_FATAL;
6556
6557 return 0;
6558 }
6559
Willy Tarreau03209342016-12-22 17:08:28 +01006560 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006561 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006562
6563 return 0;
6564}
6565
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006566/* parse the "crt-list" bind keyword */
6567static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6568{
6569 if (!*args[cur_arg + 1]) {
6570 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
6571 return ERR_ALERT | ERR_FATAL;
6572 }
6573
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006574 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006575 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006576 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006577 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006578
6579 return 0;
6580}
6581
Emeric Brunfb510ea2012-10-05 12:00:26 +02006582/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006583static int ssl_bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02006584{
Emeric Brun051cdab2012-10-02 19:25:50 +02006585#ifndef X509_V_FLAG_CRL_CHECK
6586 if (err)
6587 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6588 return ERR_ALERT | ERR_FATAL;
6589#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006590 if (!*args[cur_arg + 1]) {
6591 if (err)
6592 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6593 return ERR_ALERT | ERR_FATAL;
6594 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006595
Willy Tarreauef934602016-12-22 23:12:01 +01006596 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6597 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006598 else
6599 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006600
Emeric Brun2b58d042012-09-20 17:10:03 +02006601 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006602#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006603}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006604static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6605{
6606 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6607}
Emeric Brun2b58d042012-09-20 17:10:03 +02006608
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006609/* parse the "curves" bind keyword keyword */
6610static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6611{
6612#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6613 if (!*args[cur_arg + 1]) {
6614 if (err)
6615 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6616 return ERR_ALERT | ERR_FATAL;
6617 }
6618 conf->curves = strdup(args[cur_arg + 1]);
6619 return 0;
6620#else
6621 if (err)
6622 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6623 return ERR_ALERT | ERR_FATAL;
6624#endif
6625}
6626static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6627{
6628 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6629}
6630
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006631/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006632static int ssl_bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2b58d042012-09-20 17:10:03 +02006633{
6634#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6635 if (err)
6636 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6637 return ERR_ALERT | ERR_FATAL;
6638#elif defined(OPENSSL_NO_ECDH)
6639 if (err)
6640 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6641 return ERR_ALERT | ERR_FATAL;
6642#else
6643 if (!*args[cur_arg + 1]) {
6644 if (err)
6645 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6646 return ERR_ALERT | ERR_FATAL;
6647 }
6648
6649 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006650
6651 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006652#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006653}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006654static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6655{
6656 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6657}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006658
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006659/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006660static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6661{
6662 int code;
6663 char *p = args[cur_arg + 1];
6664 unsigned long long *ignerr = &conf->crt_ignerr;
6665
6666 if (!*p) {
6667 if (err)
6668 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6669 return ERR_ALERT | ERR_FATAL;
6670 }
6671
6672 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6673 ignerr = &conf->ca_ignerr;
6674
6675 if (strcmp(p, "all") == 0) {
6676 *ignerr = ~0ULL;
6677 return 0;
6678 }
6679
6680 while (p) {
6681 code = atoi(p);
6682 if ((code <= 0) || (code > 63)) {
6683 if (err)
6684 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6685 args[cur_arg], code, args[cur_arg + 1]);
6686 return ERR_ALERT | ERR_FATAL;
6687 }
6688 *ignerr |= 1ULL << code;
6689 p = strchr(p, ',');
6690 if (p)
6691 p++;
6692 }
6693
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006694 return 0;
6695}
6696
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006697/* parse tls_method_options "no-xxx" and "force-xxx" */
6698static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006699{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006700 uint16_t v;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006701 char *p;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006702 p = strchr(arg, '-');
6703 if (!p)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006704 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006705 p++;
6706 if (!strcmp(p, "sslv3"))
6707 v = CONF_SSLV3;
6708 else if (!strcmp(p, "tlsv10"))
6709 v = CONF_TLSV10;
6710 else if (!strcmp(p, "tlsv11"))
6711 v = CONF_TLSV11;
6712 else if (!strcmp(p, "tlsv12"))
6713 v = CONF_TLSV12;
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02006714 else if (!strcmp(p, "tlsv13"))
6715 v = CONF_TLSV13;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006716 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006717 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006718 if (!strncmp(arg, "no-", 3))
6719 methods->flags |= methodVersions[v].flag;
6720 else if (!strncmp(arg, "force-", 6))
6721 methods->min = methods->max = v;
6722 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006723 goto fail;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006724 return 0;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006725 fail:
6726 if (err)
6727 memprintf(err, "'%s' : option not implemented", arg);
6728 return ERR_ALERT | ERR_FATAL;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006729}
6730
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006731static int bind_parse_tls_method_options(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006732{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006733 return parse_tls_method_options(args[cur_arg], &conf->ssl_methods, err);
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006734}
6735
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006736static int srv_parse_tls_method_options(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006737{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006738 return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
6739}
6740
6741/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
6742static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
6743{
6744 uint16_t i, v = 0;
6745 char *argv = args[cur_arg + 1];
6746 if (!*argv) {
6747 if (err)
6748 memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
6749 return ERR_ALERT | ERR_FATAL;
6750 }
6751 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
6752 if (!strcmp(argv, methodVersions[i].name))
6753 v = i;
6754 if (!v) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006755 if (err)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006756 memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006757 return ERR_ALERT | ERR_FATAL;
6758 }
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006759 if (!strcmp("ssl-min-ver", args[cur_arg]))
6760 methods->min = v;
6761 else if (!strcmp("ssl-max-ver", args[cur_arg]))
6762 methods->max = v;
6763 else {
6764 if (err)
6765 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
6766 return ERR_ALERT | ERR_FATAL;
6767 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006768 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006769}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006770
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02006771static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6772{
6773#if !defined(OPENSSL_IS_BORINGSSL)
6774 Warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
6775#endif
6776 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6777}
6778
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006779static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6780{
6781 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6782}
6783
6784static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6785{
6786 return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
6787}
6788
Emeric Brun2d0c4822012-10-02 13:45:20 +02006789/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006790static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2d0c4822012-10-02 13:45:20 +02006791{
Emeric Brun89675492012-10-05 13:48:26 +02006792 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006793 return 0;
6794}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006795
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006796/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006797static int ssl_bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006798{
6799#ifdef OPENSSL_NPN_NEGOTIATED
6800 char *p1, *p2;
6801
6802 if (!*args[cur_arg + 1]) {
6803 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6804 return ERR_ALERT | ERR_FATAL;
6805 }
6806
6807 free(conf->npn_str);
6808
Willy Tarreau3724da12016-02-12 17:11:12 +01006809 /* the NPN string is built as a suite of (<len> <name>)*,
6810 * so we reuse each comma to store the next <len> and need
6811 * one more for the end of the string.
6812 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006813 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006814 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006815 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6816
6817 /* replace commas with the name length */
6818 p1 = conf->npn_str;
6819 p2 = p1 + 1;
6820 while (1) {
6821 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6822 if (!p2)
6823 p2 = p1 + 1 + strlen(p1 + 1);
6824
6825 if (p2 - (p1 + 1) > 255) {
6826 *p2 = '\0';
6827 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6828 return ERR_ALERT | ERR_FATAL;
6829 }
6830
6831 *p1 = p2 - (p1 + 1);
6832 p1 = p2;
6833
6834 if (!*p2)
6835 break;
6836
6837 *(p2++) = '\0';
6838 }
6839 return 0;
6840#else
6841 if (err)
6842 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6843 return ERR_ALERT | ERR_FATAL;
6844#endif
6845}
6846
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006847static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6848{
6849 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6850}
6851
Willy Tarreauab861d32013-04-02 02:30:41 +02006852/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006853static int ssl_bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreauab861d32013-04-02 02:30:41 +02006854{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006855#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006856 char *p1, *p2;
6857
6858 if (!*args[cur_arg + 1]) {
6859 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6860 return ERR_ALERT | ERR_FATAL;
6861 }
6862
6863 free(conf->alpn_str);
6864
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006865 /* the ALPN string is built as a suite of (<len> <name>)*,
6866 * so we reuse each comma to store the next <len> and need
6867 * one more for the end of the string.
6868 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006869 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006870 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006871 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6872
6873 /* replace commas with the name length */
6874 p1 = conf->alpn_str;
6875 p2 = p1 + 1;
6876 while (1) {
6877 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6878 if (!p2)
6879 p2 = p1 + 1 + strlen(p1 + 1);
6880
6881 if (p2 - (p1 + 1) > 255) {
6882 *p2 = '\0';
6883 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6884 return ERR_ALERT | ERR_FATAL;
6885 }
6886
6887 *p1 = p2 - (p1 + 1);
6888 p1 = p2;
6889
6890 if (!*p2)
6891 break;
6892
6893 *(p2++) = '\0';
6894 }
6895 return 0;
6896#else
6897 if (err)
6898 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6899 return ERR_ALERT | ERR_FATAL;
6900#endif
6901}
6902
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006903static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6904{
6905 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6906}
6907
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006908/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006909static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006910{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006911 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006912 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006913
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006914 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6915 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006916 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006917 conf->ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
6918 if (!conf->ssl_methods.min)
6919 conf->ssl_methods.min = global_ssl.listen_default_sslmethods.min;
6920 if (!conf->ssl_methods.max)
6921 conf->ssl_methods.max = global_ssl.listen_default_sslmethods.max;
Emeric Brun76d88952012-10-05 15:47:31 +02006922
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006923 return 0;
6924}
6925
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006926/* parse the "prefer-client-ciphers" bind keyword */
6927static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6928{
6929 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
6930 return 0;
6931}
6932
Christopher Faulet31af49d2015-06-09 17:29:50 +02006933/* parse the "generate-certificates" bind keyword */
6934static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6935{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006936#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006937 conf->generate_certs = 1;
6938#else
6939 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6940 err && *err ? *err : "");
6941#endif
6942 return 0;
6943}
6944
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006945/* parse the "strict-sni" bind keyword */
6946static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6947{
6948 conf->strict_sni = 1;
6949 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006950}
6951
6952/* parse the "tls-ticket-keys" bind keyword */
6953static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6954{
6955#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6956 FILE *f;
6957 int i = 0;
6958 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006959 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006960
6961 if (!*args[cur_arg + 1]) {
6962 if (err)
6963 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6964 return ERR_ALERT | ERR_FATAL;
6965 }
6966
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006967 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6968 if(keys_ref) {
6969 conf->keys_ref = keys_ref;
6970 return 0;
6971 }
6972
Vincent Bernat02779b62016-04-03 13:48:43 +02006973 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006974 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006975
6976 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6977 if (err)
6978 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6979 return ERR_ALERT | ERR_FATAL;
6980 }
6981
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006982 keys_ref->filename = strdup(args[cur_arg + 1]);
6983
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006984 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6985 int len = strlen(thisline);
6986 /* Strip newline characters from the end */
6987 if(thisline[len - 1] == '\n')
6988 thisline[--len] = 0;
6989
6990 if(thisline[len - 1] == '\r')
6991 thisline[--len] = 0;
6992
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006993 if (base64dec(thisline, len, (char *) (keys_ref->tlskeys + i % TLS_TICKETS_NO), sizeof(struct tls_sess_key)) != sizeof(struct tls_sess_key)) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006994 if (err)
6995 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006996 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006997 return ERR_ALERT | ERR_FATAL;
6998 }
6999 i++;
7000 }
7001
7002 if (i < TLS_TICKETS_NO) {
7003 if (err)
7004 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
mildis16aa0152016-06-22 17:46:29 +02007005 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007006 return ERR_ALERT | ERR_FATAL;
7007 }
7008
7009 fclose(f);
7010
7011 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01007012 i -= 2;
7013 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02007014 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02007015 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007016
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02007017 LIST_ADD(&tlskeys_reference, &keys_ref->list);
7018
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007019 return 0;
7020#else
7021 if (err)
7022 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
7023 return ERR_ALERT | ERR_FATAL;
7024#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01007025}
7026
Emeric Brund94b3fe2012-09-20 18:23:56 +02007027/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007028static int ssl_bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02007029{
7030 if (!*args[cur_arg + 1]) {
7031 if (err)
7032 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
7033 return ERR_ALERT | ERR_FATAL;
7034 }
7035
7036 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007037 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007038 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007039 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007040 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007041 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007042 else {
7043 if (err)
7044 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
7045 args[cur_arg], args[cur_arg + 1]);
7046 return ERR_ALERT | ERR_FATAL;
7047 }
7048
7049 return 0;
7050}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007051static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
7052{
7053 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
7054}
Emeric Brund94b3fe2012-09-20 18:23:56 +02007055
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02007056/* parse the "no-ca-names" bind keyword */
7057static int ssl_bind_parse_no_ca_names(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
7058{
7059 conf->no_ca_names = 1;
7060 return 0;
7061}
7062static int bind_parse_no_ca_names(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
7063{
7064 return ssl_bind_parse_no_ca_names(args, cur_arg, px, &conf->ssl_conf, err);
7065}
7066
Willy Tarreau92faadf2012-10-10 23:04:25 +02007067/************** "server" keywords ****************/
7068
Emeric Brunef42d922012-10-11 16:11:36 +02007069/* parse the "ca-file" server keyword */
7070static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7071{
7072 if (!*args[*cur_arg + 1]) {
7073 if (err)
7074 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
7075 return ERR_ALERT | ERR_FATAL;
7076 }
7077
Willy Tarreauef934602016-12-22 23:12:01 +01007078 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
7079 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02007080 else
7081 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
7082
7083 return 0;
7084}
7085
Willy Tarreau92faadf2012-10-10 23:04:25 +02007086/* parse the "check-ssl" server keyword */
7087static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7088{
7089 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007090 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7091 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
7092 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007093 newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
7094 if (!newsrv->ssl_ctx.methods.min)
7095 newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
7096 if (!newsrv->ssl_ctx.methods.max)
7097 newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
7098
Willy Tarreau92faadf2012-10-10 23:04:25 +02007099 return 0;
7100}
7101
7102/* parse the "ciphers" server keyword */
7103static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7104{
7105 if (!*args[*cur_arg + 1]) {
7106 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
7107 return ERR_ALERT | ERR_FATAL;
7108 }
7109
7110 free(newsrv->ssl_ctx.ciphers);
7111 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
7112 return 0;
7113}
7114
Emeric Brunef42d922012-10-11 16:11:36 +02007115/* parse the "crl-file" server keyword */
7116static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7117{
7118#ifndef X509_V_FLAG_CRL_CHECK
7119 if (err)
7120 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
7121 return ERR_ALERT | ERR_FATAL;
7122#else
7123 if (!*args[*cur_arg + 1]) {
7124 if (err)
7125 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
7126 return ERR_ALERT | ERR_FATAL;
7127 }
7128
Willy Tarreauef934602016-12-22 23:12:01 +01007129 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
7130 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02007131 else
7132 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
7133
7134 return 0;
7135#endif
7136}
7137
Emeric Bruna7aa3092012-10-26 12:58:00 +02007138/* parse the "crt" server keyword */
7139static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7140{
7141 if (!*args[*cur_arg + 1]) {
7142 if (err)
7143 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
7144 return ERR_ALERT | ERR_FATAL;
7145 }
7146
Willy Tarreauef934602016-12-22 23:12:01 +01007147 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
7148 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02007149 else
7150 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
7151
7152 return 0;
7153}
Emeric Brunef42d922012-10-11 16:11:36 +02007154
Frédéric Lécaille340ae602017-03-13 10:38:04 +01007155/* parse the "no-check-ssl" server keyword */
7156static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7157{
7158 newsrv->check.use_ssl = 0;
7159 free(newsrv->ssl_ctx.ciphers);
7160 newsrv->ssl_ctx.ciphers = NULL;
7161 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
7162 return 0;
7163}
7164
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01007165/* parse the "no-send-proxy-v2-ssl" server keyword */
7166static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7167{
7168 newsrv->pp_opts &= ~SRV_PP_V2;
7169 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7170 return 0;
7171}
7172
7173/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
7174static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7175{
7176 newsrv->pp_opts &= ~SRV_PP_V2;
7177 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7178 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
7179 return 0;
7180}
7181
Frédéric Lécaillee381d762017-03-13 11:54:17 +01007182/* parse the "no-ssl" server keyword */
7183static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7184{
7185 newsrv->use_ssl = 0;
7186 free(newsrv->ssl_ctx.ciphers);
7187 newsrv->ssl_ctx.ciphers = NULL;
7188 return 0;
7189}
7190
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007191/* parse the "no-ssl-reuse" server keyword */
7192static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7193{
7194 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
7195 return 0;
7196}
7197
Emeric Brunf9c5c472012-10-11 15:28:34 +02007198/* parse the "no-tls-tickets" server keyword */
7199static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7200{
7201 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
7202 return 0;
7203}
David Safb76832014-05-08 23:42:08 -04007204/* parse the "send-proxy-v2-ssl" server keyword */
7205static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7206{
7207 newsrv->pp_opts |= SRV_PP_V2;
7208 newsrv->pp_opts |= SRV_PP_V2_SSL;
7209 return 0;
7210}
7211
7212/* parse the "send-proxy-v2-ssl-cn" server keyword */
7213static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7214{
7215 newsrv->pp_opts |= SRV_PP_V2;
7216 newsrv->pp_opts |= SRV_PP_V2_SSL;
7217 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
7218 return 0;
7219}
Emeric Brunf9c5c472012-10-11 15:28:34 +02007220
Willy Tarreau732eac42015-07-09 11:40:25 +02007221/* parse the "sni" server keyword */
7222static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7223{
7224#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
7225 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
7226 return ERR_ALERT | ERR_FATAL;
7227#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007228 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02007229
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007230 arg = args[*cur_arg + 1];
7231 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02007232 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
7233 return ERR_ALERT | ERR_FATAL;
7234 }
7235
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007236 free(newsrv->sni_expr);
7237 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02007238
Willy Tarreau732eac42015-07-09 11:40:25 +02007239 return 0;
7240#endif
7241}
7242
Willy Tarreau92faadf2012-10-10 23:04:25 +02007243/* parse the "ssl" server keyword */
7244static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7245{
7246 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007247 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7248 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007249 return 0;
7250}
7251
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007252/* parse the "ssl-reuse" server keyword */
7253static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7254{
7255 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
7256 return 0;
7257}
7258
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007259/* parse the "tls-tickets" server keyword */
7260static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7261{
7262 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
7263 return 0;
7264}
7265
Emeric Brunef42d922012-10-11 16:11:36 +02007266/* parse the "verify" server keyword */
7267static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7268{
7269 if (!*args[*cur_arg + 1]) {
7270 if (err)
7271 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
7272 return ERR_ALERT | ERR_FATAL;
7273 }
7274
7275 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007276 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02007277 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007278 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02007279 else {
7280 if (err)
7281 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
7282 args[*cur_arg], args[*cur_arg + 1]);
7283 return ERR_ALERT | ERR_FATAL;
7284 }
7285
Evan Broderbe554312013-06-27 00:05:25 -07007286 return 0;
7287}
7288
7289/* parse the "verifyhost" server keyword */
7290static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7291{
7292 if (!*args[*cur_arg + 1]) {
7293 if (err)
7294 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
7295 return ERR_ALERT | ERR_FATAL;
7296 }
7297
Frédéric Lécaille273f3212017-03-13 15:52:01 +01007298 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07007299 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
7300
Emeric Brunef42d922012-10-11 16:11:36 +02007301 return 0;
7302}
7303
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007304/* parse the "ssl-default-bind-options" keyword in global section */
7305static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
7306 struct proxy *defpx, const char *file, int line,
7307 char **err) {
7308 int i = 1;
7309
7310 if (*(args[i]) == 0) {
7311 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7312 return -1;
7313 }
7314 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007315 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007316 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Lukas Tribus53ae85c2017-05-04 15:45:40 +00007317 else if (!strcmp(args[i], "prefer-client-ciphers"))
7318 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007319 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7320 if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
7321 i++;
7322 else {
7323 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7324 return -1;
7325 }
7326 }
7327 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007328 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7329 return -1;
7330 }
7331 i++;
7332 }
7333 return 0;
7334}
7335
7336/* parse the "ssl-default-server-options" keyword in global section */
7337static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
7338 struct proxy *defpx, const char *file, int line,
7339 char **err) {
7340 int i = 1;
7341
7342 if (*(args[i]) == 0) {
7343 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7344 return -1;
7345 }
7346 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007347 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007348 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007349 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7350 if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
7351 i++;
7352 else {
7353 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7354 return -1;
7355 }
7356 }
7357 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007358 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7359 return -1;
7360 }
7361 i++;
7362 }
7363 return 0;
7364}
7365
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007366/* parse the "ca-base" / "crt-base" keywords in global section.
7367 * Returns <0 on alert, >0 on warning, 0 on success.
7368 */
7369static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
7370 struct proxy *defpx, const char *file, int line,
7371 char **err)
7372{
7373 char **target;
7374
Willy Tarreauef934602016-12-22 23:12:01 +01007375 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007376
7377 if (too_many_args(1, args, err, NULL))
7378 return -1;
7379
7380 if (*target) {
7381 memprintf(err, "'%s' already specified.", args[0]);
7382 return -1;
7383 }
7384
7385 if (*(args[1]) == 0) {
7386 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
7387 return -1;
7388 }
7389 *target = strdup(args[1]);
7390 return 0;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007391}
7392
7393/* parse the "ssl-mode-async" keyword in global section.
7394 * Returns <0 on alert, >0 on warning, 0 on success.
7395 */
7396static int ssl_parse_global_ssl_async(char **args, int section_type, struct proxy *curpx,
7397 struct proxy *defpx, const char *file, int line,
7398 char **err)
7399{
7400#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
7401 global_ssl.async = 1;
7402 return 0;
7403#else
7404 memprintf(err, "'%s': openssl library does not support async mode", args[0]);
7405 return -1;
7406#endif
7407}
7408
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007409#ifndef OPENSSL_NO_ENGINE
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007410static int ssl_check_async_engine_count(void) {
7411 int err_code = 0;
7412
Emeric Brun3854e012017-05-17 20:42:48 +02007413 if (global_ssl.async && (openssl_engines_initialized > 32)) {
7414 Alert("ssl-mode-async only supports a maximum of 32 engines.\n");
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007415 err_code = ERR_ABORT;
7416 }
7417 return err_code;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007418}
7419
Grant Zhang872f9c22017-01-21 01:10:18 +00007420/* parse the "ssl-engine" keyword in global section.
7421 * Returns <0 on alert, >0 on warning, 0 on success.
7422 */
7423static int ssl_parse_global_ssl_engine(char **args, int section_type, struct proxy *curpx,
7424 struct proxy *defpx, const char *file, int line,
7425 char **err)
7426{
7427 char *algo;
7428 int ret = -1;
7429
7430 if (*(args[1]) == 0) {
7431 memprintf(err, "global statement '%s' expects a valid engine name as an argument.", args[0]);
7432 return ret;
7433 }
7434
7435 if (*(args[2]) == 0) {
7436 /* if no list of algorithms is given, it defaults to ALL */
7437 algo = strdup("ALL");
7438 goto add_engine;
7439 }
7440
7441 /* otherwise the expected format is ssl-engine <engine_name> algo <list of algo> */
7442 if (strcmp(args[2], "algo") != 0) {
7443 memprintf(err, "global statement '%s' expects to have algo keyword.", args[0]);
7444 return ret;
7445 }
7446
7447 if (*(args[3]) == 0) {
7448 memprintf(err, "global statement '%s' expects algorithm names as an argument.", args[0]);
7449 return ret;
7450 }
7451 algo = strdup(args[3]);
7452
7453add_engine:
7454 if (ssl_init_single_engine(args[1], algo)==0) {
7455 openssl_engines_initialized++;
7456 ret = 0;
7457 }
7458 free(algo);
7459 return ret;
7460}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007461#endif
Grant Zhang872f9c22017-01-21 01:10:18 +00007462
Willy Tarreauf22e9682016-12-21 23:23:19 +01007463/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
7464 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
7465 */
7466static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
7467 struct proxy *defpx, const char *file, int line,
7468 char **err)
7469{
7470 char **target;
7471
Willy Tarreauef934602016-12-22 23:12:01 +01007472 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01007473
7474 if (too_many_args(1, args, err, NULL))
7475 return -1;
7476
7477 if (*(args[1]) == 0) {
7478 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
7479 return -1;
7480 }
7481
7482 free(*target);
7483 *target = strdup(args[1]);
7484 return 0;
7485}
7486
Willy Tarreau9ceda382016-12-21 23:13:03 +01007487/* parse various global tune.ssl settings consisting in positive integers.
7488 * Returns <0 on alert, >0 on warning, 0 on success.
7489 */
7490static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
7491 struct proxy *defpx, const char *file, int line,
7492 char **err)
7493{
7494 int *target;
7495
7496 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
7497 target = &global.tune.sslcachesize;
7498 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007499 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007500 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007501 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007502 else if (strcmp(args[0], "maxsslconn") == 0)
7503 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007504 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
7505 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007506 else {
7507 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
7508 return -1;
7509 }
7510
7511 if (too_many_args(1, args, err, NULL))
7512 return -1;
7513
7514 if (*(args[1]) == 0) {
7515 memprintf(err, "'%s' expects an integer argument.", args[0]);
7516 return -1;
7517 }
7518
7519 *target = atoi(args[1]);
7520 if (*target < 0) {
7521 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
7522 return -1;
7523 }
7524 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007525}
7526
7527static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
7528 struct proxy *defpx, const char *file, int line,
7529 char **err)
7530{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007531 int ret;
7532
7533 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
7534 if (ret != 0)
7535 return ret;
7536
7537 if (pool2_ssl_capture) {
7538 memprintf(err, "'%s' is already configured.", args[0]);
7539 return -1;
7540 }
7541
7542 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
7543 if (!pool2_ssl_capture) {
7544 memprintf(err, "Out of memory error.");
7545 return -1;
7546 }
7547 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007548}
7549
7550/* parse "ssl.force-private-cache".
7551 * Returns <0 on alert, >0 on warning, 0 on success.
7552 */
7553static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
7554 struct proxy *defpx, const char *file, int line,
7555 char **err)
7556{
7557 if (too_many_args(0, args, err, NULL))
7558 return -1;
7559
Willy Tarreauef934602016-12-22 23:12:01 +01007560 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007561 return 0;
7562}
7563
7564/* parse "ssl.lifetime".
7565 * Returns <0 on alert, >0 on warning, 0 on success.
7566 */
7567static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
7568 struct proxy *defpx, const char *file, int line,
7569 char **err)
7570{
7571 const char *res;
7572
7573 if (too_many_args(1, args, err, NULL))
7574 return -1;
7575
7576 if (*(args[1]) == 0) {
7577 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
7578 return -1;
7579 }
7580
Willy Tarreauef934602016-12-22 23:12:01 +01007581 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01007582 if (res) {
7583 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
7584 return -1;
7585 }
7586 return 0;
7587}
7588
7589#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01007590/* parse "ssl-dh-param-file".
7591 * Returns <0 on alert, >0 on warning, 0 on success.
7592 */
7593static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
7594 struct proxy *defpx, const char *file, int line,
7595 char **err)
7596{
7597 if (too_many_args(1, args, err, NULL))
7598 return -1;
7599
7600 if (*(args[1]) == 0) {
7601 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
7602 return -1;
7603 }
7604
7605 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
7606 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
7607 return -1;
7608 }
7609 return 0;
7610}
7611
Willy Tarreau9ceda382016-12-21 23:13:03 +01007612/* parse "ssl.default-dh-param".
7613 * Returns <0 on alert, >0 on warning, 0 on success.
7614 */
7615static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
7616 struct proxy *defpx, const char *file, int line,
7617 char **err)
7618{
7619 if (too_many_args(1, args, err, NULL))
7620 return -1;
7621
7622 if (*(args[1]) == 0) {
7623 memprintf(err, "'%s' expects an integer argument.", args[0]);
7624 return -1;
7625 }
7626
Willy Tarreauef934602016-12-22 23:12:01 +01007627 global_ssl.default_dh_param = atoi(args[1]);
7628 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01007629 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
7630 return -1;
7631 }
7632 return 0;
7633}
7634#endif
7635
7636
William Lallemand32af2032016-10-29 18:09:35 +02007637/* This function is used with TLS ticket keys management. It permits to browse
7638 * each reference. The variable <getnext> must contain the current node,
7639 * <end> point to the root node.
7640 */
7641#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7642static inline
7643struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
7644{
7645 struct tls_keys_ref *ref = getnext;
7646
7647 while (1) {
7648
7649 /* Get next list entry. */
7650 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
7651
7652 /* If the entry is the last of the list, return NULL. */
7653 if (&ref->list == end)
7654 return NULL;
7655
7656 return ref;
7657 }
7658}
7659
7660static inline
7661struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7662{
7663 int id;
7664 char *error;
7665
7666 /* If the reference starts by a '#', this is numeric id. */
7667 if (reference[0] == '#') {
7668 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7669 id = strtol(reference + 1, &error, 10);
7670 if (*error != '\0')
7671 return NULL;
7672
7673 /* Perform the unique id lookup. */
7674 return tlskeys_ref_lookupid(id);
7675 }
7676
7677 /* Perform the string lookup. */
7678 return tlskeys_ref_lookup(reference);
7679}
7680#endif
7681
7682
7683#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7684
7685static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7686
7687static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7688 return cli_io_handler_tlskeys_files(appctx);
7689}
7690
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007691/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7692 * (next index to be dumped), and cli.p0 (next key reference).
7693 */
William Lallemand32af2032016-10-29 18:09:35 +02007694static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7695
7696 struct stream_interface *si = appctx->owner;
7697
7698 switch (appctx->st2) {
7699 case STAT_ST_INIT:
7700 /* Display the column headers. If the message cannot be sent,
7701 * quit the fucntion with returning 0. The function is called
7702 * later and restart at the state "STAT_ST_INIT".
7703 */
7704 chunk_reset(&trash);
7705
7706 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7707 chunk_appendf(&trash, "# id secret\n");
7708 else
7709 chunk_appendf(&trash, "# id (file)\n");
7710
7711 if (bi_putchk(si_ic(si), &trash) == -1) {
7712 si_applet_cant_put(si);
7713 return 0;
7714 }
7715
William Lallemand32af2032016-10-29 18:09:35 +02007716 /* Now, we start the browsing of the references lists.
7717 * Note that the following call to LIST_ELEM return bad pointer. The only
7718 * available field of this pointer is <list>. It is used with the function
7719 * tlskeys_list_get_next() for retruning the first available entry
7720 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007721 if (appctx->ctx.cli.p0 == NULL) {
7722 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7723 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007724 }
7725
7726 appctx->st2 = STAT_ST_LIST;
7727 /* fall through */
7728
7729 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007730 while (appctx->ctx.cli.p0) {
7731 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7732 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007733
7734 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007735 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007736 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007737
7738 if (appctx->ctx.cli.i1 == 0)
7739 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7740
William Lallemand32af2032016-10-29 18:09:35 +02007741 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007742 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007743 struct chunk *t2 = get_trash_chunk();
7744
7745 chunk_reset(t2);
7746 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007747 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007748 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007749 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007750
7751 if (bi_putchk(si_ic(si), &trash) == -1) {
7752 /* let's try again later from this stream. We add ourselves into
7753 * this stream's users so that it can remove us upon termination.
7754 */
7755 si_applet_cant_put(si);
7756 return 0;
7757 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007758 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007759 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007760 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007761 }
7762 if (bi_putchk(si_ic(si), &trash) == -1) {
7763 /* let's try again later from this stream. We add ourselves into
7764 * this stream's users so that it can remove us upon termination.
7765 */
7766 si_applet_cant_put(si);
7767 return 0;
7768 }
7769
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007770 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007771 break;
7772
7773 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007774 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007775 }
7776
7777 appctx->st2 = STAT_ST_FIN;
7778 /* fall through */
7779
7780 default:
7781 appctx->st2 = STAT_ST_FIN;
7782 return 1;
7783 }
7784 return 0;
7785}
7786
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007787/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007788static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7789{
William Lallemand32af2032016-10-29 18:09:35 +02007790 /* no parameter, shows only file list */
7791 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007792 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007793 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007794 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007795 }
7796
7797 if (args[2][0] == '*') {
7798 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007799 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007800 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007801 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7802 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007803 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007804 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007805 return 1;
7806 }
7807 }
William Lallemand32af2032016-10-29 18:09:35 +02007808 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007809 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007810}
7811
William Lallemand32af2032016-10-29 18:09:35 +02007812static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7813{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007814 struct tls_keys_ref *ref;
7815
William Lallemand32af2032016-10-29 18:09:35 +02007816 /* Expect two parameters: the filename and the new new TLS key in encoding */
7817 if (!*args[3] || !*args[4]) {
7818 appctx->ctx.cli.msg = "'set ssl tls-key' expects a filename and the new TLS key in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007819 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007820 return 1;
7821 }
7822
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007823 ref = tlskeys_ref_lookup_ref(args[3]);
7824 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007825 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007826 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007827 return 1;
7828 }
7829
7830 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7831 if (trash.len != sizeof(struct tls_sess_key)) {
7832 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007833 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007834 return 1;
7835 }
7836
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007837 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7838 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007839
7840 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007841 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007842 return 1;
7843
7844}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007845#endif
William Lallemand32af2032016-10-29 18:09:35 +02007846
7847static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7848{
7849#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7850 char *err = NULL;
7851
7852 /* Expect one parameter: the new response in base64 encoding */
7853 if (!*args[3]) {
7854 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007855 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007856 return 1;
7857 }
7858
7859 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7860 if (trash.len < 0) {
7861 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007862 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007863 return 1;
7864 }
7865
7866 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7867 if (err) {
7868 memprintf(&err, "%s.\n", err);
7869 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007870 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007871 }
7872 return 1;
7873 }
7874 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007875 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007876 return 1;
7877#else
7878 appctx->ctx.cli.msg = "HAProxy was compiled against a version of OpenSSL that doesn't support OCSP stapling.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007879 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007880 return 1;
7881#endif
7882
7883}
7884
7885/* register cli keywords */
7886static struct cli_kw_list cli_kws = {{ },{
7887#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7888 { { "show", "tls-keys", NULL }, "show tls-keys [id|*]: show tls keys references or dump tls ticket keys when id specified", cli_parse_show_tlskeys, NULL },
7889 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007890#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007891 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007892 { { NULL }, NULL, NULL, NULL }
7893}};
7894
7895
Willy Tarreau7875d092012-09-10 08:20:03 +02007896/* Note: must not be declared <const> as its list will be overwritten.
7897 * Please take care of keeping this list alphabetically sorted.
7898 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007899static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007900 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007901 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
Emeric Brun645ae792014-04-30 14:21:06 +02007902 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7903 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007904 { "ssl_bc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007905 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
Emeric Brun645ae792014-04-30 14:21:06 +02007906 { "ssl_bc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007907 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7908 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007909 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007910 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007911 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7912 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7913 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7914 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7915 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7916 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7917 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7918 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007919 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007920 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7921 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007922 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007923 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7924 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7925 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7926 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7927 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7928 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7929 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007930 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007931 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007932 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007933 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007934 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007935 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7936 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02007937 { "ssl_fc_is_resumed", smp_fetch_ssl_fc_is_resumed, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007938#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007939 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007940#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007941#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007942 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007943#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007944 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007945 { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007946 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007947 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7948 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007949 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7950 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7951 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7952 { "ssl_fc_cipherlist_xxh", smp_fetch_ssl_fc_cl_xxh64, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02007953 { NULL, NULL, 0, 0, 0 },
7954}};
7955
7956/* Note: must not be declared <const> as its list will be overwritten.
7957 * Please take care of keeping this list alphabetically sorted.
7958 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007959static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007960 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7961 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007962 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007963}};
7964
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007965/* Note: must not be declared <const> as its list will be overwritten.
7966 * Please take care of keeping this list alphabetically sorted, doing so helps
7967 * all code contributors.
7968 * Optional keywords are also declared with a NULL ->parse() function so that
7969 * the config parser can report an appropriate error when a known keyword was
7970 * not enabled.
7971 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007972static struct ssl_bind_kw ssl_bind_kws[] = {
7973 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7974 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7975 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7976 { "crl-file", ssl_bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01007977 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007978 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02007979 { "no-ca-names", ssl_bind_parse_no_ca_names, 0 }, /* do not send ca names to clients (ca_file related) */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007980 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02007981 { "ssl-min-ver", ssl_bind_parse_tls_method_minmax,1 }, /* minimum version */
7982 { "ssl-max-ver", ssl_bind_parse_tls_method_minmax,1 }, /* maximum version */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007983 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7984 { NULL, NULL, 0 },
7985};
7986
Willy Tarreau51fb7652012-09-18 18:24:39 +02007987static struct bind_kw_list bind_kws = { "SSL", { }, {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007988 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7989 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7990 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
7991 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7992 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
7993 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7994 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7995 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7996 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7997 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
7998 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
7999 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
8000 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
8001 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
8002 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
8003 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02008004 { "force-tlsv13", bind_parse_tls_method_options, 0 }, /* force TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008005 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02008006 { "no-ca-names", bind_parse_no_ca_names, 0 }, /* do not send ca names to clients (ca_file related) */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008007 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
8008 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
8009 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
8010 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02008011 { "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008012 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
8013 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02008014 { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
8015 { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008016 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
8017 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
8018 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
8019 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
8020 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02008021 { NULL, NULL, 0 },
8022}};
Emeric Brun46591952012-05-18 15:47:34 +02008023
Willy Tarreau92faadf2012-10-10 23:04:25 +02008024/* Note: must not be declared <const> as its list will be overwritten.
8025 * Please take care of keeping this list alphabetically sorted, doing so helps
8026 * all code contributors.
8027 * Optional keywords are also declared with a NULL ->parse() function so that
8028 * the config parser can report an appropriate error when a known keyword was
8029 * not enabled.
8030 */
8031static struct srv_kw_list srv_kws = { "SSL", { }, {
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02008032 { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
8033 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
8034 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
8035 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
8036 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
8037 { "force-sslv3", srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
8038 { "force-tlsv10", srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
8039 { "force-tlsv11", srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
8040 { "force-tlsv12", srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
8041 { "force-tlsv13", srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
8042 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
8043 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
8044 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
8045 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
8046 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
8047 { "no-sslv3", srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
8048 { "no-tlsv10", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
8049 { "no-tlsv11", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
8050 { "no-tlsv12", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
8051 { "no-tlsv13", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
8052 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
8053 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
8054 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
8055 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
8056 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
8057 { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1 }, /* minimum version */
8058 { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1 }, /* maximum version */
8059 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
8060 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
8061 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
8062 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02008063 { NULL, NULL, 0, 0 },
8064}};
8065
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008066static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01008067 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
8068 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01008069 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008070 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
8071 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01008072#ifndef OPENSSL_NO_DH
8073 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
8074#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008075 { CFG_GLOBAL, "ssl-mode-async", ssl_parse_global_ssl_async },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008076#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008077 { CFG_GLOBAL, "ssl-engine", ssl_parse_global_ssl_engine },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008078#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01008079 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
8080#ifndef OPENSSL_NO_DH
8081 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
8082#endif
8083 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
8084 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
8085 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
8086 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01008087 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01008088 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
8089 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008090 { 0, NULL, NULL },
8091}};
8092
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02008093/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01008094static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02008095 .snd_buf = ssl_sock_from_buf,
8096 .rcv_buf = ssl_sock_to_buf,
8097 .rcv_pipe = NULL,
8098 .snd_pipe = NULL,
8099 .shutr = NULL,
8100 .shutw = ssl_sock_shutw,
8101 .close = ssl_sock_close,
8102 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01008103 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01008104 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01008105 .prepare_srv = ssl_sock_prepare_srv_ctx,
8106 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8743f7e2016-12-04 18:44:29 +01008107 .get_alpn = ssl_sock_get_alpn,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01008108 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02008109};
8110
Daniel Jakots54ffb912015-11-06 20:02:41 +01008111#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008112
8113static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
8114{
8115 if (ptr) {
8116 chunk_destroy(ptr);
8117 free(ptr);
8118 }
8119}
8120
8121#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01008122static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
8123{
8124 pool_free2(pool2_ssl_capture, ptr);
8125}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008126
Emeric Brun46591952012-05-18 15:47:34 +02008127__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02008128static void __ssl_sock_init(void)
8129{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008130 char *ptr;
Emmanuel Hocdetf80bc242017-07-12 14:25:38 +02008131 int i;
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008132
Emeric Brun46591952012-05-18 15:47:34 +02008133 STACK_OF(SSL_COMP)* cm;
8134
Willy Tarreauef934602016-12-22 23:12:01 +01008135 if (global_ssl.listen_default_ciphers)
8136 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
8137 if (global_ssl.connect_default_ciphers)
8138 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01008139
Willy Tarreau13e14102016-12-22 20:25:26 +01008140 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02008141 SSL_library_init();
8142 cm = SSL_COMP_get_compression_methods();
8143 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01008144#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008145 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
8146#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01008147 ssl_capture_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_capture_free_func);
Willy Tarreau7875d092012-09-10 08:20:03 +02008148 sample_register_fetches(&sample_fetch_keywords);
8149 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02008150 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02008151 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008152 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02008153 cli_register_kw(&cli_kws);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008154#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008155 ENGINE_load_builtin_engines();
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008156 hap_register_post_check(ssl_check_async_engine_count);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008157#endif
Willy Tarreaud1c57502016-12-22 22:46:15 +01008158#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
8159 hap_register_post_check(tlskeys_finalize_config);
8160#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008161
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008162 ptr = NULL;
8163 memprintf(&ptr, "Built with OpenSSL version : "
8164#ifdef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008165 "BoringSSL");
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008166#else /* OPENSSL_IS_BORINGSSL */
8167 OPENSSL_VERSION_TEXT
8168 "\nRunning on OpenSSL version : %s%s",
8169 SSLeay_version(SSLEAY_VERSION),
8170 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
8171#endif
8172 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
8173#if OPENSSL_VERSION_NUMBER < 0x00907000L
8174 "no (library version too old)"
8175#elif defined(OPENSSL_NO_TLSEXT)
8176 "no (disabled via OPENSSL_NO_TLSEXT)"
8177#else
8178 "yes"
8179#endif
8180 "", ptr);
8181
8182 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
8183#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
8184 "yes"
8185#else
8186#ifdef OPENSSL_NO_TLSEXT
8187 "no (because of OPENSSL_NO_TLSEXT)"
8188#else
8189 "no (version might be too old, 0.9.8f min needed)"
8190#endif
8191#endif
8192 "", ptr);
8193
Emmanuel Hocdetf80bc242017-07-12 14:25:38 +02008194 memprintf(&ptr, "%s\nOpenSSL library supports :", ptr);
8195 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
8196 if (methodVersions[i].option)
8197 memprintf(&ptr, "%s %s", ptr, methodVersions[i].name);
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008198
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008199 hap_register_build_opts(ptr, 1);
8200
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008201 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
8202 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02008203
8204#ifndef OPENSSL_NO_DH
8205 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
Grant Zhang872f9c22017-01-21 01:10:18 +00008206 hap_register_post_deinit(ssl_free_dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02008207#endif
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008208#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008209 hap_register_post_deinit(ssl_free_engines);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008210#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02008211 /* Load SSL string for the verbose & debug mode. */
8212 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02008213}
8214
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008215#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008216void ssl_free_engines(void) {
8217 struct ssl_engine_list *wl, *wlb;
8218 /* free up engine list */
8219 list_for_each_entry_safe(wl, wlb, &openssl_engines, list) {
8220 ENGINE_finish(wl->e);
8221 ENGINE_free(wl->e);
8222 LIST_DEL(&wl->list);
8223 free(wl);
8224 }
8225}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008226#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02008227
Remi Gacogned3a23c32015-05-28 16:39:47 +02008228#ifndef OPENSSL_NO_DH
Grant Zhang872f9c22017-01-21 01:10:18 +00008229void ssl_free_dh(void) {
8230 if (local_dh_1024) {
8231 DH_free(local_dh_1024);
8232 local_dh_1024 = NULL;
8233 }
8234 if (local_dh_2048) {
8235 DH_free(local_dh_2048);
8236 local_dh_2048 = NULL;
8237 }
8238 if (local_dh_4096) {
8239 DH_free(local_dh_4096);
8240 local_dh_4096 = NULL;
8241 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02008242 if (global_dh) {
8243 DH_free(global_dh);
8244 global_dh = NULL;
8245 }
Grant Zhang872f9c22017-01-21 01:10:18 +00008246}
8247#endif
8248
8249__attribute__((destructor))
8250static void __ssl_sock_deinit(void)
8251{
8252#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
8253 lru64_destroy(ssl_ctx_lru_tree);
Remi Gacogned3a23c32015-05-28 16:39:47 +02008254#endif
8255
8256 ERR_remove_state(0);
8257 ERR_free_strings();
8258
8259 EVP_cleanup();
8260
8261#if OPENSSL_VERSION_NUMBER >= 0x00907000L
8262 CRYPTO_cleanup_all_ex_data();
8263#endif
8264}
8265
8266
Emeric Brun46591952012-05-18 15:47:34 +02008267/*
8268 * Local variables:
8269 * c-indent-level: 8
8270 * c-basic-offset: 8
8271 * End:
8272 */