blob: 8a5d66fd29445ddc8a55573b12924dbd4381aed3 [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",
Willy Tarreau585744b2017-08-24 14:31:19 +0200289 (unsigned short)conn->handle.fd, ret,
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100290 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;
Emmanuel Hocdet15969292017-08-11 10:56:00 +02001583 SSL *tmp_ssl = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001584 X509_NAME *name;
1585 const EVP_MD *digest;
1586 X509V3_CTX ctx;
1587 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001588 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001589
Christopher Faulet48a83322017-07-28 16:56:09 +02001590 /* Get the private key of the default certificate and use it */
Emmanuel Hocdet15969292017-08-11 10:56:00 +02001591#if (OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined LIBRESSL_VERSION_NUMBER)
1592 pkey = SSL_CTX_get0_privatekey(bind_conf->default_ctx);
1593#else
1594 tmp_ssl = SSL_new(bind_conf->default_ctx);
1595 if (tmp_ssl)
1596 pkey = SSL_get_privatekey(tmp_ssl);
1597#endif
1598 if (!pkey)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001599 goto mkcert_error;
1600
1601 /* Create the certificate */
1602 if (!(newcrt = X509_new()))
1603 goto mkcert_error;
1604
1605 /* Set version number for the certificate (X509v3) and the serial
1606 * number */
1607 if (X509_set_version(newcrt, 2L) != 1)
1608 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001609 if (!serial)
1610 serial = now_ms;
1611 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001612
1613 /* Set duration for the certificate */
1614 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1615 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1616 goto mkcert_error;
1617
1618 /* set public key in the certificate */
1619 if (X509_set_pubkey(newcrt, pkey) != 1)
1620 goto mkcert_error;
1621
1622 /* Set issuer name from the CA */
1623 if (!(name = X509_get_subject_name(cacert)))
1624 goto mkcert_error;
1625 if (X509_set_issuer_name(newcrt, name) != 1)
1626 goto mkcert_error;
1627
1628 /* Set the subject name using the same, but the CN */
1629 name = X509_NAME_dup(name);
1630 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1631 (const unsigned char *)servername,
1632 -1, -1, 0) != 1) {
1633 X509_NAME_free(name);
1634 goto mkcert_error;
1635 }
1636 if (X509_set_subject_name(newcrt, name) != 1) {
1637 X509_NAME_free(name);
1638 goto mkcert_error;
1639 }
1640 X509_NAME_free(name);
1641
1642 /* Add x509v3 extensions as specified */
1643 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1644 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1645 X509_EXTENSION *ext;
1646
1647 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1648 goto mkcert_error;
1649 if (!X509_add_ext(newcrt, ext, -1)) {
1650 X509_EXTENSION_free(ext);
1651 goto mkcert_error;
1652 }
1653 X509_EXTENSION_free(ext);
1654 }
1655
1656 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001657
1658 key_type = EVP_PKEY_base_id(capkey);
1659
1660 if (key_type == EVP_PKEY_DSA)
1661 digest = EVP_sha1();
1662 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001663 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001664 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001665 digest = EVP_sha256();
1666 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001667#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001668 int nid;
1669
1670 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1671 goto mkcert_error;
1672 if (!(digest = EVP_get_digestbynid(nid)))
1673 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001674#else
1675 goto mkcert_error;
1676#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001677 }
1678
Christopher Faulet31af49d2015-06-09 17:29:50 +02001679 if (!(X509_sign(newcrt, capkey, digest)))
1680 goto mkcert_error;
1681
1682 /* Create and set the new SSL_CTX */
1683 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1684 goto mkcert_error;
1685 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1686 goto mkcert_error;
1687 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1688 goto mkcert_error;
1689 if (!SSL_CTX_check_private_key(ssl_ctx))
1690 goto mkcert_error;
1691
1692 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001693
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001694#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001695 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001696#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001697#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1698 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001699 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001700 EC_KEY *ecc;
1701 int nid;
1702
1703 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1704 goto end;
1705 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1706 goto end;
1707 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1708 EC_KEY_free(ecc);
1709 }
1710#endif
1711 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001712 return ssl_ctx;
1713
1714 mkcert_error:
Emmanuel Hocdet15969292017-08-11 10:56:00 +02001715 if (tmp_ssl) SSL_free(tmp_ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001716 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1717 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001718 return NULL;
1719}
1720
Christopher Faulet7969a332015-10-09 11:15:03 +02001721SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001722ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001723{
1724 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001725
1726 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001727}
1728
Christopher Faulet30548802015-06-11 13:39:32 +02001729/* Do a lookup for a certificate in the LRU cache used to store generated
1730 * certificates. */
1731SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001732ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001733{
1734 struct lru64 *lru = NULL;
1735
1736 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001737 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001738 if (lru && lru->domain)
1739 return (SSL_CTX *)lru->data;
1740 }
1741 return NULL;
1742}
1743
Christopher Fauletd2cab922015-07-28 16:03:47 +02001744/* Set a certificate int the LRU cache used to store generated
1745 * certificate. Return 0 on success, otherwise -1 */
1746int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001747ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001748{
1749 struct lru64 *lru = NULL;
1750
1751 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001752 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001753 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001754 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001755 if (lru->domain && lru->data)
1756 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001757 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001758 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001759 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001760 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001761}
1762
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001763/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001764unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001765ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001766{
1767 return XXH32(data, len, ssl_ctx_lru_seed);
1768}
1769
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001770/* Generate a cert and immediately assign it to the SSL session so that the cert's
1771 * refcount is maintained regardless of the cert's presence in the LRU cache.
1772 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001773static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001774ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001775{
1776 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001777 SSL_CTX *ssl_ctx = NULL;
1778 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001779 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001780
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001781 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001782 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001783 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001784 if (lru && lru->domain)
1785 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001786 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001787 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001788 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001789 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001790 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001791 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001792 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001793 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001794 SSL_set_SSL_CTX(ssl, ssl_ctx);
1795 /* No LRU cache, this CTX will be released as soon as the session dies */
1796 SSL_CTX_free(ssl_ctx);
1797 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001798 return ssl_ctx;
1799}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001800#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001801
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001802
1803#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1804#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1805#endif
1806
1807#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1808#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
1809#define SSL_renegotiate_pending(arg) 0
1810#endif
1811#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1812#define SSL_OP_SINGLE_ECDH_USE 0
1813#endif
1814#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1815#define SSL_OP_NO_TICKET 0
1816#endif
1817#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1818#define SSL_OP_NO_COMPRESSION 0
1819#endif
Emmanuel Hocdet23877ab2017-07-12 12:53:02 +02001820#ifdef OPENSSL_NO_SSL3 /* SSLv3 support removed */
1821#undef SSL_OP_NO_SSLv3
1822#define SSL_OP_NO_SSLv3 0
1823#endif
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001824#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1825#define SSL_OP_NO_TLSv1_1 0
1826#endif
1827#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1828#define SSL_OP_NO_TLSv1_2 0
1829#endif
1830#ifndef SSL_OP_NO_TLSv1_3 /* dev */
1831#define SSL_OP_NO_TLSv1_3 0
1832#endif
1833#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1834#define SSL_OP_SINGLE_DH_USE 0
1835#endif
1836#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1837#define SSL_OP_SINGLE_ECDH_USE 0
1838#endif
1839#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1840#define SSL_MODE_RELEASE_BUFFERS 0
1841#endif
1842#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1843#define SSL_MODE_SMALL_BUFFERS 0
1844#endif
1845
1846#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001847typedef enum { SET_CLIENT, SET_SERVER } set_context_func;
1848
1849static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001850{
Emmanuel Hocdet23877ab2017-07-12 12:53:02 +02001851#if SSL_OP_NO_SSLv3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001852 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, SSLv3_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001853 : SSL_CTX_set_ssl_version(ctx, SSLv3_client_method());
1854#endif
1855}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001856static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1857 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001858 : SSL_CTX_set_ssl_version(ctx, TLSv1_client_method());
1859}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001860static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001861#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001862 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001863 : SSL_CTX_set_ssl_version(ctx, TLSv1_1_client_method());
1864#endif
1865}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001866static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001867#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001868 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001869 : SSL_CTX_set_ssl_version(ctx, TLSv1_2_client_method());
1870#endif
1871}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001872/* TLS 1.2 is the last supported version in this context. */
1873static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {}
1874/* Unusable in this context. */
1875static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {}
1876static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {}
1877static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {}
1878static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {}
1879static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {}
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001880#else /* openssl >= 1.1.0 */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001881typedef enum { SET_MIN, SET_MAX } set_context_func;
1882
1883static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c) {
1884 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001885 : SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
1886}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001887static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {
1888 c == SET_MAX ? SSL_set_max_proto_version(ssl, SSL3_VERSION)
1889 : SSL_set_min_proto_version(ssl, SSL3_VERSION);
1890}
1891static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1892 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001893 : SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1894}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001895static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {
1896 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_VERSION)
1897 : SSL_set_min_proto_version(ssl, TLS1_VERSION);
1898}
1899static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
1900 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001901 : SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
1902}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001903static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {
1904 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_1_VERSION)
1905 : SSL_set_min_proto_version(ssl, TLS1_1_VERSION);
1906}
1907static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
1908 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001909 : SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
1910}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001911static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {
1912 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_2_VERSION)
1913 : SSL_set_min_proto_version(ssl, TLS1_2_VERSION);
1914}
1915static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001916#if SSL_OP_NO_TLSv1_3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001917 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001918 : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
1919#endif
1920}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001921static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {
1922#if SSL_OP_NO_TLSv1_3
1923 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_3_VERSION)
1924 : SSL_set_min_proto_version(ssl, TLS1_3_VERSION);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001925#endif
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001926}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001927#endif
1928static void ctx_set_None_func(SSL_CTX *ctx, set_context_func c) { }
1929static void ssl_set_None_func(SSL *ssl, set_context_func c) { }
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001930
1931static struct {
1932 int option;
1933 uint16_t flag;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001934 void (*ctx_set_version)(SSL_CTX *, set_context_func);
1935 void (*ssl_set_version)(SSL *, set_context_func);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001936 const char *name;
1937} methodVersions[] = {
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001938 {0, 0, ctx_set_None_func, ssl_set_None_func, "NONE"}, /* CONF_TLSV_NONE */
1939 {SSL_OP_NO_SSLv3, MC_SSL_O_NO_SSLV3, ctx_set_SSLv3_func, ssl_set_SSLv3_func, "SSLv3"}, /* CONF_SSLV3 */
1940 {SSL_OP_NO_TLSv1, MC_SSL_O_NO_TLSV10, ctx_set_TLSv10_func, ssl_set_TLSv10_func, "TLSv1.0"}, /* CONF_TLSV10 */
1941 {SSL_OP_NO_TLSv1_1, MC_SSL_O_NO_TLSV11, ctx_set_TLSv11_func, ssl_set_TLSv11_func, "TLSv1.1"}, /* CONF_TLSV11 */
1942 {SSL_OP_NO_TLSv1_2, MC_SSL_O_NO_TLSV12, ctx_set_TLSv12_func, ssl_set_TLSv12_func, "TLSv1.2"}, /* CONF_TLSV12 */
1943 {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 +02001944};
1945
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001946static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1947{
1948 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1949 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1950 SSL_set_SSL_CTX(ssl, ctx);
1951}
1952
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001953#ifdef OPENSSL_IS_BORINGSSL
1954
1955static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1956{
1957 (void)al; /* shut gcc stupid warning */
1958 (void)priv;
1959
1960 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1961 return SSL_TLSEXT_ERR_NOACK;
1962 return SSL_TLSEXT_ERR_OK;
1963}
1964
1965static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1966{
1967 struct connection *conn;
1968 struct bind_conf *s;
1969 const uint8_t *extension_data;
1970 size_t extension_len;
1971 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1972 const SSL_CIPHER *cipher;
1973 uint16_t cipher_suite;
1974 uint8_t name_type, hash, sign;
1975 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1976
1977 char *wildp = NULL;
1978 const uint8_t *servername;
1979 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1980 int i;
1981
1982 conn = SSL_get_app_data(ctx->ssl);
1983 s = objt_listener(conn->target)->bind_conf;
1984
1985 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1986 &extension_data, &extension_len)) {
1987 CBS_init(&extension, extension_data, extension_len);
1988
1989 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1990 || !CBS_get_u8(&server_name_list, &name_type)
1991 /* Although the server_name extension was intended to be extensible to
1992 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1993 * different name types will cause an error. Further, RFC 4366 originally
1994 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1995 * adding new name types is no longer feasible.
1996 *
1997 * Act as if the extensibility does not exist to simplify parsing. */
1998 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1999 || CBS_len(&server_name_list) != 0
2000 || CBS_len(&extension) != 0
2001 || name_type != TLSEXT_NAMETYPE_host_name
2002 || CBS_len(&host_name) == 0
2003 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
2004 || CBS_contains_zero_byte(&host_name)) {
2005 goto abort;
2006 }
2007 } else {
2008 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002009 if (!s->strict_sni) {
2010 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002011 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002012 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002013 goto abort;
2014 }
2015
2016 /* extract/check clientHello informations */
2017 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
2018 CBS_init(&extension, extension_data, extension_len);
2019
2020 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
2021 || CBS_len(&sig_algs) == 0
2022 || CBS_len(&extension) != 0) {
2023 goto abort;
2024 }
2025 if (CBS_len(&sig_algs) % 2 != 0) {
2026 goto abort;
2027 }
2028 while (CBS_len(&sig_algs) != 0) {
2029 if (!CBS_get_u8(&sig_algs, &hash)
2030 || !CBS_get_u8(&sig_algs, &sign)) {
2031 goto abort;
2032 }
2033 switch (sign) {
2034 case TLSEXT_signature_rsa:
2035 has_rsa = 1;
2036 break;
2037 case TLSEXT_signature_ecdsa:
2038 has_ecdsa_sig = 1;
2039 break;
2040 default:
2041 continue;
2042 }
2043 if (has_ecdsa_sig && has_rsa)
2044 break;
2045 }
2046 } else {
2047 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
2048 has_rsa = 1;
2049 }
2050 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
2051 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
2052
2053 while (CBS_len(&cipher_suites) != 0) {
2054 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
2055 goto abort;
2056 }
2057 cipher = SSL_get_cipher_by_value(cipher_suite);
2058 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
2059 has_ecdsa = 1;
2060 break;
2061 }
2062 }
2063 }
2064
2065 servername = CBS_data(&host_name);
2066 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
2067 trash.str[i] = tolower(servername[i]);
2068 if (!wildp && (trash.str[i] == '.'))
2069 wildp = &trash.str[i];
2070 }
2071 trash.str[i] = 0;
2072
2073 /* lookup in full qualified names */
2074 node = ebst_lookup(&s->sni_ctx, trash.str);
2075
2076 /* lookup a not neg filter */
2077 for (n = node; n; n = ebmb_next_dup(n)) {
2078 if (!container_of(n, struct sni_ctx, name)->neg) {
2079 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2080 case TLSEXT_signature_ecdsa:
2081 if (has_ecdsa) {
2082 node_ecdsa = n;
2083 goto find_one;
2084 }
2085 break;
2086 case TLSEXT_signature_rsa:
2087 if (has_rsa && !node_rsa) {
2088 node_rsa = n;
2089 if (!has_ecdsa)
2090 goto find_one;
2091 }
2092 break;
2093 default: /* TLSEXT_signature_anonymous */
2094 if (!node_anonymous)
2095 node_anonymous = n;
2096 break;
2097 }
2098 }
2099 }
2100 if (wildp) {
2101 /* lookup in wildcards names */
2102 node = ebst_lookup(&s->sni_w_ctx, wildp);
2103 for (n = node; n; n = ebmb_next_dup(n)) {
2104 if (!container_of(n, struct sni_ctx, name)->neg) {
2105 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2106 case TLSEXT_signature_ecdsa:
2107 if (has_ecdsa) {
2108 node_ecdsa = n;
2109 goto find_one;
2110 }
2111 break;
2112 case TLSEXT_signature_rsa:
2113 if (has_rsa && !node_rsa) {
2114 node_rsa = n;
2115 if (!has_ecdsa)
2116 goto find_one;
2117 }
2118 break;
2119 default: /* TLSEXT_signature_anonymous */
2120 if (!node_anonymous)
2121 node_anonymous = n;
2122 break;
2123 }
2124 }
2125 }
2126 }
2127 find_one:
2128 /* select by key_signature priority order */
2129 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
2130
2131 if (node) {
2132 /* switch ctx */
Emmanuel Hocdet43664762017-08-09 18:26:20 +02002133 struct ssl_bind_conf *conf = container_of(node, struct sni_ctx, name)->conf;
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002134 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdet43664762017-08-09 18:26:20 +02002135 methodVersions[conf->ssl_methods.min].ssl_set_version(ctx->ssl, SET_MIN);
2136 methodVersions[conf->ssl_methods.max].ssl_set_version(ctx->ssl, SET_MAX);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002137 return 1;
2138 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002139 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002140 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002141 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002142 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002143 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002144 abort:
2145 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
2146 conn->err_code = CO_ER_SSL_HANDSHAKE;
2147 return -1;
2148}
2149
2150#else /* OPENSSL_IS_BORINGSSL */
2151
Emeric Brunfc0421f2012-09-07 17:30:07 +02002152/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
2153 * warning when no match is found, which implies the default (first) cert
2154 * will keep being used.
2155 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002156static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002157{
2158 const char *servername;
2159 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002160 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002161 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002162 int i;
2163 (void)al; /* shut gcc stupid warning */
2164
2165 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002166 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002167#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02002168 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002169 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002170 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02002171 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02002172
Willy Tarreauf6721452015-07-07 18:04:38 +02002173 conn_get_to_addr(conn);
2174 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002175 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
2176 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02002177 if (ctx) {
2178 /* switch ctx */
2179 SSL_set_SSL_CTX(ssl, ctx);
2180 return SSL_TLSEXT_ERR_OK;
2181 }
Christopher Faulet30548802015-06-11 13:39:32 +02002182 }
2183 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002184#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002185 if (s->strict_sni)
2186 return SSL_TLSEXT_ERR_ALERT_FATAL;
2187 ssl_sock_switchctx_set(ssl, s->default_ctx);
2188 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002189 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002190
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002191 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002192 if (!servername[i])
2193 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002194 trash.str[i] = tolower(servername[i]);
2195 if (!wildp && (trash.str[i] == '.'))
2196 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002197 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002198 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002199
2200 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002201 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002202
2203 /* lookup a not neg filter */
2204 for (n = node; n; n = ebmb_next_dup(n)) {
2205 if (!container_of(n, struct sni_ctx, name)->neg) {
2206 node = n;
2207 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002208 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002209 }
2210 if (!node && wildp) {
2211 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002212 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002213 }
2214 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002215#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02002216 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002217 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02002218 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02002219 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02002220 return SSL_TLSEXT_ERR_OK;
2221 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002222#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002223 if (s->strict_sni)
2224 return SSL_TLSEXT_ERR_ALERT_FATAL;
2225 ssl_sock_switchctx_set(ssl, s->default_ctx);
2226 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002227 }
2228
2229 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002230 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002231 return SSL_TLSEXT_ERR_OK;
2232}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002233#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002234#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2235
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002236#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002237
2238static DH * ssl_get_dh_1024(void)
2239{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002240 static unsigned char dh1024_p[]={
2241 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
2242 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
2243 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
2244 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
2245 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
2246 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
2247 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
2248 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
2249 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
2250 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
2251 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
2252 };
2253 static unsigned char dh1024_g[]={
2254 0x02,
2255 };
2256
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002257 BIGNUM *p;
2258 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002259 DH *dh = DH_new();
2260 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002261 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
2262 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002263
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002264 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002265 DH_free(dh);
2266 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002267 } else {
2268 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002269 }
2270 }
2271 return dh;
2272}
2273
2274static DH *ssl_get_dh_2048(void)
2275{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002276 static unsigned char dh2048_p[]={
2277 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
2278 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
2279 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
2280 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
2281 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
2282 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
2283 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
2284 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
2285 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
2286 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
2287 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
2288 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
2289 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
2290 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
2291 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
2292 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
2293 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
2294 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
2295 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
2296 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
2297 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
2298 0xB7,0x1F,0x77,0xF3,
2299 };
2300 static unsigned char dh2048_g[]={
2301 0x02,
2302 };
2303
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002304 BIGNUM *p;
2305 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002306 DH *dh = DH_new();
2307 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002308 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
2309 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002310
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002311 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002312 DH_free(dh);
2313 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002314 } else {
2315 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002316 }
2317 }
2318 return dh;
2319}
2320
2321static DH *ssl_get_dh_4096(void)
2322{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002323 static unsigned char dh4096_p[]={
2324 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
2325 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
2326 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
2327 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
2328 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
2329 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
2330 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
2331 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
2332 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
2333 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
2334 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
2335 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
2336 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
2337 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
2338 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
2339 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
2340 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
2341 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
2342 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
2343 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
2344 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
2345 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
2346 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
2347 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
2348 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
2349 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
2350 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
2351 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
2352 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
2353 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
2354 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
2355 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
2356 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
2357 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
2358 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
2359 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
2360 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
2361 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
2362 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
2363 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
2364 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
2365 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
2366 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002367 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02002368 static unsigned char dh4096_g[]={
2369 0x02,
2370 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002371
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002372 BIGNUM *p;
2373 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002374 DH *dh = DH_new();
2375 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002376 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
2377 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002378
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002379 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002380 DH_free(dh);
2381 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002382 } else {
2383 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002384 }
2385 }
2386 return dh;
2387}
2388
2389/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01002390 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002391static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
2392{
2393 DH *dh = NULL;
2394 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002395 int type;
2396
2397 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002398
2399 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2400 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2401 */
2402 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2403 keylen = EVP_PKEY_bits(pkey);
2404 }
2405
Willy Tarreauef934602016-12-22 23:12:01 +01002406 if (keylen > global_ssl.default_dh_param) {
2407 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002408 }
2409
Remi Gacogned3a341a2015-05-29 16:26:17 +02002410 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002411 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002412 }
2413 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002414 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002415 }
2416 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002417 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002418 }
2419
2420 return dh;
2421}
2422
Remi Gacogne47783ef2015-05-29 15:53:22 +02002423static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002424{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002425 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002426 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002427
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002428 if (in == NULL)
2429 goto end;
2430
Remi Gacogne47783ef2015-05-29 15:53:22 +02002431 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002432 goto end;
2433
Remi Gacogne47783ef2015-05-29 15:53:22 +02002434 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2435
2436end:
2437 if (in)
2438 BIO_free(in);
2439
2440 return dh;
2441}
2442
2443int ssl_sock_load_global_dh_param_from_file(const char *filename)
2444{
2445 global_dh = ssl_sock_get_dh_from_file(filename);
2446
2447 if (global_dh) {
2448 return 0;
2449 }
2450
2451 return -1;
2452}
2453
2454/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2455 if an error occured, and 0 if parameter not found. */
2456int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2457{
2458 int ret = -1;
2459 DH *dh = ssl_sock_get_dh_from_file(file);
2460
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002461 if (dh) {
2462 ret = 1;
2463 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002464
2465 if (ssl_dh_ptr_index >= 0) {
2466 /* store a pointer to the DH params to avoid complaining about
2467 ssl-default-dh-param not being set for this SSL_CTX */
2468 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2469 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002470 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002471 else if (global_dh) {
2472 SSL_CTX_set_tmp_dh(ctx, global_dh);
2473 ret = 0; /* DH params not found */
2474 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002475 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002476 /* Clear openssl global errors stack */
2477 ERR_clear_error();
2478
Willy Tarreauef934602016-12-22 23:12:01 +01002479 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002480 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002481 if (local_dh_1024 == NULL)
2482 local_dh_1024 = ssl_get_dh_1024();
2483
Remi Gacogne8de54152014-07-15 11:36:40 +02002484 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002485 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002486
Remi Gacogne8de54152014-07-15 11:36:40 +02002487 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002488 }
2489 else {
2490 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2491 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002492
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002493 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002494 }
Emeric Brun644cde02012-12-14 11:21:13 +01002495
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002496end:
2497 if (dh)
2498 DH_free(dh);
2499
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002500 return ret;
2501}
2502#endif
2503
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002504static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2505 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002506{
2507 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002508 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002509 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002510
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002511 if (*name == '!') {
2512 neg = 1;
2513 name++;
2514 }
2515 if (*name == '*') {
2516 wild = 1;
2517 name++;
2518 }
2519 /* !* filter is a nop */
2520 if (neg && wild)
2521 return order;
2522 if (*name) {
2523 int j, len;
2524 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002525 for (j = 0; j < len && j < trash.size; j++)
2526 trash.str[j] = tolower(name[j]);
2527 if (j >= trash.size)
2528 return order;
2529 trash.str[j] = 0;
2530
2531 /* Check for duplicates. */
2532 if (wild)
2533 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2534 else
2535 node = ebst_lookup(&s->sni_ctx, trash.str);
2536 for (; node; node = ebmb_next_dup(node)) {
2537 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002538 if (sc->ctx == ctx && sc->conf == conf &&
2539 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002540 return order;
2541 }
2542
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002543 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002544 if (!sc)
2545 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002546 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002547 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002548 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002549 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002550 sc->order = order++;
2551 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002552 if (wild)
2553 ebst_insert(&s->sni_w_ctx, &sc->name);
2554 else
2555 ebst_insert(&s->sni_ctx, &sc->name);
2556 }
2557 return order;
2558}
2559
yanbzhu488a4d22015-12-01 15:16:07 -05002560
2561/* The following code is used for loading multiple crt files into
2562 * SSL_CTX's based on CN/SAN
2563 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002564#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002565/* This is used to preload the certifcate, private key
2566 * and Cert Chain of a file passed in via the crt
2567 * argument
2568 *
2569 * This way, we do not have to read the file multiple times
2570 */
2571struct cert_key_and_chain {
2572 X509 *cert;
2573 EVP_PKEY *key;
2574 unsigned int num_chain_certs;
2575 /* This is an array of X509 pointers */
2576 X509 **chain_certs;
2577};
2578
yanbzhu08ce6ab2015-12-02 13:01:29 -05002579#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2580
2581struct key_combo_ctx {
2582 SSL_CTX *ctx;
2583 int order;
2584};
2585
2586/* Map used for processing multiple keypairs for a single purpose
2587 *
2588 * This maps CN/SNI name to certificate type
2589 */
2590struct sni_keytype {
2591 int keytypes; /* BITMASK for keytypes */
2592 struct ebmb_node name; /* node holding the servername value */
2593};
2594
2595
yanbzhu488a4d22015-12-01 15:16:07 -05002596/* Frees the contents of a cert_key_and_chain
2597 */
2598static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2599{
2600 int i;
2601
2602 if (!ckch)
2603 return;
2604
2605 /* Free the certificate and set pointer to NULL */
2606 if (ckch->cert)
2607 X509_free(ckch->cert);
2608 ckch->cert = NULL;
2609
2610 /* Free the key and set pointer to NULL */
2611 if (ckch->key)
2612 EVP_PKEY_free(ckch->key);
2613 ckch->key = NULL;
2614
2615 /* Free each certificate in the chain */
2616 for (i = 0; i < ckch->num_chain_certs; i++) {
2617 if (ckch->chain_certs[i])
2618 X509_free(ckch->chain_certs[i]);
2619 }
2620
2621 /* Free the chain obj itself and set to NULL */
2622 if (ckch->num_chain_certs > 0) {
2623 free(ckch->chain_certs);
2624 ckch->num_chain_certs = 0;
2625 ckch->chain_certs = NULL;
2626 }
2627
2628}
2629
2630/* checks if a key and cert exists in the ckch
2631 */
2632static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2633{
2634 return (ckch->cert != NULL && ckch->key != NULL);
2635}
2636
2637
2638/* Loads the contents of a crt file (path) into a cert_key_and_chain
2639 * This allows us to carry the contents of the file without having to
2640 * read the file multiple times.
2641 *
2642 * returns:
2643 * 0 on Success
2644 * 1 on SSL Failure
2645 * 2 on file not found
2646 */
2647static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2648{
2649
2650 BIO *in;
2651 X509 *ca = NULL;
2652 int ret = 1;
2653
2654 ssl_sock_free_cert_key_and_chain_contents(ckch);
2655
2656 in = BIO_new(BIO_s_file());
2657 if (in == NULL)
2658 goto end;
2659
2660 if (BIO_read_filename(in, path) <= 0)
2661 goto end;
2662
yanbzhu488a4d22015-12-01 15:16:07 -05002663 /* Read Private Key */
2664 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2665 if (ckch->key == NULL) {
2666 memprintf(err, "%sunable to load private key from file '%s'.\n",
2667 err && *err ? *err : "", path);
2668 goto end;
2669 }
2670
Willy Tarreaubb137a82016-04-06 19:02:38 +02002671 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002672 if (BIO_reset(in) == -1) {
2673 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2674 err && *err ? *err : "", path);
2675 goto end;
2676 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002677
2678 /* Read Certificate */
2679 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2680 if (ckch->cert == NULL) {
2681 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2682 err && *err ? *err : "", path);
2683 goto end;
2684 }
2685
yanbzhu488a4d22015-12-01 15:16:07 -05002686 /* Read Certificate Chain */
2687 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2688 /* Grow the chain certs */
2689 ckch->num_chain_certs++;
2690 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2691
2692 /* use - 1 here since we just incremented it above */
2693 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2694 }
2695 ret = ERR_get_error();
2696 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2697 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2698 err && *err ? *err : "", path);
2699 ret = 1;
2700 goto end;
2701 }
2702
2703 ret = 0;
2704
2705end:
2706
2707 ERR_clear_error();
2708 if (in)
2709 BIO_free(in);
2710
2711 /* Something went wrong in one of the reads */
2712 if (ret != 0)
2713 ssl_sock_free_cert_key_and_chain_contents(ckch);
2714
2715 return ret;
2716}
2717
2718/* Loads the info in ckch into ctx
2719 * Currently, this does not process any information about ocsp, dhparams or
2720 * sctl
2721 * Returns
2722 * 0 on success
2723 * 1 on failure
2724 */
2725static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2726{
2727 int i = 0;
2728
2729 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2730 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2731 err && *err ? *err : "", path);
2732 return 1;
2733 }
2734
2735 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2736 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2737 err && *err ? *err : "", path);
2738 return 1;
2739 }
2740
yanbzhu488a4d22015-12-01 15:16:07 -05002741 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2742 for (i = 0; i < ckch->num_chain_certs; i++) {
2743 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002744 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2745 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002746 return 1;
2747 }
2748 }
2749
2750 if (SSL_CTX_check_private_key(ctx) <= 0) {
2751 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2752 err && *err ? *err : "", path);
2753 return 1;
2754 }
2755
2756 return 0;
2757}
2758
yanbzhu08ce6ab2015-12-02 13:01:29 -05002759
2760static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2761{
2762 struct sni_keytype *s_kt = NULL;
2763 struct ebmb_node *node;
2764 int i;
2765
2766 for (i = 0; i < trash.size; i++) {
2767 if (!str[i])
2768 break;
2769 trash.str[i] = tolower(str[i]);
2770 }
2771 trash.str[i] = 0;
2772 node = ebst_lookup(sni_keytypes, trash.str);
2773 if (!node) {
2774 /* CN not found in tree */
2775 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2776 /* Using memcpy here instead of strncpy.
2777 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2778 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2779 */
2780 memcpy(s_kt->name.key, trash.str, i+1);
2781 s_kt->keytypes = 0;
2782 ebst_insert(sni_keytypes, &s_kt->name);
2783 } else {
2784 /* CN found in tree */
2785 s_kt = container_of(node, struct sni_keytype, name);
2786 }
2787
2788 /* Mark that this CN has the keytype of key_index via keytypes mask */
2789 s_kt->keytypes |= 1<<key_index;
2790
2791}
2792
2793
2794/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2795 * If any are found, group these files into a set of SSL_CTX*
2796 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2797 *
2798 * This will allow the user to explictly group multiple cert/keys for a single purpose
2799 *
2800 * Returns
2801 * 0 on success
2802 * 1 on failure
2803 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002804static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2805 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002806{
2807 char fp[MAXPATHLEN+1] = {0};
2808 int n = 0;
2809 int i = 0;
2810 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2811 struct eb_root sni_keytypes_map = { {0} };
2812 struct ebmb_node *node;
2813 struct ebmb_node *next;
2814 /* Array of SSL_CTX pointers corresponding to each possible combo
2815 * of keytypes
2816 */
2817 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2818 int rv = 0;
2819 X509_NAME *xname = NULL;
2820 char *str = NULL;
2821#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2822 STACK_OF(GENERAL_NAME) *names = NULL;
2823#endif
2824
2825 /* Load all possible certs and keys */
2826 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2827 struct stat buf;
2828
2829 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2830 if (stat(fp, &buf) == 0) {
2831 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2832 rv = 1;
2833 goto end;
2834 }
2835 }
2836 }
2837
2838 /* Process each ckch and update keytypes for each CN/SAN
2839 * for example, if CN/SAN www.a.com is associated with
2840 * certs with keytype 0 and 2, then at the end of the loop,
2841 * www.a.com will have:
2842 * keyindex = 0 | 1 | 4 = 5
2843 */
2844 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2845
2846 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2847 continue;
2848
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002849 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002850 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002851 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2852 } else {
2853 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2854 * so the line that contains logic is marked via comments
2855 */
2856 xname = X509_get_subject_name(certs_and_keys[n].cert);
2857 i = -1;
2858 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2859 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002860 ASN1_STRING *value;
2861 value = X509_NAME_ENTRY_get_data(entry);
2862 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002863 /* Important line is here */
2864 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002865
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002866 OPENSSL_free(str);
2867 str = NULL;
2868 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002869 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002870
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002871 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002872#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002873 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2874 if (names) {
2875 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2876 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002877
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002878 if (name->type == GEN_DNS) {
2879 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2880 /* Important line is here */
2881 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002882
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002883 OPENSSL_free(str);
2884 str = NULL;
2885 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002886 }
2887 }
2888 }
2889 }
2890#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2891 }
2892
2893 /* If no files found, return error */
2894 if (eb_is_empty(&sni_keytypes_map)) {
2895 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2896 err && *err ? *err : "", path);
2897 rv = 1;
2898 goto end;
2899 }
2900
2901 /* We now have a map of CN/SAN to keytypes that are loaded in
2902 * Iterate through the map to create the SSL_CTX's (if needed)
2903 * and add each CTX to the SNI tree
2904 *
2905 * Some math here:
2906 * There are 2^n - 1 possibile combinations, each unique
2907 * combination is denoted by the key in the map. Each key
2908 * has a value between 1 and 2^n - 1. Conveniently, the array
2909 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2910 * entry in the array to correspond to the unique combo (key)
2911 * associated with i. This unique key combo (i) will be associated
2912 * with combos[i-1]
2913 */
2914
2915 node = ebmb_first(&sni_keytypes_map);
2916 while (node) {
2917 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002918 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002919
2920 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2921 i = container_of(node, struct sni_keytype, name)->keytypes;
2922 cur_ctx = key_combos[i-1].ctx;
2923
2924 if (cur_ctx == NULL) {
2925 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002926 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002927 if (cur_ctx == NULL) {
2928 memprintf(err, "%sunable to allocate SSL context.\n",
2929 err && *err ? *err : "");
2930 rv = 1;
2931 goto end;
2932 }
2933
yanbzhube2774d2015-12-10 15:07:30 -05002934 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002935 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2936 if (i & (1<<n)) {
2937 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002938 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2939 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002940 SSL_CTX_free(cur_ctx);
2941 rv = 1;
2942 goto end;
2943 }
yanbzhube2774d2015-12-10 15:07:30 -05002944
2945#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2946 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002947 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002948 if (err)
2949 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 +00002950 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002951 SSL_CTX_free(cur_ctx);
2952 rv = 1;
2953 goto end;
2954 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02002955#elif (defined OPENSSL_IS_BORINGSSL)
2956 ssl_sock_set_ocsp_response_from_file(cur_ctx, cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002957#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002958 }
2959 }
2960
2961 /* Load DH params into the ctx to support DHE keys */
2962#ifndef OPENSSL_NO_DH
2963 if (ssl_dh_ptr_index >= 0)
2964 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2965
2966 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2967 if (rv < 0) {
2968 if (err)
2969 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2970 *err ? *err : "", path);
2971 rv = 1;
2972 goto end;
2973 }
2974#endif
2975
2976 /* Update key_combos */
2977 key_combos[i-1].ctx = cur_ctx;
2978 }
2979
2980 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002981 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2982 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002983 node = ebmb_next(node);
2984 }
2985
2986
2987 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2988 if (!bind_conf->default_ctx) {
2989 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2990 if (key_combos[i].ctx) {
2991 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002992 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002993 break;
2994 }
2995 }
2996 }
2997
2998end:
2999
3000 if (names)
3001 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
3002
3003 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
3004 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
3005
3006 node = ebmb_first(&sni_keytypes_map);
3007 while (node) {
3008 next = ebmb_next(node);
3009 ebmb_delete(node);
3010 node = next;
3011 }
3012
3013 return rv;
3014}
3015#else
3016/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003017static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3018 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05003019{
3020 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3021 err && *err ? *err : "", path, strerror(errno));
3022 return 1;
3023}
3024
yanbzhu488a4d22015-12-01 15:16:07 -05003025#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
3026
Emeric Brunfc0421f2012-09-07 17:30:07 +02003027/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
3028 * an early error happens and the caller must call SSL_CTX_free() by itelf.
3029 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003030static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
3031 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003032{
3033 BIO *in;
3034 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003035 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003036 int ret = -1;
3037 int order = 0;
3038 X509_NAME *xname;
3039 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003040 pem_password_cb *passwd_cb;
3041 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003042 EVP_PKEY *pkey;
3043 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003044
Emeric Brunfc0421f2012-09-07 17:30:07 +02003045#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3046 STACK_OF(GENERAL_NAME) *names;
3047#endif
3048
3049 in = BIO_new(BIO_s_file());
3050 if (in == NULL)
3051 goto end;
3052
3053 if (BIO_read_filename(in, file) <= 0)
3054 goto end;
3055
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003056
3057 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
3058 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
3059
3060 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003061 if (x == NULL)
3062 goto end;
3063
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003064 pkey = X509_get_pubkey(x);
3065 if (pkey) {
3066 switch(EVP_PKEY_base_id(pkey)) {
3067 case EVP_PKEY_RSA:
3068 key_sig = TLSEXT_signature_rsa;
3069 break;
3070 case EVP_PKEY_EC:
3071 key_sig = TLSEXT_signature_ecdsa;
3072 break;
3073 }
3074 EVP_PKEY_free(pkey);
3075 }
3076
Emeric Brun50bcecc2013-04-22 13:05:23 +02003077 if (fcount) {
3078 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003079 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003080 }
3081 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003082#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003083 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
3084 if (names) {
3085 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
3086 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
3087 if (name->type == GEN_DNS) {
3088 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003089 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003090 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003091 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003092 }
3093 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003094 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003095 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003096#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003097 xname = X509_get_subject_name(x);
3098 i = -1;
3099 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
3100 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003101 ASN1_STRING *value;
3102
3103 value = X509_NAME_ENTRY_get_data(entry);
3104 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003105 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003106 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003107 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003108 }
3109 }
3110
3111 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
3112 if (!SSL_CTX_use_certificate(ctx, x))
3113 goto end;
3114
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003115#ifdef SSL_CTX_clear_extra_chain_certs
3116 SSL_CTX_clear_extra_chain_certs(ctx);
3117#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02003118 if (ctx->extra_certs != NULL) {
3119 sk_X509_pop_free(ctx->extra_certs, X509_free);
3120 ctx->extra_certs = NULL;
3121 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003122#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003123
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003124 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003125 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
3126 X509_free(ca);
3127 goto end;
3128 }
3129 }
3130
3131 err = ERR_get_error();
3132 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
3133 /* we successfully reached the last cert in the file */
3134 ret = 1;
3135 }
3136 ERR_clear_error();
3137
3138end:
3139 if (x)
3140 X509_free(x);
3141
3142 if (in)
3143 BIO_free(in);
3144
3145 return ret;
3146}
3147
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003148static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3149 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003150{
3151 int ret;
3152 SSL_CTX *ctx;
3153
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003154 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02003155 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003156 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
3157 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003158 return 1;
3159 }
3160
3161 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003162 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
3163 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003164 SSL_CTX_free(ctx);
3165 return 1;
3166 }
3167
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003168 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003169 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003170 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
3171 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003172 if (ret < 0) /* serious error, must do that ourselves */
3173 SSL_CTX_free(ctx);
3174 return 1;
3175 }
Emeric Brun61694ab2012-10-26 13:35:33 +02003176
3177 if (SSL_CTX_check_private_key(ctx) <= 0) {
3178 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3179 err && *err ? *err : "", path);
3180 return 1;
3181 }
3182
Emeric Brunfc0421f2012-09-07 17:30:07 +02003183 /* we must not free the SSL_CTX anymore below, since it's already in
3184 * the tree, so it will be discovered and cleaned in time.
3185 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003186#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02003187 /* store a NULL pointer to indicate we have not yet loaded
3188 a custom DH param file */
3189 if (ssl_dh_ptr_index >= 0) {
3190 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
3191 }
3192
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003193 ret = ssl_sock_load_dh_params(ctx, path);
3194 if (ret < 0) {
3195 if (err)
3196 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
3197 *err ? *err : "", path);
3198 return 1;
3199 }
3200#endif
3201
Lukas Tribuse4e30f72014-12-09 16:32:51 +01003202#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02003203 ret = ssl_sock_load_ocsp(ctx, path);
3204 if (ret < 0) {
3205 if (err)
3206 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",
3207 *err ? *err : "", path);
3208 return 1;
3209 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02003210#elif (defined OPENSSL_IS_BORINGSSL)
3211 ssl_sock_set_ocsp_response_from_file(ctx, path);
Emeric Brun4147b2e2014-06-16 18:36:30 +02003212#endif
3213
Daniel Jakots54ffb912015-11-06 20:02:41 +01003214#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01003215 if (sctl_ex_index >= 0) {
3216 ret = ssl_sock_load_sctl(ctx, path);
3217 if (ret < 0) {
3218 if (err)
3219 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
3220 *err ? *err : "", path);
3221 return 1;
3222 }
3223 }
3224#endif
3225
Emeric Brunfc0421f2012-09-07 17:30:07 +02003226#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003227 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003228 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
3229 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02003230 return 1;
3231 }
3232#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003233 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003234 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003235 bind_conf->default_ssl_conf = ssl_conf;
3236 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003237
3238 return 0;
3239}
3240
Willy Tarreau03209342016-12-22 17:08:28 +01003241int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003242{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003243 struct dirent **de_list;
3244 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003245 DIR *dir;
3246 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01003247 char *end;
3248 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02003249 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05003250#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3251 int is_bundle;
3252 int j;
3253#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003254
yanbzhu08ce6ab2015-12-02 13:01:29 -05003255 if (stat(path, &buf) == 0) {
3256 dir = opendir(path);
3257 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003258 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003259
yanbzhu08ce6ab2015-12-02 13:01:29 -05003260 /* strip trailing slashes, including first one */
3261 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
3262 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003263
yanbzhu08ce6ab2015-12-02 13:01:29 -05003264 n = scandir(path, &de_list, 0, alphasort);
3265 if (n < 0) {
3266 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
3267 err && *err ? *err : "", path, strerror(errno));
3268 cfgerr++;
3269 }
3270 else {
3271 for (i = 0; i < n; i++) {
3272 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02003273
yanbzhu08ce6ab2015-12-02 13:01:29 -05003274 end = strrchr(de->d_name, '.');
3275 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
3276 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003277
yanbzhu08ce6ab2015-12-02 13:01:29 -05003278 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
3279 if (stat(fp, &buf) != 0) {
3280 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3281 err && *err ? *err : "", fp, strerror(errno));
3282 cfgerr++;
3283 goto ignore_entry;
3284 }
3285 if (!S_ISREG(buf.st_mode))
3286 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05003287
3288#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3289 is_bundle = 0;
3290 /* Check if current entry in directory is part of a multi-cert bundle */
3291
3292 if (end) {
3293 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
3294 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
3295 is_bundle = 1;
3296 break;
3297 }
3298 }
3299
3300 if (is_bundle) {
3301 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
3302 int dp_len;
3303
3304 dp_len = end - de->d_name;
3305 snprintf(dp, dp_len + 1, "%s", de->d_name);
3306
3307 /* increment i and free de until we get to a non-bundle cert
3308 * Note here that we look at de_list[i + 1] before freeing de
3309 * this is important since ignore_entry will free de
3310 */
3311 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
3312 free(de);
3313 i++;
3314 de = de_list[i];
3315 }
3316
3317 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003318 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05003319
3320 /* Successfully processed the bundle */
3321 goto ignore_entry;
3322 }
3323 }
3324
3325#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003326 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003327ignore_entry:
3328 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003329 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003330 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003331 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003332 closedir(dir);
3333 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003334 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003335
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003336 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003337
Emeric Brunfc0421f2012-09-07 17:30:07 +02003338 return cfgerr;
3339}
3340
Thierry Fournier383085f2013-01-24 14:15:43 +01003341/* Make sure openssl opens /dev/urandom before the chroot. The work is only
3342 * done once. Zero is returned if the operation fails. No error is returned
3343 * if the random is said as not implemented, because we expect that openssl
3344 * will use another method once needed.
3345 */
3346static int ssl_initialize_random()
3347{
3348 unsigned char random;
3349 static int random_initialized = 0;
3350
3351 if (!random_initialized && RAND_bytes(&random, 1) != 0)
3352 random_initialized = 1;
3353
3354 return random_initialized;
3355}
3356
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003357/* release ssl bind conf */
3358void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003359{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003360 if (conf) {
3361#ifdef OPENSSL_NPN_NEGOTIATED
3362 free(conf->npn_str);
3363 conf->npn_str = NULL;
3364#endif
3365#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
3366 free(conf->alpn_str);
3367 conf->alpn_str = NULL;
3368#endif
3369 free(conf->ca_file);
3370 conf->ca_file = NULL;
3371 free(conf->crl_file);
3372 conf->crl_file = NULL;
3373 free(conf->ciphers);
3374 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003375 free(conf->curves);
3376 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003377 free(conf->ecdhe);
3378 conf->ecdhe = NULL;
3379 }
3380}
3381
3382int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
3383{
3384 char thisline[CRT_LINESIZE];
3385 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003386 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05003387 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003388 int linenum = 0;
3389 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003390
Willy Tarreauad1731d2013-04-02 17:35:58 +02003391 if ((f = fopen(file, "r")) == NULL) {
3392 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003393 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003394 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003395
3396 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003397 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003398 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003399 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003400 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003401 char *crt_path;
3402 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003403
3404 linenum++;
3405 end = line + strlen(line);
3406 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3407 /* Check if we reached the limit and the last char is not \n.
3408 * Watch out for the last line without the terminating '\n'!
3409 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003410 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3411 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003412 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003413 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003414 }
3415
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003416 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003417 newarg = 1;
3418 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003419 if (*line == '#' || *line == '\n' || *line == '\r') {
3420 /* end of string, end of loop */
3421 *line = 0;
3422 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003423 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003424 newarg = 1;
3425 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003426 } else if (*line == '[') {
3427 if (ssl_b) {
3428 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3429 cfgerr = 1;
3430 break;
3431 }
3432 if (!arg) {
3433 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3434 cfgerr = 1;
3435 break;
3436 }
3437 ssl_b = arg;
3438 newarg = 1;
3439 *line = 0;
3440 } else if (*line == ']') {
3441 if (ssl_e) {
3442 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003443 cfgerr = 1;
3444 break;
3445 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003446 if (!ssl_b) {
3447 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3448 cfgerr = 1;
3449 break;
3450 }
3451 ssl_e = arg;
3452 newarg = 1;
3453 *line = 0;
3454 } else if (newarg) {
3455 if (arg == MAX_CRT_ARGS) {
3456 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3457 cfgerr = 1;
3458 break;
3459 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003460 newarg = 0;
3461 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003462 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003463 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003464 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003465 if (cfgerr)
3466 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003467 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003468
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003469 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003470 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003471 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003472
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003473 crt_path = args[0];
3474 if (*crt_path != '/' && global_ssl.crt_base) {
3475 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3476 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3477 crt_path, linenum, file);
3478 cfgerr = 1;
3479 break;
3480 }
3481 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3482 crt_path = path;
3483 }
3484
3485 ssl_conf = calloc(1, sizeof *ssl_conf);
3486 cur_arg = ssl_b ? ssl_b : 1;
3487 while (cur_arg < ssl_e) {
3488 newarg = 0;
3489 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3490 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3491 newarg = 1;
3492 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3493 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3494 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3495 args[cur_arg], linenum, file);
3496 cfgerr = 1;
3497 }
3498 cur_arg += 1 + ssl_bind_kws[i].skip;
3499 break;
3500 }
3501 }
3502 if (!cfgerr && !newarg) {
3503 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3504 args[cur_arg], linenum, file);
3505 cfgerr = 1;
3506 break;
3507 }
3508 }
3509 if (cfgerr) {
3510 ssl_sock_free_ssl_conf(ssl_conf);
3511 free(ssl_conf);
3512 ssl_conf = NULL;
3513 break;
3514 }
3515
3516 if (stat(crt_path, &buf) == 0) {
3517 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3518 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003519 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003520 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3521 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003522 }
3523
Willy Tarreauad1731d2013-04-02 17:35:58 +02003524 if (cfgerr) {
3525 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003526 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003527 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003528 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003529 fclose(f);
3530 return cfgerr;
3531}
3532
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003533/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003534static int
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003535ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003536{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003537 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003538 long options =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003539 SSL_OP_ALL | /* all known workarounds for bugs */
3540 SSL_OP_NO_SSLv2 |
3541 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003542 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003543 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003544 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3545 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003546 long mode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003547 SSL_MODE_ENABLE_PARTIAL_WRITE |
3548 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003549 SSL_MODE_RELEASE_BUFFERS |
3550 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet43664762017-08-09 18:26:20 +02003551 struct tls_version_filter *conf_ssl_methods = &bind_conf->ssl_conf.ssl_methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003552 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003553 int flags = MC_SSL_O_ALL;
3554 int cfgerr = 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003555
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003556 ctx = SSL_CTX_new(SSLv23_server_method());
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003557 bind_conf->initial_ctx = ctx;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003558
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003559 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
3560 Warning("Proxy '%s': no-sslv3/no-tlsv1x are ignored for bind '%s' at [%s:%d]. "
3561 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
3562 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3563 else
3564 flags = conf_ssl_methods->flags;
3565
Emmanuel Hocdetbd695fe2017-05-15 15:53:41 +02003566 min = conf_ssl_methods->min;
3567 max = conf_ssl_methods->max;
3568 /* start with TLSv10 to remove SSLv3 per default */
3569 if (!min && (!max || max >= CONF_TLSV10))
3570 min = CONF_TLSV10;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003571 /* Real min and max should be determinate with configuration and openssl's capabilities */
Emmanuel Hocdetbd695fe2017-05-15 15:53:41 +02003572 if (min)
3573 flags |= (methodVersions[min].flag - 1);
3574 if (max)
3575 flags |= ~((methodVersions[max].flag << 1) - 1);
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003576 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003577 min = max = CONF_TLSV_NONE;
3578 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003579 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003580 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003581 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003582 if (min) {
3583 if (hole) {
3584 Warning("Proxy '%s': SSL/TLS versions range not contiguous for bind '%s' at [%s:%d]. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003585 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003586 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line,
3587 methodVersions[hole].name);
3588 hole = 0;
3589 }
3590 max = i;
3591 }
3592 else {
3593 min = max = i;
3594 }
3595 }
3596 else {
3597 if (min)
3598 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003599 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003600 if (!min) {
3601 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003602 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003603 cfgerr += 1;
3604 }
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003605 /* save real min/max in bind_conf */
3606 conf_ssl_methods->min = min;
3607 conf_ssl_methods->max = max;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003608
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003609#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3610 /* Keep force-xxx implementation as it is in older haproxy. It's a
3611 precautionary measure to avoid any suprise with older openssl version. */
3612 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003613 methodVersions[min].ctx_set_version(ctx, SET_SERVER);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003614 else
3615 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3616 if (flags & methodVersions[i].flag)
3617 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003618#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003619 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003620 methodVersions[min].ctx_set_version(ctx, SET_MIN);
3621 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003622#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003623
3624 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3625 options |= SSL_OP_NO_TICKET;
3626 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
3627 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
3628 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00003629
3630#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
3631 if (global_ssl.async)
3632 mode |= SSL_MODE_ASYNC;
3633#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003634 SSL_CTX_set_mode(ctx, mode);
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003635 if (global_ssl.life_time)
3636 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003637
3638#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3639#ifdef OPENSSL_IS_BORINGSSL
3640 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3641 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3642#else
3643 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3644 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3645#endif
3646#endif
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003647 return cfgerr;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003648}
3649
3650int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3651{
3652 struct proxy *curproxy = bind_conf->frontend;
3653 int cfgerr = 0;
3654 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003655 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003656 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003657 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003658
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003659 if (ssl_conf) {
3660 struct tls_version_filter *conf_ssl_methods = &ssl_conf->ssl_methods;
3661 int i, min, max;
3662 int flags = MC_SSL_O_ALL;
3663
3664 /* Real min and max should be determinate with configuration and openssl's capabilities */
Emmanuel Hocdet43664762017-08-09 18:26:20 +02003665 min = conf_ssl_methods->min ? conf_ssl_methods->min : bind_conf->ssl_conf.ssl_methods.min;
3666 max = conf_ssl_methods->max ? conf_ssl_methods->max : bind_conf->ssl_conf.ssl_methods.max;
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003667 if (min)
3668 flags |= (methodVersions[min].flag - 1);
3669 if (max)
3670 flags |= ~((methodVersions[max].flag << 1) - 1);
3671 min = max = CONF_TLSV_NONE;
3672 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3673 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
3674 if (min)
3675 max = i;
3676 else
3677 min = max = i;
3678 }
3679 /* save real min/max */
3680 conf_ssl_methods->min = min;
3681 conf_ssl_methods->max = max;
3682 if (!min) {
3683 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
3684 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3685 cfgerr += 1;
3686 }
3687 }
3688
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003689 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003690 case SSL_SOCK_VERIFY_NONE:
3691 verify = SSL_VERIFY_NONE;
3692 break;
3693 case SSL_SOCK_VERIFY_OPTIONAL:
3694 verify = SSL_VERIFY_PEER;
3695 break;
3696 case SSL_SOCK_VERIFY_REQUIRED:
3697 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3698 break;
3699 }
3700 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3701 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003702 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3703 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3704 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003705 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003706 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003707 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003708 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003709 cfgerr++;
3710 }
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02003711 if (!((ssl_conf && ssl_conf->no_ca_names) || bind_conf->ssl_conf.no_ca_names)) {
3712 /* set CA names for client cert request, function returns void */
3713 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
3714 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003715 }
Emeric Brun850efd52014-01-29 12:24:34 +01003716 else {
3717 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3718 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3719 cfgerr++;
3720 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003721#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003722 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003723 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3724
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003725 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003726 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003727 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003728 cfgerr++;
3729 }
Emeric Brun561e5742012-10-02 15:20:55 +02003730 else {
3731 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3732 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003733 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003734#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003735 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003736 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003737#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003738 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003739 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3740 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3741 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3742 cfgerr++;
3743 }
3744 }
3745#endif
3746
Emeric Brunfc0421f2012-09-07 17:30:07 +02003747 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003748 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3749 if (conf_ciphers &&
3750 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003751 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 +01003752 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003753 cfgerr++;
3754 }
3755
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003756#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003757 /* If tune.ssl.default-dh-param has not been set,
3758 neither has ssl-default-dh-file and no static DH
3759 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003760 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003761 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003762 (ssl_dh_ptr_index == -1 ||
3763 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003764 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3765 const SSL_CIPHER * cipher = NULL;
3766 char cipher_description[128];
3767 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3768 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3769 which is not ephemeral DH. */
3770 const char dhe_description[] = " Kx=DH ";
3771 const char dhe_export_description[] = " Kx=DH(";
3772 int idx = 0;
3773 int dhe_found = 0;
3774 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003775
Remi Gacogne23d5d372014-10-10 17:04:26 +02003776 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003777
Remi Gacogne23d5d372014-10-10 17:04:26 +02003778 if (ssl) {
3779 ciphers = SSL_get_ciphers(ssl);
3780
3781 if (ciphers) {
3782 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3783 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3784 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3785 if (strstr(cipher_description, dhe_description) != NULL ||
3786 strstr(cipher_description, dhe_export_description) != NULL) {
3787 dhe_found = 1;
3788 break;
3789 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003790 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003791 }
3792 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003793 SSL_free(ssl);
3794 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003795 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003796
Lukas Tribus90132722014-08-18 00:56:33 +02003797 if (dhe_found) {
3798 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 +02003799 }
3800
Willy Tarreauef934602016-12-22 23:12:01 +01003801 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003802 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003803
Willy Tarreauef934602016-12-22 23:12:01 +01003804 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003805 if (local_dh_1024 == NULL) {
3806 local_dh_1024 = ssl_get_dh_1024();
3807 }
Willy Tarreauef934602016-12-22 23:12:01 +01003808 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003809 if (local_dh_2048 == NULL) {
3810 local_dh_2048 = ssl_get_dh_2048();
3811 }
Willy Tarreauef934602016-12-22 23:12:01 +01003812 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003813 if (local_dh_4096 == NULL) {
3814 local_dh_4096 = ssl_get_dh_4096();
3815 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003816 }
3817 }
3818 }
3819#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003820
Emeric Brunfc0421f2012-09-07 17:30:07 +02003821 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003822#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003823 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003824#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003825
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003826#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003827 ssl_conf_cur = NULL;
3828 if (ssl_conf && ssl_conf->npn_str)
3829 ssl_conf_cur = ssl_conf;
3830 else if (bind_conf->ssl_conf.npn_str)
3831 ssl_conf_cur = &bind_conf->ssl_conf;
3832 if (ssl_conf_cur)
3833 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003834#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003835#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003836 ssl_conf_cur = NULL;
3837 if (ssl_conf && ssl_conf->alpn_str)
3838 ssl_conf_cur = ssl_conf;
3839 else if (bind_conf->ssl_conf.alpn_str)
3840 ssl_conf_cur = &bind_conf->ssl_conf;
3841 if (ssl_conf_cur)
3842 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003843#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003844#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3845 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3846 if (conf_curves) {
3847 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3848 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3849 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3850 cfgerr++;
3851 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003852#if defined(SSL_CTX_set_ecdh_auto)
3853 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3854#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003855 }
3856#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003857#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003858 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003859 int i;
3860 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003861 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3862 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003863
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003864 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003865 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3866 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 +01003867 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003868 cfgerr++;
3869 }
3870 else {
3871 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3872 EC_KEY_free(ecdh);
3873 }
3874 }
3875#endif
3876
Emeric Brunfc0421f2012-09-07 17:30:07 +02003877 return cfgerr;
3878}
3879
Evan Broderbe554312013-06-27 00:05:25 -07003880static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3881{
3882 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3883 size_t prefixlen, suffixlen;
3884
3885 /* Trivial case */
3886 if (strcmp(pattern, hostname) == 0)
3887 return 1;
3888
Evan Broderbe554312013-06-27 00:05:25 -07003889 /* The rest of this logic is based on RFC 6125, section 6.4.3
3890 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3891
Emeric Bruna848dae2013-10-08 11:27:28 +02003892 pattern_wildcard = NULL;
3893 pattern_left_label_end = pattern;
3894 while (*pattern_left_label_end != '.') {
3895 switch (*pattern_left_label_end) {
3896 case 0:
3897 /* End of label not found */
3898 return 0;
3899 case '*':
3900 /* If there is more than one wildcards */
3901 if (pattern_wildcard)
3902 return 0;
3903 pattern_wildcard = pattern_left_label_end;
3904 break;
3905 }
3906 pattern_left_label_end++;
3907 }
3908
3909 /* If it's not trivial and there is no wildcard, it can't
3910 * match */
3911 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003912 return 0;
3913
3914 /* Make sure all labels match except the leftmost */
3915 hostname_left_label_end = strchr(hostname, '.');
3916 if (!hostname_left_label_end
3917 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3918 return 0;
3919
3920 /* Make sure the leftmost label of the hostname is long enough
3921 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003922 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003923 return 0;
3924
3925 /* Finally compare the string on either side of the
3926 * wildcard */
3927 prefixlen = pattern_wildcard - pattern;
3928 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003929 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3930 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003931 return 0;
3932
3933 return 1;
3934}
3935
3936static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3937{
3938 SSL *ssl;
3939 struct connection *conn;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003940 const char *servername;
Willy Tarreau71d058c2017-07-26 20:09:56 +02003941 const char *sni;
Evan Broderbe554312013-06-27 00:05:25 -07003942
3943 int depth;
3944 X509 *cert;
3945 STACK_OF(GENERAL_NAME) *alt_names;
3946 int i;
3947 X509_NAME *cert_subject;
3948 char *str;
3949
3950 if (ok == 0)
3951 return ok;
3952
3953 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003954 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003955
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003956 /* We're checking if the provided hostnames match the desired one. The
3957 * desired hostname comes from the SNI we presented if any, or if not
3958 * provided then it may have been explicitly stated using a "verifyhost"
3959 * directive. If neither is set, we don't care about the name so the
3960 * verification is OK.
Willy Tarreau2ab88672017-07-05 18:23:03 +02003961 */
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003962 servername = SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau71d058c2017-07-26 20:09:56 +02003963 sni = servername;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003964 if (!servername) {
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003965 servername = objt_server(conn->target)->ssl_ctx.verify_host;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003966 if (!servername)
3967 return ok;
3968 }
Evan Broderbe554312013-06-27 00:05:25 -07003969
3970 /* We only need to verify the CN on the actual server cert,
3971 * not the indirect CAs */
3972 depth = X509_STORE_CTX_get_error_depth(ctx);
3973 if (depth != 0)
3974 return ok;
3975
3976 /* At this point, the cert is *not* OK unless we can find a
3977 * hostname match */
3978 ok = 0;
3979
3980 cert = X509_STORE_CTX_get_current_cert(ctx);
3981 /* It seems like this might happen if verify peer isn't set */
3982 if (!cert)
3983 return ok;
3984
3985 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3986 if (alt_names) {
3987 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3988 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3989 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003990#if OPENSSL_VERSION_NUMBER < 0x00907000L
3991 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3992#else
Evan Broderbe554312013-06-27 00:05:25 -07003993 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003994#endif
Evan Broderbe554312013-06-27 00:05:25 -07003995 ok = ssl_sock_srv_hostcheck(str, servername);
3996 OPENSSL_free(str);
3997 }
3998 }
3999 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02004000 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07004001 }
4002
4003 cert_subject = X509_get_subject_name(cert);
4004 i = -1;
4005 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
4006 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004007 ASN1_STRING *value;
4008 value = X509_NAME_ENTRY_get_data(entry);
4009 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07004010 ok = ssl_sock_srv_hostcheck(str, servername);
4011 OPENSSL_free(str);
4012 }
4013 }
4014
Willy Tarreau71d058c2017-07-26 20:09:56 +02004015 /* report the mismatch and indicate if SNI was used or not */
4016 if (!ok && !conn->err_code)
4017 conn->err_code = sni ? CO_ER_SSL_MISMATCH_SNI : CO_ER_SSL_MISMATCH;
Evan Broderbe554312013-06-27 00:05:25 -07004018 return ok;
4019}
4020
Emeric Brun94324a42012-10-11 14:00:19 +02004021/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01004022int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02004023{
Willy Tarreau03209342016-12-22 17:08:28 +01004024 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02004025 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02004026 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02004027 SSL_OP_ALL | /* all known workarounds for bugs */
4028 SSL_OP_NO_SSLv2 |
4029 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02004030 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02004031 SSL_MODE_ENABLE_PARTIAL_WRITE |
4032 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01004033 SSL_MODE_RELEASE_BUFFERS |
4034 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01004035 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004036 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004037 struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004038 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004039 int flags = MC_SSL_O_ALL;
Emeric Brun94324a42012-10-11 14:00:19 +02004040
Thierry Fournier383085f2013-01-24 14:15:43 +01004041 /* Make sure openssl opens /dev/urandom before the chroot */
4042 if (!ssl_initialize_random()) {
4043 Alert("OpenSSL random data generator initialization failed.\n");
4044 cfgerr++;
4045 }
4046
Willy Tarreaufce03112015-01-15 21:32:40 +01004047 /* Automatic memory computations need to know we use SSL there */
4048 global.ssl_used_backend = 1;
4049
4050 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02004051 srv->ssl_ctx.reused_sess = NULL;
4052 if (srv->use_ssl)
4053 srv->xprt = &ssl_sock;
4054 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01004055 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02004056
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004057 ctx = SSL_CTX_new(SSLv23_client_method());
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004058 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02004059 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
4060 proxy_type_str(curproxy), curproxy->id,
4061 srv->id);
4062 cfgerr++;
4063 return cfgerr;
4064 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004065
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004066 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
4067 Warning("config : %s '%s': no-sslv3/no-tlsv1x are ignored for server '%s'. "
4068 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
4069 proxy_type_str(curproxy), curproxy->id, srv->id);
4070 else
4071 flags = conf_ssl_methods->flags;
4072
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004073 /* Real min and max should be determinate with configuration and openssl's capabilities */
4074 if (conf_ssl_methods->min)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004075 flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004076 if (conf_ssl_methods->max)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004077 flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004078
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004079 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004080 min = max = CONF_TLSV_NONE;
4081 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004082 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004083 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004084 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004085 if (min) {
4086 if (hole) {
4087 Warning("config : %s '%s': SSL/TLS versions range not contiguous for server '%s'. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02004088 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004089 proxy_type_str(curproxy), curproxy->id, srv->id,
4090 methodVersions[hole].name);
4091 hole = 0;
4092 }
4093 max = i;
4094 }
4095 else {
4096 min = max = i;
4097 }
4098 }
4099 else {
4100 if (min)
4101 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004102 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004103 if (!min) {
4104 Alert("config : %s '%s': all SSL/TLS versions are disabled for server '%s'.\n",
4105 proxy_type_str(curproxy), curproxy->id, srv->id);
4106 cfgerr += 1;
4107 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004108
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004109#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
4110 /* Keep force-xxx implementation as it is in older haproxy. It's a
4111 precautionary measure to avoid any suprise with older openssl version. */
4112 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004113 methodVersions[min].ctx_set_version(ctx, SET_CLIENT);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004114 else
4115 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
4116 if (flags & methodVersions[i].flag)
4117 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004118#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004119 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004120 methodVersions[min].ctx_set_version(ctx, SET_MIN);
4121 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004122#endif
4123
4124 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
4125 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004126 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004127
4128#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4129 if (global_ssl.async)
4130 mode |= SSL_MODE_ASYNC;
4131#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004132 SSL_CTX_set_mode(ctx, mode);
4133 srv->ssl_ctx.ctx = ctx;
4134
Emeric Bruna7aa3092012-10-26 12:58:00 +02004135 if (srv->ssl_ctx.client_crt) {
4136 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
4137 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
4138 proxy_type_str(curproxy), curproxy->id,
4139 srv->id, srv->ssl_ctx.client_crt);
4140 cfgerr++;
4141 }
4142 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
4143 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
4144 proxy_type_str(curproxy), curproxy->id,
4145 srv->id, srv->ssl_ctx.client_crt);
4146 cfgerr++;
4147 }
4148 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
4149 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
4150 proxy_type_str(curproxy), curproxy->id,
4151 srv->id, srv->ssl_ctx.client_crt);
4152 cfgerr++;
4153 }
4154 }
Emeric Brun94324a42012-10-11 14:00:19 +02004155
Emeric Brun850efd52014-01-29 12:24:34 +01004156 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
4157 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01004158 switch (srv->ssl_ctx.verify) {
4159 case SSL_SOCK_VERIFY_NONE:
4160 verify = SSL_VERIFY_NONE;
4161 break;
4162 case SSL_SOCK_VERIFY_REQUIRED:
4163 verify = SSL_VERIFY_PEER;
4164 break;
4165 }
Evan Broderbe554312013-06-27 00:05:25 -07004166 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01004167 verify,
Willy Tarreau2ab88672017-07-05 18:23:03 +02004168 (srv->ssl_ctx.verify_host || (verify & SSL_VERIFY_PEER)) ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01004169 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02004170 if (srv->ssl_ctx.ca_file) {
4171 /* load CAfile to verify */
4172 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004173 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004174 curproxy->id, srv->id,
4175 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
4176 cfgerr++;
4177 }
4178 }
Emeric Brun850efd52014-01-29 12:24:34 +01004179 else {
4180 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004181 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 +01004182 curproxy->id, srv->id,
4183 srv->conf.file, srv->conf.line);
4184 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004185 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01004186 curproxy->id, srv->id,
4187 srv->conf.file, srv->conf.line);
4188 cfgerr++;
4189 }
Emeric Brunef42d922012-10-11 16:11:36 +02004190#ifdef X509_V_FLAG_CRL_CHECK
4191 if (srv->ssl_ctx.crl_file) {
4192 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
4193
4194 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004195 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004196 curproxy->id, srv->id,
4197 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
4198 cfgerr++;
4199 }
4200 else {
4201 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
4202 }
4203 }
4204#endif
4205 }
4206
Emeric Brun94324a42012-10-11 14:00:19 +02004207 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
4208 if (srv->ssl_ctx.ciphers &&
4209 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
4210 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
4211 curproxy->id, srv->id,
4212 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
4213 cfgerr++;
4214 }
4215
4216 return cfgerr;
4217}
4218
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004219/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004220 * be NULL, in which case nothing is done. Returns the number of errors
4221 * encountered.
4222 */
Willy Tarreau03209342016-12-22 17:08:28 +01004223int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004224{
4225 struct ebmb_node *node;
4226 struct sni_ctx *sni;
4227 int err = 0;
4228
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004229 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004230 return 0;
4231
Willy Tarreaufce03112015-01-15 21:32:40 +01004232 /* Automatic memory computations need to know we use SSL there */
4233 global.ssl_used_frontend = 1;
4234
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004235 /* Make sure openssl opens /dev/urandom before the chroot */
4236 if (!ssl_initialize_random()) {
4237 Alert("OpenSSL random data generator initialization failed.\n");
4238 err++;
4239 }
4240 /* Create initial_ctx used to start the ssl connection before do switchctx */
4241 if (!bind_conf->initial_ctx) {
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004242 err += ssl_sock_initial_ctx(bind_conf);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004243 /* It should not be necessary to call this function, but it's
4244 necessary first to check and move all initialisation related
4245 to initial_ctx in ssl_sock_initial_ctx. */
4246 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
4247 }
Emeric Brun0bed9942014-10-30 19:25:24 +01004248 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004249 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01004250
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004251 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004252 while (node) {
4253 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004254 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4255 /* only initialize the CTX on its first occurrence and
4256 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004257 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004258 node = ebmb_next(node);
4259 }
4260
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004261 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004262 while (node) {
4263 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004264 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4265 /* only initialize the CTX on its first occurrence and
4266 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004267 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004268 node = ebmb_next(node);
4269 }
4270 return err;
4271}
4272
Willy Tarreau55d37912016-12-21 23:38:39 +01004273/* Prepares all the contexts for a bind_conf and allocates the shared SSL
4274 * context if needed. Returns < 0 on error, 0 on success. The warnings and
4275 * alerts are directly emitted since the rest of the stack does it below.
4276 */
4277int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
4278{
4279 struct proxy *px = bind_conf->frontend;
4280 int alloc_ctx;
4281 int err;
4282
4283 if (!bind_conf->is_ssl) {
4284 if (bind_conf->default_ctx) {
4285 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
4286 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4287 }
4288 return 0;
4289 }
4290 if (!bind_conf->default_ctx) {
Emmanuel Hocdetaa0d6372017-08-09 11:24:25 +02004291 if (bind_conf->strict_sni && !bind_conf->generate_certs) {
4292 Warning("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d], ssl connections will fail (use 'crt').\n",
4293 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4294 }
4295 else {
4296 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
4297 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4298 return -1;
4299 }
Willy Tarreau55d37912016-12-21 23:38:39 +01004300 }
4301
Willy Tarreauef934602016-12-22 23:12:01 +01004302 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01004303 if (alloc_ctx < 0) {
4304 if (alloc_ctx == SHCTX_E_INIT_LOCK)
4305 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");
4306 else
4307 Alert("Unable to allocate SSL session cache.\n");
4308 return -1;
4309 }
4310
4311 err = 0;
4312 /* initialize all certificate contexts */
4313 err += ssl_sock_prepare_all_ctx(bind_conf);
4314
4315 /* initialize CA variables if the certificates generation is enabled */
4316 err += ssl_sock_load_ca(bind_conf);
4317
4318 return -err;
4319}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02004320
4321/* release ssl context allocated for servers. */
4322void ssl_sock_free_srv_ctx(struct server *srv)
4323{
4324 if (srv->ssl_ctx.ctx)
4325 SSL_CTX_free(srv->ssl_ctx.ctx);
4326}
4327
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004328/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004329 * be NULL, in which case nothing is done. The default_ctx is nullified too.
4330 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004331void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004332{
4333 struct ebmb_node *node, *back;
4334 struct sni_ctx *sni;
4335
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004336 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004337 return;
4338
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004339 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004340 while (node) {
4341 sni = ebmb_entry(node, struct sni_ctx, name);
4342 back = ebmb_next(node);
4343 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004344 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004345 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004346 ssl_sock_free_ssl_conf(sni->conf);
4347 free(sni->conf);
4348 sni->conf = NULL;
4349 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004350 free(sni);
4351 node = back;
4352 }
4353
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004354 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004355 while (node) {
4356 sni = ebmb_entry(node, struct sni_ctx, name);
4357 back = ebmb_next(node);
4358 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004359 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004360 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004361 ssl_sock_free_ssl_conf(sni->conf);
4362 free(sni->conf);
4363 sni->conf = NULL;
4364 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004365 free(sni);
4366 node = back;
4367 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004368 SSL_CTX_free(bind_conf->initial_ctx);
4369 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004370 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004371 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02004372}
4373
Willy Tarreau795cdab2016-12-22 17:30:54 +01004374/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
4375void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
4376{
4377 ssl_sock_free_ca(bind_conf);
4378 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004379 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004380 free(bind_conf->ca_sign_file);
4381 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004382 if (bind_conf->keys_ref) {
4383 free(bind_conf->keys_ref->filename);
4384 free(bind_conf->keys_ref->tlskeys);
4385 LIST_DEL(&bind_conf->keys_ref->list);
4386 free(bind_conf->keys_ref);
4387 }
4388 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004389 bind_conf->ca_sign_pass = NULL;
4390 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004391}
4392
Christopher Faulet31af49d2015-06-09 17:29:50 +02004393/* Load CA cert file and private key used to generate certificates */
4394int
Willy Tarreau03209342016-12-22 17:08:28 +01004395ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02004396{
Willy Tarreau03209342016-12-22 17:08:28 +01004397 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004398 FILE *fp;
4399 X509 *cacert = NULL;
4400 EVP_PKEY *capkey = NULL;
4401 int err = 0;
4402
4403 if (!bind_conf || !bind_conf->generate_certs)
4404 return err;
4405
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004406#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01004407 if (global_ssl.ctx_cache)
4408 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02004409 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02004410#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02004411
Christopher Faulet31af49d2015-06-09 17:29:50 +02004412 if (!bind_conf->ca_sign_file) {
4413 Alert("Proxy '%s': cannot enable certificate generation, "
4414 "no CA certificate File configured at [%s:%d].\n",
4415 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004416 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004417 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004418
4419 /* read in the CA certificate */
4420 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
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 Faulet31af49d2015-06-09 17:29:50 +02004423 goto load_error;
4424 }
4425 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
4426 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4427 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004428 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004429 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004430 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004431 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
4432 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
4433 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004434 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004435 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004436
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004437 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004438 bind_conf->ca_sign_cert = cacert;
4439 bind_conf->ca_sign_pkey = capkey;
4440 return err;
4441
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004442 read_error:
4443 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004444 if (capkey) EVP_PKEY_free(capkey);
4445 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004446 load_error:
4447 bind_conf->generate_certs = 0;
4448 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004449 return err;
4450}
4451
4452/* Release CA cert and private key used to generate certificated */
4453void
4454ssl_sock_free_ca(struct bind_conf *bind_conf)
4455{
4456 if (!bind_conf)
4457 return;
4458
4459 if (bind_conf->ca_sign_pkey)
4460 EVP_PKEY_free(bind_conf->ca_sign_pkey);
4461 if (bind_conf->ca_sign_cert)
4462 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01004463 bind_conf->ca_sign_pkey = NULL;
4464 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004465}
4466
Emeric Brun46591952012-05-18 15:47:34 +02004467/*
4468 * This function is called if SSL * context is not yet allocated. The function
4469 * is designed to be called before any other data-layer operation and sets the
4470 * handshake flag on the connection. It is safe to call it multiple times.
4471 * It returns 0 on success and -1 in error case.
4472 */
4473static int ssl_sock_init(struct connection *conn)
4474{
4475 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004476 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004477 return 0;
4478
Willy Tarreau3c728722014-01-23 13:50:42 +01004479 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004480 return 0;
4481
Willy Tarreau20879a02012-12-03 16:32:10 +01004482 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4483 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004484 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004485 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004486
Emeric Brun46591952012-05-18 15:47:34 +02004487 /* If it is in client mode initiate SSL session
4488 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004489 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004490 int may_retry = 1;
4491
4492 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004493 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004494 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004495 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004496 if (may_retry--) {
4497 pool_gc2();
4498 goto retry_connect;
4499 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004500 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004501 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004502 }
Emeric Brun46591952012-05-18 15:47:34 +02004503
Emeric Brun46591952012-05-18 15:47:34 +02004504 /* set fd on SSL session context */
Willy Tarreau585744b2017-08-24 14:31:19 +02004505 if (!SSL_set_fd(conn->xprt_ctx, conn->handle.fd)) {
Emeric Brun55476152014-11-12 17:35:37 +01004506 SSL_free(conn->xprt_ctx);
4507 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004508 if (may_retry--) {
4509 pool_gc2();
4510 goto retry_connect;
4511 }
Emeric Brun55476152014-11-12 17:35:37 +01004512 conn->err_code = CO_ER_SSL_NO_MEM;
4513 return -1;
4514 }
Emeric Brun46591952012-05-18 15:47:34 +02004515
Evan Broderbe554312013-06-27 00:05:25 -07004516 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004517 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4518 SSL_free(conn->xprt_ctx);
4519 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004520 if (may_retry--) {
4521 pool_gc2();
4522 goto retry_connect;
4523 }
Emeric Brun55476152014-11-12 17:35:37 +01004524 conn->err_code = CO_ER_SSL_NO_MEM;
4525 return -1;
4526 }
4527
4528 SSL_set_connect_state(conn->xprt_ctx);
4529 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4530 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4531 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4532 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4533 }
4534 }
Evan Broderbe554312013-06-27 00:05:25 -07004535
Emeric Brun46591952012-05-18 15:47:34 +02004536 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004537 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004538
4539 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004540 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004541 return 0;
4542 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004543 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004544 int may_retry = 1;
4545
4546 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004547 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004548 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004549 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004550 if (may_retry--) {
4551 pool_gc2();
4552 goto retry_accept;
4553 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004554 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004555 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004556 }
Emeric Brun46591952012-05-18 15:47:34 +02004557
Emeric Brun46591952012-05-18 15:47:34 +02004558 /* set fd on SSL session context */
Willy Tarreau585744b2017-08-24 14:31:19 +02004559 if (!SSL_set_fd(conn->xprt_ctx, conn->handle.fd)) {
Emeric Brun55476152014-11-12 17:35:37 +01004560 SSL_free(conn->xprt_ctx);
4561 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004562 if (may_retry--) {
4563 pool_gc2();
4564 goto retry_accept;
4565 }
Emeric Brun55476152014-11-12 17:35:37 +01004566 conn->err_code = CO_ER_SSL_NO_MEM;
4567 return -1;
4568 }
Emeric Brun46591952012-05-18 15:47:34 +02004569
Emeric Brune1f38db2012-09-03 20:36:47 +02004570 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004571 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4572 SSL_free(conn->xprt_ctx);
4573 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004574 if (may_retry--) {
4575 pool_gc2();
4576 goto retry_accept;
4577 }
Emeric Brun55476152014-11-12 17:35:37 +01004578 conn->err_code = CO_ER_SSL_NO_MEM;
4579 return -1;
4580 }
4581
4582 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004583
Emeric Brun46591952012-05-18 15:47:34 +02004584 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004585 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004586
4587 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004588 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004589 return 0;
4590 }
4591 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004592 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004593 return -1;
4594}
4595
4596
4597/* This is the callback which is used when an SSL handshake is pending. It
4598 * updates the FD status if it wants some polling before being called again.
4599 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4600 * otherwise it returns non-zero and removes itself from the connection's
4601 * flags (the bit is provided in <flag> by the caller).
4602 */
4603int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4604{
4605 int ret;
4606
Willy Tarreau3c728722014-01-23 13:50:42 +01004607 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004608 return 0;
4609
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004610 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004611 goto out_error;
4612
Emeric Brun674b7432012-11-08 19:21:55 +01004613 /* If we use SSL_do_handshake to process a reneg initiated by
4614 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4615 * Usually SSL_write and SSL_read are used and process implicitly
4616 * the reneg handshake.
4617 * Here we use SSL_peek as a workaround for reneg.
4618 */
4619 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4620 char c;
4621
4622 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4623 if (ret <= 0) {
4624 /* handshake may have not been completed, let's find why */
4625 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004626
Emeric Brun674b7432012-11-08 19:21:55 +01004627 if (ret == SSL_ERROR_WANT_WRITE) {
4628 /* SSL handshake needs to write, L4 connection may not be ready */
4629 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004630 __conn_sock_want_send(conn);
Willy Tarreau585744b2017-08-24 14:31:19 +02004631 fd_cant_send(conn->handle.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004632 return 0;
4633 }
4634 else if (ret == SSL_ERROR_WANT_READ) {
4635 /* handshake may have been completed but we have
4636 * no more data to read.
4637 */
4638 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4639 ret = 1;
4640 goto reneg_ok;
4641 }
4642 /* SSL handshake needs to read, L4 connection is ready */
4643 if (conn->flags & CO_FL_WAIT_L4_CONN)
4644 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4645 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004646 __conn_sock_want_recv(conn);
Willy Tarreau585744b2017-08-24 14:31:19 +02004647 fd_cant_recv(conn->handle.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004648 return 0;
4649 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004650#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4651 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004652 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004653 return 0;
4654 }
4655#endif
Emeric Brun674b7432012-11-08 19:21:55 +01004656 else if (ret == SSL_ERROR_SYSCALL) {
4657 /* if errno is null, then connection was successfully established */
4658 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4659 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004660 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004661#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4662 conn->err_code = CO_ER_SSL_HANDSHAKE;
4663#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004664 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004665#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004666 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4667 empty_handshake = state == TLS_ST_BEFORE;
4668#else
4669 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4670#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004671 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004672 if (!errno) {
4673 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4674 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4675 else
4676 conn->err_code = CO_ER_SSL_EMPTY;
4677 }
4678 else {
4679 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4680 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4681 else
4682 conn->err_code = CO_ER_SSL_ABORT;
4683 }
4684 }
4685 else {
4686 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4687 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004688 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004689 conn->err_code = CO_ER_SSL_HANDSHAKE;
4690 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004691#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004692 }
Emeric Brun674b7432012-11-08 19:21:55 +01004693 goto out_error;
4694 }
4695 else {
4696 /* Fail on all other handshake errors */
4697 /* Note: OpenSSL may leave unread bytes in the socket's
4698 * buffer, causing an RST to be emitted upon close() on
4699 * TCP sockets. We first try to drain possibly pending
4700 * data to avoid this as much as possible.
4701 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004702 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004703 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004704 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4705 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004706 goto out_error;
4707 }
4708 }
4709 /* read some data: consider handshake completed */
4710 goto reneg_ok;
4711 }
4712
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004713 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004714 if (ret != 1) {
4715 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004716 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004717
4718 if (ret == SSL_ERROR_WANT_WRITE) {
4719 /* SSL handshake needs to write, L4 connection may not be ready */
4720 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004721 __conn_sock_want_send(conn);
Willy Tarreau585744b2017-08-24 14:31:19 +02004722 fd_cant_send(conn->handle.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004723 return 0;
4724 }
4725 else if (ret == SSL_ERROR_WANT_READ) {
4726 /* SSL handshake needs to read, L4 connection is ready */
4727 if (conn->flags & CO_FL_WAIT_L4_CONN)
4728 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4729 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004730 __conn_sock_want_recv(conn);
Willy Tarreau585744b2017-08-24 14:31:19 +02004731 fd_cant_recv(conn->handle.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004732 return 0;
4733 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004734#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4735 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004736 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004737 return 0;
4738 }
4739#endif
Willy Tarreau89230192012-09-28 20:22:13 +02004740 else if (ret == SSL_ERROR_SYSCALL) {
4741 /* if errno is null, then connection was successfully established */
4742 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4743 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004744 if (!conn->err_code) {
4745#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4746 conn->err_code = CO_ER_SSL_HANDSHAKE;
4747#else
4748 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004749#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004750 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4751 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004752#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004753 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004754#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004755 if (empty_handshake) {
4756 if (!errno) {
4757 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4758 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4759 else
4760 conn->err_code = CO_ER_SSL_EMPTY;
4761 }
4762 else {
4763 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4764 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4765 else
4766 conn->err_code = CO_ER_SSL_ABORT;
4767 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004768 }
4769 else {
4770 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4771 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4772 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004773 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004774 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004775#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004776 }
Willy Tarreau89230192012-09-28 20:22:13 +02004777 goto out_error;
4778 }
Emeric Brun46591952012-05-18 15:47:34 +02004779 else {
4780 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004781 /* Note: OpenSSL may leave unread bytes in the socket's
4782 * buffer, causing an RST to be emitted upon close() on
4783 * TCP sockets. We first try to drain possibly pending
4784 * data to avoid this as much as possible.
4785 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004786 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004787 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004788 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4789 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004790 goto out_error;
4791 }
4792 }
4793
Emeric Brun674b7432012-11-08 19:21:55 +01004794reneg_ok:
Emeric Brunb5e42a82017-06-06 12:35:14 +00004795
4796#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4797 /* ASYNC engine API doesn't support moving read/write
4798 * buffers. So we disable ASYNC mode right after
4799 * the handshake to avoid buffer oveflows.
4800 */
4801 if (global_ssl.async)
4802 SSL_clear_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4803#endif
Emeric Brun46591952012-05-18 15:47:34 +02004804 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004805 if (!SSL_session_reused(conn->xprt_ctx)) {
4806 if (objt_server(conn->target)) {
4807 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4808 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4809 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4810
Emeric Brun46591952012-05-18 15:47:34 +02004811 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004812 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004813 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004814 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4815 }
Emeric Brun46591952012-05-18 15:47:34 +02004816
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004817 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4818 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004819 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004820 else {
4821 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4822 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4823 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4824 }
Emeric Brun46591952012-05-18 15:47:34 +02004825 }
4826
4827 /* The connection is now established at both layers, it's time to leave */
4828 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4829 return 1;
4830
4831 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004832 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004833 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004834 ERR_clear_error();
4835
Emeric Brun9fa89732012-10-04 17:09:56 +02004836 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004837 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4838 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4839 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004840 }
4841
Emeric Brun46591952012-05-18 15:47:34 +02004842 /* Fail on all other handshake errors */
4843 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004844 if (!conn->err_code)
4845 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004846 return 0;
4847}
4848
4849/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004850 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004851 * buffer wraps, in which case a second call may be performed. The connection's
4852 * flags are updated with whatever special event is detected (error, read0,
4853 * empty). The caller is responsible for taking care of those events and
4854 * avoiding the call if inappropriate. The function does not call the
4855 * connection's polling update function, so the caller is responsible for this.
4856 */
4857static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4858{
4859 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004860 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004861
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004862 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004863 goto out_error;
4864
4865 if (conn->flags & CO_FL_HANDSHAKE)
4866 /* a handshake was requested */
4867 return 0;
4868
Willy Tarreauabf08d92014-01-14 11:31:27 +01004869 /* let's realign the buffer to optimize I/O */
4870 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004871 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004872
4873 /* read the largest possible block. For this, we perform only one call
4874 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4875 * in which case we accept to do it once again. A new attempt is made on
4876 * EINTR too.
4877 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004878 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004879 /* first check if we have some room after p+i */
4880 try = buf->data + buf->size - (buf->p + buf->i);
4881 /* otherwise continue between data and p-o */
4882 if (try <= 0) {
4883 try = buf->p - (buf->data + buf->o);
4884 if (try <= 0)
4885 break;
4886 }
4887 if (try > count)
4888 try = count;
4889
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004890 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004891 if (conn->flags & CO_FL_ERROR) {
4892 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004893 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004894 }
Emeric Brun46591952012-05-18 15:47:34 +02004895 if (ret > 0) {
4896 buf->i += ret;
4897 done += ret;
Emeric Brun46591952012-05-18 15:47:34 +02004898 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004899 }
4900 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004901 ret = SSL_get_error(conn->xprt_ctx, ret);
4902 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004903 /* error on protocol or underlying transport */
4904 if ((ret != SSL_ERROR_SYSCALL)
4905 || (errno && (errno != EAGAIN)))
4906 conn->flags |= CO_FL_ERROR;
4907
Emeric Brun644cde02012-12-14 11:21:13 +01004908 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004909 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004910 ERR_clear_error();
4911 }
Emeric Brun46591952012-05-18 15:47:34 +02004912 goto read0;
4913 }
4914 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004915 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004916 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004917 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004918 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004919 __conn_sock_want_send(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00004920#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4921 /* Async mode can be re-enabled, because we're leaving data state.*/
4922 if (global_ssl.async)
4923 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4924#endif
Emeric Brun46591952012-05-18 15:47:34 +02004925 break;
4926 }
4927 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004928 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4929 /* handshake is running, and it may need to re-enable read */
4930 conn->flags |= CO_FL_SSL_WAIT_HS;
4931 __conn_sock_want_recv(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00004932#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4933 /* Async mode can be re-enabled, because we're leaving data state.*/
4934 if (global_ssl.async)
4935 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4936#endif
Emeric Brun282a76a2012-11-08 18:02:56 +01004937 break;
4938 }
Emeric Brun46591952012-05-18 15:47:34 +02004939 /* we need to poll for retry a read later */
Willy Tarreau585744b2017-08-24 14:31:19 +02004940 fd_cant_recv(conn->handle.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004941 break;
4942 }
4943 /* otherwise it's a real error */
4944 goto out_error;
4945 }
4946 }
4947 return done;
4948
4949 read0:
4950 conn_sock_read0(conn);
4951 return done;
4952 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004953 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004954 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004955 ERR_clear_error();
4956
Emeric Brun46591952012-05-18 15:47:34 +02004957 conn->flags |= CO_FL_ERROR;
4958 return done;
4959}
4960
4961
4962/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004963 * <flags> may contain some CO_SFL_* flags to hint the system about other
4964 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004965 * Only one call to send() is performed, unless the buffer wraps, in which case
4966 * a second call may be performed. The connection's flags are updated with
4967 * whatever special event is detected (error, empty). The caller is responsible
4968 * for taking care of those events and avoiding the call if inappropriate. The
4969 * function does not call the connection's polling update function, so the caller
4970 * is responsible for this.
4971 */
4972static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4973{
4974 int ret, try, done;
4975
4976 done = 0;
4977
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004978 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004979 goto out_error;
4980
4981 if (conn->flags & CO_FL_HANDSHAKE)
4982 /* a handshake was requested */
4983 return 0;
4984
4985 /* send the largest possible block. For this we perform only one call
4986 * to send() unless the buffer wraps and we exactly fill the first hunk,
4987 * in which case we accept to do it once again.
4988 */
4989 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004990 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004991
Willy Tarreau7bed9452014-02-02 02:00:24 +01004992 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004993 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004994 global_ssl.max_record && try > global_ssl.max_record) {
4995 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004996 }
4997 else {
4998 /* we need to keep the information about the fact that
4999 * we're not limiting the upcoming send(), because if it
5000 * fails, we'll have to retry with at least as many data.
5001 */
5002 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
5003 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01005004
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005005 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01005006
Emeric Brune1f38db2012-09-03 20:36:47 +02005007 if (conn->flags & CO_FL_ERROR) {
5008 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01005009 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02005010 }
Emeric Brun46591952012-05-18 15:47:34 +02005011 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01005012 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
5013
Emeric Brun46591952012-05-18 15:47:34 +02005014 buf->o -= ret;
5015 done += ret;
5016
Willy Tarreau5fb38032012-12-16 19:39:09 +01005017 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02005018 /* optimize data alignment in the buffer */
5019 buf->p = buf->data;
5020
5021 /* if the system buffer is full, don't insist */
5022 if (ret < try)
5023 break;
5024 }
5025 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005026 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005027
Emeric Brun46591952012-05-18 15:47:34 +02005028 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01005029 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
5030 /* handshake is running, and it may need to re-enable write */
5031 conn->flags |= CO_FL_SSL_WAIT_HS;
5032 __conn_sock_want_send(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00005033#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
5034 /* Async mode can be re-enabled, because we're leaving data state.*/
5035 if (global_ssl.async)
5036 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
5037#endif
Emeric Brun282a76a2012-11-08 18:02:56 +01005038 break;
5039 }
Emeric Brun46591952012-05-18 15:47:34 +02005040 /* we need to poll to retry a write later */
Willy Tarreau585744b2017-08-24 14:31:19 +02005041 fd_cant_send(conn->handle.fd);
Emeric Brun46591952012-05-18 15:47:34 +02005042 break;
5043 }
5044 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01005045 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02005046 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01005047 __conn_sock_want_recv(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005048#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brunb5e42a82017-06-06 12:35:14 +00005049 /* Async mode can be re-enabled, because we're leaving data state.*/
5050 if (global_ssl.async)
5051 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
5052#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005053 break;
5054 }
Emeric Brun46591952012-05-18 15:47:34 +02005055 goto out_error;
5056 }
5057 }
5058 return done;
5059
5060 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01005061 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005062 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005063 ERR_clear_error();
5064
Emeric Brun46591952012-05-18 15:47:34 +02005065 conn->flags |= CO_FL_ERROR;
5066 return done;
5067}
5068
Emeric Brun46591952012-05-18 15:47:34 +02005069static void ssl_sock_close(struct connection *conn) {
5070
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005071 if (conn->xprt_ctx) {
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005072#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brun3854e012017-05-17 20:42:48 +02005073 if (global_ssl.async) {
5074 OSSL_ASYNC_FD all_fd[32], afd;
5075 size_t num_all_fds = 0;
5076 int i;
5077
5078 SSL_get_all_async_fds(conn->xprt_ctx, NULL, &num_all_fds);
5079 if (num_all_fds > 32) {
5080 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
5081 return;
5082 }
5083
5084 SSL_get_all_async_fds(conn->xprt_ctx, all_fd, &num_all_fds);
5085
5086 /* If an async job is pending, we must try to
5087 to catch the end using polling before calling
5088 SSL_free */
5089 if (num_all_fds && SSL_waiting_for_async(conn->xprt_ctx)) {
5090 for (i=0 ; i < num_all_fds ; i++) {
5091 /* switch on an handler designed to
5092 * handle the SSL_free
5093 */
5094 afd = all_fd[i];
5095 fdtab[afd].iocb = ssl_async_fd_free;
5096 fdtab[afd].owner = conn->xprt_ctx;
5097 fd_want_recv(afd);
Emeric Brunce9e01c2017-05-31 10:02:53 +00005098 /* To ensure that the fd cache won't be used
5099 * and we'll catch a real RD event.
5100 */
5101 fd_cant_recv(afd);
Emeric Brun3854e012017-05-17 20:42:48 +02005102 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005103 conn->xprt_ctx = NULL;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005104 jobs++;
5105 return;
5106 }
Emeric Brun3854e012017-05-17 20:42:48 +02005107 /* Else we can remove the fds from the fdtab
5108 * and call SSL_free.
5109 * note: we do a fd_remove and not a delete
5110 * because the fd is owned by the engine.
5111 * the engine is responsible to close
5112 */
5113 for (i=0 ; i < num_all_fds ; i++)
5114 fd_remove(all_fd[i]);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005115 }
5116#endif
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005117 SSL_free(conn->xprt_ctx);
5118 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02005119 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02005120 }
Emeric Brun46591952012-05-18 15:47:34 +02005121}
5122
5123/* This function tries to perform a clean shutdown on an SSL connection, and in
5124 * any case, flags the connection as reusable if no handshake was in progress.
5125 */
5126static void ssl_sock_shutw(struct connection *conn, int clean)
5127{
5128 if (conn->flags & CO_FL_HANDSHAKE)
5129 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005130 if (!clean)
5131 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01005132 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02005133 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005134 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01005135 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005136 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005137 ERR_clear_error();
5138 }
Emeric Brun46591952012-05-18 15:47:34 +02005139}
5140
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02005141/* used for logging, may be changed for a sample fetch later */
5142const char *ssl_sock_get_cipher_name(struct connection *conn)
5143{
5144 if (!conn->xprt && !conn->xprt_ctx)
5145 return NULL;
5146 return SSL_get_cipher_name(conn->xprt_ctx);
5147}
5148
5149/* used for logging, may be changed for a sample fetch later */
5150const char *ssl_sock_get_proto_version(struct connection *conn)
5151{
5152 if (!conn->xprt && !conn->xprt_ctx)
5153 return NULL;
5154 return SSL_get_version(conn->xprt_ctx);
5155}
5156
Willy Tarreau8d598402012-10-22 17:58:39 +02005157/* Extract a serial from a cert, and copy it to a chunk.
5158 * Returns 1 if serial is found and copied, 0 if no serial found and
5159 * -1 if output is not large enough.
5160 */
5161static int
5162ssl_sock_get_serial(X509 *crt, struct chunk *out)
5163{
5164 ASN1_INTEGER *serial;
5165
5166 serial = X509_get_serialNumber(crt);
5167 if (!serial)
5168 return 0;
5169
5170 if (out->size < serial->length)
5171 return -1;
5172
5173 memcpy(out->str, serial->data, serial->length);
5174 out->len = serial->length;
5175 return 1;
5176}
5177
Emeric Brun43e79582014-10-29 19:03:26 +01005178/* Extract a cert to der, and copy it to a chunk.
5179 * Returns 1 if cert is found and copied, 0 on der convertion failure and
5180 * -1 if output is not large enough.
5181 */
5182static int
5183ssl_sock_crt2der(X509 *crt, struct chunk *out)
5184{
5185 int len;
5186 unsigned char *p = (unsigned char *)out->str;;
5187
5188 len =i2d_X509(crt, NULL);
5189 if (len <= 0)
5190 return 1;
5191
5192 if (out->size < len)
5193 return -1;
5194
5195 i2d_X509(crt,&p);
5196 out->len = len;
5197 return 1;
5198}
5199
Emeric Brunce5ad802012-10-22 14:11:22 +02005200
5201/* Copy Date in ASN1_UTCTIME format in struct chunk out.
5202 * Returns 1 if serial is found and copied, 0 if no valid time found
5203 * and -1 if output is not large enough.
5204 */
5205static int
5206ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
5207{
5208 if (tm->type == V_ASN1_GENERALIZEDTIME) {
5209 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
5210
5211 if (gentm->length < 12)
5212 return 0;
5213 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
5214 return 0;
5215 if (out->size < gentm->length-2)
5216 return -1;
5217
5218 memcpy(out->str, gentm->data+2, gentm->length-2);
5219 out->len = gentm->length-2;
5220 return 1;
5221 }
5222 else if (tm->type == V_ASN1_UTCTIME) {
5223 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
5224
5225 if (utctm->length < 10)
5226 return 0;
5227 if (utctm->data[0] >= 0x35)
5228 return 0;
5229 if (out->size < utctm->length)
5230 return -1;
5231
5232 memcpy(out->str, utctm->data, utctm->length);
5233 out->len = utctm->length;
5234 return 1;
5235 }
5236
5237 return 0;
5238}
5239
Emeric Brun87855892012-10-17 17:39:35 +02005240/* Extract an entry from a X509_NAME and copy its value to an output chunk.
5241 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
5242 */
5243static int
5244ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
5245{
5246 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005247 ASN1_OBJECT *obj;
5248 ASN1_STRING *data;
5249 const unsigned char *data_ptr;
5250 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005251 int i, j, n;
5252 int cur = 0;
5253 const char *s;
5254 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005255 int name_count;
5256
5257 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005258
5259 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005260 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02005261 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005262 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02005263 else
5264 j = i;
5265
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005266 ne = X509_NAME_get_entry(a, j);
5267 obj = X509_NAME_ENTRY_get_object(ne);
5268 data = X509_NAME_ENTRY_get_data(ne);
5269 data_ptr = ASN1_STRING_get0_data(data);
5270 data_len = ASN1_STRING_length(data);
5271 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005272 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005273 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005274 s = tmp;
5275 }
5276
5277 if (chunk_strcasecmp(entry, s) != 0)
5278 continue;
5279
5280 if (pos < 0)
5281 cur--;
5282 else
5283 cur++;
5284
5285 if (cur != pos)
5286 continue;
5287
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005288 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02005289 return -1;
5290
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005291 memcpy(out->str, data_ptr, data_len);
5292 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005293 return 1;
5294 }
5295
5296 return 0;
5297
5298}
5299
5300/* Extract and format full DN from a X509_NAME and copy result into a chunk
5301 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
5302 */
5303static int
5304ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
5305{
5306 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005307 ASN1_OBJECT *obj;
5308 ASN1_STRING *data;
5309 const unsigned char *data_ptr;
5310 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005311 int i, n, ln;
5312 int l = 0;
5313 const char *s;
5314 char *p;
5315 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005316 int name_count;
5317
5318
5319 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005320
5321 out->len = 0;
5322 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005323 for (i = 0; i < name_count; i++) {
5324 ne = X509_NAME_get_entry(a, i);
5325 obj = X509_NAME_ENTRY_get_object(ne);
5326 data = X509_NAME_ENTRY_get_data(ne);
5327 data_ptr = ASN1_STRING_get0_data(data);
5328 data_len = ASN1_STRING_length(data);
5329 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005330 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005331 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005332 s = tmp;
5333 }
5334 ln = strlen(s);
5335
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005336 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005337 if (l > out->size)
5338 return -1;
5339 out->len = l;
5340
5341 *(p++)='/';
5342 memcpy(p, s, ln);
5343 p += ln;
5344 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005345 memcpy(p, data_ptr, data_len);
5346 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005347 }
5348
5349 if (!out->len)
5350 return 0;
5351
5352 return 1;
5353}
5354
David Safb76832014-05-08 23:42:08 -04005355char *ssl_sock_get_version(struct connection *conn)
5356{
5357 if (!ssl_sock_is_ssl(conn))
5358 return NULL;
5359
5360 return (char *)SSL_get_version(conn->xprt_ctx);
5361}
5362
Willy Tarreau119a4082016-12-22 21:58:38 +01005363/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
5364 * to disable SNI.
5365 */
Willy Tarreau63076412015-07-10 11:33:32 +02005366void ssl_sock_set_servername(struct connection *conn, const char *hostname)
5367{
5368#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01005369 char *prev_name;
5370
Willy Tarreau63076412015-07-10 11:33:32 +02005371 if (!ssl_sock_is_ssl(conn))
5372 return;
5373
Willy Tarreau119a4082016-12-22 21:58:38 +01005374 /* if the SNI changes, we must destroy the reusable context so that a
5375 * new connection will present a new SNI. As an optimization we could
5376 * later imagine having a small cache of ssl_ctx to hold a few SNI per
5377 * server.
5378 */
5379 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5380 if ((!prev_name && hostname) ||
5381 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
5382 SSL_set_session(conn->xprt_ctx, NULL);
5383
Willy Tarreau63076412015-07-10 11:33:32 +02005384 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
5385#endif
5386}
5387
Emeric Brun0abf8362014-06-24 18:26:41 +02005388/* Extract peer certificate's common name into the chunk dest
5389 * Returns
5390 * the len of the extracted common name
5391 * or 0 if no CN found in DN
5392 * or -1 on error case (i.e. no peer certificate)
5393 */
5394int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04005395{
5396 X509 *crt = NULL;
5397 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04005398 const char find_cn[] = "CN";
5399 const struct chunk find_cn_chunk = {
5400 .str = (char *)&find_cn,
5401 .len = sizeof(find_cn)-1
5402 };
Emeric Brun0abf8362014-06-24 18:26:41 +02005403 int result = -1;
David Safb76832014-05-08 23:42:08 -04005404
5405 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02005406 goto out;
David Safb76832014-05-08 23:42:08 -04005407
5408 /* SSL_get_peer_certificate, it increase X509 * ref count */
5409 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5410 if (!crt)
5411 goto out;
5412
5413 name = X509_get_subject_name(crt);
5414 if (!name)
5415 goto out;
David Safb76832014-05-08 23:42:08 -04005416
Emeric Brun0abf8362014-06-24 18:26:41 +02005417 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
5418out:
David Safb76832014-05-08 23:42:08 -04005419 if (crt)
5420 X509_free(crt);
5421
5422 return result;
5423}
5424
Dave McCowan328fb582014-07-30 10:39:13 -04005425/* returns 1 if client passed a certificate for this session, 0 if not */
5426int ssl_sock_get_cert_used_sess(struct connection *conn)
5427{
5428 X509 *crt = NULL;
5429
5430 if (!ssl_sock_is_ssl(conn))
5431 return 0;
5432
5433 /* SSL_get_peer_certificate, it increase X509 * ref count */
5434 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5435 if (!crt)
5436 return 0;
5437
5438 X509_free(crt);
5439 return 1;
5440}
5441
5442/* returns 1 if client passed a certificate for this connection, 0 if not */
5443int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04005444{
5445 if (!ssl_sock_is_ssl(conn))
5446 return 0;
5447
5448 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
5449}
5450
5451/* returns result from SSL verify */
5452unsigned int ssl_sock_get_verify_result(struct connection *conn)
5453{
5454 if (!ssl_sock_is_ssl(conn))
5455 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
5456
5457 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
5458}
5459
Willy Tarreau8743f7e2016-12-04 18:44:29 +01005460/* Returns the application layer protocol name in <str> and <len> when known.
5461 * Zero is returned if the protocol name was not found, otherwise non-zero is
5462 * returned. The string is allocated in the SSL context and doesn't have to be
5463 * freed by the caller. NPN is also checked if available since older versions
5464 * of openssl (1.0.1) which are more common in field only support this one.
5465 */
5466static int ssl_sock_get_alpn(const struct connection *conn, const char **str, int *len)
5467{
5468 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5469 return 0;
5470
5471 *str = NULL;
5472
5473#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
5474 SSL_get0_alpn_selected(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
5475 if (*str)
5476 return 1;
5477#endif
5478#ifdef OPENSSL_NPN_NEGOTIATED
5479 SSL_get0_next_proto_negotiated(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
5480 if (*str)
5481 return 1;
5482#endif
5483 return 0;
5484}
5485
Willy Tarreau7875d092012-09-10 08:20:03 +02005486/***** Below are some sample fetching functions for ACL/patterns *****/
5487
Emeric Brune64aef12012-09-21 13:15:06 +02005488/* boolean, returns true if client cert was present */
5489static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005490smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02005491{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005492 struct connection *conn;
5493
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005494 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005495 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02005496 return 0;
5497
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005498 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02005499 smp->flags |= SMP_F_MAY_CHANGE;
5500 return 0;
5501 }
5502
5503 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005504 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005505 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02005506
5507 return 1;
5508}
5509
Emeric Brun43e79582014-10-29 19:03:26 +01005510/* binary, returns a certificate in a binary chunk (der/raw).
5511 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5512 * should be use.
5513 */
5514static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005515smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01005516{
5517 int cert_peer = (kw[4] == 'c') ? 1 : 0;
5518 X509 *crt = NULL;
5519 int ret = 0;
5520 struct chunk *smp_trash;
5521 struct connection *conn;
5522
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005523 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01005524 if (!conn || conn->xprt != &ssl_sock)
5525 return 0;
5526
5527 if (!(conn->flags & CO_FL_CONNECTED)) {
5528 smp->flags |= SMP_F_MAY_CHANGE;
5529 return 0;
5530 }
5531
5532 if (cert_peer)
5533 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5534 else
5535 crt = SSL_get_certificate(conn->xprt_ctx);
5536
5537 if (!crt)
5538 goto out;
5539
5540 smp_trash = get_trash_chunk();
5541 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
5542 goto out;
5543
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005544 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005545 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01005546 ret = 1;
5547out:
5548 /* SSL_get_peer_certificate, it increase X509 * ref count */
5549 if (cert_peer && crt)
5550 X509_free(crt);
5551 return ret;
5552}
5553
Emeric Brunba841a12014-04-30 17:05:08 +02005554/* binary, returns serial of certificate in a binary chunk.
5555 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5556 * should be use.
5557 */
Willy Tarreau8d598402012-10-22 17:58:39 +02005558static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005559smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02005560{
Emeric Brunba841a12014-04-30 17:05:08 +02005561 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02005562 X509 *crt = NULL;
5563 int ret = 0;
5564 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005565 struct connection *conn;
5566
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005567 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005568 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02005569 return 0;
5570
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005571 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02005572 smp->flags |= SMP_F_MAY_CHANGE;
5573 return 0;
5574 }
5575
Emeric Brunba841a12014-04-30 17:05:08 +02005576 if (cert_peer)
5577 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5578 else
5579 crt = SSL_get_certificate(conn->xprt_ctx);
5580
Willy Tarreau8d598402012-10-22 17:58:39 +02005581 if (!crt)
5582 goto out;
5583
Willy Tarreau47ca5452012-12-23 20:22:19 +01005584 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005585 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5586 goto out;
5587
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005588 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005589 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005590 ret = 1;
5591out:
Emeric Brunba841a12014-04-30 17:05:08 +02005592 /* SSL_get_peer_certificate, it increase X509 * ref count */
5593 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005594 X509_free(crt);
5595 return ret;
5596}
Emeric Brune64aef12012-09-21 13:15:06 +02005597
Emeric Brunba841a12014-04-30 17:05:08 +02005598/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5599 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5600 * should be use.
5601 */
James Votha051b4a2013-05-14 20:37:59 +02005602static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005603smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005604{
Emeric Brunba841a12014-04-30 17:05:08 +02005605 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005606 X509 *crt = NULL;
5607 const EVP_MD *digest;
5608 int ret = 0;
5609 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005610 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005611
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005612 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005613 if (!conn || conn->xprt != &ssl_sock)
5614 return 0;
5615
5616 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005617 smp->flags |= SMP_F_MAY_CHANGE;
5618 return 0;
5619 }
5620
Emeric Brunba841a12014-04-30 17:05:08 +02005621 if (cert_peer)
5622 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5623 else
5624 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005625 if (!crt)
5626 goto out;
5627
5628 smp_trash = get_trash_chunk();
5629 digest = EVP_sha1();
5630 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5631
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005632 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005633 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005634 ret = 1;
5635out:
Emeric Brunba841a12014-04-30 17:05:08 +02005636 /* SSL_get_peer_certificate, it increase X509 * ref count */
5637 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005638 X509_free(crt);
5639 return ret;
5640}
5641
Emeric Brunba841a12014-04-30 17:05:08 +02005642/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5643 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5644 * should be use.
5645 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005646static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005647smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005648{
Emeric Brunba841a12014-04-30 17:05:08 +02005649 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005650 X509 *crt = NULL;
5651 int ret = 0;
5652 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005653 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005654
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005655 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005656 if (!conn || conn->xprt != &ssl_sock)
5657 return 0;
5658
5659 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005660 smp->flags |= SMP_F_MAY_CHANGE;
5661 return 0;
5662 }
5663
Emeric Brunba841a12014-04-30 17:05:08 +02005664 if (cert_peer)
5665 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5666 else
5667 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005668 if (!crt)
5669 goto out;
5670
Willy Tarreau47ca5452012-12-23 20:22:19 +01005671 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005672 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5673 goto out;
5674
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005675 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005676 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005677 ret = 1;
5678out:
Emeric Brunba841a12014-04-30 17:05:08 +02005679 /* SSL_get_peer_certificate, it increase X509 * ref count */
5680 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005681 X509_free(crt);
5682 return ret;
5683}
5684
Emeric Brunba841a12014-04-30 17:05:08 +02005685/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5686 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5687 * should be use.
5688 */
Emeric Brun87855892012-10-17 17:39:35 +02005689static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005690smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005691{
Emeric Brunba841a12014-04-30 17:05:08 +02005692 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005693 X509 *crt = NULL;
5694 X509_NAME *name;
5695 int ret = 0;
5696 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005697 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005698
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005699 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005700 if (!conn || conn->xprt != &ssl_sock)
5701 return 0;
5702
5703 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005704 smp->flags |= SMP_F_MAY_CHANGE;
5705 return 0;
5706 }
5707
Emeric Brunba841a12014-04-30 17:05:08 +02005708 if (cert_peer)
5709 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5710 else
5711 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005712 if (!crt)
5713 goto out;
5714
5715 name = X509_get_issuer_name(crt);
5716 if (!name)
5717 goto out;
5718
Willy Tarreau47ca5452012-12-23 20:22:19 +01005719 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005720 if (args && args[0].type == ARGT_STR) {
5721 int pos = 1;
5722
5723 if (args[1].type == ARGT_SINT)
5724 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005725
5726 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5727 goto out;
5728 }
5729 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5730 goto out;
5731
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005732 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005733 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005734 ret = 1;
5735out:
Emeric Brunba841a12014-04-30 17:05:08 +02005736 /* SSL_get_peer_certificate, it increase X509 * ref count */
5737 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005738 X509_free(crt);
5739 return ret;
5740}
5741
Emeric Brunba841a12014-04-30 17:05:08 +02005742/* string, returns notbefore date in ASN1_UTCTIME format.
5743 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5744 * should be use.
5745 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005746static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005747smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005748{
Emeric Brunba841a12014-04-30 17:05:08 +02005749 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005750 X509 *crt = NULL;
5751 int ret = 0;
5752 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005753 struct connection *conn;
5754
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005755 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005756 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005757 return 0;
5758
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005759 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005760 smp->flags |= SMP_F_MAY_CHANGE;
5761 return 0;
5762 }
5763
Emeric Brunba841a12014-04-30 17:05:08 +02005764 if (cert_peer)
5765 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5766 else
5767 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005768 if (!crt)
5769 goto out;
5770
Willy Tarreau47ca5452012-12-23 20:22:19 +01005771 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005772 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5773 goto out;
5774
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005775 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005776 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005777 ret = 1;
5778out:
Emeric Brunba841a12014-04-30 17:05:08 +02005779 /* SSL_get_peer_certificate, it increase X509 * ref count */
5780 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005781 X509_free(crt);
5782 return ret;
5783}
5784
Emeric Brunba841a12014-04-30 17:05:08 +02005785/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5786 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5787 * should be use.
5788 */
Emeric Brun87855892012-10-17 17:39:35 +02005789static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005790smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005791{
Emeric Brunba841a12014-04-30 17:05:08 +02005792 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005793 X509 *crt = NULL;
5794 X509_NAME *name;
5795 int ret = 0;
5796 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005797 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005798
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005799 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005800 if (!conn || conn->xprt != &ssl_sock)
5801 return 0;
5802
5803 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005804 smp->flags |= SMP_F_MAY_CHANGE;
5805 return 0;
5806 }
5807
Emeric Brunba841a12014-04-30 17:05:08 +02005808 if (cert_peer)
5809 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5810 else
5811 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005812 if (!crt)
5813 goto out;
5814
5815 name = X509_get_subject_name(crt);
5816 if (!name)
5817 goto out;
5818
Willy Tarreau47ca5452012-12-23 20:22:19 +01005819 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005820 if (args && args[0].type == ARGT_STR) {
5821 int pos = 1;
5822
5823 if (args[1].type == ARGT_SINT)
5824 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005825
5826 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5827 goto out;
5828 }
5829 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5830 goto out;
5831
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005832 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005833 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005834 ret = 1;
5835out:
Emeric Brunba841a12014-04-30 17:05:08 +02005836 /* SSL_get_peer_certificate, it increase X509 * ref count */
5837 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005838 X509_free(crt);
5839 return ret;
5840}
Emeric Brun9143d372012-12-20 15:44:16 +01005841
5842/* integer, returns true if current session use a client certificate */
5843static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005844smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005845{
5846 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005847 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005848
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005849 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005850 if (!conn || conn->xprt != &ssl_sock)
5851 return 0;
5852
5853 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005854 smp->flags |= SMP_F_MAY_CHANGE;
5855 return 0;
5856 }
5857
5858 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005859 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005860 if (crt) {
5861 X509_free(crt);
5862 }
5863
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005864 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005865 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005866 return 1;
5867}
5868
Emeric Brunba841a12014-04-30 17:05:08 +02005869/* integer, returns the certificate version
5870 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5871 * should be use.
5872 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005873static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005874smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005875{
Emeric Brunba841a12014-04-30 17:05:08 +02005876 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005877 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005878 struct connection *conn;
5879
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005880 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005881 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005882 return 0;
5883
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005884 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005885 smp->flags |= SMP_F_MAY_CHANGE;
5886 return 0;
5887 }
5888
Emeric Brunba841a12014-04-30 17:05:08 +02005889 if (cert_peer)
5890 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5891 else
5892 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005893 if (!crt)
5894 return 0;
5895
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005896 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005897 /* SSL_get_peer_certificate increase X509 * ref count */
5898 if (cert_peer)
5899 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005900 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005901
5902 return 1;
5903}
5904
Emeric Brunba841a12014-04-30 17:05:08 +02005905/* string, returns the certificate's signature algorithm.
5906 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5907 * should be use.
5908 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005909static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005910smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005911{
Emeric Brunba841a12014-04-30 17:05:08 +02005912 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005913 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005914 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005915 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005916 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005917
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005918 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005919 if (!conn || conn->xprt != &ssl_sock)
5920 return 0;
5921
5922 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005923 smp->flags |= SMP_F_MAY_CHANGE;
5924 return 0;
5925 }
5926
Emeric Brunba841a12014-04-30 17:05:08 +02005927 if (cert_peer)
5928 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5929 else
5930 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005931 if (!crt)
5932 return 0;
5933
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005934 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5935 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005936
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005937 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5938 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005939 /* SSL_get_peer_certificate increase X509 * ref count */
5940 if (cert_peer)
5941 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005942 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005943 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005944
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005945 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005946 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005947 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005948 /* SSL_get_peer_certificate increase X509 * ref count */
5949 if (cert_peer)
5950 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005951
5952 return 1;
5953}
5954
Emeric Brunba841a12014-04-30 17:05:08 +02005955/* string, returns the certificate's key algorithm.
5956 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5957 * should be use.
5958 */
Emeric Brun521a0112012-10-22 12:22:55 +02005959static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005960smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005961{
Emeric Brunba841a12014-04-30 17:05:08 +02005962 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005963 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005964 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005965 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005966 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005967
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005968 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005969 if (!conn || conn->xprt != &ssl_sock)
5970 return 0;
5971
5972 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005973 smp->flags |= SMP_F_MAY_CHANGE;
5974 return 0;
5975 }
5976
Emeric Brunba841a12014-04-30 17:05:08 +02005977 if (cert_peer)
5978 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5979 else
5980 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005981 if (!crt)
5982 return 0;
5983
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005984 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5985 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005986
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005987 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5988 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005989 /* SSL_get_peer_certificate increase X509 * ref count */
5990 if (cert_peer)
5991 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005992 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005993 }
Emeric Brun521a0112012-10-22 12:22:55 +02005994
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005995 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005996 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005997 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005998 if (cert_peer)
5999 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02006000
6001 return 1;
6002}
6003
Emeric Brun645ae792014-04-30 14:21:06 +02006004/* boolean, returns true if front conn. transport layer is SSL.
6005 * This function is also usable on backend conn if the fetch keyword 5th
6006 * char is 'b'.
6007 */
Willy Tarreau7875d092012-09-10 08:20:03 +02006008static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006009smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006010{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006011 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6012 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006013
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006014 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006015 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02006016 return 1;
6017}
6018
Emeric Brun2525b6b2012-10-18 15:59:43 +02006019/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02006020static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006021smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006022{
6023#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006024 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006025
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006026 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006027 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006028 conn->xprt_ctx &&
6029 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02006030 return 1;
6031#else
6032 return 0;
6033#endif
6034}
6035
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02006036/* boolean, returns true if client session has been resumed */
6037static int
6038smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
6039{
6040 struct connection *conn = objt_conn(smp->sess->origin);
6041
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006042 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006043 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02006044 conn->xprt_ctx &&
6045 SSL_session_reused(conn->xprt_ctx);
6046 return 1;
6047}
6048
Emeric Brun645ae792014-04-30 14:21:06 +02006049/* string, returns the used cipher if front conn. transport layer is SSL.
6050 * This function is also usable on backend conn if the fetch keyword 5th
6051 * char is 'b'.
6052 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006053static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006054smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006055{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006056 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6057 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02006058
Willy Tarreaube508f12016-03-10 11:47:01 +01006059 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006060 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02006061 return 0;
6062
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006063 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
6064 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006065 return 0;
6066
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006067 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006068 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006069 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006070
6071 return 1;
6072}
6073
Emeric Brun645ae792014-04-30 14:21:06 +02006074/* integer, returns the algoritm's keysize if front conn. transport layer
6075 * is SSL.
6076 * This function is also usable on backend conn if the fetch keyword 5th
6077 * char is 'b'.
6078 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006079static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006080smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006081{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006082 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6083 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006084
Willy Tarreaue237fe12016-03-10 17:05:28 +01006085 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01006086
Emeric Brun589fcad2012-10-16 14:13:26 +02006087 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006088 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02006089 return 0;
6090
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006091 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006092 return 0;
6093
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006094 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006095 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02006096
6097 return 1;
6098}
6099
Emeric Brun645ae792014-04-30 14:21:06 +02006100/* integer, returns the used keysize if front conn. transport layer is SSL.
6101 * This function is also usable on backend conn if the fetch keyword 5th
6102 * char is 'b'.
6103 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006104static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006105smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006106{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006107 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6108 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006109
Emeric Brun589fcad2012-10-16 14:13:26 +02006110 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006111 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6112 return 0;
6113
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006114 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
6115 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02006116 return 0;
6117
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006118 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02006119
6120 return 1;
6121}
6122
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006123#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02006124static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006125smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02006126{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006127 struct connection *conn;
6128
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006129 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006130 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02006131
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006132 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006133 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6134 return 0;
6135
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006136 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006137 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006138 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02006139
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006140 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02006141 return 0;
6142
6143 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02006144}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006145#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02006146
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006147#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006148static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006149smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02006150{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006151 struct connection *conn;
6152
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006153 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006154 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02006155
Willy Tarreaue26bf052015-05-12 10:30:12 +02006156 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006157 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02006158 return 0;
6159
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006160 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006161 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006162 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02006163
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006164 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02006165 return 0;
6166
6167 return 1;
6168}
6169#endif
6170
Emeric Brun645ae792014-04-30 14:21:06 +02006171/* string, returns the used protocol if front conn. transport layer is SSL.
6172 * This function is also usable on backend conn if the fetch keyword 5th
6173 * char is 'b'.
6174 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02006175static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006176smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006177{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006178 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6179 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006180
Emeric Brun589fcad2012-10-16 14:13:26 +02006181 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006182 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6183 return 0;
6184
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006185 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
6186 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006187 return 0;
6188
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006189 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006190 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006191 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006192
6193 return 1;
6194}
6195
Willy Tarreau87b09662015-04-03 00:22:06 +02006196/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02006197 * This function is also usable on backend conn if the fetch keyword 5th
6198 * char is 'b'.
6199 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006200static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006201smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02006202{
6203#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006204 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6205 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02006206
Willy Tarreaue237fe12016-03-10 17:05:28 +01006207 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01006208
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006209 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006210 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02006211
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006212 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6213 return 0;
6214
Willy Tarreau192252e2015-04-04 01:47:55 +02006215 ssl_sess = SSL_get_session(conn->xprt_ctx);
6216 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02006217 return 0;
6218
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006219 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
6220 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02006221 return 0;
6222
6223 return 1;
6224#else
6225 return 0;
6226#endif
6227}
6228
6229static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006230smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006231{
6232#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006233 struct connection *conn;
6234
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006235 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006236 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02006237
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006238 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006239 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6240 return 0;
6241
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006242 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
6243 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02006244 return 0;
6245
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006246 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02006247 return 1;
6248#else
6249 return 0;
6250#endif
6251}
6252
David Sc1ad52e2014-04-08 18:48:47 -04006253static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006254smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
6255{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006256 struct connection *conn;
6257 struct ssl_capture *capture;
6258
6259 conn = objt_conn(smp->sess->origin);
6260 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6261 return 0;
6262
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006263 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006264 if (!capture)
6265 return 0;
6266
6267 smp->flags = SMP_F_CONST;
6268 smp->data.type = SMP_T_BIN;
6269 smp->data.u.str.str = capture->ciphersuite;
6270 smp->data.u.str.len = capture->ciphersuite_len;
6271 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006272}
6273
6274static int
6275smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
6276{
6277 struct chunk *data;
6278
6279 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6280 return 0;
6281
6282 data = get_trash_chunk();
6283 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
6284 smp->data.type = SMP_T_BIN;
6285 smp->data.u.str = *data;
6286 return 1;
6287}
6288
6289static int
6290smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
6291{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006292 struct connection *conn;
6293 struct ssl_capture *capture;
6294
6295 conn = objt_conn(smp->sess->origin);
6296 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6297 return 0;
6298
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006299 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006300 if (!capture)
6301 return 0;
6302
6303 smp->data.type = SMP_T_SINT;
6304 smp->data.u.sint = capture->xxh64;
6305 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006306}
6307
6308static int
6309smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
6310{
Emmanuel Hocdetddcde192017-09-01 17:32:08 +02006311#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(LIBRESSL_VERSION_NUMBER)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006312 struct chunk *data;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006313 int i;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006314
6315 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6316 return 0;
6317
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006318 data = get_trash_chunk();
6319 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
Emmanuel Hocdetddcde192017-09-01 17:32:08 +02006320 const char *str;
6321 const SSL_CIPHER *cipher;
6322 const unsigned char *bin = (const unsigned char *)smp->data.u.str.str + i;
6323 uint16_t id = (bin[0] << 8) | bin[1];
6324#if defined(OPENSSL_IS_BORINGSSL)
6325 cipher = SSL_get_cipher_by_value(id);
6326#else
6327 struct connection *conn = objt_conn(smp->sess->origin);
6328 cipher = SSL_CIPHER_find(conn->xprt_ctx, bin);
6329#endif
6330 str = SSL_CIPHER_get_name(cipher);
6331 if (!str || strcmp(str, "(NONE)") == 0)
6332 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", id);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006333 else
6334 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
6335 }
6336 smp->data.type = SMP_T_STR;
6337 smp->data.u.str = *data;
6338 return 1;
6339#else
6340 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
6341#endif
6342}
6343
6344static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006345smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04006346{
6347#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006348 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6349 smp->strm ? smp->strm->si[1].end : NULL);
6350
David Sc1ad52e2014-04-08 18:48:47 -04006351 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04006352 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04006353
6354 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04006355 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6356 return 0;
6357
6358 if (!(conn->flags & CO_FL_CONNECTED)) {
6359 smp->flags |= SMP_F_MAY_CHANGE;
6360 return 0;
6361 }
6362
6363 finished_trash = get_trash_chunk();
6364 if (!SSL_session_reused(conn->xprt_ctx))
6365 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6366 else
6367 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6368
6369 if (!finished_len)
6370 return 0;
6371
Emeric Brunb73a9b02014-04-30 18:49:19 +02006372 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006373 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006374 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04006375
6376 return 1;
6377#else
6378 return 0;
6379#endif
6380}
6381
Emeric Brun2525b6b2012-10-18 15:59:43 +02006382/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006383static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006384smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006385{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006386 struct connection *conn;
6387
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006388 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006389 if (!conn || conn->xprt != &ssl_sock)
6390 return 0;
6391
6392 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006393 smp->flags = SMP_F_MAY_CHANGE;
6394 return 0;
6395 }
6396
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006397 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006398 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006399 smp->flags = 0;
6400
6401 return 1;
6402}
6403
Emeric Brun2525b6b2012-10-18 15:59:43 +02006404/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006405static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006406smp_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 +02006407{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006408 struct connection *conn;
6409
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006410 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006411 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02006412 return 0;
6413
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006414 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006415 smp->flags = SMP_F_MAY_CHANGE;
6416 return 0;
6417 }
6418
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006419 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006420 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006421 smp->flags = 0;
6422
6423 return 1;
6424}
6425
Emeric Brun2525b6b2012-10-18 15:59:43 +02006426/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02006427static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006428smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006429{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006430 struct connection *conn;
6431
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006432 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006433 if (!conn || conn->xprt != &ssl_sock)
6434 return 0;
6435
6436 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006437 smp->flags = SMP_F_MAY_CHANGE;
6438 return 0;
6439 }
6440
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006441 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006442 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006443 smp->flags = 0;
6444
6445 return 1;
6446}
6447
Emeric Brun2525b6b2012-10-18 15:59:43 +02006448/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006449static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006450smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006451{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006452 struct connection *conn;
6453
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006454 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006455 if (!conn || conn->xprt != &ssl_sock)
6456 return 0;
6457
6458 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006459 smp->flags = SMP_F_MAY_CHANGE;
6460 return 0;
6461 }
6462
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006463 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006464 return 0;
6465
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006466 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006467 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006468 smp->flags = 0;
6469
6470 return 1;
6471}
6472
Emeric Brunfb510ea2012-10-05 12:00:26 +02006473/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006474static 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 +02006475{
6476 if (!*args[cur_arg + 1]) {
6477 if (err)
6478 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6479 return ERR_ALERT | ERR_FATAL;
6480 }
6481
Willy Tarreauef934602016-12-22 23:12:01 +01006482 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6483 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006484 else
6485 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006486
Emeric Brund94b3fe2012-09-20 18:23:56 +02006487 return 0;
6488}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006489static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6490{
6491 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
6492}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006493
Christopher Faulet31af49d2015-06-09 17:29:50 +02006494/* parse the "ca-sign-file" bind keyword */
6495static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6496{
6497 if (!*args[cur_arg + 1]) {
6498 if (err)
6499 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6500 return ERR_ALERT | ERR_FATAL;
6501 }
6502
Willy Tarreauef934602016-12-22 23:12:01 +01006503 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6504 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02006505 else
6506 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
6507
6508 return 0;
6509}
6510
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006511/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006512static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6513{
6514 if (!*args[cur_arg + 1]) {
6515 if (err)
6516 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
6517 return ERR_ALERT | ERR_FATAL;
6518 }
6519 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
6520 return 0;
6521}
6522
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006523/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006524static 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 +02006525{
6526 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006527 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006528 return ERR_ALERT | ERR_FATAL;
6529 }
6530
Emeric Brun76d88952012-10-05 15:47:31 +02006531 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02006532 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006533 return 0;
6534}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006535static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6536{
6537 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
6538}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006539/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006540static 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 +02006541{
Willy Tarreau38011032013-08-13 16:59:39 +02006542 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02006543
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006544 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006545 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006546 return ERR_ALERT | ERR_FATAL;
6547 }
6548
Willy Tarreauef934602016-12-22 23:12:01 +01006549 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
6550 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02006551 memprintf(err, "'%s' : path too long", args[cur_arg]);
6552 return ERR_ALERT | ERR_FATAL;
6553 }
Willy Tarreauef934602016-12-22 23:12:01 +01006554 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01006555 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02006556 return ERR_ALERT | ERR_FATAL;
6557
6558 return 0;
6559 }
6560
Willy Tarreau03209342016-12-22 17:08:28 +01006561 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006562 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006563
6564 return 0;
6565}
6566
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006567/* parse the "crt-list" bind keyword */
6568static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6569{
6570 if (!*args[cur_arg + 1]) {
6571 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
6572 return ERR_ALERT | ERR_FATAL;
6573 }
6574
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006575 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006576 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006577 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006578 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006579
6580 return 0;
6581}
6582
Emeric Brunfb510ea2012-10-05 12:00:26 +02006583/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006584static 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 +02006585{
Emeric Brun051cdab2012-10-02 19:25:50 +02006586#ifndef X509_V_FLAG_CRL_CHECK
6587 if (err)
6588 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6589 return ERR_ALERT | ERR_FATAL;
6590#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006591 if (!*args[cur_arg + 1]) {
6592 if (err)
6593 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6594 return ERR_ALERT | ERR_FATAL;
6595 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006596
Willy Tarreauef934602016-12-22 23:12:01 +01006597 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6598 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006599 else
6600 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006601
Emeric Brun2b58d042012-09-20 17:10:03 +02006602 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006603#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006604}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006605static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6606{
6607 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6608}
Emeric Brun2b58d042012-09-20 17:10:03 +02006609
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006610/* parse the "curves" bind keyword keyword */
6611static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6612{
6613#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6614 if (!*args[cur_arg + 1]) {
6615 if (err)
6616 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6617 return ERR_ALERT | ERR_FATAL;
6618 }
6619 conf->curves = strdup(args[cur_arg + 1]);
6620 return 0;
6621#else
6622 if (err)
6623 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6624 return ERR_ALERT | ERR_FATAL;
6625#endif
6626}
6627static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6628{
6629 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6630}
6631
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006632/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006633static 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 +02006634{
6635#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6636 if (err)
6637 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6638 return ERR_ALERT | ERR_FATAL;
6639#elif defined(OPENSSL_NO_ECDH)
6640 if (err)
6641 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6642 return ERR_ALERT | ERR_FATAL;
6643#else
6644 if (!*args[cur_arg + 1]) {
6645 if (err)
6646 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6647 return ERR_ALERT | ERR_FATAL;
6648 }
6649
6650 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006651
6652 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006653#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006654}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006655static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6656{
6657 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6658}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006659
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006660/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006661static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6662{
6663 int code;
6664 char *p = args[cur_arg + 1];
6665 unsigned long long *ignerr = &conf->crt_ignerr;
6666
6667 if (!*p) {
6668 if (err)
6669 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6670 return ERR_ALERT | ERR_FATAL;
6671 }
6672
6673 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6674 ignerr = &conf->ca_ignerr;
6675
6676 if (strcmp(p, "all") == 0) {
6677 *ignerr = ~0ULL;
6678 return 0;
6679 }
6680
6681 while (p) {
6682 code = atoi(p);
6683 if ((code <= 0) || (code > 63)) {
6684 if (err)
6685 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6686 args[cur_arg], code, args[cur_arg + 1]);
6687 return ERR_ALERT | ERR_FATAL;
6688 }
6689 *ignerr |= 1ULL << code;
6690 p = strchr(p, ',');
6691 if (p)
6692 p++;
6693 }
6694
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006695 return 0;
6696}
6697
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006698/* parse tls_method_options "no-xxx" and "force-xxx" */
6699static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006700{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006701 uint16_t v;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006702 char *p;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006703 p = strchr(arg, '-');
6704 if (!p)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006705 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006706 p++;
6707 if (!strcmp(p, "sslv3"))
6708 v = CONF_SSLV3;
6709 else if (!strcmp(p, "tlsv10"))
6710 v = CONF_TLSV10;
6711 else if (!strcmp(p, "tlsv11"))
6712 v = CONF_TLSV11;
6713 else if (!strcmp(p, "tlsv12"))
6714 v = CONF_TLSV12;
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02006715 else if (!strcmp(p, "tlsv13"))
6716 v = CONF_TLSV13;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006717 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006718 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006719 if (!strncmp(arg, "no-", 3))
6720 methods->flags |= methodVersions[v].flag;
6721 else if (!strncmp(arg, "force-", 6))
6722 methods->min = methods->max = v;
6723 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006724 goto fail;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006725 return 0;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006726 fail:
6727 if (err)
6728 memprintf(err, "'%s' : option not implemented", arg);
6729 return ERR_ALERT | ERR_FATAL;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006730}
6731
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006732static 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 +02006733{
Emmanuel Hocdet43664762017-08-09 18:26:20 +02006734 return parse_tls_method_options(args[cur_arg], &conf->ssl_conf.ssl_methods, err);
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006735}
6736
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006737static 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 +02006738{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006739 return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
6740}
6741
6742/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
6743static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
6744{
6745 uint16_t i, v = 0;
6746 char *argv = args[cur_arg + 1];
6747 if (!*argv) {
6748 if (err)
6749 memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
6750 return ERR_ALERT | ERR_FATAL;
6751 }
6752 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
6753 if (!strcmp(argv, methodVersions[i].name))
6754 v = i;
6755 if (!v) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006756 if (err)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006757 memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006758 return ERR_ALERT | ERR_FATAL;
6759 }
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006760 if (!strcmp("ssl-min-ver", args[cur_arg]))
6761 methods->min = v;
6762 else if (!strcmp("ssl-max-ver", args[cur_arg]))
6763 methods->max = v;
6764 else {
6765 if (err)
6766 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
6767 return ERR_ALERT | ERR_FATAL;
6768 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006769 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006770}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006771
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02006772static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6773{
6774#if !defined(OPENSSL_IS_BORINGSSL)
6775 Warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
6776#endif
6777 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6778}
6779
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006780static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6781{
Emmanuel Hocdet43664762017-08-09 18:26:20 +02006782 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_conf.ssl_methods, err);
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006783}
6784
6785static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6786{
6787 return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
6788}
6789
Emeric Brun2d0c4822012-10-02 13:45:20 +02006790/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006791static 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 +02006792{
Emeric Brun89675492012-10-05 13:48:26 +02006793 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006794 return 0;
6795}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006796
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006797/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006798static 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 +02006799{
6800#ifdef OPENSSL_NPN_NEGOTIATED
6801 char *p1, *p2;
6802
6803 if (!*args[cur_arg + 1]) {
6804 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6805 return ERR_ALERT | ERR_FATAL;
6806 }
6807
6808 free(conf->npn_str);
6809
Willy Tarreau3724da12016-02-12 17:11:12 +01006810 /* the NPN string is built as a suite of (<len> <name>)*,
6811 * so we reuse each comma to store the next <len> and need
6812 * one more for the end of the string.
6813 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006814 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006815 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006816 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6817
6818 /* replace commas with the name length */
6819 p1 = conf->npn_str;
6820 p2 = p1 + 1;
6821 while (1) {
6822 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6823 if (!p2)
6824 p2 = p1 + 1 + strlen(p1 + 1);
6825
6826 if (p2 - (p1 + 1) > 255) {
6827 *p2 = '\0';
6828 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6829 return ERR_ALERT | ERR_FATAL;
6830 }
6831
6832 *p1 = p2 - (p1 + 1);
6833 p1 = p2;
6834
6835 if (!*p2)
6836 break;
6837
6838 *(p2++) = '\0';
6839 }
6840 return 0;
6841#else
6842 if (err)
6843 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6844 return ERR_ALERT | ERR_FATAL;
6845#endif
6846}
6847
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006848static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6849{
6850 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6851}
6852
Willy Tarreauab861d32013-04-02 02:30:41 +02006853/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006854static 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 +02006855{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006856#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006857 char *p1, *p2;
6858
6859 if (!*args[cur_arg + 1]) {
6860 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6861 return ERR_ALERT | ERR_FATAL;
6862 }
6863
6864 free(conf->alpn_str);
6865
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006866 /* the ALPN string is built as a suite of (<len> <name>)*,
6867 * so we reuse each comma to store the next <len> and need
6868 * one more for the end of the string.
6869 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006870 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006871 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006872 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6873
6874 /* replace commas with the name length */
6875 p1 = conf->alpn_str;
6876 p2 = p1 + 1;
6877 while (1) {
6878 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6879 if (!p2)
6880 p2 = p1 + 1 + strlen(p1 + 1);
6881
6882 if (p2 - (p1 + 1) > 255) {
6883 *p2 = '\0';
6884 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6885 return ERR_ALERT | ERR_FATAL;
6886 }
6887
6888 *p1 = p2 - (p1 + 1);
6889 p1 = p2;
6890
6891 if (!*p2)
6892 break;
6893
6894 *(p2++) = '\0';
6895 }
6896 return 0;
6897#else
6898 if (err)
6899 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6900 return ERR_ALERT | ERR_FATAL;
6901#endif
6902}
6903
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006904static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6905{
6906 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6907}
6908
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006909/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006910static 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 +02006911{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006912 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006913 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006914
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006915 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6916 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006917 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emmanuel Hocdet43664762017-08-09 18:26:20 +02006918 conf->ssl_conf.ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
6919 if (!conf->ssl_conf.ssl_methods.min)
6920 conf->ssl_conf.ssl_methods.min = global_ssl.listen_default_sslmethods.min;
6921 if (!conf->ssl_conf.ssl_methods.max)
6922 conf->ssl_conf.ssl_methods.max = global_ssl.listen_default_sslmethods.max;
Emeric Brun76d88952012-10-05 15:47:31 +02006923
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006924 return 0;
6925}
6926
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006927/* parse the "prefer-client-ciphers" bind keyword */
6928static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6929{
6930 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
6931 return 0;
6932}
6933
Christopher Faulet31af49d2015-06-09 17:29:50 +02006934/* parse the "generate-certificates" bind keyword */
6935static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6936{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006937#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006938 conf->generate_certs = 1;
6939#else
6940 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6941 err && *err ? *err : "");
6942#endif
6943 return 0;
6944}
6945
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006946/* parse the "strict-sni" bind keyword */
6947static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6948{
6949 conf->strict_sni = 1;
6950 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006951}
6952
6953/* parse the "tls-ticket-keys" bind keyword */
6954static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6955{
6956#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6957 FILE *f;
6958 int i = 0;
6959 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006960 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006961
6962 if (!*args[cur_arg + 1]) {
6963 if (err)
6964 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6965 return ERR_ALERT | ERR_FATAL;
6966 }
6967
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006968 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6969 if(keys_ref) {
6970 conf->keys_ref = keys_ref;
6971 return 0;
6972 }
6973
Vincent Bernat02779b62016-04-03 13:48:43 +02006974 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006975 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006976
6977 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6978 if (err)
6979 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6980 return ERR_ALERT | ERR_FATAL;
6981 }
6982
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006983 keys_ref->filename = strdup(args[cur_arg + 1]);
6984
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006985 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6986 int len = strlen(thisline);
6987 /* Strip newline characters from the end */
6988 if(thisline[len - 1] == '\n')
6989 thisline[--len] = 0;
6990
6991 if(thisline[len - 1] == '\r')
6992 thisline[--len] = 0;
6993
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006994 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 +01006995 if (err)
6996 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006997 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006998 return ERR_ALERT | ERR_FATAL;
6999 }
7000 i++;
7001 }
7002
7003 if (i < TLS_TICKETS_NO) {
7004 if (err)
7005 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 +02007006 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007007 return ERR_ALERT | ERR_FATAL;
7008 }
7009
7010 fclose(f);
7011
7012 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01007013 i -= 2;
7014 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02007015 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02007016 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007017
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02007018 LIST_ADD(&tlskeys_reference, &keys_ref->list);
7019
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007020 return 0;
7021#else
7022 if (err)
7023 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
7024 return ERR_ALERT | ERR_FATAL;
7025#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01007026}
7027
Emeric Brund94b3fe2012-09-20 18:23:56 +02007028/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007029static 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 +02007030{
7031 if (!*args[cur_arg + 1]) {
7032 if (err)
7033 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
7034 return ERR_ALERT | ERR_FATAL;
7035 }
7036
7037 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007038 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007039 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007040 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007041 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007042 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007043 else {
7044 if (err)
7045 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
7046 args[cur_arg], args[cur_arg + 1]);
7047 return ERR_ALERT | ERR_FATAL;
7048 }
7049
7050 return 0;
7051}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007052static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
7053{
7054 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
7055}
Emeric Brund94b3fe2012-09-20 18:23:56 +02007056
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02007057/* parse the "no-ca-names" bind keyword */
7058static int ssl_bind_parse_no_ca_names(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
7059{
7060 conf->no_ca_names = 1;
7061 return 0;
7062}
7063static int bind_parse_no_ca_names(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
7064{
7065 return ssl_bind_parse_no_ca_names(args, cur_arg, px, &conf->ssl_conf, err);
7066}
7067
Willy Tarreau92faadf2012-10-10 23:04:25 +02007068/************** "server" keywords ****************/
7069
Emeric Brunef42d922012-10-11 16:11:36 +02007070/* parse the "ca-file" server keyword */
7071static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7072{
7073 if (!*args[*cur_arg + 1]) {
7074 if (err)
7075 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
7076 return ERR_ALERT | ERR_FATAL;
7077 }
7078
Willy Tarreauef934602016-12-22 23:12:01 +01007079 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
7080 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02007081 else
7082 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
7083
7084 return 0;
7085}
7086
Willy Tarreau92faadf2012-10-10 23:04:25 +02007087/* parse the "check-ssl" server keyword */
7088static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7089{
7090 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007091 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7092 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
7093 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007094 newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
7095 if (!newsrv->ssl_ctx.methods.min)
7096 newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
7097 if (!newsrv->ssl_ctx.methods.max)
7098 newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
7099
Willy Tarreau92faadf2012-10-10 23:04:25 +02007100 return 0;
7101}
7102
7103/* parse the "ciphers" server keyword */
7104static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7105{
7106 if (!*args[*cur_arg + 1]) {
7107 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
7108 return ERR_ALERT | ERR_FATAL;
7109 }
7110
7111 free(newsrv->ssl_ctx.ciphers);
7112 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
7113 return 0;
7114}
7115
Emeric Brunef42d922012-10-11 16:11:36 +02007116/* parse the "crl-file" server keyword */
7117static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7118{
7119#ifndef X509_V_FLAG_CRL_CHECK
7120 if (err)
7121 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
7122 return ERR_ALERT | ERR_FATAL;
7123#else
7124 if (!*args[*cur_arg + 1]) {
7125 if (err)
7126 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
7127 return ERR_ALERT | ERR_FATAL;
7128 }
7129
Willy Tarreauef934602016-12-22 23:12:01 +01007130 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
7131 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02007132 else
7133 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
7134
7135 return 0;
7136#endif
7137}
7138
Emeric Bruna7aa3092012-10-26 12:58:00 +02007139/* parse the "crt" server keyword */
7140static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7141{
7142 if (!*args[*cur_arg + 1]) {
7143 if (err)
7144 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
7145 return ERR_ALERT | ERR_FATAL;
7146 }
7147
Willy Tarreauef934602016-12-22 23:12:01 +01007148 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
7149 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02007150 else
7151 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
7152
7153 return 0;
7154}
Emeric Brunef42d922012-10-11 16:11:36 +02007155
Frédéric Lécaille340ae602017-03-13 10:38:04 +01007156/* parse the "no-check-ssl" server keyword */
7157static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7158{
7159 newsrv->check.use_ssl = 0;
7160 free(newsrv->ssl_ctx.ciphers);
7161 newsrv->ssl_ctx.ciphers = NULL;
7162 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
7163 return 0;
7164}
7165
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01007166/* parse the "no-send-proxy-v2-ssl" server keyword */
7167static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7168{
7169 newsrv->pp_opts &= ~SRV_PP_V2;
7170 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7171 return 0;
7172}
7173
7174/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
7175static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7176{
7177 newsrv->pp_opts &= ~SRV_PP_V2;
7178 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7179 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
7180 return 0;
7181}
7182
Frédéric Lécaillee381d762017-03-13 11:54:17 +01007183/* parse the "no-ssl" server keyword */
7184static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7185{
7186 newsrv->use_ssl = 0;
7187 free(newsrv->ssl_ctx.ciphers);
7188 newsrv->ssl_ctx.ciphers = NULL;
7189 return 0;
7190}
7191
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007192/* parse the "no-ssl-reuse" server keyword */
7193static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7194{
7195 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
7196 return 0;
7197}
7198
Emeric Brunf9c5c472012-10-11 15:28:34 +02007199/* parse the "no-tls-tickets" server keyword */
7200static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7201{
7202 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
7203 return 0;
7204}
David Safb76832014-05-08 23:42:08 -04007205/* parse the "send-proxy-v2-ssl" server keyword */
7206static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7207{
7208 newsrv->pp_opts |= SRV_PP_V2;
7209 newsrv->pp_opts |= SRV_PP_V2_SSL;
7210 return 0;
7211}
7212
7213/* parse the "send-proxy-v2-ssl-cn" server keyword */
7214static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7215{
7216 newsrv->pp_opts |= SRV_PP_V2;
7217 newsrv->pp_opts |= SRV_PP_V2_SSL;
7218 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
7219 return 0;
7220}
Emeric Brunf9c5c472012-10-11 15:28:34 +02007221
Willy Tarreau732eac42015-07-09 11:40:25 +02007222/* parse the "sni" server keyword */
7223static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7224{
7225#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
7226 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
7227 return ERR_ALERT | ERR_FATAL;
7228#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007229 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02007230
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007231 arg = args[*cur_arg + 1];
7232 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02007233 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
7234 return ERR_ALERT | ERR_FATAL;
7235 }
7236
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007237 free(newsrv->sni_expr);
7238 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02007239
Willy Tarreau732eac42015-07-09 11:40:25 +02007240 return 0;
7241#endif
7242}
7243
Willy Tarreau92faadf2012-10-10 23:04:25 +02007244/* parse the "ssl" server keyword */
7245static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7246{
7247 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007248 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7249 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007250 return 0;
7251}
7252
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007253/* parse the "ssl-reuse" server keyword */
7254static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7255{
7256 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
7257 return 0;
7258}
7259
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007260/* parse the "tls-tickets" server keyword */
7261static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7262{
7263 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
7264 return 0;
7265}
7266
Emeric Brunef42d922012-10-11 16:11:36 +02007267/* parse the "verify" server keyword */
7268static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7269{
7270 if (!*args[*cur_arg + 1]) {
7271 if (err)
7272 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
7273 return ERR_ALERT | ERR_FATAL;
7274 }
7275
7276 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007277 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02007278 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007279 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02007280 else {
7281 if (err)
7282 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
7283 args[*cur_arg], args[*cur_arg + 1]);
7284 return ERR_ALERT | ERR_FATAL;
7285 }
7286
Evan Broderbe554312013-06-27 00:05:25 -07007287 return 0;
7288}
7289
7290/* parse the "verifyhost" server keyword */
7291static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7292{
7293 if (!*args[*cur_arg + 1]) {
7294 if (err)
7295 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
7296 return ERR_ALERT | ERR_FATAL;
7297 }
7298
Frédéric Lécaille273f3212017-03-13 15:52:01 +01007299 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07007300 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
7301
Emeric Brunef42d922012-10-11 16:11:36 +02007302 return 0;
7303}
7304
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007305/* parse the "ssl-default-bind-options" keyword in global section */
7306static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
7307 struct proxy *defpx, const char *file, int line,
7308 char **err) {
7309 int i = 1;
7310
7311 if (*(args[i]) == 0) {
7312 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7313 return -1;
7314 }
7315 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007316 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007317 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Lukas Tribus53ae85c2017-05-04 15:45:40 +00007318 else if (!strcmp(args[i], "prefer-client-ciphers"))
7319 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007320 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7321 if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
7322 i++;
7323 else {
7324 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7325 return -1;
7326 }
7327 }
7328 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007329 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7330 return -1;
7331 }
7332 i++;
7333 }
7334 return 0;
7335}
7336
7337/* parse the "ssl-default-server-options" keyword in global section */
7338static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
7339 struct proxy *defpx, const char *file, int line,
7340 char **err) {
7341 int i = 1;
7342
7343 if (*(args[i]) == 0) {
7344 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7345 return -1;
7346 }
7347 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007348 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007349 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007350 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7351 if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
7352 i++;
7353 else {
7354 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7355 return -1;
7356 }
7357 }
7358 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007359 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7360 return -1;
7361 }
7362 i++;
7363 }
7364 return 0;
7365}
7366
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007367/* parse the "ca-base" / "crt-base" keywords in global section.
7368 * Returns <0 on alert, >0 on warning, 0 on success.
7369 */
7370static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
7371 struct proxy *defpx, const char *file, int line,
7372 char **err)
7373{
7374 char **target;
7375
Willy Tarreauef934602016-12-22 23:12:01 +01007376 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007377
7378 if (too_many_args(1, args, err, NULL))
7379 return -1;
7380
7381 if (*target) {
7382 memprintf(err, "'%s' already specified.", args[0]);
7383 return -1;
7384 }
7385
7386 if (*(args[1]) == 0) {
7387 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
7388 return -1;
7389 }
7390 *target = strdup(args[1]);
7391 return 0;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007392}
7393
7394/* parse the "ssl-mode-async" keyword in global section.
7395 * Returns <0 on alert, >0 on warning, 0 on success.
7396 */
7397static int ssl_parse_global_ssl_async(char **args, int section_type, struct proxy *curpx,
7398 struct proxy *defpx, const char *file, int line,
7399 char **err)
7400{
7401#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
7402 global_ssl.async = 1;
7403 return 0;
7404#else
7405 memprintf(err, "'%s': openssl library does not support async mode", args[0]);
7406 return -1;
7407#endif
7408}
7409
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007410#ifndef OPENSSL_NO_ENGINE
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007411static int ssl_check_async_engine_count(void) {
7412 int err_code = 0;
7413
Emeric Brun3854e012017-05-17 20:42:48 +02007414 if (global_ssl.async && (openssl_engines_initialized > 32)) {
7415 Alert("ssl-mode-async only supports a maximum of 32 engines.\n");
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007416 err_code = ERR_ABORT;
7417 }
7418 return err_code;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007419}
7420
Grant Zhang872f9c22017-01-21 01:10:18 +00007421/* parse the "ssl-engine" keyword in global section.
7422 * Returns <0 on alert, >0 on warning, 0 on success.
7423 */
7424static int ssl_parse_global_ssl_engine(char **args, int section_type, struct proxy *curpx,
7425 struct proxy *defpx, const char *file, int line,
7426 char **err)
7427{
7428 char *algo;
7429 int ret = -1;
7430
7431 if (*(args[1]) == 0) {
7432 memprintf(err, "global statement '%s' expects a valid engine name as an argument.", args[0]);
7433 return ret;
7434 }
7435
7436 if (*(args[2]) == 0) {
7437 /* if no list of algorithms is given, it defaults to ALL */
7438 algo = strdup("ALL");
7439 goto add_engine;
7440 }
7441
7442 /* otherwise the expected format is ssl-engine <engine_name> algo <list of algo> */
7443 if (strcmp(args[2], "algo") != 0) {
7444 memprintf(err, "global statement '%s' expects to have algo keyword.", args[0]);
7445 return ret;
7446 }
7447
7448 if (*(args[3]) == 0) {
7449 memprintf(err, "global statement '%s' expects algorithm names as an argument.", args[0]);
7450 return ret;
7451 }
7452 algo = strdup(args[3]);
7453
7454add_engine:
7455 if (ssl_init_single_engine(args[1], algo)==0) {
7456 openssl_engines_initialized++;
7457 ret = 0;
7458 }
7459 free(algo);
7460 return ret;
7461}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007462#endif
Grant Zhang872f9c22017-01-21 01:10:18 +00007463
Willy Tarreauf22e9682016-12-21 23:23:19 +01007464/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
7465 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
7466 */
7467static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
7468 struct proxy *defpx, const char *file, int line,
7469 char **err)
7470{
7471 char **target;
7472
Willy Tarreauef934602016-12-22 23:12:01 +01007473 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01007474
7475 if (too_many_args(1, args, err, NULL))
7476 return -1;
7477
7478 if (*(args[1]) == 0) {
7479 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
7480 return -1;
7481 }
7482
7483 free(*target);
7484 *target = strdup(args[1]);
7485 return 0;
7486}
7487
Willy Tarreau9ceda382016-12-21 23:13:03 +01007488/* parse various global tune.ssl settings consisting in positive integers.
7489 * Returns <0 on alert, >0 on warning, 0 on success.
7490 */
7491static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
7492 struct proxy *defpx, const char *file, int line,
7493 char **err)
7494{
7495 int *target;
7496
7497 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
7498 target = &global.tune.sslcachesize;
7499 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007500 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007501 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007502 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007503 else if (strcmp(args[0], "maxsslconn") == 0)
7504 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007505 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
7506 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007507 else {
7508 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
7509 return -1;
7510 }
7511
7512 if (too_many_args(1, args, err, NULL))
7513 return -1;
7514
7515 if (*(args[1]) == 0) {
7516 memprintf(err, "'%s' expects an integer argument.", args[0]);
7517 return -1;
7518 }
7519
7520 *target = atoi(args[1]);
7521 if (*target < 0) {
7522 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
7523 return -1;
7524 }
7525 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007526}
7527
7528static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
7529 struct proxy *defpx, const char *file, int line,
7530 char **err)
7531{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007532 int ret;
7533
7534 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
7535 if (ret != 0)
7536 return ret;
7537
7538 if (pool2_ssl_capture) {
7539 memprintf(err, "'%s' is already configured.", args[0]);
7540 return -1;
7541 }
7542
7543 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
7544 if (!pool2_ssl_capture) {
7545 memprintf(err, "Out of memory error.");
7546 return -1;
7547 }
7548 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007549}
7550
7551/* parse "ssl.force-private-cache".
7552 * Returns <0 on alert, >0 on warning, 0 on success.
7553 */
7554static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
7555 struct proxy *defpx, const char *file, int line,
7556 char **err)
7557{
7558 if (too_many_args(0, args, err, NULL))
7559 return -1;
7560
Willy Tarreauef934602016-12-22 23:12:01 +01007561 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007562 return 0;
7563}
7564
7565/* parse "ssl.lifetime".
7566 * Returns <0 on alert, >0 on warning, 0 on success.
7567 */
7568static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
7569 struct proxy *defpx, const char *file, int line,
7570 char **err)
7571{
7572 const char *res;
7573
7574 if (too_many_args(1, args, err, NULL))
7575 return -1;
7576
7577 if (*(args[1]) == 0) {
7578 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
7579 return -1;
7580 }
7581
Willy Tarreauef934602016-12-22 23:12:01 +01007582 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01007583 if (res) {
7584 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
7585 return -1;
7586 }
7587 return 0;
7588}
7589
7590#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01007591/* parse "ssl-dh-param-file".
7592 * Returns <0 on alert, >0 on warning, 0 on success.
7593 */
7594static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
7595 struct proxy *defpx, const char *file, int line,
7596 char **err)
7597{
7598 if (too_many_args(1, args, err, NULL))
7599 return -1;
7600
7601 if (*(args[1]) == 0) {
7602 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
7603 return -1;
7604 }
7605
7606 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
7607 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
7608 return -1;
7609 }
7610 return 0;
7611}
7612
Willy Tarreau9ceda382016-12-21 23:13:03 +01007613/* parse "ssl.default-dh-param".
7614 * Returns <0 on alert, >0 on warning, 0 on success.
7615 */
7616static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
7617 struct proxy *defpx, const char *file, int line,
7618 char **err)
7619{
7620 if (too_many_args(1, args, err, NULL))
7621 return -1;
7622
7623 if (*(args[1]) == 0) {
7624 memprintf(err, "'%s' expects an integer argument.", args[0]);
7625 return -1;
7626 }
7627
Willy Tarreauef934602016-12-22 23:12:01 +01007628 global_ssl.default_dh_param = atoi(args[1]);
7629 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01007630 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
7631 return -1;
7632 }
7633 return 0;
7634}
7635#endif
7636
7637
William Lallemand32af2032016-10-29 18:09:35 +02007638/* This function is used with TLS ticket keys management. It permits to browse
7639 * each reference. The variable <getnext> must contain the current node,
7640 * <end> point to the root node.
7641 */
7642#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7643static inline
7644struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
7645{
7646 struct tls_keys_ref *ref = getnext;
7647
7648 while (1) {
7649
7650 /* Get next list entry. */
7651 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
7652
7653 /* If the entry is the last of the list, return NULL. */
7654 if (&ref->list == end)
7655 return NULL;
7656
7657 return ref;
7658 }
7659}
7660
7661static inline
7662struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7663{
7664 int id;
7665 char *error;
7666
7667 /* If the reference starts by a '#', this is numeric id. */
7668 if (reference[0] == '#') {
7669 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7670 id = strtol(reference + 1, &error, 10);
7671 if (*error != '\0')
7672 return NULL;
7673
7674 /* Perform the unique id lookup. */
7675 return tlskeys_ref_lookupid(id);
7676 }
7677
7678 /* Perform the string lookup. */
7679 return tlskeys_ref_lookup(reference);
7680}
7681#endif
7682
7683
7684#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7685
7686static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7687
7688static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7689 return cli_io_handler_tlskeys_files(appctx);
7690}
7691
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007692/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7693 * (next index to be dumped), and cli.p0 (next key reference).
7694 */
William Lallemand32af2032016-10-29 18:09:35 +02007695static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7696
7697 struct stream_interface *si = appctx->owner;
7698
7699 switch (appctx->st2) {
7700 case STAT_ST_INIT:
7701 /* Display the column headers. If the message cannot be sent,
7702 * quit the fucntion with returning 0. The function is called
7703 * later and restart at the state "STAT_ST_INIT".
7704 */
7705 chunk_reset(&trash);
7706
7707 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7708 chunk_appendf(&trash, "# id secret\n");
7709 else
7710 chunk_appendf(&trash, "# id (file)\n");
7711
7712 if (bi_putchk(si_ic(si), &trash) == -1) {
7713 si_applet_cant_put(si);
7714 return 0;
7715 }
7716
William Lallemand32af2032016-10-29 18:09:35 +02007717 /* Now, we start the browsing of the references lists.
7718 * Note that the following call to LIST_ELEM return bad pointer. The only
7719 * available field of this pointer is <list>. It is used with the function
7720 * tlskeys_list_get_next() for retruning the first available entry
7721 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007722 if (appctx->ctx.cli.p0 == NULL) {
7723 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7724 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007725 }
7726
7727 appctx->st2 = STAT_ST_LIST;
7728 /* fall through */
7729
7730 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007731 while (appctx->ctx.cli.p0) {
7732 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7733 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007734
7735 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007736 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007737 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007738
7739 if (appctx->ctx.cli.i1 == 0)
7740 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7741
William Lallemand32af2032016-10-29 18:09:35 +02007742 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007743 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007744 struct chunk *t2 = get_trash_chunk();
7745
7746 chunk_reset(t2);
7747 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007748 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007749 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007750 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007751
7752 if (bi_putchk(si_ic(si), &trash) == -1) {
7753 /* let's try again later from this stream. We add ourselves into
7754 * this stream's users so that it can remove us upon termination.
7755 */
7756 si_applet_cant_put(si);
7757 return 0;
7758 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007759 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007760 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007761 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007762 }
7763 if (bi_putchk(si_ic(si), &trash) == -1) {
7764 /* let's try again later from this stream. We add ourselves into
7765 * this stream's users so that it can remove us upon termination.
7766 */
7767 si_applet_cant_put(si);
7768 return 0;
7769 }
7770
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007771 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007772 break;
7773
7774 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007775 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007776 }
7777
7778 appctx->st2 = STAT_ST_FIN;
7779 /* fall through */
7780
7781 default:
7782 appctx->st2 = STAT_ST_FIN;
7783 return 1;
7784 }
7785 return 0;
7786}
7787
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007788/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007789static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7790{
William Lallemand32af2032016-10-29 18:09:35 +02007791 /* no parameter, shows only file list */
7792 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007793 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007794 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007795 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007796 }
7797
7798 if (args[2][0] == '*') {
7799 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007800 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007801 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007802 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7803 if (!appctx->ctx.cli.p0) {
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007804 appctx->ctx.cli.severity = LOG_ERR;
William Lallemand32af2032016-10-29 18:09:35 +02007805 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007806 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007807 return 1;
7808 }
7809 }
William Lallemand32af2032016-10-29 18:09:35 +02007810 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007811 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007812}
7813
William Lallemand32af2032016-10-29 18:09:35 +02007814static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7815{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007816 struct tls_keys_ref *ref;
7817
William Lallemand32af2032016-10-29 18:09:35 +02007818 /* Expect two parameters: the filename and the new new TLS key in encoding */
7819 if (!*args[3] || !*args[4]) {
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007820 appctx->ctx.cli.severity = LOG_ERR;
William Lallemand32af2032016-10-29 18:09:35 +02007821 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 +01007822 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007823 return 1;
7824 }
7825
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007826 ref = tlskeys_ref_lookup_ref(args[3]);
7827 if (!ref) {
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007828 appctx->ctx.cli.severity = LOG_ERR;
William Lallemand32af2032016-10-29 18:09:35 +02007829 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007830 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007831 return 1;
7832 }
7833
7834 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7835 if (trash.len != sizeof(struct tls_sess_key)) {
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007836 appctx->ctx.cli.severity = LOG_ERR;
William Lallemand32af2032016-10-29 18:09:35 +02007837 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007838 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007839 return 1;
7840 }
7841
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007842 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7843 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007844
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007845 appctx->ctx.cli.severity = LOG_INFO;
William Lallemand32af2032016-10-29 18:09:35 +02007846 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007847 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007848 return 1;
7849
7850}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007851#endif
William Lallemand32af2032016-10-29 18:09:35 +02007852
7853static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7854{
7855#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7856 char *err = NULL;
7857
7858 /* Expect one parameter: the new response in base64 encoding */
7859 if (!*args[3]) {
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007860 appctx->ctx.cli.severity = LOG_ERR;
William Lallemand32af2032016-10-29 18:09:35 +02007861 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\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 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7867 if (trash.len < 0) {
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007868 appctx->ctx.cli.severity = LOG_ERR;
William Lallemand32af2032016-10-29 18:09:35 +02007869 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007870 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007871 return 1;
7872 }
7873
7874 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7875 if (err) {
7876 memprintf(&err, "%s.\n", err);
7877 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007878 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007879 }
7880 return 1;
7881 }
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007882 appctx->ctx.cli.severity = LOG_INFO;
William Lallemand32af2032016-10-29 18:09:35 +02007883 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007884 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007885 return 1;
7886#else
Andjelko Iharosc3680ec2017-07-20 16:49:14 +02007887 appctx->ctx.cli.severity = LOG_ERR;
William Lallemand32af2032016-10-29 18:09:35 +02007888 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 +01007889 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007890 return 1;
7891#endif
7892
7893}
7894
7895/* register cli keywords */
7896static struct cli_kw_list cli_kws = {{ },{
7897#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7898 { { "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 },
7899 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007900#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007901 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007902 { { NULL }, NULL, NULL, NULL }
7903}};
7904
7905
Willy Tarreau7875d092012-09-10 08:20:03 +02007906/* Note: must not be declared <const> as its list will be overwritten.
7907 * Please take care of keeping this list alphabetically sorted.
7908 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007909static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007910 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007911 { "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 +02007912 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7913 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007914 { "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 +02007915 { "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 +02007916 { "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 +02007917 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7918 { "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 +01007919 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007920 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007921 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7922 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7923 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7924 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7925 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7926 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7927 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7928 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007929 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007930 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7931 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007932 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007933 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7934 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7935 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7936 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7937 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7938 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7939 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007940 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007941 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007942 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007943 { "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 +01007944 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007945 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7946 { "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 +02007947 { "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 +02007948#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007949 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007950#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007951#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007952 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007953#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007954 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007955 { "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 +02007956 { "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 +01007957 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7958 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007959 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7960 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7961 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7962 { "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 +02007963 { NULL, NULL, 0, 0, 0 },
7964}};
7965
7966/* Note: must not be declared <const> as its list will be overwritten.
7967 * Please take care of keeping this list alphabetically sorted.
7968 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007969static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007970 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7971 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007972 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007973}};
7974
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007975/* Note: must not be declared <const> as its list will be overwritten.
7976 * Please take care of keeping this list alphabetically sorted, doing so helps
7977 * all code contributors.
7978 * Optional keywords are also declared with a NULL ->parse() function so that
7979 * the config parser can report an appropriate error when a known keyword was
7980 * not enabled.
7981 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007982static struct ssl_bind_kw ssl_bind_kws[] = {
7983 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7984 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7985 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7986 { "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 +01007987 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007988 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02007989 { "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 +01007990 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02007991 { "ssl-min-ver", ssl_bind_parse_tls_method_minmax,1 }, /* minimum version */
7992 { "ssl-max-ver", ssl_bind_parse_tls_method_minmax,1 }, /* maximum version */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007993 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7994 { NULL, NULL, 0 },
7995};
7996
Willy Tarreau51fb7652012-09-18 18:24:39 +02007997static struct bind_kw_list bind_kws = { "SSL", { }, {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007998 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7999 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
8000 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
8001 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
8002 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
8003 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
8004 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
8005 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
8006 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
8007 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
8008 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
8009 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
8010 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
8011 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
8012 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
8013 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02008014 { "force-tlsv13", bind_parse_tls_method_options, 0 }, /* force TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008015 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02008016 { "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 +02008017 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
8018 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
8019 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
8020 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02008021 { "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008022 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
8023 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02008024 { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
8025 { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008026 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
8027 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
8028 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
8029 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
8030 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02008031 { NULL, NULL, 0 },
8032}};
Emeric Brun46591952012-05-18 15:47:34 +02008033
Willy Tarreau92faadf2012-10-10 23:04:25 +02008034/* Note: must not be declared <const> as its list will be overwritten.
8035 * Please take care of keeping this list alphabetically sorted, doing so helps
8036 * all code contributors.
8037 * Optional keywords are also declared with a NULL ->parse() function so that
8038 * the config parser can report an appropriate error when a known keyword was
8039 * not enabled.
8040 */
8041static struct srv_kw_list srv_kws = { "SSL", { }, {
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02008042 { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
8043 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
8044 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
8045 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
8046 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
8047 { "force-sslv3", srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
8048 { "force-tlsv10", srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
8049 { "force-tlsv11", srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
8050 { "force-tlsv12", srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
8051 { "force-tlsv13", srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
8052 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
8053 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
8054 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
8055 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
8056 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
8057 { "no-sslv3", srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
8058 { "no-tlsv10", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
8059 { "no-tlsv11", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
8060 { "no-tlsv12", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
8061 { "no-tlsv13", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
8062 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
8063 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
8064 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
8065 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
8066 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
8067 { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1 }, /* minimum version */
8068 { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1 }, /* maximum version */
8069 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
8070 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
8071 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
8072 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02008073 { NULL, NULL, 0, 0 },
8074}};
8075
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008076static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01008077 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
8078 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01008079 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008080 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
8081 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01008082#ifndef OPENSSL_NO_DH
8083 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
8084#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008085 { CFG_GLOBAL, "ssl-mode-async", ssl_parse_global_ssl_async },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008086#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008087 { CFG_GLOBAL, "ssl-engine", ssl_parse_global_ssl_engine },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008088#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01008089 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
8090#ifndef OPENSSL_NO_DH
8091 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
8092#endif
8093 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
8094 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
8095 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
8096 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01008097 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01008098 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
8099 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008100 { 0, NULL, NULL },
8101}};
8102
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02008103/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01008104static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02008105 .snd_buf = ssl_sock_from_buf,
8106 .rcv_buf = ssl_sock_to_buf,
8107 .rcv_pipe = NULL,
8108 .snd_pipe = NULL,
8109 .shutr = NULL,
8110 .shutw = ssl_sock_shutw,
8111 .close = ssl_sock_close,
8112 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01008113 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01008114 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01008115 .prepare_srv = ssl_sock_prepare_srv_ctx,
8116 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8743f7e2016-12-04 18:44:29 +01008117 .get_alpn = ssl_sock_get_alpn,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01008118 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02008119};
8120
Daniel Jakots54ffb912015-11-06 20:02:41 +01008121#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008122
8123static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
8124{
8125 if (ptr) {
8126 chunk_destroy(ptr);
8127 free(ptr);
8128 }
8129}
8130
8131#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01008132static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
8133{
8134 pool_free2(pool2_ssl_capture, ptr);
8135}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008136
Emeric Brun46591952012-05-18 15:47:34 +02008137__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02008138static void __ssl_sock_init(void)
8139{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008140 char *ptr;
Emmanuel Hocdetf80bc242017-07-12 14:25:38 +02008141 int i;
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008142
Emeric Brun46591952012-05-18 15:47:34 +02008143 STACK_OF(SSL_COMP)* cm;
8144
Willy Tarreauef934602016-12-22 23:12:01 +01008145 if (global_ssl.listen_default_ciphers)
8146 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
8147 if (global_ssl.connect_default_ciphers)
8148 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01008149
Willy Tarreau13e14102016-12-22 20:25:26 +01008150 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02008151 SSL_library_init();
8152 cm = SSL_COMP_get_compression_methods();
8153 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01008154#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008155 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
8156#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01008157 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 +02008158 sample_register_fetches(&sample_fetch_keywords);
8159 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02008160 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02008161 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008162 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02008163 cli_register_kw(&cli_kws);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008164#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008165 ENGINE_load_builtin_engines();
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008166 hap_register_post_check(ssl_check_async_engine_count);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008167#endif
Willy Tarreaud1c57502016-12-22 22:46:15 +01008168#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
8169 hap_register_post_check(tlskeys_finalize_config);
8170#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008171
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008172 ptr = NULL;
8173 memprintf(&ptr, "Built with OpenSSL version : "
8174#ifdef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008175 "BoringSSL");
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008176#else /* OPENSSL_IS_BORINGSSL */
8177 OPENSSL_VERSION_TEXT
8178 "\nRunning on OpenSSL version : %s%s",
8179 SSLeay_version(SSLEAY_VERSION),
8180 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
8181#endif
8182 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
8183#if OPENSSL_VERSION_NUMBER < 0x00907000L
8184 "no (library version too old)"
8185#elif defined(OPENSSL_NO_TLSEXT)
8186 "no (disabled via OPENSSL_NO_TLSEXT)"
8187#else
8188 "yes"
8189#endif
8190 "", ptr);
8191
8192 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
8193#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
8194 "yes"
8195#else
8196#ifdef OPENSSL_NO_TLSEXT
8197 "no (because of OPENSSL_NO_TLSEXT)"
8198#else
8199 "no (version might be too old, 0.9.8f min needed)"
8200#endif
8201#endif
8202 "", ptr);
8203
Emmanuel Hocdetf80bc242017-07-12 14:25:38 +02008204 memprintf(&ptr, "%s\nOpenSSL library supports :", ptr);
8205 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
8206 if (methodVersions[i].option)
8207 memprintf(&ptr, "%s %s", ptr, methodVersions[i].name);
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008208
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008209 hap_register_build_opts(ptr, 1);
8210
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008211 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
8212 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02008213
8214#ifndef OPENSSL_NO_DH
8215 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
Grant Zhang872f9c22017-01-21 01:10:18 +00008216 hap_register_post_deinit(ssl_free_dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02008217#endif
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008218#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008219 hap_register_post_deinit(ssl_free_engines);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008220#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02008221 /* Load SSL string for the verbose & debug mode. */
8222 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02008223}
8224
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008225#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008226void ssl_free_engines(void) {
8227 struct ssl_engine_list *wl, *wlb;
8228 /* free up engine list */
8229 list_for_each_entry_safe(wl, wlb, &openssl_engines, list) {
8230 ENGINE_finish(wl->e);
8231 ENGINE_free(wl->e);
8232 LIST_DEL(&wl->list);
8233 free(wl);
8234 }
8235}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008236#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02008237
Remi Gacogned3a23c32015-05-28 16:39:47 +02008238#ifndef OPENSSL_NO_DH
Grant Zhang872f9c22017-01-21 01:10:18 +00008239void ssl_free_dh(void) {
8240 if (local_dh_1024) {
8241 DH_free(local_dh_1024);
8242 local_dh_1024 = NULL;
8243 }
8244 if (local_dh_2048) {
8245 DH_free(local_dh_2048);
8246 local_dh_2048 = NULL;
8247 }
8248 if (local_dh_4096) {
8249 DH_free(local_dh_4096);
8250 local_dh_4096 = NULL;
8251 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02008252 if (global_dh) {
8253 DH_free(global_dh);
8254 global_dh = NULL;
8255 }
Grant Zhang872f9c22017-01-21 01:10:18 +00008256}
8257#endif
8258
8259__attribute__((destructor))
8260static void __ssl_sock_deinit(void)
8261{
8262#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
8263 lru64_destroy(ssl_ctx_lru_tree);
Remi Gacogned3a23c32015-05-28 16:39:47 +02008264#endif
8265
8266 ERR_remove_state(0);
8267 ERR_free_strings();
8268
8269 EVP_cleanup();
8270
8271#if OPENSSL_VERSION_NUMBER >= 0x00907000L
8272 CRYPTO_cleanup_all_ex_data();
8273#endif
8274}
8275
8276
Emeric Brun46591952012-05-18 15:47:34 +02008277/*
8278 * Local variables:
8279 * c-indent-level: 8
8280 * c-basic-offset: 8
8281 * End:
8282 */