blob: b53779db7b67b06e162ba11b4ac48766011c221e [file] [log] [blame]
yanbzhu08ce6ab2015-12-02 13:01:29 -05001
Emeric Brun46591952012-05-18 15:47:34 +02002/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02004 *
5 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 *
Willy Tarreau69845df2012-09-10 09:43:09 +020012 * Acknowledgement:
13 * We'd like to specially thank the Stud project authors for a very clean
14 * and well documented code which helped us understand how the OpenSSL API
15 * ought to be used in non-blocking mode. This is one difficult part which
16 * is not easy to get from the OpenSSL doc, and reading the Stud code made
17 * it much more obvious than the examples in the OpenSSL package. Keep up
18 * the good works, guys !
19 *
20 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
21 * particularly well with haproxy. For more info about this project, visit :
22 * https://github.com/bumptech/stud
23 *
Emeric Brun46591952012-05-18 15:47:34 +020024 */
25
26#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020027#include <ctype.h>
28#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020029#include <errno.h>
30#include <fcntl.h>
31#include <stdio.h>
32#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020033#include <string.h>
34#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020035
36#include <sys/socket.h>
37#include <sys/stat.h>
38#include <sys/types.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020039#include <netdb.h>
Emeric Brun46591952012-05-18 15:47:34 +020040#include <netinet/tcp.h>
41
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020042#include <openssl/crypto.h>
Emeric Brun46591952012-05-18 15:47:34 +020043#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020044#include <openssl/x509.h>
45#include <openssl/x509v3.h>
46#include <openssl/x509.h>
47#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010048#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010049#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020050#include <openssl/ocsp.h>
51#endif
Remi Gacogne4f902b82015-05-28 16:23:00 +020052#ifndef OPENSSL_NO_DH
53#include <openssl/dh.h>
54#endif
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +020055#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +000056#include <openssl/engine.h>
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +020057#endif
Emeric Brun46591952012-05-18 15:47:34 +020058
Grant Zhangfa6c7ee2017-01-14 01:42:15 +000059#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
60#include <openssl/async.h>
61#endif
62
Christopher Faulet31af49d2015-06-09 17:29:50 +020063#include <import/lru.h>
64#include <import/xxhash.h>
65
Emeric Brun46591952012-05-18 15:47:34 +020066#include <common/buffer.h>
67#include <common/compat.h>
68#include <common/config.h>
69#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020070#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020071#include <common/standard.h>
72#include <common/ticks.h>
73#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010074#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010075#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020076
Emeric Brunfc0421f2012-09-07 17:30:07 +020077#include <ebsttree.h>
78
William Lallemand32af2032016-10-29 18:09:35 +020079#include <types/applet.h>
80#include <types/cli.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020081#include <types/global.h>
82#include <types/ssl_sock.h>
William Lallemand32af2032016-10-29 18:09:35 +020083#include <types/stats.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020084
Willy Tarreau7875d092012-09-10 08:20:03 +020085#include <proto/acl.h>
86#include <proto/arg.h>
William Lallemand32af2032016-10-29 18:09:35 +020087#include <proto/channel.h>
Emeric Brun46591952012-05-18 15:47:34 +020088#include <proto/connection.h>
William Lallemand32af2032016-10-29 18:09:35 +020089#include <proto/cli.h>
Emeric Brun46591952012-05-18 15:47:34 +020090#include <proto/fd.h>
91#include <proto/freq_ctr.h>
92#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020093#include <proto/listener.h>
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020094#include <proto/openssl-compat.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010095#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020096#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020097#include <proto/server.h>
William Lallemand32af2032016-10-29 18:09:35 +020098#include <proto/stream_interface.h>
Emeric Brun46591952012-05-18 15:47:34 +020099#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +0200100#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +0200101#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +0200102#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +0200103#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +0200104#include <proto/task.h>
105
Willy Tarreau518cedd2014-02-17 15:43:01 +0100106/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +0200107#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +0100108#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +0100109#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +0200110#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
111
Emeric Brunf282a812012-09-21 15:27:54 +0200112/* bits 0xFFFF0000 are reserved to store verify errors */
113
114/* Verify errors macros */
115#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
116#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
117#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
118
119#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
120#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
121#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200122
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100123/* Supported hash function for TLS tickets */
124#ifdef OPENSSL_NO_SHA256
125#define HASH_FUNCT EVP_sha1
126#else
127#define HASH_FUNCT EVP_sha256
128#endif /* OPENSSL_NO_SHA256 */
129
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200130/* ssl_methods flags for ssl options */
131#define MC_SSL_O_ALL 0x0000
132#define MC_SSL_O_NO_SSLV3 0x0001 /* disable SSLv3 */
133#define MC_SSL_O_NO_TLSV10 0x0002 /* disable TLSv10 */
134#define MC_SSL_O_NO_TLSV11 0x0004 /* disable TLSv11 */
135#define MC_SSL_O_NO_TLSV12 0x0008 /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +0200136#define MC_SSL_O_NO_TLSV13 0x0010 /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200137
138/* ssl_methods versions */
139enum {
140 CONF_TLSV_NONE = 0,
141 CONF_TLSV_MIN = 1,
142 CONF_SSLV3 = 1,
143 CONF_TLSV10 = 2,
144 CONF_TLSV11 = 3,
145 CONF_TLSV12 = 4,
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +0200146 CONF_TLSV13 = 5,
147 CONF_TLSV_MAX = 5,
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200148};
149
Emeric Brun850efd52014-01-29 12:24:34 +0100150/* server and bind verify method, it uses a global value as default */
151enum {
152 SSL_SOCK_VERIFY_DEFAULT = 0,
153 SSL_SOCK_VERIFY_REQUIRED = 1,
154 SSL_SOCK_VERIFY_OPTIONAL = 2,
155 SSL_SOCK_VERIFY_NONE = 3,
156};
157
Willy Tarreau71b734c2014-01-28 15:19:44 +0100158int sslconns = 0;
159int totalsslconns = 0;
Willy Tarreaud9f5cca2016-12-22 21:08:52 +0100160static struct xprt_ops ssl_sock;
Emeric Brune1f38db2012-09-03 20:36:47 +0200161
Willy Tarreauef934602016-12-22 23:12:01 +0100162static struct {
163 char *crt_base; /* base directory path for certificates */
164 char *ca_base; /* base directory path for CAs and CRLs */
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000165 int async; /* whether we use ssl async mode */
Willy Tarreauef934602016-12-22 23:12:01 +0100166
167 char *listen_default_ciphers;
168 char *connect_default_ciphers;
169 int listen_default_ssloptions;
170 int connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200171 struct tls_version_filter listen_default_sslmethods;
172 struct tls_version_filter connect_default_sslmethods;
Willy Tarreauef934602016-12-22 23:12:01 +0100173
174 int private_cache; /* Force to use a private session cache even if nbproc > 1 */
175 unsigned int life_time; /* SSL session lifetime in seconds */
176 unsigned int max_record; /* SSL max record size */
177 unsigned int default_dh_param; /* SSL maximum DH parameter size */
178 int ctx_cache; /* max number of entries in the ssl_ctx cache. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100179 int capture_cipherlist; /* Size of the cipherlist buffer. */
Willy Tarreauef934602016-12-22 23:12:01 +0100180} global_ssl = {
181#ifdef LISTEN_DEFAULT_CIPHERS
182 .listen_default_ciphers = LISTEN_DEFAULT_CIPHERS,
183#endif
184#ifdef CONNECT_DEFAULT_CIPHERS
185 .connect_default_ciphers = CONNECT_DEFAULT_CIPHERS,
186#endif
187 .listen_default_ssloptions = BC_SSL_O_NONE,
188 .connect_default_ssloptions = SRV_SSL_O_NONE,
189
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200190 .listen_default_sslmethods.flags = MC_SSL_O_ALL,
191 .listen_default_sslmethods.min = CONF_TLSV_NONE,
192 .listen_default_sslmethods.max = CONF_TLSV_NONE,
193 .connect_default_sslmethods.flags = MC_SSL_O_ALL,
194 .connect_default_sslmethods.min = CONF_TLSV_NONE,
195 .connect_default_sslmethods.max = CONF_TLSV_NONE,
196
Willy Tarreauef934602016-12-22 23:12:01 +0100197#ifdef DEFAULT_SSL_MAX_RECORD
198 .max_record = DEFAULT_SSL_MAX_RECORD,
199#endif
200 .default_dh_param = SSL_DEFAULT_DH_PARAM,
201 .ctx_cache = DEFAULT_SSL_CTX_CACHE,
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100202 .capture_cipherlist = 0,
Willy Tarreauef934602016-12-22 23:12:01 +0100203};
204
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100205/* This memory pool is used for capturing clienthello parameters. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100206struct ssl_capture {
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100207 unsigned long long int xxh64;
208 unsigned char ciphersuite_len;
209 char ciphersuite[0];
210};
211struct pool_head *pool2_ssl_capture = NULL;
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100212static int ssl_capture_ptr_index = -1;
Willy Tarreauef934602016-12-22 23:12:01 +0100213
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200214#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
215struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
216#endif
217
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +0200218#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +0000219static unsigned int openssl_engines_initialized;
220struct list openssl_engines = LIST_HEAD_INIT(openssl_engines);
221struct ssl_engine_list {
222 struct list list;
223 ENGINE *e;
224};
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +0200225#endif
Grant Zhang872f9c22017-01-21 01:10:18 +0000226
Remi Gacogne8de54152014-07-15 11:36:40 +0200227#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200228static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200229static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200230static DH *local_dh_1024 = NULL;
231static DH *local_dh_2048 = NULL;
232static DH *local_dh_4096 = NULL;
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +0100233static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
Remi Gacogne8de54152014-07-15 11:36:40 +0200234#endif /* OPENSSL_NO_DH */
235
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100236#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +0200237/* X509V3 Extensions that will be added on generated certificates */
238#define X509V3_EXT_SIZE 5
239static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
240 "basicConstraints",
241 "nsComment",
242 "subjectKeyIdentifier",
243 "authorityKeyIdentifier",
244 "keyUsage",
245};
246static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
247 "CA:FALSE",
248 "\"OpenSSL Generated Certificate\"",
249 "hash",
250 "keyid,issuer:always",
251 "nonRepudiation,digitalSignature,keyEncipherment"
252};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200253/* LRU cache to store generated certificate */
254static struct lru64_head *ssl_ctx_lru_tree = NULL;
255static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200256#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
257
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100258static struct ssl_bind_kw ssl_bind_kws[];
259
yanbzhube2774d2015-12-10 15:07:30 -0500260#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
261/* The order here matters for picking a default context,
262 * keep the most common keytype at the bottom of the list
263 */
264const char *SSL_SOCK_KEYTYPE_NAMES[] = {
265 "dsa",
266 "ecdsa",
267 "rsa"
268};
269#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100270#else
271#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500272#endif
273
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100274/*
275 * This function gives the detail of the SSL error. It is used only
276 * if the debug mode and the verbose mode are activated. It dump all
277 * the SSL error until the stack was empty.
278 */
279static forceinline void ssl_sock_dump_errors(struct connection *conn)
280{
281 unsigned long ret;
282
283 if (unlikely(global.mode & MODE_DEBUG)) {
284 while(1) {
285 ret = ERR_get_error();
286 if (ret == 0)
287 return;
288 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
289 (unsigned short)conn->t.sock.fd, ret,
290 ERR_func_error_string(ret), ERR_reason_error_string(ret));
291 }
292 }
293}
294
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200295#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500296/*
297 * struct alignment works here such that the key.key is the same as key_data
298 * Do not change the placement of key_data
299 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200300struct certificate_ocsp {
301 struct ebmb_node key;
302 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
303 struct chunk response;
304 long expire;
305};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200306
yanbzhube2774d2015-12-10 15:07:30 -0500307struct ocsp_cbk_arg {
308 int is_single;
309 int single_kt;
310 union {
311 struct certificate_ocsp *s_ocsp;
312 /*
313 * m_ocsp will have multiple entries dependent on key type
314 * Entry 0 - DSA
315 * Entry 1 - ECDSA
316 * Entry 2 - RSA
317 */
318 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
319 };
320};
321
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +0200322#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +0000323static int ssl_init_single_engine(const char *engine_id, const char *def_algorithms)
324{
325 int err_code = ERR_ABORT;
326 ENGINE *engine;
327 struct ssl_engine_list *el;
328
329 /* grab the structural reference to the engine */
330 engine = ENGINE_by_id(engine_id);
331 if (engine == NULL) {
332 Alert("ssl-engine %s: failed to get structural reference\n", engine_id);
333 goto fail_get;
334 }
335
336 if (!ENGINE_init(engine)) {
337 /* the engine couldn't initialise, release it */
338 Alert("ssl-engine %s: failed to initialize\n", engine_id);
339 goto fail_init;
340 }
341
342 if (ENGINE_set_default_string(engine, def_algorithms) == 0) {
343 Alert("ssl-engine %s: failed on ENGINE_set_default_string\n", engine_id);
344 goto fail_set_method;
345 }
346
347 el = calloc(1, sizeof(*el));
348 el->e = engine;
349 LIST_ADD(&openssl_engines, &el->list);
350 return 0;
351
352fail_set_method:
353 /* release the functional reference from ENGINE_init() */
354 ENGINE_finish(engine);
355
356fail_init:
357 /* release the structural reference from ENGINE_by_id() */
358 ENGINE_free(engine);
359
360fail_get:
361 return err_code;
362}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +0200363#endif
Grant Zhang872f9c22017-01-21 01:10:18 +0000364
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000365#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brun3854e012017-05-17 20:42:48 +0200366/*
367 * openssl async fd handler
368 */
369static void ssl_async_fd_handler(int fd)
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000370{
371 struct connection *conn = fdtab[fd].owner;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000372
Emeric Brun3854e012017-05-17 20:42:48 +0200373 /* fd is an async enfine fd, we must stop
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000374 * to poll this fd until it is requested
375 */
Emeric Brunbbc16542017-06-02 15:54:06 +0000376 fd_stop_recv(fd);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000377 fd_cant_recv(fd);
378
379 /* crypto engine is available, let's notify the associated
380 * connection that it can pursue its processing.
381 */
Emeric Brunbbc16542017-06-02 15:54:06 +0000382 __conn_sock_want_recv(conn);
383 __conn_sock_want_send(conn);
384 conn_update_sock_polling(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000385}
386
Emeric Brun3854e012017-05-17 20:42:48 +0200387/*
388 * openssl async delayed SSL_free handler
389 */
390static void ssl_async_fd_free(int fd)
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000391{
392 SSL *ssl = fdtab[fd].owner;
Emeric Brun3854e012017-05-17 20:42:48 +0200393 OSSL_ASYNC_FD all_fd[32];
394 size_t num_all_fds = 0;
395 int i;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000396
Emeric Brun3854e012017-05-17 20:42:48 +0200397 /* We suppose that the async job for a same SSL *
398 * are serialized. So if we are awake it is
399 * because the running job has just finished
400 * and we can remove all async fds safely
401 */
402 SSL_get_all_async_fds(ssl, NULL, &num_all_fds);
403 if (num_all_fds > 32) {
404 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
405 return;
406 }
407
408 SSL_get_all_async_fds(ssl, all_fd, &num_all_fds);
409 for (i=0 ; i < num_all_fds ; i++)
410 fd_remove(all_fd[i]);
411
412 /* Now we can safely call SSL_free, no more pending job in engines */
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000413 SSL_free(ssl);
414 sslconns--;
415 jobs--;
416}
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000417/*
Emeric Brun3854e012017-05-17 20:42:48 +0200418 * function used to manage a returned SSL_ERROR_WANT_ASYNC
419 * and enable/disable polling for async fds
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000420 */
Emeric Brun3854e012017-05-17 20:42:48 +0200421static void inline ssl_async_process_fds(struct connection *conn, SSL *ssl)
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000422{
Emeric Brun3854e012017-05-17 20:42:48 +0200423 OSSL_ASYNC_FD add_fd[32], afd;
424 OSSL_ASYNC_FD del_fd[32];
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000425 size_t num_add_fds = 0;
426 size_t num_del_fds = 0;
Emeric Brun3854e012017-05-17 20:42:48 +0200427 int i;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000428
429 SSL_get_changed_async_fds(ssl, NULL, &num_add_fds, NULL,
430 &num_del_fds);
Emeric Brun3854e012017-05-17 20:42:48 +0200431 if (num_add_fds > 32 || num_del_fds > 32) {
432 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000433 return;
434 }
435
Emeric Brun3854e012017-05-17 20:42:48 +0200436 SSL_get_changed_async_fds(ssl, add_fd, &num_add_fds, del_fd, &num_del_fds);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000437
Emeric Brun3854e012017-05-17 20:42:48 +0200438 /* We remove unused fds from the fdtab */
439 for (i=0 ; i < num_del_fds ; i++)
440 fd_remove(del_fd[i]);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000441
Emeric Brun3854e012017-05-17 20:42:48 +0200442 /* We add new fds to the fdtab */
443 for (i=0 ; i < num_add_fds ; i++) {
444 afd = add_fd[i];
445 fdtab[afd].owner = conn;
446 fdtab[afd].iocb = ssl_async_fd_handler;
447 fd_insert(afd);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000448 }
449
Emeric Brun3854e012017-05-17 20:42:48 +0200450 num_add_fds = 0;
451 SSL_get_all_async_fds(ssl, NULL, &num_add_fds);
452 if (num_add_fds > 32) {
453 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
454 return;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000455 }
Emeric Brun3854e012017-05-17 20:42:48 +0200456
457 /* We activate the polling for all known async fds */
458 SSL_get_all_async_fds(ssl, add_fd, &num_add_fds);
Emeric Brunce9e01c2017-05-31 10:02:53 +0000459 for (i=0 ; i < num_add_fds ; i++) {
Emeric Brun3854e012017-05-17 20:42:48 +0200460 fd_want_recv(add_fd[i]);
Emeric Brunce9e01c2017-05-31 10:02:53 +0000461 /* To ensure that the fd cache won't be used
462 * We'll prefer to catch a real RD event
463 * because handling an EAGAIN on this fd will
464 * result in a context switch and also
465 * some engines uses a fd in blocking mode.
466 */
467 fd_cant_recv(add_fd[i]);
468 }
Emeric Brun3854e012017-05-17 20:42:48 +0200469
470 /* We must also prevent the conn_handler
471 * to be called until a read event was
472 * polled on an async fd
473 */
474 __conn_sock_stop_both(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000475}
476#endif
477
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200478/*
479 * This function returns the number of seconds elapsed
480 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
481 * date presented un ASN1_GENERALIZEDTIME.
482 *
483 * In parsing error case, it returns -1.
484 */
485static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
486{
487 long epoch;
488 char *p, *end;
489 const unsigned short month_offset[12] = {
490 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
491 };
492 int year, month;
493
494 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
495
496 p = (char *)d->data;
497 end = p + d->length;
498
499 if (end - p < 4) return -1;
500 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
501 p += 4;
502 if (end - p < 2) return -1;
503 month = 10 * (p[0] - '0') + p[1] - '0';
504 if (month < 1 || month > 12) return -1;
505 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
506 We consider leap years and the current month (<marsh or not) */
507 epoch = ( ((year - 1970) * 365)
508 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
509 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
510 + month_offset[month-1]
511 ) * 24 * 60 * 60;
512 p += 2;
513 if (end - p < 2) return -1;
514 /* Add the number of seconds of completed days of current month */
515 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
516 p += 2;
517 if (end - p < 2) return -1;
518 /* Add the completed hours of the current day */
519 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
520 p += 2;
521 if (end - p < 2) return -1;
522 /* Add the completed minutes of the current hour */
523 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
524 p += 2;
525 if (p == end) return -1;
526 /* Test if there is available seconds */
527 if (p[0] < '0' || p[0] > '9')
528 goto nosec;
529 if (end - p < 2) return -1;
530 /* Add the seconds of the current minute */
531 epoch += 10 * (p[0] - '0') + p[1] - '0';
532 p += 2;
533 if (p == end) return -1;
534 /* Ignore seconds float part if present */
535 if (p[0] == '.') {
536 do {
537 if (++p == end) return -1;
538 } while (p[0] >= '0' && p[0] <= '9');
539 }
540
541nosec:
542 if (p[0] == 'Z') {
543 if (end - p != 1) return -1;
544 return epoch;
545 }
546 else if (p[0] == '+') {
547 if (end - p != 5) return -1;
548 /* Apply timezone offset */
549 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
550 }
551 else if (p[0] == '-') {
552 if (end - p != 5) return -1;
553 /* Apply timezone offset */
554 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
555 }
556
557 return -1;
558}
559
Emeric Brun1d3865b2014-06-20 15:37:32 +0200560static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200561
562/* This function starts to check if the OCSP response (in DER format) contained
563 * in chunk 'ocsp_response' is valid (else exits on error).
564 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
565 * contained in the OCSP Response and exits on error if no match.
566 * If it's a valid OCSP Response:
567 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
568 * pointed by 'ocsp'.
569 * If 'ocsp' is NULL, the function looks up into the OCSP response's
570 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
571 * from the response) and exits on error if not found. Finally, If an OCSP response is
572 * already present in the container, it will be overwritten.
573 *
574 * Note: OCSP response containing more than one OCSP Single response is not
575 * considered valid.
576 *
577 * Returns 0 on success, 1 in error case.
578 */
579static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
580{
581 OCSP_RESPONSE *resp;
582 OCSP_BASICRESP *bs = NULL;
583 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200584 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200585 unsigned char *p = (unsigned char *)ocsp_response->str;
586 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200587 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200588 int reason;
589 int ret = 1;
590
591 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
592 if (!resp) {
593 memprintf(err, "Unable to parse OCSP response");
594 goto out;
595 }
596
597 rc = OCSP_response_status(resp);
598 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
599 memprintf(err, "OCSP response status not successful");
600 goto out;
601 }
602
603 bs = OCSP_response_get1_basic(resp);
604 if (!bs) {
605 memprintf(err, "Failed to get basic response from OCSP Response");
606 goto out;
607 }
608
609 count_sr = OCSP_resp_count(bs);
610 if (count_sr > 1) {
611 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
612 goto out;
613 }
614
615 sr = OCSP_resp_get0(bs, 0);
616 if (!sr) {
617 memprintf(err, "Failed to get OCSP single response");
618 goto out;
619 }
620
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200621 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
622
Emeric Brun4147b2e2014-06-16 18:36:30 +0200623 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
624 if (rc != V_OCSP_CERTSTATUS_GOOD) {
625 memprintf(err, "OCSP single response: certificate status not good");
626 goto out;
627 }
628
Emeric Brun13a6b482014-06-20 15:44:34 +0200629 if (!nextupd) {
630 memprintf(err, "OCSP single response: missing nextupdate");
631 goto out;
632 }
633
Emeric Brunc8b27b62014-06-19 14:16:17 +0200634 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200635 if (!rc) {
636 memprintf(err, "OCSP single response: no longer valid.");
637 goto out;
638 }
639
640 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200641 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200642 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
643 goto out;
644 }
645 }
646
647 if (!ocsp) {
648 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
649 unsigned char *p;
650
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200651 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200652 if (!rc) {
653 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
654 goto out;
655 }
656
657 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
658 memprintf(err, "OCSP single response: Certificate ID too long");
659 goto out;
660 }
661
662 p = key;
663 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200664 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200665 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
666 if (!ocsp) {
667 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
668 goto out;
669 }
670 }
671
672 /* According to comments on "chunk_dup", the
673 previous chunk buffer will be freed */
674 if (!chunk_dup(&ocsp->response, ocsp_response)) {
675 memprintf(err, "OCSP response: Memory allocation error");
676 goto out;
677 }
678
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200679 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
680
Emeric Brun4147b2e2014-06-16 18:36:30 +0200681 ret = 0;
682out:
Janusz Dziemidowicz8d710492017-03-08 16:59:41 +0100683 ERR_clear_error();
684
Emeric Brun4147b2e2014-06-16 18:36:30 +0200685 if (bs)
686 OCSP_BASICRESP_free(bs);
687
688 if (resp)
689 OCSP_RESPONSE_free(resp);
690
691 return ret;
692}
693/*
694 * External function use to update the OCSP response in the OCSP response's
695 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
696 * to update in DER format.
697 *
698 * Returns 0 on success, 1 in error case.
699 */
700int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
701{
702 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
703}
704
705/*
706 * This function load the OCSP Resonse in DER format contained in file at
707 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
708 *
709 * Returns 0 on success, 1 in error case.
710 */
711static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
712{
713 int fd = -1;
714 int r = 0;
715 int ret = 1;
716
717 fd = open(ocsp_path, O_RDONLY);
718 if (fd == -1) {
719 memprintf(err, "Error opening OCSP response file");
720 goto end;
721 }
722
723 trash.len = 0;
724 while (trash.len < trash.size) {
725 r = read(fd, trash.str + trash.len, trash.size - trash.len);
726 if (r < 0) {
727 if (errno == EINTR)
728 continue;
729
730 memprintf(err, "Error reading OCSP response from file");
731 goto end;
732 }
733 else if (r == 0) {
734 break;
735 }
736 trash.len += r;
737 }
738
739 close(fd);
740 fd = -1;
741
742 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
743end:
744 if (fd != -1)
745 close(fd);
746
747 return ret;
748}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100749#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200750
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100751#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
752static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
753{
754 struct tls_sess_key *keys;
755 struct connection *conn;
756 int head;
757 int i;
758
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200759 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200760 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
761 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100762
763 if (enc) {
764 memcpy(key_name, keys[head].name, 16);
765
766 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
767 return -1;
768
769 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
770 return -1;
771
772 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
773
774 return 1;
775 } else {
776 for (i = 0; i < TLS_TICKETS_NO; i++) {
777 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
778 goto found;
779 }
780 return 0;
781
782 found:
783 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
784 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
785 return -1;
786 /* 2 for key renewal, 1 if current key is still valid */
787 return i ? 2 : 1;
788 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200789}
790
791struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
792{
793 struct tls_keys_ref *ref;
794
795 list_for_each_entry(ref, &tlskeys_reference, list)
796 if (ref->filename && strcmp(filename, ref->filename) == 0)
797 return ref;
798 return NULL;
799}
800
801struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
802{
803 struct tls_keys_ref *ref;
804
805 list_for_each_entry(ref, &tlskeys_reference, list)
806 if (ref->unique_id == unique_id)
807 return ref;
808 return NULL;
809}
810
811int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
812 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
813
814 if(!ref) {
815 memprintf(err, "Unable to locate the referenced filename: %s", filename);
816 return 1;
817 }
818
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530819 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
820 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200821
822 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100823}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200824
825/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100826 * automatic ids. It's called just after the basic checks. It returns
827 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200828 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100829static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200830{
831 int i = 0;
832 struct tls_keys_ref *ref, *ref2, *ref3;
833 struct list tkr = LIST_HEAD_INIT(tkr);
834
835 list_for_each_entry(ref, &tlskeys_reference, list) {
836 if (ref->unique_id == -1) {
837 /* Look for the first free id. */
838 while (1) {
839 list_for_each_entry(ref2, &tlskeys_reference, list) {
840 if (ref2->unique_id == i) {
841 i++;
842 break;
843 }
844 }
845 if (&ref2->list == &tlskeys_reference)
846 break;
847 }
848
849 /* Uses the unique id and increment it for the next entry. */
850 ref->unique_id = i;
851 i++;
852 }
853 }
854
855 /* This sort the reference list by id. */
856 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
857 LIST_DEL(&ref->list);
858 list_for_each_entry(ref3, &tkr, list) {
859 if (ref->unique_id < ref3->unique_id) {
860 LIST_ADDQ(&ref3->list, &ref->list);
861 break;
862 }
863 }
864 if (&ref3->list == &tkr)
865 LIST_ADDQ(&tkr, &ref->list);
866 }
867
868 /* swap root */
869 LIST_ADD(&tkr, &tlskeys_reference);
870 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100871 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200872}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100873#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
874
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100875#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500876int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
877{
878 switch (evp_keytype) {
879 case EVP_PKEY_RSA:
880 return 2;
881 case EVP_PKEY_DSA:
882 return 0;
883 case EVP_PKEY_EC:
884 return 1;
885 }
886
887 return -1;
888}
889
Emeric Brun4147b2e2014-06-16 18:36:30 +0200890/*
891 * Callback used to set OCSP status extension content in server hello.
892 */
893int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
894{
yanbzhube2774d2015-12-10 15:07:30 -0500895 struct certificate_ocsp *ocsp;
896 struct ocsp_cbk_arg *ocsp_arg;
897 char *ssl_buf;
898 EVP_PKEY *ssl_pkey;
899 int key_type;
900 int index;
901
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200902 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500903
904 ssl_pkey = SSL_get_privatekey(ssl);
905 if (!ssl_pkey)
906 return SSL_TLSEXT_ERR_NOACK;
907
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200908 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500909
910 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
911 ocsp = ocsp_arg->s_ocsp;
912 else {
913 /* For multiple certs per context, we have to find the correct OCSP response based on
914 * the certificate type
915 */
916 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
917
918 if (index < 0)
919 return SSL_TLSEXT_ERR_NOACK;
920
921 ocsp = ocsp_arg->m_ocsp[index];
922
923 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200924
925 if (!ocsp ||
926 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200927 !ocsp->response.len ||
928 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200929 return SSL_TLSEXT_ERR_NOACK;
930
931 ssl_buf = OPENSSL_malloc(ocsp->response.len);
932 if (!ssl_buf)
933 return SSL_TLSEXT_ERR_NOACK;
934
935 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
936 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
937
938 return SSL_TLSEXT_ERR_OK;
939}
940
941/*
942 * This function enables the handling of OCSP status extension on 'ctx' if a
943 * file name 'cert_path' suffixed using ".ocsp" is present.
944 * To enable OCSP status extension, the issuer's certificate is mandatory.
945 * It should be present in the certificate's extra chain builded from file
946 * 'cert_path'. If not found, the issuer certificate is loaded from a file
947 * named 'cert_path' suffixed using '.issuer'.
948 *
949 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
950 * response. If file is empty or content is not a valid OCSP response,
951 * OCSP status extension is enabled but OCSP response is ignored (a warning
952 * is displayed).
953 *
954 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
955 * succesfully enabled, or -1 in other error case.
956 */
957static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
958{
959
960 BIO *in = NULL;
961 X509 *x, *xi = NULL, *issuer = NULL;
962 STACK_OF(X509) *chain = NULL;
963 OCSP_CERTID *cid = NULL;
964 SSL *ssl;
965 char ocsp_path[MAXPATHLEN+1];
966 int i, ret = -1;
967 struct stat st;
968 struct certificate_ocsp *ocsp = NULL, *iocsp;
969 char *warn = NULL;
970 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200971 pem_password_cb *passwd_cb;
972 void *passwd_cb_userdata;
973 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200974
975 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
976
977 if (stat(ocsp_path, &st))
978 return 1;
979
980 ssl = SSL_new(ctx);
981 if (!ssl)
982 goto out;
983
984 x = SSL_get_certificate(ssl);
985 if (!x)
986 goto out;
987
988 /* Try to lookup for issuer in certificate extra chain */
989#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
990 SSL_CTX_get_extra_chain_certs(ctx, &chain);
991#else
992 chain = ctx->extra_certs;
993#endif
994 for (i = 0; i < sk_X509_num(chain); i++) {
995 issuer = sk_X509_value(chain, i);
996 if (X509_check_issued(issuer, x) == X509_V_OK)
997 break;
998 else
999 issuer = NULL;
1000 }
1001
1002 /* If not found try to load issuer from a suffixed file */
1003 if (!issuer) {
1004 char issuer_path[MAXPATHLEN+1];
1005
1006 in = BIO_new(BIO_s_file());
1007 if (!in)
1008 goto out;
1009
1010 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
1011 if (BIO_read_filename(in, issuer_path) <= 0)
1012 goto out;
1013
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001014 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
1015 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
1016
1017 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +02001018 if (!xi)
1019 goto out;
1020
1021 if (X509_check_issued(xi, x) != X509_V_OK)
1022 goto out;
1023
1024 issuer = xi;
1025 }
1026
1027 cid = OCSP_cert_to_id(0, x, issuer);
1028 if (!cid)
1029 goto out;
1030
1031 i = i2d_OCSP_CERTID(cid, NULL);
1032 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
1033 goto out;
1034
Vincent Bernat02779b62016-04-03 13:48:43 +02001035 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +02001036 if (!ocsp)
1037 goto out;
1038
1039 p = ocsp->key_data;
1040 i2d_OCSP_CERTID(cid, &p);
1041
1042 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
1043 if (iocsp == ocsp)
1044 ocsp = NULL;
1045
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001046#ifndef SSL_CTX_get_tlsext_status_cb
1047# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
1048 *cb = (void (*) (void))ctx->tlsext_status_cb;
1049#endif
1050 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
1051
1052 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +02001053 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001054 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -05001055
1056 cb_arg->is_single = 1;
1057 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001058
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001059 pkey = X509_get_pubkey(x);
1060 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
1061 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -05001062
1063 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
1064 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
1065 } else {
1066 /*
1067 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
1068 * Update that cb_arg with the new cert's staple
1069 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001070 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -05001071 struct certificate_ocsp *tmp_ocsp;
1072 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001073 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001074 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001075
1076#ifdef SSL_CTX_get_tlsext_status_arg
1077 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
1078#else
1079 cb_arg = ctx->tlsext_status_arg;
1080#endif
yanbzhube2774d2015-12-10 15:07:30 -05001081
1082 /*
1083 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
1084 * the order of operations below matter, take care when changing it
1085 */
1086 tmp_ocsp = cb_arg->s_ocsp;
1087 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
1088 cb_arg->s_ocsp = NULL;
1089 cb_arg->m_ocsp[index] = tmp_ocsp;
1090 cb_arg->is_single = 0;
1091 cb_arg->single_kt = 0;
1092
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001093 pkey = X509_get_pubkey(x);
1094 key_type = EVP_PKEY_base_id(pkey);
1095 EVP_PKEY_free(pkey);
1096
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001097 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -05001098 if (index >= 0 && !cb_arg->m_ocsp[index])
1099 cb_arg->m_ocsp[index] = iocsp;
1100
1101 }
Emeric Brun4147b2e2014-06-16 18:36:30 +02001102
1103 ret = 0;
1104
1105 warn = NULL;
1106 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
1107 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
1108 Warning("%s.\n", warn);
1109 }
1110
1111out:
1112 if (ssl)
1113 SSL_free(ssl);
1114
1115 if (in)
1116 BIO_free(in);
1117
1118 if (xi)
1119 X509_free(xi);
1120
1121 if (cid)
1122 OCSP_CERTID_free(cid);
1123
1124 if (ocsp)
1125 free(ocsp);
1126
1127 if (warn)
1128 free(warn);
1129
1130
1131 return ret;
1132}
1133
1134#endif
1135
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02001136#ifdef OPENSSL_IS_BORINGSSL
1137static int ssl_sock_set_ocsp_response_from_file(SSL_CTX *ctx, const char *cert_path)
1138{
1139 char ocsp_path[MAXPATHLEN+1];
1140 struct stat st;
1141 int fd = -1, r = 0;
1142
1143 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
1144 if (stat(ocsp_path, &st))
1145 return 0;
1146
1147 fd = open(ocsp_path, O_RDONLY);
1148 if (fd == -1) {
1149 Warning("Error opening OCSP response file %s.\n", ocsp_path);
1150 return -1;
1151 }
1152
1153 trash.len = 0;
1154 while (trash.len < trash.size) {
1155 r = read(fd, trash.str + trash.len, trash.size - trash.len);
1156 if (r < 0) {
1157 if (errno == EINTR)
1158 continue;
1159 Warning("Error reading OCSP response from file %s.\n", ocsp_path);
1160 close(fd);
1161 return -1;
1162 }
1163 else if (r == 0) {
1164 break;
1165 }
1166 trash.len += r;
1167 }
1168 close(fd);
1169 return SSL_CTX_set_ocsp_response(ctx, (const uint8_t *)trash.str, trash.len);
1170}
1171#endif
1172
Daniel Jakots54ffb912015-11-06 20:02:41 +01001173#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001174
1175#define CT_EXTENSION_TYPE 18
1176
1177static int sctl_ex_index = -1;
1178
1179/*
1180 * Try to parse Signed Certificate Timestamp List structure. This function
1181 * makes only basic test if the data seems like SCTL. No signature validation
1182 * is performed.
1183 */
1184static int ssl_sock_parse_sctl(struct chunk *sctl)
1185{
1186 int ret = 1;
1187 int len, pos, sct_len;
1188 unsigned char *data;
1189
1190 if (sctl->len < 2)
1191 goto out;
1192
1193 data = (unsigned char *)sctl->str;
1194 len = (data[0] << 8) | data[1];
1195
1196 if (len + 2 != sctl->len)
1197 goto out;
1198
1199 data = data + 2;
1200 pos = 0;
1201 while (pos < len) {
1202 if (len - pos < 2)
1203 goto out;
1204
1205 sct_len = (data[pos] << 8) | data[pos + 1];
1206 if (pos + sct_len + 2 > len)
1207 goto out;
1208
1209 pos += sct_len + 2;
1210 }
1211
1212 ret = 0;
1213
1214out:
1215 return ret;
1216}
1217
1218static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
1219{
1220 int fd = -1;
1221 int r = 0;
1222 int ret = 1;
1223
1224 *sctl = NULL;
1225
1226 fd = open(sctl_path, O_RDONLY);
1227 if (fd == -1)
1228 goto end;
1229
1230 trash.len = 0;
1231 while (trash.len < trash.size) {
1232 r = read(fd, trash.str + trash.len, trash.size - trash.len);
1233 if (r < 0) {
1234 if (errno == EINTR)
1235 continue;
1236
1237 goto end;
1238 }
1239 else if (r == 0) {
1240 break;
1241 }
1242 trash.len += r;
1243 }
1244
1245 ret = ssl_sock_parse_sctl(&trash);
1246 if (ret)
1247 goto end;
1248
Vincent Bernat02779b62016-04-03 13:48:43 +02001249 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001250 if (!chunk_dup(*sctl, &trash)) {
1251 free(*sctl);
1252 *sctl = NULL;
1253 goto end;
1254 }
1255
1256end:
1257 if (fd != -1)
1258 close(fd);
1259
1260 return ret;
1261}
1262
1263int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1264{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001265 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001266
1267 *out = (unsigned char *)sctl->str;
1268 *outlen = sctl->len;
1269
1270 return 1;
1271}
1272
1273int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1274{
1275 return 1;
1276}
1277
1278static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1279{
1280 char sctl_path[MAXPATHLEN+1];
1281 int ret = -1;
1282 struct stat st;
1283 struct chunk *sctl = NULL;
1284
1285 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1286
1287 if (stat(sctl_path, &st))
1288 return 1;
1289
1290 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1291 goto out;
1292
1293 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1294 free(sctl);
1295 goto out;
1296 }
1297
1298 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1299
1300 ret = 0;
1301
1302out:
1303 return ret;
1304}
1305
1306#endif
1307
Emeric Brune1f38db2012-09-03 20:36:47 +02001308void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1309{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001310 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001311 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001312 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001313
1314 if (where & SSL_CB_HANDSHAKE_START) {
1315 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001316 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001317 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001318 conn->err_code = CO_ER_SSL_RENEG;
1319 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001320 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001321
1322 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1323 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1324 /* Long certificate chains optimz
1325 If write and read bios are differents, we
1326 consider that the buffering was activated,
1327 so we rise the output buffer size from 4k
1328 to 16k */
1329 write_bio = SSL_get_wbio(ssl);
1330 if (write_bio != SSL_get_rbio(ssl)) {
1331 BIO_set_write_buffer_size(write_bio, 16384);
1332 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1333 }
1334 }
1335 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001336}
1337
Emeric Brune64aef12012-09-21 13:15:06 +02001338/* Callback is called for each certificate of the chain during a verify
1339 ok is set to 1 if preverify detect no error on current certificate.
1340 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001341int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001342{
1343 SSL *ssl;
1344 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001345 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001346
1347 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001348 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001349
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001350 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001351
Emeric Brun81c00f02012-09-21 14:31:21 +02001352 if (ok) /* no errors */
1353 return ok;
1354
1355 depth = X509_STORE_CTX_get_error_depth(x_store);
1356 err = X509_STORE_CTX_get_error(x_store);
1357
1358 /* check if CA error needs to be ignored */
1359 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001360 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1361 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1362 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001363 }
1364
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001365 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001366 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001367 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001368 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001369 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001370
Willy Tarreau20879a02012-12-03 16:32:10 +01001371 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001372 return 0;
1373 }
1374
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001375 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1376 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001377
Emeric Brun81c00f02012-09-21 14:31:21 +02001378 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001379 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001380 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001381 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001382 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001383 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001384
Willy Tarreau20879a02012-12-03 16:32:10 +01001385 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001386 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001387}
1388
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001389static inline
1390void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001391 const void *buf, size_t len, SSL *ssl)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001392{
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001393 struct ssl_capture *capture;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001394 unsigned char *msg;
1395 unsigned char *end;
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001396 size_t rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001397
1398 /* This function is called for "from client" and "to server"
1399 * connections. The combination of write_p == 0 and content_type == 22
1400 * is only avalaible during "from client" connection.
1401 */
1402
1403 /* "write_p" is set to 0 is the bytes are received messages,
1404 * otherwise it is set to 1.
1405 */
1406 if (write_p != 0)
1407 return;
1408
1409 /* content_type contains the type of message received or sent
1410 * according with the SSL/TLS protocol spec. This message is
1411 * encoded with one byte. The value 256 (two bytes) is used
1412 * for designing the SSL/TLS record layer. According with the
1413 * rfc6101, the expected message (other than 256) are:
1414 * - change_cipher_spec(20)
1415 * - alert(21)
1416 * - handshake(22)
1417 * - application_data(23)
1418 * - (255)
1419 * We are interessed by the handshake and specially the client
1420 * hello.
1421 */
1422 if (content_type != 22)
1423 return;
1424
1425 /* The message length is at least 4 bytes, containing the
1426 * message type and the message length.
1427 */
1428 if (len < 4)
1429 return;
1430
1431 /* First byte of the handshake message id the type of
1432 * message. The konwn types are:
1433 * - hello_request(0)
1434 * - client_hello(1)
1435 * - server_hello(2)
1436 * - certificate(11)
1437 * - server_key_exchange (12)
1438 * - certificate_request(13)
1439 * - server_hello_done(14)
1440 * We are interested by the client hello.
1441 */
1442 msg = (unsigned char *)buf;
1443 if (msg[0] != 1)
1444 return;
1445
1446 /* Next three bytes are the length of the message. The total length
1447 * must be this decoded length + 4. If the length given as argument
1448 * is not the same, we abort the protocol dissector.
1449 */
1450 rec_len = (msg[1] << 16) + (msg[2] << 8) + msg[3];
1451 if (len < rec_len + 4)
1452 return;
1453 msg += 4;
1454 end = msg + rec_len;
1455 if (end < msg)
1456 return;
1457
1458 /* Expect 2 bytes for protocol version (1 byte for major and 1 byte
1459 * for minor, the random, composed by 4 bytes for the unix time and
1460 * 28 bytes for unix payload, and them 1 byte for the session id. So
1461 * we jump 1 + 1 + 4 + 28 + 1 bytes.
1462 */
1463 msg += 1 + 1 + 4 + 28 + 1;
1464 if (msg > end)
1465 return;
1466
1467 /* Next two bytes are the ciphersuite length. */
1468 if (msg + 2 > end)
1469 return;
1470 rec_len = (msg[0] << 8) + msg[1];
1471 msg += 2;
1472 if (msg + rec_len > end || msg + rec_len < msg)
1473 return;
1474
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001475 capture = pool_alloc_dirty(pool2_ssl_capture);
1476 if (!capture)
1477 return;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001478 /* Compute the xxh64 of the ciphersuite. */
1479 capture->xxh64 = XXH64(msg, rec_len, 0);
1480
1481 /* Capture the ciphersuite. */
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001482 capture->ciphersuite_len = (global_ssl.capture_cipherlist < rec_len) ?
1483 global_ssl.capture_cipherlist : rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001484 memcpy(capture->ciphersuite, msg, capture->ciphersuite_len);
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001485
1486 SSL_set_ex_data(ssl, ssl_capture_ptr_index, capture);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001487}
1488
Emeric Brun29f037d2014-04-25 19:05:36 +02001489/* Callback is called for ssl protocol analyse */
1490void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1491{
Emeric Brun29f037d2014-04-25 19:05:36 +02001492#ifdef TLS1_RT_HEARTBEAT
1493 /* test heartbeat received (write_p is set to 0
1494 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001495 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001496 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001497 const unsigned char *p = buf;
1498 unsigned int payload;
1499
Emeric Brun29f037d2014-04-25 19:05:36 +02001500 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001501
1502 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1503 if (*p != TLS1_HB_REQUEST)
1504 return;
1505
Willy Tarreauaeed6722014-04-25 23:59:58 +02001506 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001507 goto kill_it;
1508
1509 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001510 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001511 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001512 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001513 /* We have a clear heartbleed attack (CVE-2014-0160), the
1514 * advertised payload is larger than the advertised packet
1515 * length, so we have garbage in the buffer between the
1516 * payload and the end of the buffer (p+len). We can't know
1517 * if the SSL stack is patched, and we don't know if we can
1518 * safely wipe out the area between p+3+len and payload.
1519 * So instead, we prevent the response from being sent by
1520 * setting the max_send_fragment to 0 and we report an SSL
1521 * error, which will kill this connection. It will be reported
1522 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001523 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1524 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001525 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001526 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1527 return;
1528 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001529#endif
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001530 if (global_ssl.capture_cipherlist > 0)
1531 ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
Emeric Brun29f037d2014-04-25 19:05:36 +02001532}
1533
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001534#ifdef OPENSSL_NPN_NEGOTIATED
1535/* This callback is used so that the server advertises the list of
1536 * negociable protocols for NPN.
1537 */
1538static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1539 unsigned int *len, void *arg)
1540{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001541 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001542
1543 *data = (const unsigned char *)conf->npn_str;
1544 *len = conf->npn_len;
1545 return SSL_TLSEXT_ERR_OK;
1546}
1547#endif
1548
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001549#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001550/* This callback is used so that the server advertises the list of
1551 * negociable protocols for ALPN.
1552 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001553static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1554 unsigned char *outlen,
1555 const unsigned char *server,
1556 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001557{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001558 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001559
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001560 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1561 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1562 return SSL_TLSEXT_ERR_NOACK;
1563 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001564 return SSL_TLSEXT_ERR_OK;
1565}
1566#endif
1567
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001568#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001569#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001570
Christopher Faulet30548802015-06-11 13:39:32 +02001571/* Create a X509 certificate with the specified servername and serial. This
1572 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001573static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001574ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001575{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001576 static unsigned int serial = 0;
1577
Christopher Faulet7969a332015-10-09 11:15:03 +02001578 X509 *cacert = bind_conf->ca_sign_cert;
1579 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001580 SSL_CTX *ssl_ctx = NULL;
1581 X509 *newcrt = NULL;
1582 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001583 X509_NAME *name;
1584 const EVP_MD *digest;
1585 X509V3_CTX ctx;
1586 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001587 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001588
Christopher Faulet7969a332015-10-09 11:15:03 +02001589 /* Get the private key of the defautl certificate and use it */
1590 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001591 goto mkcert_error;
1592
1593 /* Create the certificate */
1594 if (!(newcrt = X509_new()))
1595 goto mkcert_error;
1596
1597 /* Set version number for the certificate (X509v3) and the serial
1598 * number */
1599 if (X509_set_version(newcrt, 2L) != 1)
1600 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001601 if (!serial)
1602 serial = now_ms;
1603 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001604
1605 /* Set duration for the certificate */
1606 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1607 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1608 goto mkcert_error;
1609
1610 /* set public key in the certificate */
1611 if (X509_set_pubkey(newcrt, pkey) != 1)
1612 goto mkcert_error;
1613
1614 /* Set issuer name from the CA */
1615 if (!(name = X509_get_subject_name(cacert)))
1616 goto mkcert_error;
1617 if (X509_set_issuer_name(newcrt, name) != 1)
1618 goto mkcert_error;
1619
1620 /* Set the subject name using the same, but the CN */
1621 name = X509_NAME_dup(name);
1622 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1623 (const unsigned char *)servername,
1624 -1, -1, 0) != 1) {
1625 X509_NAME_free(name);
1626 goto mkcert_error;
1627 }
1628 if (X509_set_subject_name(newcrt, name) != 1) {
1629 X509_NAME_free(name);
1630 goto mkcert_error;
1631 }
1632 X509_NAME_free(name);
1633
1634 /* Add x509v3 extensions as specified */
1635 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1636 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1637 X509_EXTENSION *ext;
1638
1639 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1640 goto mkcert_error;
1641 if (!X509_add_ext(newcrt, ext, -1)) {
1642 X509_EXTENSION_free(ext);
1643 goto mkcert_error;
1644 }
1645 X509_EXTENSION_free(ext);
1646 }
1647
1648 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001649
1650 key_type = EVP_PKEY_base_id(capkey);
1651
1652 if (key_type == EVP_PKEY_DSA)
1653 digest = EVP_sha1();
1654 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001655 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001656 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001657 digest = EVP_sha256();
1658 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001659#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001660 int nid;
1661
1662 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1663 goto mkcert_error;
1664 if (!(digest = EVP_get_digestbynid(nid)))
1665 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001666#else
1667 goto mkcert_error;
1668#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001669 }
1670
Christopher Faulet31af49d2015-06-09 17:29:50 +02001671 if (!(X509_sign(newcrt, capkey, digest)))
1672 goto mkcert_error;
1673
1674 /* Create and set the new SSL_CTX */
1675 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1676 goto mkcert_error;
1677 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1678 goto mkcert_error;
1679 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1680 goto mkcert_error;
1681 if (!SSL_CTX_check_private_key(ssl_ctx))
1682 goto mkcert_error;
1683
1684 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001685
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001686#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001687 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001688#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001689#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1690 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001691 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001692 EC_KEY *ecc;
1693 int nid;
1694
1695 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1696 goto end;
1697 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1698 goto end;
1699 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1700 EC_KEY_free(ecc);
1701 }
1702#endif
1703 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001704 return ssl_ctx;
1705
1706 mkcert_error:
1707 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1708 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001709 return NULL;
1710}
1711
Christopher Faulet7969a332015-10-09 11:15:03 +02001712SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001713ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001714{
1715 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001716
1717 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001718}
1719
Christopher Faulet30548802015-06-11 13:39:32 +02001720/* Do a lookup for a certificate in the LRU cache used to store generated
1721 * certificates. */
1722SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001723ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001724{
1725 struct lru64 *lru = NULL;
1726
1727 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001728 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001729 if (lru && lru->domain)
1730 return (SSL_CTX *)lru->data;
1731 }
1732 return NULL;
1733}
1734
Christopher Fauletd2cab922015-07-28 16:03:47 +02001735/* Set a certificate int the LRU cache used to store generated
1736 * certificate. Return 0 on success, otherwise -1 */
1737int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001738ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001739{
1740 struct lru64 *lru = NULL;
1741
1742 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001743 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001744 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001745 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001746 if (lru->domain && lru->data)
1747 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001748 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001749 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001750 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001751 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001752}
1753
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001754/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001755unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001756ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001757{
1758 return XXH32(data, len, ssl_ctx_lru_seed);
1759}
1760
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001761/* Generate a cert and immediately assign it to the SSL session so that the cert's
1762 * refcount is maintained regardless of the cert's presence in the LRU cache.
1763 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001764static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001765ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001766{
1767 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001768 SSL_CTX *ssl_ctx = NULL;
1769 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001770 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001771
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001772 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001773 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001774 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001775 if (lru && lru->domain)
1776 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001777 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001778 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001779 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001780 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001781 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001782 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001783 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001784 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001785 SSL_set_SSL_CTX(ssl, ssl_ctx);
1786 /* No LRU cache, this CTX will be released as soon as the session dies */
1787 SSL_CTX_free(ssl_ctx);
1788 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001789 return ssl_ctx;
1790}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001791#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001792
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001793
1794#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1795#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1796#endif
1797
1798#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1799#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
1800#define SSL_renegotiate_pending(arg) 0
1801#endif
1802#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1803#define SSL_OP_SINGLE_ECDH_USE 0
1804#endif
1805#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1806#define SSL_OP_NO_TICKET 0
1807#endif
1808#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1809#define SSL_OP_NO_COMPRESSION 0
1810#endif
1811#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1812#define SSL_OP_NO_TLSv1_1 0
1813#endif
1814#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1815#define SSL_OP_NO_TLSv1_2 0
1816#endif
1817#ifndef SSL_OP_NO_TLSv1_3 /* dev */
1818#define SSL_OP_NO_TLSv1_3 0
1819#endif
1820#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1821#define SSL_OP_SINGLE_DH_USE 0
1822#endif
1823#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1824#define SSL_OP_SINGLE_ECDH_USE 0
1825#endif
1826#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1827#define SSL_MODE_RELEASE_BUFFERS 0
1828#endif
1829#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1830#define SSL_MODE_SMALL_BUFFERS 0
1831#endif
1832
1833#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001834typedef enum { SET_CLIENT, SET_SERVER } set_context_func;
1835
1836static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001837{
Christopher Faulet1e59fcc2017-06-08 22:18:52 +02001838#if SSL_OP_NO_SSLv3 && !defined(OPENSSL_NO_SSL3_METHOD)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001839 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, SSLv3_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001840 : SSL_CTX_set_ssl_version(ctx, SSLv3_client_method());
1841#endif
1842}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001843static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1844 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001845 : SSL_CTX_set_ssl_version(ctx, TLSv1_client_method());
1846}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001847static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001848#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001849 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001850 : SSL_CTX_set_ssl_version(ctx, TLSv1_1_client_method());
1851#endif
1852}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001853static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001854#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001855 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001856 : SSL_CTX_set_ssl_version(ctx, TLSv1_2_client_method());
1857#endif
1858}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001859/* TLS 1.2 is the last supported version in this context. */
1860static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {}
1861/* Unusable in this context. */
1862static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {}
1863static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {}
1864static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {}
1865static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {}
1866static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {}
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001867#else /* openssl >= 1.1.0 */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001868typedef enum { SET_MIN, SET_MAX } set_context_func;
1869
1870static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c) {
1871 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001872 : SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
1873}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001874static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {
1875 c == SET_MAX ? SSL_set_max_proto_version(ssl, SSL3_VERSION)
1876 : SSL_set_min_proto_version(ssl, SSL3_VERSION);
1877}
1878static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1879 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001880 : SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1881}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001882static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {
1883 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_VERSION)
1884 : SSL_set_min_proto_version(ssl, TLS1_VERSION);
1885}
1886static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
1887 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001888 : SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
1889}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001890static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {
1891 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_1_VERSION)
1892 : SSL_set_min_proto_version(ssl, TLS1_1_VERSION);
1893}
1894static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
1895 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001896 : SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
1897}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001898static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {
1899 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_2_VERSION)
1900 : SSL_set_min_proto_version(ssl, TLS1_2_VERSION);
1901}
1902static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001903#if SSL_OP_NO_TLSv1_3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001904 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001905 : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
1906#endif
1907}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001908static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {
1909#if SSL_OP_NO_TLSv1_3
1910 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_3_VERSION)
1911 : SSL_set_min_proto_version(ssl, TLS1_3_VERSION);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001912#endif
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001913}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001914#endif
1915static void ctx_set_None_func(SSL_CTX *ctx, set_context_func c) { }
1916static void ssl_set_None_func(SSL *ssl, set_context_func c) { }
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001917
1918static struct {
1919 int option;
1920 uint16_t flag;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001921 void (*ctx_set_version)(SSL_CTX *, set_context_func);
1922 void (*ssl_set_version)(SSL *, set_context_func);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001923 const char *name;
1924} methodVersions[] = {
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001925 {0, 0, ctx_set_None_func, ssl_set_None_func, "NONE"}, /* CONF_TLSV_NONE */
1926 {SSL_OP_NO_SSLv3, MC_SSL_O_NO_SSLV3, ctx_set_SSLv3_func, ssl_set_SSLv3_func, "SSLv3"}, /* CONF_SSLV3 */
1927 {SSL_OP_NO_TLSv1, MC_SSL_O_NO_TLSV10, ctx_set_TLSv10_func, ssl_set_TLSv10_func, "TLSv1.0"}, /* CONF_TLSV10 */
1928 {SSL_OP_NO_TLSv1_1, MC_SSL_O_NO_TLSV11, ctx_set_TLSv11_func, ssl_set_TLSv11_func, "TLSv1.1"}, /* CONF_TLSV11 */
1929 {SSL_OP_NO_TLSv1_2, MC_SSL_O_NO_TLSV12, ctx_set_TLSv12_func, ssl_set_TLSv12_func, "TLSv1.2"}, /* CONF_TLSV12 */
1930 {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 +02001931};
1932
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001933static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1934{
1935 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1936 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1937 SSL_set_SSL_CTX(ssl, ctx);
1938}
1939
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001940#ifdef OPENSSL_IS_BORINGSSL
1941
1942static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1943{
1944 (void)al; /* shut gcc stupid warning */
1945 (void)priv;
1946
1947 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1948 return SSL_TLSEXT_ERR_NOACK;
1949 return SSL_TLSEXT_ERR_OK;
1950}
1951
1952static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1953{
1954 struct connection *conn;
1955 struct bind_conf *s;
1956 const uint8_t *extension_data;
1957 size_t extension_len;
1958 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1959 const SSL_CIPHER *cipher;
1960 uint16_t cipher_suite;
1961 uint8_t name_type, hash, sign;
1962 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1963
1964 char *wildp = NULL;
1965 const uint8_t *servername;
1966 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1967 int i;
1968
1969 conn = SSL_get_app_data(ctx->ssl);
1970 s = objt_listener(conn->target)->bind_conf;
1971
1972 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1973 &extension_data, &extension_len)) {
1974 CBS_init(&extension, extension_data, extension_len);
1975
1976 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1977 || !CBS_get_u8(&server_name_list, &name_type)
1978 /* Although the server_name extension was intended to be extensible to
1979 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1980 * different name types will cause an error. Further, RFC 4366 originally
1981 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1982 * adding new name types is no longer feasible.
1983 *
1984 * Act as if the extensibility does not exist to simplify parsing. */
1985 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1986 || CBS_len(&server_name_list) != 0
1987 || CBS_len(&extension) != 0
1988 || name_type != TLSEXT_NAMETYPE_host_name
1989 || CBS_len(&host_name) == 0
1990 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1991 || CBS_contains_zero_byte(&host_name)) {
1992 goto abort;
1993 }
1994 } else {
1995 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001996 if (!s->strict_sni) {
1997 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001998 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001999 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002000 goto abort;
2001 }
2002
2003 /* extract/check clientHello informations */
2004 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
2005 CBS_init(&extension, extension_data, extension_len);
2006
2007 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
2008 || CBS_len(&sig_algs) == 0
2009 || CBS_len(&extension) != 0) {
2010 goto abort;
2011 }
2012 if (CBS_len(&sig_algs) % 2 != 0) {
2013 goto abort;
2014 }
2015 while (CBS_len(&sig_algs) != 0) {
2016 if (!CBS_get_u8(&sig_algs, &hash)
2017 || !CBS_get_u8(&sig_algs, &sign)) {
2018 goto abort;
2019 }
2020 switch (sign) {
2021 case TLSEXT_signature_rsa:
2022 has_rsa = 1;
2023 break;
2024 case TLSEXT_signature_ecdsa:
2025 has_ecdsa_sig = 1;
2026 break;
2027 default:
2028 continue;
2029 }
2030 if (has_ecdsa_sig && has_rsa)
2031 break;
2032 }
2033 } else {
2034 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
2035 has_rsa = 1;
2036 }
2037 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
2038 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
2039
2040 while (CBS_len(&cipher_suites) != 0) {
2041 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
2042 goto abort;
2043 }
2044 cipher = SSL_get_cipher_by_value(cipher_suite);
2045 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
2046 has_ecdsa = 1;
2047 break;
2048 }
2049 }
2050 }
2051
2052 servername = CBS_data(&host_name);
2053 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
2054 trash.str[i] = tolower(servername[i]);
2055 if (!wildp && (trash.str[i] == '.'))
2056 wildp = &trash.str[i];
2057 }
2058 trash.str[i] = 0;
2059
2060 /* lookup in full qualified names */
2061 node = ebst_lookup(&s->sni_ctx, trash.str);
2062
2063 /* lookup a not neg filter */
2064 for (n = node; n; n = ebmb_next_dup(n)) {
2065 if (!container_of(n, struct sni_ctx, name)->neg) {
2066 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2067 case TLSEXT_signature_ecdsa:
2068 if (has_ecdsa) {
2069 node_ecdsa = n;
2070 goto find_one;
2071 }
2072 break;
2073 case TLSEXT_signature_rsa:
2074 if (has_rsa && !node_rsa) {
2075 node_rsa = n;
2076 if (!has_ecdsa)
2077 goto find_one;
2078 }
2079 break;
2080 default: /* TLSEXT_signature_anonymous */
2081 if (!node_anonymous)
2082 node_anonymous = n;
2083 break;
2084 }
2085 }
2086 }
2087 if (wildp) {
2088 /* lookup in wildcards names */
2089 node = ebst_lookup(&s->sni_w_ctx, wildp);
2090 for (n = node; n; n = ebmb_next_dup(n)) {
2091 if (!container_of(n, struct sni_ctx, name)->neg) {
2092 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2093 case TLSEXT_signature_ecdsa:
2094 if (has_ecdsa) {
2095 node_ecdsa = n;
2096 goto find_one;
2097 }
2098 break;
2099 case TLSEXT_signature_rsa:
2100 if (has_rsa && !node_rsa) {
2101 node_rsa = n;
2102 if (!has_ecdsa)
2103 goto find_one;
2104 }
2105 break;
2106 default: /* TLSEXT_signature_anonymous */
2107 if (!node_anonymous)
2108 node_anonymous = n;
2109 break;
2110 }
2111 }
2112 }
2113 }
2114 find_one:
2115 /* select by key_signature priority order */
2116 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
2117
2118 if (node) {
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02002119 int min, max;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002120 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002121 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02002122 min = container_of(node, struct sni_ctx, name)->conf->ssl_methods.min;
2123 if (min != s->ssl_methods.min)
2124 methodVersions[min].ssl_set_version(ctx->ssl, SET_MIN);
2125 max = container_of(node, struct sni_ctx, name)->conf->ssl_methods.max;
2126 if (max != s->ssl_methods.max)
2127 methodVersions[max].ssl_set_version(ctx->ssl, SET_MAX);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002128 return 1;
2129 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002130 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002131 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002132 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002133 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002134 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002135 abort:
2136 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
2137 conn->err_code = CO_ER_SSL_HANDSHAKE;
2138 return -1;
2139}
2140
2141#else /* OPENSSL_IS_BORINGSSL */
2142
Emeric Brunfc0421f2012-09-07 17:30:07 +02002143/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
2144 * warning when no match is found, which implies the default (first) cert
2145 * will keep being used.
2146 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002147static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002148{
2149 const char *servername;
2150 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002151 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002152 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002153 int i;
2154 (void)al; /* shut gcc stupid warning */
2155
2156 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002157 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002158#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02002159 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002160 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002161 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02002162 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02002163
Willy Tarreauf6721452015-07-07 18:04:38 +02002164 conn_get_to_addr(conn);
2165 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002166 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
2167 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02002168 if (ctx) {
2169 /* switch ctx */
2170 SSL_set_SSL_CTX(ssl, ctx);
2171 return SSL_TLSEXT_ERR_OK;
2172 }
Christopher Faulet30548802015-06-11 13:39:32 +02002173 }
2174 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002175#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002176 if (s->strict_sni)
2177 return SSL_TLSEXT_ERR_ALERT_FATAL;
2178 ssl_sock_switchctx_set(ssl, s->default_ctx);
2179 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002180 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002181
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002182 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002183 if (!servername[i])
2184 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002185 trash.str[i] = tolower(servername[i]);
2186 if (!wildp && (trash.str[i] == '.'))
2187 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002188 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002189 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002190
2191 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002192 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002193
2194 /* lookup a not neg filter */
2195 for (n = node; n; n = ebmb_next_dup(n)) {
2196 if (!container_of(n, struct sni_ctx, name)->neg) {
2197 node = n;
2198 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002199 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002200 }
2201 if (!node && wildp) {
2202 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002203 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002204 }
2205 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002206#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02002207 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002208 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02002209 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02002210 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02002211 return SSL_TLSEXT_ERR_OK;
2212 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002213#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002214 if (s->strict_sni)
2215 return SSL_TLSEXT_ERR_ALERT_FATAL;
2216 ssl_sock_switchctx_set(ssl, s->default_ctx);
2217 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002218 }
2219
2220 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002221 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002222 return SSL_TLSEXT_ERR_OK;
2223}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002224#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002225#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2226
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002227#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002228
2229static DH * ssl_get_dh_1024(void)
2230{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002231 static unsigned char dh1024_p[]={
2232 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
2233 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
2234 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
2235 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
2236 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
2237 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
2238 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
2239 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
2240 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
2241 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
2242 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
2243 };
2244 static unsigned char dh1024_g[]={
2245 0x02,
2246 };
2247
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002248 BIGNUM *p;
2249 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002250 DH *dh = DH_new();
2251 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002252 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
2253 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002254
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002255 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002256 DH_free(dh);
2257 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002258 } else {
2259 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002260 }
2261 }
2262 return dh;
2263}
2264
2265static DH *ssl_get_dh_2048(void)
2266{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002267 static unsigned char dh2048_p[]={
2268 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
2269 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
2270 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
2271 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
2272 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
2273 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
2274 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
2275 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
2276 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
2277 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
2278 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
2279 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
2280 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
2281 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
2282 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
2283 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
2284 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
2285 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
2286 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
2287 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
2288 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
2289 0xB7,0x1F,0x77,0xF3,
2290 };
2291 static unsigned char dh2048_g[]={
2292 0x02,
2293 };
2294
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002295 BIGNUM *p;
2296 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002297 DH *dh = DH_new();
2298 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002299 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
2300 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002301
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002302 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002303 DH_free(dh);
2304 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002305 } else {
2306 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002307 }
2308 }
2309 return dh;
2310}
2311
2312static DH *ssl_get_dh_4096(void)
2313{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002314 static unsigned char dh4096_p[]={
2315 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
2316 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
2317 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
2318 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
2319 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
2320 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
2321 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
2322 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
2323 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
2324 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
2325 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
2326 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
2327 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
2328 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
2329 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
2330 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
2331 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
2332 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
2333 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
2334 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
2335 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
2336 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
2337 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
2338 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
2339 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
2340 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
2341 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
2342 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
2343 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
2344 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
2345 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
2346 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
2347 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
2348 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
2349 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
2350 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
2351 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
2352 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
2353 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
2354 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
2355 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
2356 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
2357 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002358 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02002359 static unsigned char dh4096_g[]={
2360 0x02,
2361 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002362
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002363 BIGNUM *p;
2364 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002365 DH *dh = DH_new();
2366 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002367 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
2368 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002369
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002370 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002371 DH_free(dh);
2372 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002373 } else {
2374 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002375 }
2376 }
2377 return dh;
2378}
2379
2380/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01002381 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002382static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
2383{
2384 DH *dh = NULL;
2385 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002386 int type;
2387
2388 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002389
2390 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2391 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2392 */
2393 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2394 keylen = EVP_PKEY_bits(pkey);
2395 }
2396
Willy Tarreauef934602016-12-22 23:12:01 +01002397 if (keylen > global_ssl.default_dh_param) {
2398 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002399 }
2400
Remi Gacogned3a341a2015-05-29 16:26:17 +02002401 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002402 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002403 }
2404 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002405 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002406 }
2407 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002408 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002409 }
2410
2411 return dh;
2412}
2413
Remi Gacogne47783ef2015-05-29 15:53:22 +02002414static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002415{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002416 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002417 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002418
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002419 if (in == NULL)
2420 goto end;
2421
Remi Gacogne47783ef2015-05-29 15:53:22 +02002422 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002423 goto end;
2424
Remi Gacogne47783ef2015-05-29 15:53:22 +02002425 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2426
2427end:
2428 if (in)
2429 BIO_free(in);
2430
2431 return dh;
2432}
2433
2434int ssl_sock_load_global_dh_param_from_file(const char *filename)
2435{
2436 global_dh = ssl_sock_get_dh_from_file(filename);
2437
2438 if (global_dh) {
2439 return 0;
2440 }
2441
2442 return -1;
2443}
2444
2445/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2446 if an error occured, and 0 if parameter not found. */
2447int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2448{
2449 int ret = -1;
2450 DH *dh = ssl_sock_get_dh_from_file(file);
2451
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002452 if (dh) {
2453 ret = 1;
2454 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002455
2456 if (ssl_dh_ptr_index >= 0) {
2457 /* store a pointer to the DH params to avoid complaining about
2458 ssl-default-dh-param not being set for this SSL_CTX */
2459 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2460 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002461 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002462 else if (global_dh) {
2463 SSL_CTX_set_tmp_dh(ctx, global_dh);
2464 ret = 0; /* DH params not found */
2465 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002466 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002467 /* Clear openssl global errors stack */
2468 ERR_clear_error();
2469
Willy Tarreauef934602016-12-22 23:12:01 +01002470 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002471 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002472 if (local_dh_1024 == NULL)
2473 local_dh_1024 = ssl_get_dh_1024();
2474
Remi Gacogne8de54152014-07-15 11:36:40 +02002475 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002476 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002477
Remi Gacogne8de54152014-07-15 11:36:40 +02002478 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002479 }
2480 else {
2481 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2482 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002483
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002484 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002485 }
Emeric Brun644cde02012-12-14 11:21:13 +01002486
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002487end:
2488 if (dh)
2489 DH_free(dh);
2490
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002491 return ret;
2492}
2493#endif
2494
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002495static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2496 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002497{
2498 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002499 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002500 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002501
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002502 if (*name == '!') {
2503 neg = 1;
2504 name++;
2505 }
2506 if (*name == '*') {
2507 wild = 1;
2508 name++;
2509 }
2510 /* !* filter is a nop */
2511 if (neg && wild)
2512 return order;
2513 if (*name) {
2514 int j, len;
2515 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002516 for (j = 0; j < len && j < trash.size; j++)
2517 trash.str[j] = tolower(name[j]);
2518 if (j >= trash.size)
2519 return order;
2520 trash.str[j] = 0;
2521
2522 /* Check for duplicates. */
2523 if (wild)
2524 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2525 else
2526 node = ebst_lookup(&s->sni_ctx, trash.str);
2527 for (; node; node = ebmb_next_dup(node)) {
2528 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002529 if (sc->ctx == ctx && sc->conf == conf &&
2530 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002531 return order;
2532 }
2533
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002534 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002535 if (!sc)
2536 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002537 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002538 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002539 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002540 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002541 sc->order = order++;
2542 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002543 if (wild)
2544 ebst_insert(&s->sni_w_ctx, &sc->name);
2545 else
2546 ebst_insert(&s->sni_ctx, &sc->name);
2547 }
2548 return order;
2549}
2550
yanbzhu488a4d22015-12-01 15:16:07 -05002551
2552/* The following code is used for loading multiple crt files into
2553 * SSL_CTX's based on CN/SAN
2554 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002555#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002556/* This is used to preload the certifcate, private key
2557 * and Cert Chain of a file passed in via the crt
2558 * argument
2559 *
2560 * This way, we do not have to read the file multiple times
2561 */
2562struct cert_key_and_chain {
2563 X509 *cert;
2564 EVP_PKEY *key;
2565 unsigned int num_chain_certs;
2566 /* This is an array of X509 pointers */
2567 X509 **chain_certs;
2568};
2569
yanbzhu08ce6ab2015-12-02 13:01:29 -05002570#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2571
2572struct key_combo_ctx {
2573 SSL_CTX *ctx;
2574 int order;
2575};
2576
2577/* Map used for processing multiple keypairs for a single purpose
2578 *
2579 * This maps CN/SNI name to certificate type
2580 */
2581struct sni_keytype {
2582 int keytypes; /* BITMASK for keytypes */
2583 struct ebmb_node name; /* node holding the servername value */
2584};
2585
2586
yanbzhu488a4d22015-12-01 15:16:07 -05002587/* Frees the contents of a cert_key_and_chain
2588 */
2589static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2590{
2591 int i;
2592
2593 if (!ckch)
2594 return;
2595
2596 /* Free the certificate and set pointer to NULL */
2597 if (ckch->cert)
2598 X509_free(ckch->cert);
2599 ckch->cert = NULL;
2600
2601 /* Free the key and set pointer to NULL */
2602 if (ckch->key)
2603 EVP_PKEY_free(ckch->key);
2604 ckch->key = NULL;
2605
2606 /* Free each certificate in the chain */
2607 for (i = 0; i < ckch->num_chain_certs; i++) {
2608 if (ckch->chain_certs[i])
2609 X509_free(ckch->chain_certs[i]);
2610 }
2611
2612 /* Free the chain obj itself and set to NULL */
2613 if (ckch->num_chain_certs > 0) {
2614 free(ckch->chain_certs);
2615 ckch->num_chain_certs = 0;
2616 ckch->chain_certs = NULL;
2617 }
2618
2619}
2620
2621/* checks if a key and cert exists in the ckch
2622 */
2623static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2624{
2625 return (ckch->cert != NULL && ckch->key != NULL);
2626}
2627
2628
2629/* Loads the contents of a crt file (path) into a cert_key_and_chain
2630 * This allows us to carry the contents of the file without having to
2631 * read the file multiple times.
2632 *
2633 * returns:
2634 * 0 on Success
2635 * 1 on SSL Failure
2636 * 2 on file not found
2637 */
2638static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2639{
2640
2641 BIO *in;
2642 X509 *ca = NULL;
2643 int ret = 1;
2644
2645 ssl_sock_free_cert_key_and_chain_contents(ckch);
2646
2647 in = BIO_new(BIO_s_file());
2648 if (in == NULL)
2649 goto end;
2650
2651 if (BIO_read_filename(in, path) <= 0)
2652 goto end;
2653
yanbzhu488a4d22015-12-01 15:16:07 -05002654 /* Read Private Key */
2655 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2656 if (ckch->key == NULL) {
2657 memprintf(err, "%sunable to load private key from file '%s'.\n",
2658 err && *err ? *err : "", path);
2659 goto end;
2660 }
2661
Willy Tarreaubb137a82016-04-06 19:02:38 +02002662 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002663 if (BIO_reset(in) == -1) {
2664 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2665 err && *err ? *err : "", path);
2666 goto end;
2667 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002668
2669 /* Read Certificate */
2670 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2671 if (ckch->cert == NULL) {
2672 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2673 err && *err ? *err : "", path);
2674 goto end;
2675 }
2676
yanbzhu488a4d22015-12-01 15:16:07 -05002677 /* Read Certificate Chain */
2678 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2679 /* Grow the chain certs */
2680 ckch->num_chain_certs++;
2681 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2682
2683 /* use - 1 here since we just incremented it above */
2684 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2685 }
2686 ret = ERR_get_error();
2687 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2688 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2689 err && *err ? *err : "", path);
2690 ret = 1;
2691 goto end;
2692 }
2693
2694 ret = 0;
2695
2696end:
2697
2698 ERR_clear_error();
2699 if (in)
2700 BIO_free(in);
2701
2702 /* Something went wrong in one of the reads */
2703 if (ret != 0)
2704 ssl_sock_free_cert_key_and_chain_contents(ckch);
2705
2706 return ret;
2707}
2708
2709/* Loads the info in ckch into ctx
2710 * Currently, this does not process any information about ocsp, dhparams or
2711 * sctl
2712 * Returns
2713 * 0 on success
2714 * 1 on failure
2715 */
2716static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2717{
2718 int i = 0;
2719
2720 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2721 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2722 err && *err ? *err : "", path);
2723 return 1;
2724 }
2725
2726 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2727 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2728 err && *err ? *err : "", path);
2729 return 1;
2730 }
2731
yanbzhu488a4d22015-12-01 15:16:07 -05002732 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2733 for (i = 0; i < ckch->num_chain_certs; i++) {
2734 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002735 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2736 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002737 return 1;
2738 }
2739 }
2740
2741 if (SSL_CTX_check_private_key(ctx) <= 0) {
2742 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2743 err && *err ? *err : "", path);
2744 return 1;
2745 }
2746
2747 return 0;
2748}
2749
yanbzhu08ce6ab2015-12-02 13:01:29 -05002750
2751static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2752{
2753 struct sni_keytype *s_kt = NULL;
2754 struct ebmb_node *node;
2755 int i;
2756
2757 for (i = 0; i < trash.size; i++) {
2758 if (!str[i])
2759 break;
2760 trash.str[i] = tolower(str[i]);
2761 }
2762 trash.str[i] = 0;
2763 node = ebst_lookup(sni_keytypes, trash.str);
2764 if (!node) {
2765 /* CN not found in tree */
2766 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2767 /* Using memcpy here instead of strncpy.
2768 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2769 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2770 */
2771 memcpy(s_kt->name.key, trash.str, i+1);
2772 s_kt->keytypes = 0;
2773 ebst_insert(sni_keytypes, &s_kt->name);
2774 } else {
2775 /* CN found in tree */
2776 s_kt = container_of(node, struct sni_keytype, name);
2777 }
2778
2779 /* Mark that this CN has the keytype of key_index via keytypes mask */
2780 s_kt->keytypes |= 1<<key_index;
2781
2782}
2783
2784
2785/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2786 * If any are found, group these files into a set of SSL_CTX*
2787 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2788 *
2789 * This will allow the user to explictly group multiple cert/keys for a single purpose
2790 *
2791 * Returns
2792 * 0 on success
2793 * 1 on failure
2794 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002795static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2796 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002797{
2798 char fp[MAXPATHLEN+1] = {0};
2799 int n = 0;
2800 int i = 0;
2801 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2802 struct eb_root sni_keytypes_map = { {0} };
2803 struct ebmb_node *node;
2804 struct ebmb_node *next;
2805 /* Array of SSL_CTX pointers corresponding to each possible combo
2806 * of keytypes
2807 */
2808 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2809 int rv = 0;
2810 X509_NAME *xname = NULL;
2811 char *str = NULL;
2812#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2813 STACK_OF(GENERAL_NAME) *names = NULL;
2814#endif
2815
2816 /* Load all possible certs and keys */
2817 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2818 struct stat buf;
2819
2820 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2821 if (stat(fp, &buf) == 0) {
2822 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2823 rv = 1;
2824 goto end;
2825 }
2826 }
2827 }
2828
2829 /* Process each ckch and update keytypes for each CN/SAN
2830 * for example, if CN/SAN www.a.com is associated with
2831 * certs with keytype 0 and 2, then at the end of the loop,
2832 * www.a.com will have:
2833 * keyindex = 0 | 1 | 4 = 5
2834 */
2835 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2836
2837 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2838 continue;
2839
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002840 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002841 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002842 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2843 } else {
2844 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2845 * so the line that contains logic is marked via comments
2846 */
2847 xname = X509_get_subject_name(certs_and_keys[n].cert);
2848 i = -1;
2849 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2850 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002851 ASN1_STRING *value;
2852 value = X509_NAME_ENTRY_get_data(entry);
2853 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002854 /* Important line is here */
2855 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002856
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002857 OPENSSL_free(str);
2858 str = NULL;
2859 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002860 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002861
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002862 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002863#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002864 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2865 if (names) {
2866 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2867 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002868
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002869 if (name->type == GEN_DNS) {
2870 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2871 /* Important line is here */
2872 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002873
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002874 OPENSSL_free(str);
2875 str = NULL;
2876 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002877 }
2878 }
2879 }
2880 }
2881#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2882 }
2883
2884 /* If no files found, return error */
2885 if (eb_is_empty(&sni_keytypes_map)) {
2886 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2887 err && *err ? *err : "", path);
2888 rv = 1;
2889 goto end;
2890 }
2891
2892 /* We now have a map of CN/SAN to keytypes that are loaded in
2893 * Iterate through the map to create the SSL_CTX's (if needed)
2894 * and add each CTX to the SNI tree
2895 *
2896 * Some math here:
2897 * There are 2^n - 1 possibile combinations, each unique
2898 * combination is denoted by the key in the map. Each key
2899 * has a value between 1 and 2^n - 1. Conveniently, the array
2900 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2901 * entry in the array to correspond to the unique combo (key)
2902 * associated with i. This unique key combo (i) will be associated
2903 * with combos[i-1]
2904 */
2905
2906 node = ebmb_first(&sni_keytypes_map);
2907 while (node) {
2908 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002909 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002910
2911 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2912 i = container_of(node, struct sni_keytype, name)->keytypes;
2913 cur_ctx = key_combos[i-1].ctx;
2914
2915 if (cur_ctx == NULL) {
2916 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002917 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002918 if (cur_ctx == NULL) {
2919 memprintf(err, "%sunable to allocate SSL context.\n",
2920 err && *err ? *err : "");
2921 rv = 1;
2922 goto end;
2923 }
2924
yanbzhube2774d2015-12-10 15:07:30 -05002925 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002926 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2927 if (i & (1<<n)) {
2928 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002929 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2930 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002931 SSL_CTX_free(cur_ctx);
2932 rv = 1;
2933 goto end;
2934 }
yanbzhube2774d2015-12-10 15:07:30 -05002935
2936#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2937 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002938 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002939 if (err)
2940 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 +00002941 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002942 SSL_CTX_free(cur_ctx);
2943 rv = 1;
2944 goto end;
2945 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02002946#elif (defined OPENSSL_IS_BORINGSSL)
2947 ssl_sock_set_ocsp_response_from_file(cur_ctx, cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002948#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002949 }
2950 }
2951
2952 /* Load DH params into the ctx to support DHE keys */
2953#ifndef OPENSSL_NO_DH
2954 if (ssl_dh_ptr_index >= 0)
2955 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2956
2957 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2958 if (rv < 0) {
2959 if (err)
2960 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2961 *err ? *err : "", path);
2962 rv = 1;
2963 goto end;
2964 }
2965#endif
2966
2967 /* Update key_combos */
2968 key_combos[i-1].ctx = cur_ctx;
2969 }
2970
2971 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002972 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2973 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002974 node = ebmb_next(node);
2975 }
2976
2977
2978 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2979 if (!bind_conf->default_ctx) {
2980 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2981 if (key_combos[i].ctx) {
2982 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002983 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002984 break;
2985 }
2986 }
2987 }
2988
2989end:
2990
2991 if (names)
2992 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2993
2994 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2995 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2996
2997 node = ebmb_first(&sni_keytypes_map);
2998 while (node) {
2999 next = ebmb_next(node);
3000 ebmb_delete(node);
3001 node = next;
3002 }
3003
3004 return rv;
3005}
3006#else
3007/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003008static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3009 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05003010{
3011 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3012 err && *err ? *err : "", path, strerror(errno));
3013 return 1;
3014}
3015
yanbzhu488a4d22015-12-01 15:16:07 -05003016#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
3017
Emeric Brunfc0421f2012-09-07 17:30:07 +02003018/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
3019 * an early error happens and the caller must call SSL_CTX_free() by itelf.
3020 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003021static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
3022 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003023{
3024 BIO *in;
3025 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003026 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003027 int ret = -1;
3028 int order = 0;
3029 X509_NAME *xname;
3030 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003031 pem_password_cb *passwd_cb;
3032 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003033 EVP_PKEY *pkey;
3034 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003035
Emeric Brunfc0421f2012-09-07 17:30:07 +02003036#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3037 STACK_OF(GENERAL_NAME) *names;
3038#endif
3039
3040 in = BIO_new(BIO_s_file());
3041 if (in == NULL)
3042 goto end;
3043
3044 if (BIO_read_filename(in, file) <= 0)
3045 goto end;
3046
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003047
3048 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
3049 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
3050
3051 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003052 if (x == NULL)
3053 goto end;
3054
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003055 pkey = X509_get_pubkey(x);
3056 if (pkey) {
3057 switch(EVP_PKEY_base_id(pkey)) {
3058 case EVP_PKEY_RSA:
3059 key_sig = TLSEXT_signature_rsa;
3060 break;
3061 case EVP_PKEY_EC:
3062 key_sig = TLSEXT_signature_ecdsa;
3063 break;
3064 }
3065 EVP_PKEY_free(pkey);
3066 }
3067
Emeric Brun50bcecc2013-04-22 13:05:23 +02003068 if (fcount) {
3069 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003070 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003071 }
3072 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003073#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003074 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
3075 if (names) {
3076 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
3077 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
3078 if (name->type == GEN_DNS) {
3079 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003080 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003081 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003082 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003083 }
3084 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003085 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003086 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003087#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003088 xname = X509_get_subject_name(x);
3089 i = -1;
3090 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
3091 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003092 ASN1_STRING *value;
3093
3094 value = X509_NAME_ENTRY_get_data(entry);
3095 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003096 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003097 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003098 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003099 }
3100 }
3101
3102 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
3103 if (!SSL_CTX_use_certificate(ctx, x))
3104 goto end;
3105
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003106#ifdef SSL_CTX_clear_extra_chain_certs
3107 SSL_CTX_clear_extra_chain_certs(ctx);
3108#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02003109 if (ctx->extra_certs != NULL) {
3110 sk_X509_pop_free(ctx->extra_certs, X509_free);
3111 ctx->extra_certs = NULL;
3112 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003113#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003114
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003115 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003116 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
3117 X509_free(ca);
3118 goto end;
3119 }
3120 }
3121
3122 err = ERR_get_error();
3123 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
3124 /* we successfully reached the last cert in the file */
3125 ret = 1;
3126 }
3127 ERR_clear_error();
3128
3129end:
3130 if (x)
3131 X509_free(x);
3132
3133 if (in)
3134 BIO_free(in);
3135
3136 return ret;
3137}
3138
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003139static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3140 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003141{
3142 int ret;
3143 SSL_CTX *ctx;
3144
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003145 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02003146 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003147 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
3148 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003149 return 1;
3150 }
3151
3152 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003153 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
3154 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003155 SSL_CTX_free(ctx);
3156 return 1;
3157 }
3158
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003159 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003160 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003161 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
3162 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003163 if (ret < 0) /* serious error, must do that ourselves */
3164 SSL_CTX_free(ctx);
3165 return 1;
3166 }
Emeric Brun61694ab2012-10-26 13:35:33 +02003167
3168 if (SSL_CTX_check_private_key(ctx) <= 0) {
3169 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3170 err && *err ? *err : "", path);
3171 return 1;
3172 }
3173
Emeric Brunfc0421f2012-09-07 17:30:07 +02003174 /* we must not free the SSL_CTX anymore below, since it's already in
3175 * the tree, so it will be discovered and cleaned in time.
3176 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003177#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02003178 /* store a NULL pointer to indicate we have not yet loaded
3179 a custom DH param file */
3180 if (ssl_dh_ptr_index >= 0) {
3181 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
3182 }
3183
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003184 ret = ssl_sock_load_dh_params(ctx, path);
3185 if (ret < 0) {
3186 if (err)
3187 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
3188 *err ? *err : "", path);
3189 return 1;
3190 }
3191#endif
3192
Lukas Tribuse4e30f72014-12-09 16:32:51 +01003193#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02003194 ret = ssl_sock_load_ocsp(ctx, path);
3195 if (ret < 0) {
3196 if (err)
3197 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",
3198 *err ? *err : "", path);
3199 return 1;
3200 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02003201#elif (defined OPENSSL_IS_BORINGSSL)
3202 ssl_sock_set_ocsp_response_from_file(ctx, path);
Emeric Brun4147b2e2014-06-16 18:36:30 +02003203#endif
3204
Daniel Jakots54ffb912015-11-06 20:02:41 +01003205#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01003206 if (sctl_ex_index >= 0) {
3207 ret = ssl_sock_load_sctl(ctx, path);
3208 if (ret < 0) {
3209 if (err)
3210 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
3211 *err ? *err : "", path);
3212 return 1;
3213 }
3214 }
3215#endif
3216
Emeric Brunfc0421f2012-09-07 17:30:07 +02003217#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003218 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003219 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
3220 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02003221 return 1;
3222 }
3223#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003224 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003225 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003226 bind_conf->default_ssl_conf = ssl_conf;
3227 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003228
3229 return 0;
3230}
3231
Willy Tarreau03209342016-12-22 17:08:28 +01003232int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003233{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003234 struct dirent **de_list;
3235 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003236 DIR *dir;
3237 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01003238 char *end;
3239 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02003240 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05003241#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3242 int is_bundle;
3243 int j;
3244#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003245
yanbzhu08ce6ab2015-12-02 13:01:29 -05003246 if (stat(path, &buf) == 0) {
3247 dir = opendir(path);
3248 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003249 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003250
yanbzhu08ce6ab2015-12-02 13:01:29 -05003251 /* strip trailing slashes, including first one */
3252 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
3253 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003254
yanbzhu08ce6ab2015-12-02 13:01:29 -05003255 n = scandir(path, &de_list, 0, alphasort);
3256 if (n < 0) {
3257 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
3258 err && *err ? *err : "", path, strerror(errno));
3259 cfgerr++;
3260 }
3261 else {
3262 for (i = 0; i < n; i++) {
3263 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02003264
yanbzhu08ce6ab2015-12-02 13:01:29 -05003265 end = strrchr(de->d_name, '.');
3266 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
3267 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003268
yanbzhu08ce6ab2015-12-02 13:01:29 -05003269 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
3270 if (stat(fp, &buf) != 0) {
3271 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3272 err && *err ? *err : "", fp, strerror(errno));
3273 cfgerr++;
3274 goto ignore_entry;
3275 }
3276 if (!S_ISREG(buf.st_mode))
3277 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05003278
3279#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3280 is_bundle = 0;
3281 /* Check if current entry in directory is part of a multi-cert bundle */
3282
3283 if (end) {
3284 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
3285 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
3286 is_bundle = 1;
3287 break;
3288 }
3289 }
3290
3291 if (is_bundle) {
3292 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
3293 int dp_len;
3294
3295 dp_len = end - de->d_name;
3296 snprintf(dp, dp_len + 1, "%s", de->d_name);
3297
3298 /* increment i and free de until we get to a non-bundle cert
3299 * Note here that we look at de_list[i + 1] before freeing de
3300 * this is important since ignore_entry will free de
3301 */
3302 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
3303 free(de);
3304 i++;
3305 de = de_list[i];
3306 }
3307
3308 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003309 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05003310
3311 /* Successfully processed the bundle */
3312 goto ignore_entry;
3313 }
3314 }
3315
3316#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003317 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003318ignore_entry:
3319 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003320 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003321 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003322 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003323 closedir(dir);
3324 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003325 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003326
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003327 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003328
Emeric Brunfc0421f2012-09-07 17:30:07 +02003329 return cfgerr;
3330}
3331
Thierry Fournier383085f2013-01-24 14:15:43 +01003332/* Make sure openssl opens /dev/urandom before the chroot. The work is only
3333 * done once. Zero is returned if the operation fails. No error is returned
3334 * if the random is said as not implemented, because we expect that openssl
3335 * will use another method once needed.
3336 */
3337static int ssl_initialize_random()
3338{
3339 unsigned char random;
3340 static int random_initialized = 0;
3341
3342 if (!random_initialized && RAND_bytes(&random, 1) != 0)
3343 random_initialized = 1;
3344
3345 return random_initialized;
3346}
3347
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003348/* release ssl bind conf */
3349void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003350{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003351 if (conf) {
3352#ifdef OPENSSL_NPN_NEGOTIATED
3353 free(conf->npn_str);
3354 conf->npn_str = NULL;
3355#endif
3356#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
3357 free(conf->alpn_str);
3358 conf->alpn_str = NULL;
3359#endif
3360 free(conf->ca_file);
3361 conf->ca_file = NULL;
3362 free(conf->crl_file);
3363 conf->crl_file = NULL;
3364 free(conf->ciphers);
3365 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003366 free(conf->curves);
3367 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003368 free(conf->ecdhe);
3369 conf->ecdhe = NULL;
3370 }
3371}
3372
3373int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
3374{
3375 char thisline[CRT_LINESIZE];
3376 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003377 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05003378 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003379 int linenum = 0;
3380 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003381
Willy Tarreauad1731d2013-04-02 17:35:58 +02003382 if ((f = fopen(file, "r")) == NULL) {
3383 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003384 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003385 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003386
3387 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003388 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003389 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003390 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003391 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003392 char *crt_path;
3393 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003394
3395 linenum++;
3396 end = line + strlen(line);
3397 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3398 /* Check if we reached the limit and the last char is not \n.
3399 * Watch out for the last line without the terminating '\n'!
3400 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003401 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3402 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003403 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003404 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003405 }
3406
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003407 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003408 newarg = 1;
3409 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003410 if (*line == '#' || *line == '\n' || *line == '\r') {
3411 /* end of string, end of loop */
3412 *line = 0;
3413 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003414 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003415 newarg = 1;
3416 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003417 } else if (*line == '[') {
3418 if (ssl_b) {
3419 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3420 cfgerr = 1;
3421 break;
3422 }
3423 if (!arg) {
3424 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3425 cfgerr = 1;
3426 break;
3427 }
3428 ssl_b = arg;
3429 newarg = 1;
3430 *line = 0;
3431 } else if (*line == ']') {
3432 if (ssl_e) {
3433 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003434 cfgerr = 1;
3435 break;
3436 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003437 if (!ssl_b) {
3438 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3439 cfgerr = 1;
3440 break;
3441 }
3442 ssl_e = arg;
3443 newarg = 1;
3444 *line = 0;
3445 } else if (newarg) {
3446 if (arg == MAX_CRT_ARGS) {
3447 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3448 cfgerr = 1;
3449 break;
3450 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003451 newarg = 0;
3452 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003453 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003454 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003455 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003456 if (cfgerr)
3457 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003458 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003459
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003460 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003461 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003462 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003463
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003464 crt_path = args[0];
3465 if (*crt_path != '/' && global_ssl.crt_base) {
3466 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3467 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3468 crt_path, linenum, file);
3469 cfgerr = 1;
3470 break;
3471 }
3472 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3473 crt_path = path;
3474 }
3475
3476 ssl_conf = calloc(1, sizeof *ssl_conf);
3477 cur_arg = ssl_b ? ssl_b : 1;
3478 while (cur_arg < ssl_e) {
3479 newarg = 0;
3480 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3481 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3482 newarg = 1;
3483 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3484 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3485 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3486 args[cur_arg], linenum, file);
3487 cfgerr = 1;
3488 }
3489 cur_arg += 1 + ssl_bind_kws[i].skip;
3490 break;
3491 }
3492 }
3493 if (!cfgerr && !newarg) {
3494 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3495 args[cur_arg], linenum, file);
3496 cfgerr = 1;
3497 break;
3498 }
3499 }
3500 if (cfgerr) {
3501 ssl_sock_free_ssl_conf(ssl_conf);
3502 free(ssl_conf);
3503 ssl_conf = NULL;
3504 break;
3505 }
3506
3507 if (stat(crt_path, &buf) == 0) {
3508 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3509 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003510 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003511 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3512 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003513 }
3514
Willy Tarreauad1731d2013-04-02 17:35:58 +02003515 if (cfgerr) {
3516 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003517 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003518 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003519 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003520 fclose(f);
3521 return cfgerr;
3522}
3523
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003524/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003525static int
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003526ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003527{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003528 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003529 long options =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003530 SSL_OP_ALL | /* all known workarounds for bugs */
3531 SSL_OP_NO_SSLv2 |
3532 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003533 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003534 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003535 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3536 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003537 long mode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003538 SSL_MODE_ENABLE_PARTIAL_WRITE |
3539 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003540 SSL_MODE_RELEASE_BUFFERS |
3541 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003542 struct tls_version_filter *conf_ssl_methods = &bind_conf->ssl_methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003543 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003544 int flags = MC_SSL_O_ALL;
3545 int cfgerr = 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003546
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003547 ctx = SSL_CTX_new(SSLv23_server_method());
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003548 bind_conf->initial_ctx = ctx;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003549
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003550 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
3551 Warning("Proxy '%s': no-sslv3/no-tlsv1x are ignored for bind '%s' at [%s:%d]. "
3552 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
3553 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3554 else
3555 flags = conf_ssl_methods->flags;
3556
Emmanuel Hocdetbd695fe2017-05-15 15:53:41 +02003557 min = conf_ssl_methods->min;
3558 max = conf_ssl_methods->max;
3559 /* start with TLSv10 to remove SSLv3 per default */
3560 if (!min && (!max || max >= CONF_TLSV10))
3561 min = CONF_TLSV10;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003562 /* Real min and max should be determinate with configuration and openssl's capabilities */
Emmanuel Hocdetbd695fe2017-05-15 15:53:41 +02003563 if (min)
3564 flags |= (methodVersions[min].flag - 1);
3565 if (max)
3566 flags |= ~((methodVersions[max].flag << 1) - 1);
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003567 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003568 min = max = CONF_TLSV_NONE;
3569 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003570 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003571 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003572 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003573 if (min) {
3574 if (hole) {
3575 Warning("Proxy '%s': SSL/TLS versions range not contiguous for bind '%s' at [%s:%d]. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003576 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003577 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line,
3578 methodVersions[hole].name);
3579 hole = 0;
3580 }
3581 max = i;
3582 }
3583 else {
3584 min = max = i;
3585 }
3586 }
3587 else {
3588 if (min)
3589 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003590 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003591 if (!min) {
3592 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003593 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003594 cfgerr += 1;
3595 }
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003596 /* save real min/max in bind_conf */
3597 conf_ssl_methods->min = min;
3598 conf_ssl_methods->max = max;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003599
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003600#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3601 /* Keep force-xxx implementation as it is in older haproxy. It's a
3602 precautionary measure to avoid any suprise with older openssl version. */
3603 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003604 methodVersions[min].ctx_set_version(ctx, SET_SERVER);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003605 else
3606 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3607 if (flags & methodVersions[i].flag)
3608 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003609#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003610 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003611 methodVersions[min].ctx_set_version(ctx, SET_MIN);
3612 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003613#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003614
3615 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3616 options |= SSL_OP_NO_TICKET;
3617 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
3618 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
3619 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00003620
3621#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
3622 if (global_ssl.async)
3623 mode |= SSL_MODE_ASYNC;
3624#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003625 SSL_CTX_set_mode(ctx, mode);
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003626 if (global_ssl.life_time)
3627 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003628
3629#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3630#ifdef OPENSSL_IS_BORINGSSL
3631 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3632 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3633#else
3634 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3635 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3636#endif
3637#endif
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003638 return cfgerr;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003639}
3640
3641int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3642{
3643 struct proxy *curproxy = bind_conf->frontend;
3644 int cfgerr = 0;
3645 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003646 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003647 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003648 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003649
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003650 if (ssl_conf) {
3651 struct tls_version_filter *conf_ssl_methods = &ssl_conf->ssl_methods;
3652 int i, min, max;
3653 int flags = MC_SSL_O_ALL;
3654
3655 /* Real min and max should be determinate with configuration and openssl's capabilities */
3656 min = conf_ssl_methods->min ? conf_ssl_methods->min : bind_conf->ssl_methods.min;
3657 max = conf_ssl_methods->max ? conf_ssl_methods->max : bind_conf->ssl_methods.max;
3658 if (min)
3659 flags |= (methodVersions[min].flag - 1);
3660 if (max)
3661 flags |= ~((methodVersions[max].flag << 1) - 1);
3662 min = max = CONF_TLSV_NONE;
3663 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3664 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
3665 if (min)
3666 max = i;
3667 else
3668 min = max = i;
3669 }
3670 /* save real min/max */
3671 conf_ssl_methods->min = min;
3672 conf_ssl_methods->max = max;
3673 if (!min) {
3674 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
3675 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3676 cfgerr += 1;
3677 }
3678 }
3679
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003680 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003681 case SSL_SOCK_VERIFY_NONE:
3682 verify = SSL_VERIFY_NONE;
3683 break;
3684 case SSL_SOCK_VERIFY_OPTIONAL:
3685 verify = SSL_VERIFY_PEER;
3686 break;
3687 case SSL_SOCK_VERIFY_REQUIRED:
3688 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3689 break;
3690 }
3691 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3692 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003693 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3694 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3695 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003696 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003697 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003698 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003699 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003700 cfgerr++;
3701 }
3702 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003703 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003704 }
Emeric Brun850efd52014-01-29 12:24:34 +01003705 else {
3706 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3707 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3708 cfgerr++;
3709 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003710#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003711 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003712 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3713
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003714 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003715 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003716 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003717 cfgerr++;
3718 }
Emeric Brun561e5742012-10-02 15:20:55 +02003719 else {
3720 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3721 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003722 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003723#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003724 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003725 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003726#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003727 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003728 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3729 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3730 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3731 cfgerr++;
3732 }
3733 }
3734#endif
3735
Emeric Brunfc0421f2012-09-07 17:30:07 +02003736 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003737 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3738 if (conf_ciphers &&
3739 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003740 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 +01003741 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003742 cfgerr++;
3743 }
3744
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003745#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003746 /* If tune.ssl.default-dh-param has not been set,
3747 neither has ssl-default-dh-file and no static DH
3748 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003749 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003750 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003751 (ssl_dh_ptr_index == -1 ||
3752 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003753 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3754 const SSL_CIPHER * cipher = NULL;
3755 char cipher_description[128];
3756 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3757 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3758 which is not ephemeral DH. */
3759 const char dhe_description[] = " Kx=DH ";
3760 const char dhe_export_description[] = " Kx=DH(";
3761 int idx = 0;
3762 int dhe_found = 0;
3763 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003764
Remi Gacogne23d5d372014-10-10 17:04:26 +02003765 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003766
Remi Gacogne23d5d372014-10-10 17:04:26 +02003767 if (ssl) {
3768 ciphers = SSL_get_ciphers(ssl);
3769
3770 if (ciphers) {
3771 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3772 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3773 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3774 if (strstr(cipher_description, dhe_description) != NULL ||
3775 strstr(cipher_description, dhe_export_description) != NULL) {
3776 dhe_found = 1;
3777 break;
3778 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003779 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003780 }
3781 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003782 SSL_free(ssl);
3783 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003784 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003785
Lukas Tribus90132722014-08-18 00:56:33 +02003786 if (dhe_found) {
3787 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 +02003788 }
3789
Willy Tarreauef934602016-12-22 23:12:01 +01003790 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003791 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003792
Willy Tarreauef934602016-12-22 23:12:01 +01003793 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003794 if (local_dh_1024 == NULL) {
3795 local_dh_1024 = ssl_get_dh_1024();
3796 }
Willy Tarreauef934602016-12-22 23:12:01 +01003797 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003798 if (local_dh_2048 == NULL) {
3799 local_dh_2048 = ssl_get_dh_2048();
3800 }
Willy Tarreauef934602016-12-22 23:12:01 +01003801 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003802 if (local_dh_4096 == NULL) {
3803 local_dh_4096 = ssl_get_dh_4096();
3804 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003805 }
3806 }
3807 }
3808#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003809
Emeric Brunfc0421f2012-09-07 17:30:07 +02003810 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003811#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003812 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003813#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003814
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003815#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003816 ssl_conf_cur = NULL;
3817 if (ssl_conf && ssl_conf->npn_str)
3818 ssl_conf_cur = ssl_conf;
3819 else if (bind_conf->ssl_conf.npn_str)
3820 ssl_conf_cur = &bind_conf->ssl_conf;
3821 if (ssl_conf_cur)
3822 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003823#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003824#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003825 ssl_conf_cur = NULL;
3826 if (ssl_conf && ssl_conf->alpn_str)
3827 ssl_conf_cur = ssl_conf;
3828 else if (bind_conf->ssl_conf.alpn_str)
3829 ssl_conf_cur = &bind_conf->ssl_conf;
3830 if (ssl_conf_cur)
3831 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003832#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003833#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3834 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3835 if (conf_curves) {
3836 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3837 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3838 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3839 cfgerr++;
3840 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003841#if defined(SSL_CTX_set_ecdh_auto)
3842 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3843#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003844 }
3845#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003846#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003847 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003848 int i;
3849 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003850 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3851 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003852
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003853 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003854 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3855 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 +01003856 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003857 cfgerr++;
3858 }
3859 else {
3860 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3861 EC_KEY_free(ecdh);
3862 }
3863 }
3864#endif
3865
Emeric Brunfc0421f2012-09-07 17:30:07 +02003866 return cfgerr;
3867}
3868
Evan Broderbe554312013-06-27 00:05:25 -07003869static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3870{
3871 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3872 size_t prefixlen, suffixlen;
3873
3874 /* Trivial case */
3875 if (strcmp(pattern, hostname) == 0)
3876 return 1;
3877
Evan Broderbe554312013-06-27 00:05:25 -07003878 /* The rest of this logic is based on RFC 6125, section 6.4.3
3879 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3880
Emeric Bruna848dae2013-10-08 11:27:28 +02003881 pattern_wildcard = NULL;
3882 pattern_left_label_end = pattern;
3883 while (*pattern_left_label_end != '.') {
3884 switch (*pattern_left_label_end) {
3885 case 0:
3886 /* End of label not found */
3887 return 0;
3888 case '*':
3889 /* If there is more than one wildcards */
3890 if (pattern_wildcard)
3891 return 0;
3892 pattern_wildcard = pattern_left_label_end;
3893 break;
3894 }
3895 pattern_left_label_end++;
3896 }
3897
3898 /* If it's not trivial and there is no wildcard, it can't
3899 * match */
3900 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003901 return 0;
3902
3903 /* Make sure all labels match except the leftmost */
3904 hostname_left_label_end = strchr(hostname, '.');
3905 if (!hostname_left_label_end
3906 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3907 return 0;
3908
3909 /* Make sure the leftmost label of the hostname is long enough
3910 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003911 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003912 return 0;
3913
3914 /* Finally compare the string on either side of the
3915 * wildcard */
3916 prefixlen = pattern_wildcard - pattern;
3917 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003918 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3919 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003920 return 0;
3921
3922 return 1;
3923}
3924
3925static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3926{
3927 SSL *ssl;
3928 struct connection *conn;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003929 const char *servername;
Evan Broderbe554312013-06-27 00:05:25 -07003930
3931 int depth;
3932 X509 *cert;
3933 STACK_OF(GENERAL_NAME) *alt_names;
3934 int i;
3935 X509_NAME *cert_subject;
3936 char *str;
3937
3938 if (ok == 0)
3939 return ok;
3940
3941 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003942 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003943
Willy Tarreau2ab88672017-07-05 18:23:03 +02003944 /* we're checking against the configured "verifyhost" directive if
3945 * present, or against the SNI used on this connection if present.
3946 * If neither is set, the verification is OK.
3947 */
Evan Broderbe554312013-06-27 00:05:25 -07003948 servername = objt_server(conn->target)->ssl_ctx.verify_host;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003949 if (!servername) {
3950 SSL_SESSION *ssl_sess = SSL_get_session(conn->xprt_ctx);
3951 if (!ssl_sess)
3952 return ok;
3953
3954 servername = SSL_SESSION_get0_hostname(ssl_sess);
3955 if (!servername)
3956 return ok;
3957 }
Evan Broderbe554312013-06-27 00:05:25 -07003958
3959 /* We only need to verify the CN on the actual server cert,
3960 * not the indirect CAs */
3961 depth = X509_STORE_CTX_get_error_depth(ctx);
3962 if (depth != 0)
3963 return ok;
3964
3965 /* At this point, the cert is *not* OK unless we can find a
3966 * hostname match */
3967 ok = 0;
3968
3969 cert = X509_STORE_CTX_get_current_cert(ctx);
3970 /* It seems like this might happen if verify peer isn't set */
3971 if (!cert)
3972 return ok;
3973
3974 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3975 if (alt_names) {
3976 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3977 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3978 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003979#if OPENSSL_VERSION_NUMBER < 0x00907000L
3980 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3981#else
Evan Broderbe554312013-06-27 00:05:25 -07003982 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003983#endif
Evan Broderbe554312013-06-27 00:05:25 -07003984 ok = ssl_sock_srv_hostcheck(str, servername);
3985 OPENSSL_free(str);
3986 }
3987 }
3988 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003989 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003990 }
3991
3992 cert_subject = X509_get_subject_name(cert);
3993 i = -1;
3994 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3995 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003996 ASN1_STRING *value;
3997 value = X509_NAME_ENTRY_get_data(entry);
3998 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003999 ok = ssl_sock_srv_hostcheck(str, servername);
4000 OPENSSL_free(str);
4001 }
4002 }
4003
4004 return ok;
4005}
4006
Emeric Brun94324a42012-10-11 14:00:19 +02004007/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01004008int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02004009{
Willy Tarreau03209342016-12-22 17:08:28 +01004010 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02004011 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02004012 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02004013 SSL_OP_ALL | /* all known workarounds for bugs */
4014 SSL_OP_NO_SSLv2 |
4015 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02004016 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02004017 SSL_MODE_ENABLE_PARTIAL_WRITE |
4018 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01004019 SSL_MODE_RELEASE_BUFFERS |
4020 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01004021 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004022 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004023 struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004024 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004025 int flags = MC_SSL_O_ALL;
Emeric Brun94324a42012-10-11 14:00:19 +02004026
Thierry Fournier383085f2013-01-24 14:15:43 +01004027 /* Make sure openssl opens /dev/urandom before the chroot */
4028 if (!ssl_initialize_random()) {
4029 Alert("OpenSSL random data generator initialization failed.\n");
4030 cfgerr++;
4031 }
4032
Willy Tarreaufce03112015-01-15 21:32:40 +01004033 /* Automatic memory computations need to know we use SSL there */
4034 global.ssl_used_backend = 1;
4035
4036 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02004037 srv->ssl_ctx.reused_sess = NULL;
4038 if (srv->use_ssl)
4039 srv->xprt = &ssl_sock;
4040 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01004041 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02004042
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004043 ctx = SSL_CTX_new(SSLv23_client_method());
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004044 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02004045 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
4046 proxy_type_str(curproxy), curproxy->id,
4047 srv->id);
4048 cfgerr++;
4049 return cfgerr;
4050 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004051
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004052 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
4053 Warning("config : %s '%s': no-sslv3/no-tlsv1x are ignored for server '%s'. "
4054 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
4055 proxy_type_str(curproxy), curproxy->id, srv->id);
4056 else
4057 flags = conf_ssl_methods->flags;
4058
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004059 /* Real min and max should be determinate with configuration and openssl's capabilities */
4060 if (conf_ssl_methods->min)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004061 flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004062 if (conf_ssl_methods->max)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004063 flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004064
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004065 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004066 min = max = CONF_TLSV_NONE;
4067 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004068 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004069 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004070 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004071 if (min) {
4072 if (hole) {
4073 Warning("config : %s '%s': SSL/TLS versions range not contiguous for server '%s'. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02004074 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004075 proxy_type_str(curproxy), curproxy->id, srv->id,
4076 methodVersions[hole].name);
4077 hole = 0;
4078 }
4079 max = i;
4080 }
4081 else {
4082 min = max = i;
4083 }
4084 }
4085 else {
4086 if (min)
4087 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004088 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004089 if (!min) {
4090 Alert("config : %s '%s': all SSL/TLS versions are disabled for server '%s'.\n",
4091 proxy_type_str(curproxy), curproxy->id, srv->id);
4092 cfgerr += 1;
4093 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004094
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004095#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
4096 /* Keep force-xxx implementation as it is in older haproxy. It's a
4097 precautionary measure to avoid any suprise with older openssl version. */
4098 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004099 methodVersions[min].ctx_set_version(ctx, SET_CLIENT);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004100 else
4101 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
4102 if (flags & methodVersions[i].flag)
4103 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004104#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004105 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004106 methodVersions[min].ctx_set_version(ctx, SET_MIN);
4107 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004108#endif
4109
4110 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
4111 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004112 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004113
4114#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4115 if (global_ssl.async)
4116 mode |= SSL_MODE_ASYNC;
4117#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004118 SSL_CTX_set_mode(ctx, mode);
4119 srv->ssl_ctx.ctx = ctx;
4120
Emeric Bruna7aa3092012-10-26 12:58:00 +02004121 if (srv->ssl_ctx.client_crt) {
4122 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
4123 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
4124 proxy_type_str(curproxy), curproxy->id,
4125 srv->id, srv->ssl_ctx.client_crt);
4126 cfgerr++;
4127 }
4128 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
4129 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
4130 proxy_type_str(curproxy), curproxy->id,
4131 srv->id, srv->ssl_ctx.client_crt);
4132 cfgerr++;
4133 }
4134 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
4135 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
4136 proxy_type_str(curproxy), curproxy->id,
4137 srv->id, srv->ssl_ctx.client_crt);
4138 cfgerr++;
4139 }
4140 }
Emeric Brun94324a42012-10-11 14:00:19 +02004141
Emeric Brun850efd52014-01-29 12:24:34 +01004142 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
4143 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01004144 switch (srv->ssl_ctx.verify) {
4145 case SSL_SOCK_VERIFY_NONE:
4146 verify = SSL_VERIFY_NONE;
4147 break;
4148 case SSL_SOCK_VERIFY_REQUIRED:
4149 verify = SSL_VERIFY_PEER;
4150 break;
4151 }
Evan Broderbe554312013-06-27 00:05:25 -07004152 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01004153 verify,
Willy Tarreau2ab88672017-07-05 18:23:03 +02004154 (srv->ssl_ctx.verify_host || (verify & SSL_VERIFY_PEER)) ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01004155 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02004156 if (srv->ssl_ctx.ca_file) {
4157 /* load CAfile to verify */
4158 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004159 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004160 curproxy->id, srv->id,
4161 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
4162 cfgerr++;
4163 }
4164 }
Emeric Brun850efd52014-01-29 12:24:34 +01004165 else {
4166 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004167 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 +01004168 curproxy->id, srv->id,
4169 srv->conf.file, srv->conf.line);
4170 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004171 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01004172 curproxy->id, srv->id,
4173 srv->conf.file, srv->conf.line);
4174 cfgerr++;
4175 }
Emeric Brunef42d922012-10-11 16:11:36 +02004176#ifdef X509_V_FLAG_CRL_CHECK
4177 if (srv->ssl_ctx.crl_file) {
4178 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
4179
4180 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004181 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004182 curproxy->id, srv->id,
4183 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
4184 cfgerr++;
4185 }
4186 else {
4187 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
4188 }
4189 }
4190#endif
4191 }
4192
Emeric Brun94324a42012-10-11 14:00:19 +02004193 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
4194 if (srv->ssl_ctx.ciphers &&
4195 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
4196 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
4197 curproxy->id, srv->id,
4198 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
4199 cfgerr++;
4200 }
4201
4202 return cfgerr;
4203}
4204
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004205/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004206 * be NULL, in which case nothing is done. Returns the number of errors
4207 * encountered.
4208 */
Willy Tarreau03209342016-12-22 17:08:28 +01004209int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004210{
4211 struct ebmb_node *node;
4212 struct sni_ctx *sni;
4213 int err = 0;
4214
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004215 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004216 return 0;
4217
Willy Tarreaufce03112015-01-15 21:32:40 +01004218 /* Automatic memory computations need to know we use SSL there */
4219 global.ssl_used_frontend = 1;
4220
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004221 /* Make sure openssl opens /dev/urandom before the chroot */
4222 if (!ssl_initialize_random()) {
4223 Alert("OpenSSL random data generator initialization failed.\n");
4224 err++;
4225 }
4226 /* Create initial_ctx used to start the ssl connection before do switchctx */
4227 if (!bind_conf->initial_ctx) {
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004228 err += ssl_sock_initial_ctx(bind_conf);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004229 /* It should not be necessary to call this function, but it's
4230 necessary first to check and move all initialisation related
4231 to initial_ctx in ssl_sock_initial_ctx. */
4232 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
4233 }
Emeric Brun0bed9942014-10-30 19:25:24 +01004234 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004235 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01004236
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004237 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004238 while (node) {
4239 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004240 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4241 /* only initialize the CTX on its first occurrence and
4242 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004243 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004244 node = ebmb_next(node);
4245 }
4246
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004247 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004248 while (node) {
4249 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004250 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4251 /* only initialize the CTX on its first occurrence and
4252 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004253 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004254 node = ebmb_next(node);
4255 }
4256 return err;
4257}
4258
Willy Tarreau55d37912016-12-21 23:38:39 +01004259/* Prepares all the contexts for a bind_conf and allocates the shared SSL
4260 * context if needed. Returns < 0 on error, 0 on success. The warnings and
4261 * alerts are directly emitted since the rest of the stack does it below.
4262 */
4263int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
4264{
4265 struct proxy *px = bind_conf->frontend;
4266 int alloc_ctx;
4267 int err;
4268
4269 if (!bind_conf->is_ssl) {
4270 if (bind_conf->default_ctx) {
4271 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
4272 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4273 }
4274 return 0;
4275 }
4276 if (!bind_conf->default_ctx) {
4277 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
4278 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4279 return -1;
4280 }
4281
Willy Tarreauef934602016-12-22 23:12:01 +01004282 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01004283 if (alloc_ctx < 0) {
4284 if (alloc_ctx == SHCTX_E_INIT_LOCK)
4285 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");
4286 else
4287 Alert("Unable to allocate SSL session cache.\n");
4288 return -1;
4289 }
4290
4291 err = 0;
4292 /* initialize all certificate contexts */
4293 err += ssl_sock_prepare_all_ctx(bind_conf);
4294
4295 /* initialize CA variables if the certificates generation is enabled */
4296 err += ssl_sock_load_ca(bind_conf);
4297
4298 return -err;
4299}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02004300
4301/* release ssl context allocated for servers. */
4302void ssl_sock_free_srv_ctx(struct server *srv)
4303{
4304 if (srv->ssl_ctx.ctx)
4305 SSL_CTX_free(srv->ssl_ctx.ctx);
4306}
4307
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004308/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004309 * be NULL, in which case nothing is done. The default_ctx is nullified too.
4310 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004311void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004312{
4313 struct ebmb_node *node, *back;
4314 struct sni_ctx *sni;
4315
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004316 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004317 return;
4318
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004319 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004320 while (node) {
4321 sni = ebmb_entry(node, struct sni_ctx, name);
4322 back = ebmb_next(node);
4323 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004324 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004325 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004326 ssl_sock_free_ssl_conf(sni->conf);
4327 free(sni->conf);
4328 sni->conf = NULL;
4329 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004330 free(sni);
4331 node = back;
4332 }
4333
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004334 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004335 while (node) {
4336 sni = ebmb_entry(node, struct sni_ctx, name);
4337 back = ebmb_next(node);
4338 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004339 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004340 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004341 ssl_sock_free_ssl_conf(sni->conf);
4342 free(sni->conf);
4343 sni->conf = NULL;
4344 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004345 free(sni);
4346 node = back;
4347 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004348 SSL_CTX_free(bind_conf->initial_ctx);
4349 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004350 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004351 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02004352}
4353
Willy Tarreau795cdab2016-12-22 17:30:54 +01004354/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
4355void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
4356{
4357 ssl_sock_free_ca(bind_conf);
4358 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004359 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004360 free(bind_conf->ca_sign_file);
4361 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004362 if (bind_conf->keys_ref) {
4363 free(bind_conf->keys_ref->filename);
4364 free(bind_conf->keys_ref->tlskeys);
4365 LIST_DEL(&bind_conf->keys_ref->list);
4366 free(bind_conf->keys_ref);
4367 }
4368 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004369 bind_conf->ca_sign_pass = NULL;
4370 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004371}
4372
Christopher Faulet31af49d2015-06-09 17:29:50 +02004373/* Load CA cert file and private key used to generate certificates */
4374int
Willy Tarreau03209342016-12-22 17:08:28 +01004375ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02004376{
Willy Tarreau03209342016-12-22 17:08:28 +01004377 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004378 FILE *fp;
4379 X509 *cacert = NULL;
4380 EVP_PKEY *capkey = NULL;
4381 int err = 0;
4382
4383 if (!bind_conf || !bind_conf->generate_certs)
4384 return err;
4385
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004386#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01004387 if (global_ssl.ctx_cache)
4388 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02004389 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02004390#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02004391
Christopher Faulet31af49d2015-06-09 17:29:50 +02004392 if (!bind_conf->ca_sign_file) {
4393 Alert("Proxy '%s': cannot enable certificate generation, "
4394 "no CA certificate File configured at [%s:%d].\n",
4395 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004396 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004397 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004398
4399 /* read in the CA certificate */
4400 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
4401 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4402 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004403 goto load_error;
4404 }
4405 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
4406 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4407 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004408 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004409 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004410 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004411 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
4412 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
4413 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004414 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004415 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004416
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004417 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004418 bind_conf->ca_sign_cert = cacert;
4419 bind_conf->ca_sign_pkey = capkey;
4420 return err;
4421
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004422 read_error:
4423 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004424 if (capkey) EVP_PKEY_free(capkey);
4425 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004426 load_error:
4427 bind_conf->generate_certs = 0;
4428 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004429 return err;
4430}
4431
4432/* Release CA cert and private key used to generate certificated */
4433void
4434ssl_sock_free_ca(struct bind_conf *bind_conf)
4435{
4436 if (!bind_conf)
4437 return;
4438
4439 if (bind_conf->ca_sign_pkey)
4440 EVP_PKEY_free(bind_conf->ca_sign_pkey);
4441 if (bind_conf->ca_sign_cert)
4442 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01004443 bind_conf->ca_sign_pkey = NULL;
4444 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004445}
4446
Emeric Brun46591952012-05-18 15:47:34 +02004447/*
4448 * This function is called if SSL * context is not yet allocated. The function
4449 * is designed to be called before any other data-layer operation and sets the
4450 * handshake flag on the connection. It is safe to call it multiple times.
4451 * It returns 0 on success and -1 in error case.
4452 */
4453static int ssl_sock_init(struct connection *conn)
4454{
4455 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004456 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004457 return 0;
4458
Willy Tarreau3c728722014-01-23 13:50:42 +01004459 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004460 return 0;
4461
Willy Tarreau20879a02012-12-03 16:32:10 +01004462 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4463 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004464 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004465 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004466
Emeric Brun46591952012-05-18 15:47:34 +02004467 /* If it is in client mode initiate SSL session
4468 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004469 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004470 int may_retry = 1;
4471
4472 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004473 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004474 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004475 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004476 if (may_retry--) {
4477 pool_gc2();
4478 goto retry_connect;
4479 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004480 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004481 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004482 }
Emeric Brun46591952012-05-18 15:47:34 +02004483
Emeric Brun46591952012-05-18 15:47:34 +02004484 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004485 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4486 SSL_free(conn->xprt_ctx);
4487 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004488 if (may_retry--) {
4489 pool_gc2();
4490 goto retry_connect;
4491 }
Emeric Brun55476152014-11-12 17:35:37 +01004492 conn->err_code = CO_ER_SSL_NO_MEM;
4493 return -1;
4494 }
Emeric Brun46591952012-05-18 15:47:34 +02004495
Evan Broderbe554312013-06-27 00:05:25 -07004496 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004497 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4498 SSL_free(conn->xprt_ctx);
4499 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004500 if (may_retry--) {
4501 pool_gc2();
4502 goto retry_connect;
4503 }
Emeric Brun55476152014-11-12 17:35:37 +01004504 conn->err_code = CO_ER_SSL_NO_MEM;
4505 return -1;
4506 }
4507
4508 SSL_set_connect_state(conn->xprt_ctx);
4509 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4510 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4511 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4512 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4513 }
4514 }
Evan Broderbe554312013-06-27 00:05:25 -07004515
Emeric Brun46591952012-05-18 15:47:34 +02004516 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004517 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004518
4519 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004520 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004521 return 0;
4522 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004523 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004524 int may_retry = 1;
4525
4526 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004527 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004528 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004529 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004530 if (may_retry--) {
4531 pool_gc2();
4532 goto retry_accept;
4533 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004534 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004535 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004536 }
Emeric Brun46591952012-05-18 15:47:34 +02004537
Emeric Brun46591952012-05-18 15:47:34 +02004538 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004539 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4540 SSL_free(conn->xprt_ctx);
4541 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004542 if (may_retry--) {
4543 pool_gc2();
4544 goto retry_accept;
4545 }
Emeric Brun55476152014-11-12 17:35:37 +01004546 conn->err_code = CO_ER_SSL_NO_MEM;
4547 return -1;
4548 }
Emeric Brun46591952012-05-18 15:47:34 +02004549
Emeric Brune1f38db2012-09-03 20:36:47 +02004550 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004551 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4552 SSL_free(conn->xprt_ctx);
4553 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004554 if (may_retry--) {
4555 pool_gc2();
4556 goto retry_accept;
4557 }
Emeric Brun55476152014-11-12 17:35:37 +01004558 conn->err_code = CO_ER_SSL_NO_MEM;
4559 return -1;
4560 }
4561
4562 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004563
Emeric Brun46591952012-05-18 15:47:34 +02004564 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004565 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004566
4567 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004568 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004569 return 0;
4570 }
4571 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004572 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004573 return -1;
4574}
4575
4576
4577/* This is the callback which is used when an SSL handshake is pending. It
4578 * updates the FD status if it wants some polling before being called again.
4579 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4580 * otherwise it returns non-zero and removes itself from the connection's
4581 * flags (the bit is provided in <flag> by the caller).
4582 */
4583int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4584{
4585 int ret;
4586
Willy Tarreau3c728722014-01-23 13:50:42 +01004587 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004588 return 0;
4589
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004590 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004591 goto out_error;
4592
Emeric Brun674b7432012-11-08 19:21:55 +01004593 /* If we use SSL_do_handshake to process a reneg initiated by
4594 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4595 * Usually SSL_write and SSL_read are used and process implicitly
4596 * the reneg handshake.
4597 * Here we use SSL_peek as a workaround for reneg.
4598 */
4599 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4600 char c;
4601
4602 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4603 if (ret <= 0) {
4604 /* handshake may have not been completed, let's find why */
4605 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004606
Emeric Brun674b7432012-11-08 19:21:55 +01004607 if (ret == SSL_ERROR_WANT_WRITE) {
4608 /* SSL handshake needs to write, L4 connection may not be ready */
4609 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004610 __conn_sock_want_send(conn);
4611 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004612 return 0;
4613 }
4614 else if (ret == SSL_ERROR_WANT_READ) {
4615 /* handshake may have been completed but we have
4616 * no more data to read.
4617 */
4618 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4619 ret = 1;
4620 goto reneg_ok;
4621 }
4622 /* SSL handshake needs to read, L4 connection is ready */
4623 if (conn->flags & CO_FL_WAIT_L4_CONN)
4624 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4625 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004626 __conn_sock_want_recv(conn);
4627 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004628 return 0;
4629 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004630#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4631 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004632 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004633 return 0;
4634 }
4635#endif
Emeric Brun674b7432012-11-08 19:21:55 +01004636 else if (ret == SSL_ERROR_SYSCALL) {
4637 /* if errno is null, then connection was successfully established */
4638 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4639 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004640 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004641#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4642 conn->err_code = CO_ER_SSL_HANDSHAKE;
4643#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004644 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004645#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004646 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4647 empty_handshake = state == TLS_ST_BEFORE;
4648#else
4649 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4650#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004651 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004652 if (!errno) {
4653 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4654 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4655 else
4656 conn->err_code = CO_ER_SSL_EMPTY;
4657 }
4658 else {
4659 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4660 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4661 else
4662 conn->err_code = CO_ER_SSL_ABORT;
4663 }
4664 }
4665 else {
4666 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4667 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004668 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004669 conn->err_code = CO_ER_SSL_HANDSHAKE;
4670 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004671#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004672 }
Emeric Brun674b7432012-11-08 19:21:55 +01004673 goto out_error;
4674 }
4675 else {
4676 /* Fail on all other handshake errors */
4677 /* Note: OpenSSL may leave unread bytes in the socket's
4678 * buffer, causing an RST to be emitted upon close() on
4679 * TCP sockets. We first try to drain possibly pending
4680 * data to avoid this as much as possible.
4681 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004682 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004683 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004684 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4685 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004686 goto out_error;
4687 }
4688 }
4689 /* read some data: consider handshake completed */
4690 goto reneg_ok;
4691 }
4692
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004693 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004694 if (ret != 1) {
4695 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004696 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004697
4698 if (ret == SSL_ERROR_WANT_WRITE) {
4699 /* SSL handshake needs to write, L4 connection may not be ready */
4700 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004701 __conn_sock_want_send(conn);
4702 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004703 return 0;
4704 }
4705 else if (ret == SSL_ERROR_WANT_READ) {
4706 /* SSL handshake needs to read, L4 connection is ready */
4707 if (conn->flags & CO_FL_WAIT_L4_CONN)
4708 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4709 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004710 __conn_sock_want_recv(conn);
4711 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004712 return 0;
4713 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004714#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4715 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004716 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004717 return 0;
4718 }
4719#endif
Willy Tarreau89230192012-09-28 20:22:13 +02004720 else if (ret == SSL_ERROR_SYSCALL) {
4721 /* if errno is null, then connection was successfully established */
4722 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4723 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004724 if (!conn->err_code) {
4725#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4726 conn->err_code = CO_ER_SSL_HANDSHAKE;
4727#else
4728 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004729#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004730 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4731 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004732#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004733 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004734#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004735 if (empty_handshake) {
4736 if (!errno) {
4737 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4738 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4739 else
4740 conn->err_code = CO_ER_SSL_EMPTY;
4741 }
4742 else {
4743 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4744 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4745 else
4746 conn->err_code = CO_ER_SSL_ABORT;
4747 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004748 }
4749 else {
4750 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4751 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4752 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004753 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004754 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004755#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004756 }
Willy Tarreau89230192012-09-28 20:22:13 +02004757 goto out_error;
4758 }
Emeric Brun46591952012-05-18 15:47:34 +02004759 else {
4760 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004761 /* Note: OpenSSL may leave unread bytes in the socket's
4762 * buffer, causing an RST to be emitted upon close() on
4763 * TCP sockets. We first try to drain possibly pending
4764 * data to avoid this as much as possible.
4765 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004766 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004767 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004768 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4769 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004770 goto out_error;
4771 }
4772 }
4773
Emeric Brun674b7432012-11-08 19:21:55 +01004774reneg_ok:
Emeric Brunb5e42a82017-06-06 12:35:14 +00004775
4776#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4777 /* ASYNC engine API doesn't support moving read/write
4778 * buffers. So we disable ASYNC mode right after
4779 * the handshake to avoid buffer oveflows.
4780 */
4781 if (global_ssl.async)
4782 SSL_clear_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4783#endif
Emeric Brun46591952012-05-18 15:47:34 +02004784 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004785 if (!SSL_session_reused(conn->xprt_ctx)) {
4786 if (objt_server(conn->target)) {
4787 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4788 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4789 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4790
Emeric Brun46591952012-05-18 15:47:34 +02004791 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004792 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004793 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004794 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4795 }
Emeric Brun46591952012-05-18 15:47:34 +02004796
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004797 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4798 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004799 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004800 else {
4801 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4802 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4803 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4804 }
Emeric Brun46591952012-05-18 15:47:34 +02004805 }
4806
4807 /* The connection is now established at both layers, it's time to leave */
4808 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4809 return 1;
4810
4811 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004812 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004813 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004814 ERR_clear_error();
4815
Emeric Brun9fa89732012-10-04 17:09:56 +02004816 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004817 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4818 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4819 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004820 }
4821
Emeric Brun46591952012-05-18 15:47:34 +02004822 /* Fail on all other handshake errors */
4823 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004824 if (!conn->err_code)
4825 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004826 return 0;
4827}
4828
4829/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004830 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004831 * buffer wraps, in which case a second call may be performed. The connection's
4832 * flags are updated with whatever special event is detected (error, read0,
4833 * empty). The caller is responsible for taking care of those events and
4834 * avoiding the call if inappropriate. The function does not call the
4835 * connection's polling update function, so the caller is responsible for this.
4836 */
4837static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4838{
4839 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004840 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004841
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004842 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004843 goto out_error;
4844
4845 if (conn->flags & CO_FL_HANDSHAKE)
4846 /* a handshake was requested */
4847 return 0;
4848
Willy Tarreauabf08d92014-01-14 11:31:27 +01004849 /* let's realign the buffer to optimize I/O */
4850 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004851 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004852
4853 /* read the largest possible block. For this, we perform only one call
4854 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4855 * in which case we accept to do it once again. A new attempt is made on
4856 * EINTR too.
4857 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004858 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004859 /* first check if we have some room after p+i */
4860 try = buf->data + buf->size - (buf->p + buf->i);
4861 /* otherwise continue between data and p-o */
4862 if (try <= 0) {
4863 try = buf->p - (buf->data + buf->o);
4864 if (try <= 0)
4865 break;
4866 }
4867 if (try > count)
4868 try = count;
4869
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004870 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004871 if (conn->flags & CO_FL_ERROR) {
4872 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004873 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004874 }
Emeric Brun46591952012-05-18 15:47:34 +02004875 if (ret > 0) {
4876 buf->i += ret;
4877 done += ret;
Emeric Brun46591952012-05-18 15:47:34 +02004878 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004879 }
4880 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004881 ret = SSL_get_error(conn->xprt_ctx, ret);
4882 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004883 /* error on protocol or underlying transport */
4884 if ((ret != SSL_ERROR_SYSCALL)
4885 || (errno && (errno != EAGAIN)))
4886 conn->flags |= CO_FL_ERROR;
4887
Emeric Brun644cde02012-12-14 11:21:13 +01004888 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004889 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004890 ERR_clear_error();
4891 }
Emeric Brun46591952012-05-18 15:47:34 +02004892 goto read0;
4893 }
4894 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004895 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004896 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004897 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004898 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004899 __conn_sock_want_send(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00004900#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4901 /* Async mode can be re-enabled, because we're leaving data state.*/
4902 if (global_ssl.async)
4903 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4904#endif
Emeric Brun46591952012-05-18 15:47:34 +02004905 break;
4906 }
4907 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004908 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4909 /* handshake is running, and it may need to re-enable read */
4910 conn->flags |= CO_FL_SSL_WAIT_HS;
4911 __conn_sock_want_recv(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00004912#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4913 /* Async mode can be re-enabled, because we're leaving data state.*/
4914 if (global_ssl.async)
4915 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4916#endif
Emeric Brun282a76a2012-11-08 18:02:56 +01004917 break;
4918 }
Emeric Brun46591952012-05-18 15:47:34 +02004919 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004920 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004921 break;
4922 }
4923 /* otherwise it's a real error */
4924 goto out_error;
4925 }
4926 }
4927 return done;
4928
4929 read0:
4930 conn_sock_read0(conn);
4931 return done;
4932 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004933 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004934 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004935 ERR_clear_error();
4936
Emeric Brun46591952012-05-18 15:47:34 +02004937 conn->flags |= CO_FL_ERROR;
4938 return done;
4939}
4940
4941
4942/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004943 * <flags> may contain some CO_SFL_* flags to hint the system about other
4944 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004945 * Only one call to send() is performed, unless the buffer wraps, in which case
4946 * a second call may be performed. The connection's flags are updated with
4947 * whatever special event is detected (error, empty). The caller is responsible
4948 * for taking care of those events and avoiding the call if inappropriate. The
4949 * function does not call the connection's polling update function, so the caller
4950 * is responsible for this.
4951 */
4952static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4953{
4954 int ret, try, done;
4955
4956 done = 0;
4957
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004958 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004959 goto out_error;
4960
4961 if (conn->flags & CO_FL_HANDSHAKE)
4962 /* a handshake was requested */
4963 return 0;
4964
4965 /* send the largest possible block. For this we perform only one call
4966 * to send() unless the buffer wraps and we exactly fill the first hunk,
4967 * in which case we accept to do it once again.
4968 */
4969 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004970 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004971
Willy Tarreau7bed9452014-02-02 02:00:24 +01004972 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004973 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004974 global_ssl.max_record && try > global_ssl.max_record) {
4975 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004976 }
4977 else {
4978 /* we need to keep the information about the fact that
4979 * we're not limiting the upcoming send(), because if it
4980 * fails, we'll have to retry with at least as many data.
4981 */
4982 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4983 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004984
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004985 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004986
Emeric Brune1f38db2012-09-03 20:36:47 +02004987 if (conn->flags & CO_FL_ERROR) {
4988 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004989 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004990 }
Emeric Brun46591952012-05-18 15:47:34 +02004991 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004992 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4993
Emeric Brun46591952012-05-18 15:47:34 +02004994 buf->o -= ret;
4995 done += ret;
4996
Willy Tarreau5fb38032012-12-16 19:39:09 +01004997 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004998 /* optimize data alignment in the buffer */
4999 buf->p = buf->data;
5000
5001 /* if the system buffer is full, don't insist */
5002 if (ret < try)
5003 break;
5004 }
5005 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005006 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005007
Emeric Brun46591952012-05-18 15:47:34 +02005008 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01005009 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
5010 /* handshake is running, and it may need to re-enable write */
5011 conn->flags |= CO_FL_SSL_WAIT_HS;
5012 __conn_sock_want_send(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00005013#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
5014 /* Async mode can be re-enabled, because we're leaving data state.*/
5015 if (global_ssl.async)
5016 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
5017#endif
Emeric Brun282a76a2012-11-08 18:02:56 +01005018 break;
5019 }
Emeric Brun46591952012-05-18 15:47:34 +02005020 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01005021 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02005022 break;
5023 }
5024 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01005025 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02005026 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01005027 __conn_sock_want_recv(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005028#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brunb5e42a82017-06-06 12:35:14 +00005029 /* Async mode can be re-enabled, because we're leaving data state.*/
5030 if (global_ssl.async)
5031 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
5032#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005033 break;
5034 }
Emeric Brun46591952012-05-18 15:47:34 +02005035 goto out_error;
5036 }
5037 }
5038 return done;
5039
5040 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01005041 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005042 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005043 ERR_clear_error();
5044
Emeric Brun46591952012-05-18 15:47:34 +02005045 conn->flags |= CO_FL_ERROR;
5046 return done;
5047}
5048
Emeric Brun46591952012-05-18 15:47:34 +02005049static void ssl_sock_close(struct connection *conn) {
5050
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005051 if (conn->xprt_ctx) {
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005052#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brun3854e012017-05-17 20:42:48 +02005053 if (global_ssl.async) {
5054 OSSL_ASYNC_FD all_fd[32], afd;
5055 size_t num_all_fds = 0;
5056 int i;
5057
5058 SSL_get_all_async_fds(conn->xprt_ctx, NULL, &num_all_fds);
5059 if (num_all_fds > 32) {
5060 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
5061 return;
5062 }
5063
5064 SSL_get_all_async_fds(conn->xprt_ctx, all_fd, &num_all_fds);
5065
5066 /* If an async job is pending, we must try to
5067 to catch the end using polling before calling
5068 SSL_free */
5069 if (num_all_fds && SSL_waiting_for_async(conn->xprt_ctx)) {
5070 for (i=0 ; i < num_all_fds ; i++) {
5071 /* switch on an handler designed to
5072 * handle the SSL_free
5073 */
5074 afd = all_fd[i];
5075 fdtab[afd].iocb = ssl_async_fd_free;
5076 fdtab[afd].owner = conn->xprt_ctx;
5077 fd_want_recv(afd);
Emeric Brunce9e01c2017-05-31 10:02:53 +00005078 /* To ensure that the fd cache won't be used
5079 * and we'll catch a real RD event.
5080 */
5081 fd_cant_recv(afd);
Emeric Brun3854e012017-05-17 20:42:48 +02005082 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005083 conn->xprt_ctx = NULL;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005084 jobs++;
5085 return;
5086 }
Emeric Brun3854e012017-05-17 20:42:48 +02005087 /* Else we can remove the fds from the fdtab
5088 * and call SSL_free.
5089 * note: we do a fd_remove and not a delete
5090 * because the fd is owned by the engine.
5091 * the engine is responsible to close
5092 */
5093 for (i=0 ; i < num_all_fds ; i++)
5094 fd_remove(all_fd[i]);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005095 }
5096#endif
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005097 SSL_free(conn->xprt_ctx);
5098 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02005099 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02005100 }
Emeric Brun46591952012-05-18 15:47:34 +02005101}
5102
5103/* This function tries to perform a clean shutdown on an SSL connection, and in
5104 * any case, flags the connection as reusable if no handshake was in progress.
5105 */
5106static void ssl_sock_shutw(struct connection *conn, int clean)
5107{
5108 if (conn->flags & CO_FL_HANDSHAKE)
5109 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005110 if (!clean)
5111 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01005112 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02005113 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005114 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01005115 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005116 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005117 ERR_clear_error();
5118 }
Emeric Brun46591952012-05-18 15:47:34 +02005119}
5120
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02005121/* used for logging, may be changed for a sample fetch later */
5122const char *ssl_sock_get_cipher_name(struct connection *conn)
5123{
5124 if (!conn->xprt && !conn->xprt_ctx)
5125 return NULL;
5126 return SSL_get_cipher_name(conn->xprt_ctx);
5127}
5128
5129/* used for logging, may be changed for a sample fetch later */
5130const char *ssl_sock_get_proto_version(struct connection *conn)
5131{
5132 if (!conn->xprt && !conn->xprt_ctx)
5133 return NULL;
5134 return SSL_get_version(conn->xprt_ctx);
5135}
5136
Willy Tarreau8d598402012-10-22 17:58:39 +02005137/* Extract a serial from a cert, and copy it to a chunk.
5138 * Returns 1 if serial is found and copied, 0 if no serial found and
5139 * -1 if output is not large enough.
5140 */
5141static int
5142ssl_sock_get_serial(X509 *crt, struct chunk *out)
5143{
5144 ASN1_INTEGER *serial;
5145
5146 serial = X509_get_serialNumber(crt);
5147 if (!serial)
5148 return 0;
5149
5150 if (out->size < serial->length)
5151 return -1;
5152
5153 memcpy(out->str, serial->data, serial->length);
5154 out->len = serial->length;
5155 return 1;
5156}
5157
Emeric Brun43e79582014-10-29 19:03:26 +01005158/* Extract a cert to der, and copy it to a chunk.
5159 * Returns 1 if cert is found and copied, 0 on der convertion failure and
5160 * -1 if output is not large enough.
5161 */
5162static int
5163ssl_sock_crt2der(X509 *crt, struct chunk *out)
5164{
5165 int len;
5166 unsigned char *p = (unsigned char *)out->str;;
5167
5168 len =i2d_X509(crt, NULL);
5169 if (len <= 0)
5170 return 1;
5171
5172 if (out->size < len)
5173 return -1;
5174
5175 i2d_X509(crt,&p);
5176 out->len = len;
5177 return 1;
5178}
5179
Emeric Brunce5ad802012-10-22 14:11:22 +02005180
5181/* Copy Date in ASN1_UTCTIME format in struct chunk out.
5182 * Returns 1 if serial is found and copied, 0 if no valid time found
5183 * and -1 if output is not large enough.
5184 */
5185static int
5186ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
5187{
5188 if (tm->type == V_ASN1_GENERALIZEDTIME) {
5189 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
5190
5191 if (gentm->length < 12)
5192 return 0;
5193 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
5194 return 0;
5195 if (out->size < gentm->length-2)
5196 return -1;
5197
5198 memcpy(out->str, gentm->data+2, gentm->length-2);
5199 out->len = gentm->length-2;
5200 return 1;
5201 }
5202 else if (tm->type == V_ASN1_UTCTIME) {
5203 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
5204
5205 if (utctm->length < 10)
5206 return 0;
5207 if (utctm->data[0] >= 0x35)
5208 return 0;
5209 if (out->size < utctm->length)
5210 return -1;
5211
5212 memcpy(out->str, utctm->data, utctm->length);
5213 out->len = utctm->length;
5214 return 1;
5215 }
5216
5217 return 0;
5218}
5219
Emeric Brun87855892012-10-17 17:39:35 +02005220/* Extract an entry from a X509_NAME and copy its value to an output chunk.
5221 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
5222 */
5223static int
5224ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
5225{
5226 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005227 ASN1_OBJECT *obj;
5228 ASN1_STRING *data;
5229 const unsigned char *data_ptr;
5230 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005231 int i, j, n;
5232 int cur = 0;
5233 const char *s;
5234 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005235 int name_count;
5236
5237 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005238
5239 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005240 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02005241 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005242 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02005243 else
5244 j = i;
5245
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005246 ne = X509_NAME_get_entry(a, j);
5247 obj = X509_NAME_ENTRY_get_object(ne);
5248 data = X509_NAME_ENTRY_get_data(ne);
5249 data_ptr = ASN1_STRING_get0_data(data);
5250 data_len = ASN1_STRING_length(data);
5251 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005252 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005253 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005254 s = tmp;
5255 }
5256
5257 if (chunk_strcasecmp(entry, s) != 0)
5258 continue;
5259
5260 if (pos < 0)
5261 cur--;
5262 else
5263 cur++;
5264
5265 if (cur != pos)
5266 continue;
5267
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005268 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02005269 return -1;
5270
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005271 memcpy(out->str, data_ptr, data_len);
5272 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005273 return 1;
5274 }
5275
5276 return 0;
5277
5278}
5279
5280/* Extract and format full DN from a X509_NAME and copy result into a chunk
5281 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
5282 */
5283static int
5284ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
5285{
5286 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005287 ASN1_OBJECT *obj;
5288 ASN1_STRING *data;
5289 const unsigned char *data_ptr;
5290 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005291 int i, n, ln;
5292 int l = 0;
5293 const char *s;
5294 char *p;
5295 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005296 int name_count;
5297
5298
5299 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005300
5301 out->len = 0;
5302 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005303 for (i = 0; i < name_count; i++) {
5304 ne = X509_NAME_get_entry(a, i);
5305 obj = X509_NAME_ENTRY_get_object(ne);
5306 data = X509_NAME_ENTRY_get_data(ne);
5307 data_ptr = ASN1_STRING_get0_data(data);
5308 data_len = ASN1_STRING_length(data);
5309 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005310 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005311 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005312 s = tmp;
5313 }
5314 ln = strlen(s);
5315
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005316 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005317 if (l > out->size)
5318 return -1;
5319 out->len = l;
5320
5321 *(p++)='/';
5322 memcpy(p, s, ln);
5323 p += ln;
5324 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005325 memcpy(p, data_ptr, data_len);
5326 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005327 }
5328
5329 if (!out->len)
5330 return 0;
5331
5332 return 1;
5333}
5334
David Safb76832014-05-08 23:42:08 -04005335char *ssl_sock_get_version(struct connection *conn)
5336{
5337 if (!ssl_sock_is_ssl(conn))
5338 return NULL;
5339
5340 return (char *)SSL_get_version(conn->xprt_ctx);
5341}
5342
Willy Tarreau119a4082016-12-22 21:58:38 +01005343/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
5344 * to disable SNI.
5345 */
Willy Tarreau63076412015-07-10 11:33:32 +02005346void ssl_sock_set_servername(struct connection *conn, const char *hostname)
5347{
5348#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01005349 char *prev_name;
5350
Willy Tarreau63076412015-07-10 11:33:32 +02005351 if (!ssl_sock_is_ssl(conn))
5352 return;
5353
Willy Tarreau119a4082016-12-22 21:58:38 +01005354 /* if the SNI changes, we must destroy the reusable context so that a
5355 * new connection will present a new SNI. As an optimization we could
5356 * later imagine having a small cache of ssl_ctx to hold a few SNI per
5357 * server.
5358 */
5359 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5360 if ((!prev_name && hostname) ||
5361 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
5362 SSL_set_session(conn->xprt_ctx, NULL);
5363
Willy Tarreau63076412015-07-10 11:33:32 +02005364 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
5365#endif
5366}
5367
Emeric Brun0abf8362014-06-24 18:26:41 +02005368/* Extract peer certificate's common name into the chunk dest
5369 * Returns
5370 * the len of the extracted common name
5371 * or 0 if no CN found in DN
5372 * or -1 on error case (i.e. no peer certificate)
5373 */
5374int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04005375{
5376 X509 *crt = NULL;
5377 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04005378 const char find_cn[] = "CN";
5379 const struct chunk find_cn_chunk = {
5380 .str = (char *)&find_cn,
5381 .len = sizeof(find_cn)-1
5382 };
Emeric Brun0abf8362014-06-24 18:26:41 +02005383 int result = -1;
David Safb76832014-05-08 23:42:08 -04005384
5385 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02005386 goto out;
David Safb76832014-05-08 23:42:08 -04005387
5388 /* SSL_get_peer_certificate, it increase X509 * ref count */
5389 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5390 if (!crt)
5391 goto out;
5392
5393 name = X509_get_subject_name(crt);
5394 if (!name)
5395 goto out;
David Safb76832014-05-08 23:42:08 -04005396
Emeric Brun0abf8362014-06-24 18:26:41 +02005397 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
5398out:
David Safb76832014-05-08 23:42:08 -04005399 if (crt)
5400 X509_free(crt);
5401
5402 return result;
5403}
5404
Dave McCowan328fb582014-07-30 10:39:13 -04005405/* returns 1 if client passed a certificate for this session, 0 if not */
5406int ssl_sock_get_cert_used_sess(struct connection *conn)
5407{
5408 X509 *crt = NULL;
5409
5410 if (!ssl_sock_is_ssl(conn))
5411 return 0;
5412
5413 /* SSL_get_peer_certificate, it increase X509 * ref count */
5414 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5415 if (!crt)
5416 return 0;
5417
5418 X509_free(crt);
5419 return 1;
5420}
5421
5422/* returns 1 if client passed a certificate for this connection, 0 if not */
5423int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04005424{
5425 if (!ssl_sock_is_ssl(conn))
5426 return 0;
5427
5428 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
5429}
5430
5431/* returns result from SSL verify */
5432unsigned int ssl_sock_get_verify_result(struct connection *conn)
5433{
5434 if (!ssl_sock_is_ssl(conn))
5435 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
5436
5437 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
5438}
5439
Willy Tarreau8743f7e2016-12-04 18:44:29 +01005440/* Returns the application layer protocol name in <str> and <len> when known.
5441 * Zero is returned if the protocol name was not found, otherwise non-zero is
5442 * returned. The string is allocated in the SSL context and doesn't have to be
5443 * freed by the caller. NPN is also checked if available since older versions
5444 * of openssl (1.0.1) which are more common in field only support this one.
5445 */
5446static int ssl_sock_get_alpn(const struct connection *conn, const char **str, int *len)
5447{
5448 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5449 return 0;
5450
5451 *str = NULL;
5452
5453#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
5454 SSL_get0_alpn_selected(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
5455 if (*str)
5456 return 1;
5457#endif
5458#ifdef OPENSSL_NPN_NEGOTIATED
5459 SSL_get0_next_proto_negotiated(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
5460 if (*str)
5461 return 1;
5462#endif
5463 return 0;
5464}
5465
Willy Tarreau7875d092012-09-10 08:20:03 +02005466/***** Below are some sample fetching functions for ACL/patterns *****/
5467
Emeric Brune64aef12012-09-21 13:15:06 +02005468/* boolean, returns true if client cert was present */
5469static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005470smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02005471{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005472 struct connection *conn;
5473
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005474 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005475 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02005476 return 0;
5477
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005478 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02005479 smp->flags |= SMP_F_MAY_CHANGE;
5480 return 0;
5481 }
5482
5483 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005484 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005485 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02005486
5487 return 1;
5488}
5489
Emeric Brun43e79582014-10-29 19:03:26 +01005490/* binary, returns a certificate in a binary chunk (der/raw).
5491 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5492 * should be use.
5493 */
5494static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005495smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01005496{
5497 int cert_peer = (kw[4] == 'c') ? 1 : 0;
5498 X509 *crt = NULL;
5499 int ret = 0;
5500 struct chunk *smp_trash;
5501 struct connection *conn;
5502
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005503 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01005504 if (!conn || conn->xprt != &ssl_sock)
5505 return 0;
5506
5507 if (!(conn->flags & CO_FL_CONNECTED)) {
5508 smp->flags |= SMP_F_MAY_CHANGE;
5509 return 0;
5510 }
5511
5512 if (cert_peer)
5513 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5514 else
5515 crt = SSL_get_certificate(conn->xprt_ctx);
5516
5517 if (!crt)
5518 goto out;
5519
5520 smp_trash = get_trash_chunk();
5521 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
5522 goto out;
5523
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005524 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005525 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01005526 ret = 1;
5527out:
5528 /* SSL_get_peer_certificate, it increase X509 * ref count */
5529 if (cert_peer && crt)
5530 X509_free(crt);
5531 return ret;
5532}
5533
Emeric Brunba841a12014-04-30 17:05:08 +02005534/* binary, returns serial of certificate in a binary chunk.
5535 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5536 * should be use.
5537 */
Willy Tarreau8d598402012-10-22 17:58:39 +02005538static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005539smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02005540{
Emeric Brunba841a12014-04-30 17:05:08 +02005541 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02005542 X509 *crt = NULL;
5543 int ret = 0;
5544 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005545 struct connection *conn;
5546
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005547 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005548 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02005549 return 0;
5550
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005551 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02005552 smp->flags |= SMP_F_MAY_CHANGE;
5553 return 0;
5554 }
5555
Emeric Brunba841a12014-04-30 17:05:08 +02005556 if (cert_peer)
5557 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5558 else
5559 crt = SSL_get_certificate(conn->xprt_ctx);
5560
Willy Tarreau8d598402012-10-22 17:58:39 +02005561 if (!crt)
5562 goto out;
5563
Willy Tarreau47ca5452012-12-23 20:22:19 +01005564 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005565 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5566 goto out;
5567
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005568 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005569 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005570 ret = 1;
5571out:
Emeric Brunba841a12014-04-30 17:05:08 +02005572 /* SSL_get_peer_certificate, it increase X509 * ref count */
5573 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005574 X509_free(crt);
5575 return ret;
5576}
Emeric Brune64aef12012-09-21 13:15:06 +02005577
Emeric Brunba841a12014-04-30 17:05:08 +02005578/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5579 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5580 * should be use.
5581 */
James Votha051b4a2013-05-14 20:37:59 +02005582static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005583smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005584{
Emeric Brunba841a12014-04-30 17:05:08 +02005585 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005586 X509 *crt = NULL;
5587 const EVP_MD *digest;
5588 int ret = 0;
5589 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005590 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005591
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005592 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005593 if (!conn || conn->xprt != &ssl_sock)
5594 return 0;
5595
5596 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005597 smp->flags |= SMP_F_MAY_CHANGE;
5598 return 0;
5599 }
5600
Emeric Brunba841a12014-04-30 17:05:08 +02005601 if (cert_peer)
5602 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5603 else
5604 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005605 if (!crt)
5606 goto out;
5607
5608 smp_trash = get_trash_chunk();
5609 digest = EVP_sha1();
5610 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5611
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005612 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005613 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005614 ret = 1;
5615out:
Emeric Brunba841a12014-04-30 17:05:08 +02005616 /* SSL_get_peer_certificate, it increase X509 * ref count */
5617 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005618 X509_free(crt);
5619 return ret;
5620}
5621
Emeric Brunba841a12014-04-30 17:05:08 +02005622/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5623 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5624 * should be use.
5625 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005626static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005627smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005628{
Emeric Brunba841a12014-04-30 17:05:08 +02005629 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005630 X509 *crt = NULL;
5631 int ret = 0;
5632 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005633 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005634
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005635 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005636 if (!conn || conn->xprt != &ssl_sock)
5637 return 0;
5638
5639 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005640 smp->flags |= SMP_F_MAY_CHANGE;
5641 return 0;
5642 }
5643
Emeric Brunba841a12014-04-30 17:05:08 +02005644 if (cert_peer)
5645 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5646 else
5647 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005648 if (!crt)
5649 goto out;
5650
Willy Tarreau47ca5452012-12-23 20:22:19 +01005651 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005652 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5653 goto out;
5654
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005655 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005656 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005657 ret = 1;
5658out:
Emeric Brunba841a12014-04-30 17:05:08 +02005659 /* SSL_get_peer_certificate, it increase X509 * ref count */
5660 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005661 X509_free(crt);
5662 return ret;
5663}
5664
Emeric Brunba841a12014-04-30 17:05:08 +02005665/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5666 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5667 * should be use.
5668 */
Emeric Brun87855892012-10-17 17:39:35 +02005669static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005670smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005671{
Emeric Brunba841a12014-04-30 17:05:08 +02005672 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005673 X509 *crt = NULL;
5674 X509_NAME *name;
5675 int ret = 0;
5676 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005677 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005678
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005679 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005680 if (!conn || conn->xprt != &ssl_sock)
5681 return 0;
5682
5683 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005684 smp->flags |= SMP_F_MAY_CHANGE;
5685 return 0;
5686 }
5687
Emeric Brunba841a12014-04-30 17:05:08 +02005688 if (cert_peer)
5689 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5690 else
5691 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005692 if (!crt)
5693 goto out;
5694
5695 name = X509_get_issuer_name(crt);
5696 if (!name)
5697 goto out;
5698
Willy Tarreau47ca5452012-12-23 20:22:19 +01005699 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005700 if (args && args[0].type == ARGT_STR) {
5701 int pos = 1;
5702
5703 if (args[1].type == ARGT_SINT)
5704 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005705
5706 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5707 goto out;
5708 }
5709 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5710 goto out;
5711
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005712 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005713 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005714 ret = 1;
5715out:
Emeric Brunba841a12014-04-30 17:05:08 +02005716 /* SSL_get_peer_certificate, it increase X509 * ref count */
5717 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005718 X509_free(crt);
5719 return ret;
5720}
5721
Emeric Brunba841a12014-04-30 17:05:08 +02005722/* string, returns notbefore date in ASN1_UTCTIME format.
5723 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5724 * should be use.
5725 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005726static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005727smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005728{
Emeric Brunba841a12014-04-30 17:05:08 +02005729 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005730 X509 *crt = NULL;
5731 int ret = 0;
5732 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005733 struct connection *conn;
5734
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005735 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005736 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005737 return 0;
5738
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005739 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005740 smp->flags |= SMP_F_MAY_CHANGE;
5741 return 0;
5742 }
5743
Emeric Brunba841a12014-04-30 17:05:08 +02005744 if (cert_peer)
5745 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5746 else
5747 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005748 if (!crt)
5749 goto out;
5750
Willy Tarreau47ca5452012-12-23 20:22:19 +01005751 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005752 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5753 goto out;
5754
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005755 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005756 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005757 ret = 1;
5758out:
Emeric Brunba841a12014-04-30 17:05:08 +02005759 /* SSL_get_peer_certificate, it increase X509 * ref count */
5760 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005761 X509_free(crt);
5762 return ret;
5763}
5764
Emeric Brunba841a12014-04-30 17:05:08 +02005765/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5766 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5767 * should be use.
5768 */
Emeric Brun87855892012-10-17 17:39:35 +02005769static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005770smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005771{
Emeric Brunba841a12014-04-30 17:05:08 +02005772 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005773 X509 *crt = NULL;
5774 X509_NAME *name;
5775 int ret = 0;
5776 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005777 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005778
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005779 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005780 if (!conn || conn->xprt != &ssl_sock)
5781 return 0;
5782
5783 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005784 smp->flags |= SMP_F_MAY_CHANGE;
5785 return 0;
5786 }
5787
Emeric Brunba841a12014-04-30 17:05:08 +02005788 if (cert_peer)
5789 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5790 else
5791 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005792 if (!crt)
5793 goto out;
5794
5795 name = X509_get_subject_name(crt);
5796 if (!name)
5797 goto out;
5798
Willy Tarreau47ca5452012-12-23 20:22:19 +01005799 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005800 if (args && args[0].type == ARGT_STR) {
5801 int pos = 1;
5802
5803 if (args[1].type == ARGT_SINT)
5804 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005805
5806 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5807 goto out;
5808 }
5809 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5810 goto out;
5811
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005812 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005813 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005814 ret = 1;
5815out:
Emeric Brunba841a12014-04-30 17:05:08 +02005816 /* SSL_get_peer_certificate, it increase X509 * ref count */
5817 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005818 X509_free(crt);
5819 return ret;
5820}
Emeric Brun9143d372012-12-20 15:44:16 +01005821
5822/* integer, returns true if current session use a client certificate */
5823static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005824smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005825{
5826 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005827 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005828
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005829 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005830 if (!conn || conn->xprt != &ssl_sock)
5831 return 0;
5832
5833 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005834 smp->flags |= SMP_F_MAY_CHANGE;
5835 return 0;
5836 }
5837
5838 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005839 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005840 if (crt) {
5841 X509_free(crt);
5842 }
5843
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005844 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005845 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005846 return 1;
5847}
5848
Emeric Brunba841a12014-04-30 17:05:08 +02005849/* integer, returns the certificate version
5850 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5851 * should be use.
5852 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005853static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005854smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005855{
Emeric Brunba841a12014-04-30 17:05:08 +02005856 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005857 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005858 struct connection *conn;
5859
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005860 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005861 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005862 return 0;
5863
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005864 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005865 smp->flags |= SMP_F_MAY_CHANGE;
5866 return 0;
5867 }
5868
Emeric Brunba841a12014-04-30 17:05:08 +02005869 if (cert_peer)
5870 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5871 else
5872 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005873 if (!crt)
5874 return 0;
5875
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005876 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005877 /* SSL_get_peer_certificate increase X509 * ref count */
5878 if (cert_peer)
5879 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005880 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005881
5882 return 1;
5883}
5884
Emeric Brunba841a12014-04-30 17:05:08 +02005885/* string, returns the certificate's signature algorithm.
5886 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5887 * should be use.
5888 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005889static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005890smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005891{
Emeric Brunba841a12014-04-30 17:05:08 +02005892 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005893 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005894 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005895 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005896 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005897
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005898 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005899 if (!conn || conn->xprt != &ssl_sock)
5900 return 0;
5901
5902 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005903 smp->flags |= SMP_F_MAY_CHANGE;
5904 return 0;
5905 }
5906
Emeric Brunba841a12014-04-30 17:05:08 +02005907 if (cert_peer)
5908 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5909 else
5910 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005911 if (!crt)
5912 return 0;
5913
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005914 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5915 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005916
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005917 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5918 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005919 /* SSL_get_peer_certificate increase X509 * ref count */
5920 if (cert_peer)
5921 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005922 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005923 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005924
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005925 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005926 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005927 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005928 /* SSL_get_peer_certificate increase X509 * ref count */
5929 if (cert_peer)
5930 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005931
5932 return 1;
5933}
5934
Emeric Brunba841a12014-04-30 17:05:08 +02005935/* string, returns the certificate's key algorithm.
5936 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5937 * should be use.
5938 */
Emeric Brun521a0112012-10-22 12:22:55 +02005939static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005940smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005941{
Emeric Brunba841a12014-04-30 17:05:08 +02005942 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005943 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005944 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005945 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005946 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005947
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005948 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005949 if (!conn || conn->xprt != &ssl_sock)
5950 return 0;
5951
5952 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005953 smp->flags |= SMP_F_MAY_CHANGE;
5954 return 0;
5955 }
5956
Emeric Brunba841a12014-04-30 17:05:08 +02005957 if (cert_peer)
5958 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5959 else
5960 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005961 if (!crt)
5962 return 0;
5963
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005964 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5965 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005966
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005967 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5968 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005969 /* SSL_get_peer_certificate increase X509 * ref count */
5970 if (cert_peer)
5971 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005972 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005973 }
Emeric Brun521a0112012-10-22 12:22:55 +02005974
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005975 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005976 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005977 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005978 if (cert_peer)
5979 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005980
5981 return 1;
5982}
5983
Emeric Brun645ae792014-04-30 14:21:06 +02005984/* boolean, returns true if front conn. transport layer is SSL.
5985 * This function is also usable on backend conn if the fetch keyword 5th
5986 * char is 'b'.
5987 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005988static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005989smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005990{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005991 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5992 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005993
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005994 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005995 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005996 return 1;
5997}
5998
Emeric Brun2525b6b2012-10-18 15:59:43 +02005999/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02006000static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006001smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006002{
6003#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006004 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006005
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006006 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006007 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006008 conn->xprt_ctx &&
6009 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02006010 return 1;
6011#else
6012 return 0;
6013#endif
6014}
6015
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02006016/* boolean, returns true if client session has been resumed */
6017static int
6018smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
6019{
6020 struct connection *conn = objt_conn(smp->sess->origin);
6021
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006022 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006023 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02006024 conn->xprt_ctx &&
6025 SSL_session_reused(conn->xprt_ctx);
6026 return 1;
6027}
6028
Emeric Brun645ae792014-04-30 14:21:06 +02006029/* string, returns the used cipher if front conn. transport layer is SSL.
6030 * This function is also usable on backend conn if the fetch keyword 5th
6031 * char is 'b'.
6032 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006033static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006034smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006035{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006036 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6037 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02006038
Willy Tarreaube508f12016-03-10 11:47:01 +01006039 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006040 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02006041 return 0;
6042
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006043 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
6044 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006045 return 0;
6046
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006047 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006048 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006049 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006050
6051 return 1;
6052}
6053
Emeric Brun645ae792014-04-30 14:21:06 +02006054/* integer, returns the algoritm's keysize if front conn. transport layer
6055 * is SSL.
6056 * This function is also usable on backend conn if the fetch keyword 5th
6057 * char is 'b'.
6058 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006059static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006060smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006061{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006062 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6063 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006064
Willy Tarreaue237fe12016-03-10 17:05:28 +01006065 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01006066
Emeric Brun589fcad2012-10-16 14:13:26 +02006067 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006068 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02006069 return 0;
6070
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006071 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006072 return 0;
6073
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006074 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006075 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02006076
6077 return 1;
6078}
6079
Emeric Brun645ae792014-04-30 14:21:06 +02006080/* integer, returns the used keysize if front conn. transport layer is SSL.
6081 * This function is also usable on backend conn if the fetch keyword 5th
6082 * char is 'b'.
6083 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006084static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006085smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006086{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006087 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6088 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006089
Emeric Brun589fcad2012-10-16 14:13:26 +02006090 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006091 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6092 return 0;
6093
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006094 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
6095 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02006096 return 0;
6097
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006098 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02006099
6100 return 1;
6101}
6102
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006103#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02006104static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006105smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02006106{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006107 struct connection *conn;
6108
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006109 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006110 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02006111
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006112 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006113 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6114 return 0;
6115
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006116 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006117 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006118 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02006119
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006120 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02006121 return 0;
6122
6123 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02006124}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006125#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02006126
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006127#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006128static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006129smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02006130{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006131 struct connection *conn;
6132
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006133 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006134 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02006135
Willy Tarreaue26bf052015-05-12 10:30:12 +02006136 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006137 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02006138 return 0;
6139
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006140 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006141 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006142 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02006143
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006144 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02006145 return 0;
6146
6147 return 1;
6148}
6149#endif
6150
Emeric Brun645ae792014-04-30 14:21:06 +02006151/* string, returns the used protocol if front conn. transport layer is SSL.
6152 * This function is also usable on backend conn if the fetch keyword 5th
6153 * char is 'b'.
6154 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02006155static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006156smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006157{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006158 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6159 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006160
Emeric Brun589fcad2012-10-16 14:13:26 +02006161 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006162 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6163 return 0;
6164
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006165 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
6166 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006167 return 0;
6168
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006169 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006170 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006171 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006172
6173 return 1;
6174}
6175
Willy Tarreau87b09662015-04-03 00:22:06 +02006176/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02006177 * This function is also usable on backend conn if the fetch keyword 5th
6178 * char is 'b'.
6179 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006180static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006181smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02006182{
6183#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006184 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6185 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02006186
Willy Tarreaue237fe12016-03-10 17:05:28 +01006187 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01006188
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006189 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006190 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02006191
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006192 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6193 return 0;
6194
Willy Tarreau192252e2015-04-04 01:47:55 +02006195 ssl_sess = SSL_get_session(conn->xprt_ctx);
6196 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02006197 return 0;
6198
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006199 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
6200 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02006201 return 0;
6202
6203 return 1;
6204#else
6205 return 0;
6206#endif
6207}
6208
6209static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006210smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006211{
6212#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006213 struct connection *conn;
6214
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006215 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006216 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02006217
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006218 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006219 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6220 return 0;
6221
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006222 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
6223 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02006224 return 0;
6225
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006226 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02006227 return 1;
6228#else
6229 return 0;
6230#endif
6231}
6232
David Sc1ad52e2014-04-08 18:48:47 -04006233static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006234smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
6235{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006236 struct connection *conn;
6237 struct ssl_capture *capture;
6238
6239 conn = objt_conn(smp->sess->origin);
6240 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6241 return 0;
6242
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006243 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006244 if (!capture)
6245 return 0;
6246
6247 smp->flags = SMP_F_CONST;
6248 smp->data.type = SMP_T_BIN;
6249 smp->data.u.str.str = capture->ciphersuite;
6250 smp->data.u.str.len = capture->ciphersuite_len;
6251 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006252}
6253
6254static int
6255smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
6256{
6257 struct chunk *data;
6258
6259 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6260 return 0;
6261
6262 data = get_trash_chunk();
6263 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
6264 smp->data.type = SMP_T_BIN;
6265 smp->data.u.str = *data;
6266 return 1;
6267}
6268
6269static int
6270smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
6271{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006272 struct connection *conn;
6273 struct ssl_capture *capture;
6274
6275 conn = objt_conn(smp->sess->origin);
6276 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6277 return 0;
6278
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006279 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006280 if (!capture)
6281 return 0;
6282
6283 smp->data.type = SMP_T_SINT;
6284 smp->data.u.sint = capture->xxh64;
6285 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006286}
6287
6288static int
6289smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
6290{
6291#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
6292 struct chunk *data;
6293 SSL_CIPHER cipher;
6294 int i;
6295 const char *str;
6296 unsigned char *bin;
6297
6298 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6299 return 0;
6300
6301 /* The cipher algorith must not be SSL_SSLV2, because this
6302 * SSL version seems to not have the same cipher encoding,
6303 * and it is not supported by OpenSSL. Unfortunately, the
6304 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
6305 * with standard defines. We just set the variable to 0,
6306 * ensure that the match with SSL_SSLV2 fails.
6307 */
6308 cipher.algorithm_ssl = 0;
6309
6310 data = get_trash_chunk();
6311 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
6312 bin = (unsigned char *)smp->data.u.str.str + i;
6313 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
6314 str = SSL_CIPHER_standard_name(&cipher);
6315 if (!str || strcmp(str, "UNKNOWN") == 0)
6316 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
6317 else
6318 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
6319 }
6320 smp->data.type = SMP_T_STR;
6321 smp->data.u.str = *data;
6322 return 1;
6323#else
6324 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
6325#endif
6326}
6327
6328static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006329smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04006330{
6331#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006332 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6333 smp->strm ? smp->strm->si[1].end : NULL);
6334
David Sc1ad52e2014-04-08 18:48:47 -04006335 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04006336 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04006337
6338 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04006339 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6340 return 0;
6341
6342 if (!(conn->flags & CO_FL_CONNECTED)) {
6343 smp->flags |= SMP_F_MAY_CHANGE;
6344 return 0;
6345 }
6346
6347 finished_trash = get_trash_chunk();
6348 if (!SSL_session_reused(conn->xprt_ctx))
6349 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6350 else
6351 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6352
6353 if (!finished_len)
6354 return 0;
6355
Emeric Brunb73a9b02014-04-30 18:49:19 +02006356 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006357 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006358 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04006359
6360 return 1;
6361#else
6362 return 0;
6363#endif
6364}
6365
Emeric Brun2525b6b2012-10-18 15:59:43 +02006366/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006367static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006368smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006369{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006370 struct connection *conn;
6371
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006372 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006373 if (!conn || conn->xprt != &ssl_sock)
6374 return 0;
6375
6376 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006377 smp->flags = SMP_F_MAY_CHANGE;
6378 return 0;
6379 }
6380
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006381 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006382 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006383 smp->flags = 0;
6384
6385 return 1;
6386}
6387
Emeric Brun2525b6b2012-10-18 15:59:43 +02006388/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006389static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006390smp_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 +02006391{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006392 struct connection *conn;
6393
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006394 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006395 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02006396 return 0;
6397
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006398 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006399 smp->flags = SMP_F_MAY_CHANGE;
6400 return 0;
6401 }
6402
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006403 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006404 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006405 smp->flags = 0;
6406
6407 return 1;
6408}
6409
Emeric Brun2525b6b2012-10-18 15:59:43 +02006410/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02006411static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006412smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006413{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006414 struct connection *conn;
6415
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006416 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006417 if (!conn || conn->xprt != &ssl_sock)
6418 return 0;
6419
6420 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006421 smp->flags = SMP_F_MAY_CHANGE;
6422 return 0;
6423 }
6424
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006425 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006426 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006427 smp->flags = 0;
6428
6429 return 1;
6430}
6431
Emeric Brun2525b6b2012-10-18 15:59:43 +02006432/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006433static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006434smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006435{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006436 struct connection *conn;
6437
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006438 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006439 if (!conn || conn->xprt != &ssl_sock)
6440 return 0;
6441
6442 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006443 smp->flags = SMP_F_MAY_CHANGE;
6444 return 0;
6445 }
6446
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006447 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006448 return 0;
6449
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006450 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006451 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006452 smp->flags = 0;
6453
6454 return 1;
6455}
6456
Emeric Brunfb510ea2012-10-05 12:00:26 +02006457/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006458static 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 +02006459{
6460 if (!*args[cur_arg + 1]) {
6461 if (err)
6462 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6463 return ERR_ALERT | ERR_FATAL;
6464 }
6465
Willy Tarreauef934602016-12-22 23:12:01 +01006466 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6467 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006468 else
6469 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006470
Emeric Brund94b3fe2012-09-20 18:23:56 +02006471 return 0;
6472}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006473static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6474{
6475 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
6476}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006477
Christopher Faulet31af49d2015-06-09 17:29:50 +02006478/* parse the "ca-sign-file" bind keyword */
6479static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6480{
6481 if (!*args[cur_arg + 1]) {
6482 if (err)
6483 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6484 return ERR_ALERT | ERR_FATAL;
6485 }
6486
Willy Tarreauef934602016-12-22 23:12:01 +01006487 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6488 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02006489 else
6490 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
6491
6492 return 0;
6493}
6494
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006495/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006496static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6497{
6498 if (!*args[cur_arg + 1]) {
6499 if (err)
6500 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
6501 return ERR_ALERT | ERR_FATAL;
6502 }
6503 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
6504 return 0;
6505}
6506
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006507/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006508static 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 +02006509{
6510 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006511 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006512 return ERR_ALERT | ERR_FATAL;
6513 }
6514
Emeric Brun76d88952012-10-05 15:47:31 +02006515 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02006516 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006517 return 0;
6518}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006519static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6520{
6521 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
6522}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006523/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006524static 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 +02006525{
Willy Tarreau38011032013-08-13 16:59:39 +02006526 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02006527
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006528 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006529 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006530 return ERR_ALERT | ERR_FATAL;
6531 }
6532
Willy Tarreauef934602016-12-22 23:12:01 +01006533 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
6534 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02006535 memprintf(err, "'%s' : path too long", args[cur_arg]);
6536 return ERR_ALERT | ERR_FATAL;
6537 }
Willy Tarreauef934602016-12-22 23:12:01 +01006538 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01006539 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02006540 return ERR_ALERT | ERR_FATAL;
6541
6542 return 0;
6543 }
6544
Willy Tarreau03209342016-12-22 17:08:28 +01006545 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006546 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006547
6548 return 0;
6549}
6550
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006551/* parse the "crt-list" bind keyword */
6552static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6553{
6554 if (!*args[cur_arg + 1]) {
6555 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
6556 return ERR_ALERT | ERR_FATAL;
6557 }
6558
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006559 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006560 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006561 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006562 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006563
6564 return 0;
6565}
6566
Emeric Brunfb510ea2012-10-05 12:00:26 +02006567/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006568static 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 +02006569{
Emeric Brun051cdab2012-10-02 19:25:50 +02006570#ifndef X509_V_FLAG_CRL_CHECK
6571 if (err)
6572 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6573 return ERR_ALERT | ERR_FATAL;
6574#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006575 if (!*args[cur_arg + 1]) {
6576 if (err)
6577 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6578 return ERR_ALERT | ERR_FATAL;
6579 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006580
Willy Tarreauef934602016-12-22 23:12:01 +01006581 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6582 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006583 else
6584 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006585
Emeric Brun2b58d042012-09-20 17:10:03 +02006586 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006587#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006588}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006589static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6590{
6591 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6592}
Emeric Brun2b58d042012-09-20 17:10:03 +02006593
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006594/* parse the "curves" bind keyword keyword */
6595static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6596{
6597#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6598 if (!*args[cur_arg + 1]) {
6599 if (err)
6600 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6601 return ERR_ALERT | ERR_FATAL;
6602 }
6603 conf->curves = strdup(args[cur_arg + 1]);
6604 return 0;
6605#else
6606 if (err)
6607 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6608 return ERR_ALERT | ERR_FATAL;
6609#endif
6610}
6611static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6612{
6613 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6614}
6615
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006616/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006617static 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 +02006618{
6619#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6620 if (err)
6621 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6622 return ERR_ALERT | ERR_FATAL;
6623#elif defined(OPENSSL_NO_ECDH)
6624 if (err)
6625 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6626 return ERR_ALERT | ERR_FATAL;
6627#else
6628 if (!*args[cur_arg + 1]) {
6629 if (err)
6630 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6631 return ERR_ALERT | ERR_FATAL;
6632 }
6633
6634 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006635
6636 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006637#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006638}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006639static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6640{
6641 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6642}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006643
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006644/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006645static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6646{
6647 int code;
6648 char *p = args[cur_arg + 1];
6649 unsigned long long *ignerr = &conf->crt_ignerr;
6650
6651 if (!*p) {
6652 if (err)
6653 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6654 return ERR_ALERT | ERR_FATAL;
6655 }
6656
6657 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6658 ignerr = &conf->ca_ignerr;
6659
6660 if (strcmp(p, "all") == 0) {
6661 *ignerr = ~0ULL;
6662 return 0;
6663 }
6664
6665 while (p) {
6666 code = atoi(p);
6667 if ((code <= 0) || (code > 63)) {
6668 if (err)
6669 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6670 args[cur_arg], code, args[cur_arg + 1]);
6671 return ERR_ALERT | ERR_FATAL;
6672 }
6673 *ignerr |= 1ULL << code;
6674 p = strchr(p, ',');
6675 if (p)
6676 p++;
6677 }
6678
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006679 return 0;
6680}
6681
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006682/* parse tls_method_options "no-xxx" and "force-xxx" */
6683static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006684{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006685 uint16_t v;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006686 char *p;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006687 p = strchr(arg, '-');
6688 if (!p)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006689 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006690 p++;
6691 if (!strcmp(p, "sslv3"))
6692 v = CONF_SSLV3;
6693 else if (!strcmp(p, "tlsv10"))
6694 v = CONF_TLSV10;
6695 else if (!strcmp(p, "tlsv11"))
6696 v = CONF_TLSV11;
6697 else if (!strcmp(p, "tlsv12"))
6698 v = CONF_TLSV12;
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02006699 else if (!strcmp(p, "tlsv13"))
6700 v = CONF_TLSV13;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006701 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006702 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006703 if (!strncmp(arg, "no-", 3))
6704 methods->flags |= methodVersions[v].flag;
6705 else if (!strncmp(arg, "force-", 6))
6706 methods->min = methods->max = v;
6707 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006708 goto fail;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006709 return 0;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006710 fail:
6711 if (err)
6712 memprintf(err, "'%s' : option not implemented", arg);
6713 return ERR_ALERT | ERR_FATAL;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006714}
6715
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006716static 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 +02006717{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006718 return parse_tls_method_options(args[cur_arg], &conf->ssl_methods, err);
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006719}
6720
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006721static 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 +02006722{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006723 return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
6724}
6725
6726/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
6727static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
6728{
6729 uint16_t i, v = 0;
6730 char *argv = args[cur_arg + 1];
6731 if (!*argv) {
6732 if (err)
6733 memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
6734 return ERR_ALERT | ERR_FATAL;
6735 }
6736 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
6737 if (!strcmp(argv, methodVersions[i].name))
6738 v = i;
6739 if (!v) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006740 if (err)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006741 memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006742 return ERR_ALERT | ERR_FATAL;
6743 }
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006744 if (!strcmp("ssl-min-ver", args[cur_arg]))
6745 methods->min = v;
6746 else if (!strcmp("ssl-max-ver", args[cur_arg]))
6747 methods->max = v;
6748 else {
6749 if (err)
6750 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
6751 return ERR_ALERT | ERR_FATAL;
6752 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006753 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006754}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006755
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02006756static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6757{
6758#if !defined(OPENSSL_IS_BORINGSSL)
6759 Warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
6760#endif
6761 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6762}
6763
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006764static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6765{
6766 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6767}
6768
6769static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6770{
6771 return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
6772}
6773
Emeric Brun2d0c4822012-10-02 13:45:20 +02006774/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006775static 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 +02006776{
Emeric Brun89675492012-10-05 13:48:26 +02006777 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006778 return 0;
6779}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006780
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006781/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006782static 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 +02006783{
6784#ifdef OPENSSL_NPN_NEGOTIATED
6785 char *p1, *p2;
6786
6787 if (!*args[cur_arg + 1]) {
6788 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6789 return ERR_ALERT | ERR_FATAL;
6790 }
6791
6792 free(conf->npn_str);
6793
Willy Tarreau3724da12016-02-12 17:11:12 +01006794 /* the NPN string is built as a suite of (<len> <name>)*,
6795 * so we reuse each comma to store the next <len> and need
6796 * one more for the end of the string.
6797 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006798 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006799 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006800 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6801
6802 /* replace commas with the name length */
6803 p1 = conf->npn_str;
6804 p2 = p1 + 1;
6805 while (1) {
6806 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6807 if (!p2)
6808 p2 = p1 + 1 + strlen(p1 + 1);
6809
6810 if (p2 - (p1 + 1) > 255) {
6811 *p2 = '\0';
6812 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6813 return ERR_ALERT | ERR_FATAL;
6814 }
6815
6816 *p1 = p2 - (p1 + 1);
6817 p1 = p2;
6818
6819 if (!*p2)
6820 break;
6821
6822 *(p2++) = '\0';
6823 }
6824 return 0;
6825#else
6826 if (err)
6827 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6828 return ERR_ALERT | ERR_FATAL;
6829#endif
6830}
6831
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006832static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6833{
6834 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6835}
6836
Willy Tarreauab861d32013-04-02 02:30:41 +02006837/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006838static 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 +02006839{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006840#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006841 char *p1, *p2;
6842
6843 if (!*args[cur_arg + 1]) {
6844 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6845 return ERR_ALERT | ERR_FATAL;
6846 }
6847
6848 free(conf->alpn_str);
6849
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006850 /* the ALPN string is built as a suite of (<len> <name>)*,
6851 * so we reuse each comma to store the next <len> and need
6852 * one more for the end of the string.
6853 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006854 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006855 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006856 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6857
6858 /* replace commas with the name length */
6859 p1 = conf->alpn_str;
6860 p2 = p1 + 1;
6861 while (1) {
6862 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6863 if (!p2)
6864 p2 = p1 + 1 + strlen(p1 + 1);
6865
6866 if (p2 - (p1 + 1) > 255) {
6867 *p2 = '\0';
6868 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6869 return ERR_ALERT | ERR_FATAL;
6870 }
6871
6872 *p1 = p2 - (p1 + 1);
6873 p1 = p2;
6874
6875 if (!*p2)
6876 break;
6877
6878 *(p2++) = '\0';
6879 }
6880 return 0;
6881#else
6882 if (err)
6883 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6884 return ERR_ALERT | ERR_FATAL;
6885#endif
6886}
6887
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006888static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6889{
6890 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6891}
6892
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006893/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006894static 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 +02006895{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006896 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006897 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006898
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006899 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6900 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006901 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006902 conf->ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
6903 if (!conf->ssl_methods.min)
6904 conf->ssl_methods.min = global_ssl.listen_default_sslmethods.min;
6905 if (!conf->ssl_methods.max)
6906 conf->ssl_methods.max = global_ssl.listen_default_sslmethods.max;
Emeric Brun76d88952012-10-05 15:47:31 +02006907
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006908 return 0;
6909}
6910
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006911/* parse the "prefer-client-ciphers" bind keyword */
6912static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6913{
6914 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
6915 return 0;
6916}
6917
Christopher Faulet31af49d2015-06-09 17:29:50 +02006918/* parse the "generate-certificates" bind keyword */
6919static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6920{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006921#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006922 conf->generate_certs = 1;
6923#else
6924 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6925 err && *err ? *err : "");
6926#endif
6927 return 0;
6928}
6929
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006930/* parse the "strict-sni" bind keyword */
6931static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6932{
6933 conf->strict_sni = 1;
6934 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006935}
6936
6937/* parse the "tls-ticket-keys" bind keyword */
6938static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6939{
6940#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6941 FILE *f;
6942 int i = 0;
6943 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006944 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006945
6946 if (!*args[cur_arg + 1]) {
6947 if (err)
6948 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6949 return ERR_ALERT | ERR_FATAL;
6950 }
6951
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006952 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6953 if(keys_ref) {
6954 conf->keys_ref = keys_ref;
6955 return 0;
6956 }
6957
Vincent Bernat02779b62016-04-03 13:48:43 +02006958 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006959 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006960
6961 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6962 if (err)
6963 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6964 return ERR_ALERT | ERR_FATAL;
6965 }
6966
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006967 keys_ref->filename = strdup(args[cur_arg + 1]);
6968
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006969 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6970 int len = strlen(thisline);
6971 /* Strip newline characters from the end */
6972 if(thisline[len - 1] == '\n')
6973 thisline[--len] = 0;
6974
6975 if(thisline[len - 1] == '\r')
6976 thisline[--len] = 0;
6977
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006978 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 +01006979 if (err)
6980 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006981 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006982 return ERR_ALERT | ERR_FATAL;
6983 }
6984 i++;
6985 }
6986
6987 if (i < TLS_TICKETS_NO) {
6988 if (err)
6989 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 +02006990 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006991 return ERR_ALERT | ERR_FATAL;
6992 }
6993
6994 fclose(f);
6995
6996 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006997 i -= 2;
6998 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006999 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02007000 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007001
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02007002 LIST_ADD(&tlskeys_reference, &keys_ref->list);
7003
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007004 return 0;
7005#else
7006 if (err)
7007 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
7008 return ERR_ALERT | ERR_FATAL;
7009#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01007010}
7011
Emeric Brund94b3fe2012-09-20 18:23:56 +02007012/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007013static 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 +02007014{
7015 if (!*args[cur_arg + 1]) {
7016 if (err)
7017 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
7018 return ERR_ALERT | ERR_FATAL;
7019 }
7020
7021 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007022 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007023 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007024 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007025 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007026 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007027 else {
7028 if (err)
7029 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
7030 args[cur_arg], args[cur_arg + 1]);
7031 return ERR_ALERT | ERR_FATAL;
7032 }
7033
7034 return 0;
7035}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007036static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
7037{
7038 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
7039}
Emeric Brund94b3fe2012-09-20 18:23:56 +02007040
Willy Tarreau92faadf2012-10-10 23:04:25 +02007041/************** "server" keywords ****************/
7042
Emeric Brunef42d922012-10-11 16:11:36 +02007043/* parse the "ca-file" server keyword */
7044static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7045{
7046 if (!*args[*cur_arg + 1]) {
7047 if (err)
7048 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
7049 return ERR_ALERT | ERR_FATAL;
7050 }
7051
Willy Tarreauef934602016-12-22 23:12:01 +01007052 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
7053 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02007054 else
7055 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
7056
7057 return 0;
7058}
7059
Willy Tarreau92faadf2012-10-10 23:04:25 +02007060/* parse the "check-ssl" server keyword */
7061static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7062{
7063 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007064 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7065 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
7066 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007067 newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
7068 if (!newsrv->ssl_ctx.methods.min)
7069 newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
7070 if (!newsrv->ssl_ctx.methods.max)
7071 newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
7072
Willy Tarreau92faadf2012-10-10 23:04:25 +02007073 return 0;
7074}
7075
7076/* parse the "ciphers" server keyword */
7077static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7078{
7079 if (!*args[*cur_arg + 1]) {
7080 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
7081 return ERR_ALERT | ERR_FATAL;
7082 }
7083
7084 free(newsrv->ssl_ctx.ciphers);
7085 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
7086 return 0;
7087}
7088
Emeric Brunef42d922012-10-11 16:11:36 +02007089/* parse the "crl-file" server keyword */
7090static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7091{
7092#ifndef X509_V_FLAG_CRL_CHECK
7093 if (err)
7094 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
7095 return ERR_ALERT | ERR_FATAL;
7096#else
7097 if (!*args[*cur_arg + 1]) {
7098 if (err)
7099 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
7100 return ERR_ALERT | ERR_FATAL;
7101 }
7102
Willy Tarreauef934602016-12-22 23:12:01 +01007103 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
7104 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02007105 else
7106 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
7107
7108 return 0;
7109#endif
7110}
7111
Emeric Bruna7aa3092012-10-26 12:58:00 +02007112/* parse the "crt" server keyword */
7113static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7114{
7115 if (!*args[*cur_arg + 1]) {
7116 if (err)
7117 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
7118 return ERR_ALERT | ERR_FATAL;
7119 }
7120
Willy Tarreauef934602016-12-22 23:12:01 +01007121 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
7122 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02007123 else
7124 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
7125
7126 return 0;
7127}
Emeric Brunef42d922012-10-11 16:11:36 +02007128
Frédéric Lécaille340ae602017-03-13 10:38:04 +01007129/* parse the "no-check-ssl" server keyword */
7130static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7131{
7132 newsrv->check.use_ssl = 0;
7133 free(newsrv->ssl_ctx.ciphers);
7134 newsrv->ssl_ctx.ciphers = NULL;
7135 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
7136 return 0;
7137}
7138
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01007139/* parse the "no-send-proxy-v2-ssl" server keyword */
7140static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7141{
7142 newsrv->pp_opts &= ~SRV_PP_V2;
7143 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7144 return 0;
7145}
7146
7147/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
7148static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7149{
7150 newsrv->pp_opts &= ~SRV_PP_V2;
7151 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7152 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
7153 return 0;
7154}
7155
Frédéric Lécaillee381d762017-03-13 11:54:17 +01007156/* parse the "no-ssl" server keyword */
7157static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7158{
7159 newsrv->use_ssl = 0;
7160 free(newsrv->ssl_ctx.ciphers);
7161 newsrv->ssl_ctx.ciphers = NULL;
7162 return 0;
7163}
7164
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007165/* parse the "no-ssl-reuse" server keyword */
7166static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7167{
7168 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
7169 return 0;
7170}
7171
Emeric Brunf9c5c472012-10-11 15:28:34 +02007172/* parse the "no-tls-tickets" server keyword */
7173static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7174{
7175 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
7176 return 0;
7177}
David Safb76832014-05-08 23:42:08 -04007178/* parse the "send-proxy-v2-ssl" server keyword */
7179static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7180{
7181 newsrv->pp_opts |= SRV_PP_V2;
7182 newsrv->pp_opts |= SRV_PP_V2_SSL;
7183 return 0;
7184}
7185
7186/* parse the "send-proxy-v2-ssl-cn" server keyword */
7187static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7188{
7189 newsrv->pp_opts |= SRV_PP_V2;
7190 newsrv->pp_opts |= SRV_PP_V2_SSL;
7191 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
7192 return 0;
7193}
Emeric Brunf9c5c472012-10-11 15:28:34 +02007194
Willy Tarreau732eac42015-07-09 11:40:25 +02007195/* parse the "sni" server keyword */
7196static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7197{
7198#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
7199 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
7200 return ERR_ALERT | ERR_FATAL;
7201#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007202 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02007203
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007204 arg = args[*cur_arg + 1];
7205 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02007206 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
7207 return ERR_ALERT | ERR_FATAL;
7208 }
7209
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007210 free(newsrv->sni_expr);
7211 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02007212
Willy Tarreau732eac42015-07-09 11:40:25 +02007213 return 0;
7214#endif
7215}
7216
Willy Tarreau92faadf2012-10-10 23:04:25 +02007217/* parse the "ssl" server keyword */
7218static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7219{
7220 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007221 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7222 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007223 return 0;
7224}
7225
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007226/* parse the "ssl-reuse" server keyword */
7227static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7228{
7229 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
7230 return 0;
7231}
7232
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007233/* parse the "tls-tickets" server keyword */
7234static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7235{
7236 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
7237 return 0;
7238}
7239
Emeric Brunef42d922012-10-11 16:11:36 +02007240/* parse the "verify" server keyword */
7241static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7242{
7243 if (!*args[*cur_arg + 1]) {
7244 if (err)
7245 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
7246 return ERR_ALERT | ERR_FATAL;
7247 }
7248
7249 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007250 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02007251 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007252 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02007253 else {
7254 if (err)
7255 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
7256 args[*cur_arg], args[*cur_arg + 1]);
7257 return ERR_ALERT | ERR_FATAL;
7258 }
7259
Evan Broderbe554312013-06-27 00:05:25 -07007260 return 0;
7261}
7262
7263/* parse the "verifyhost" server keyword */
7264static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7265{
7266 if (!*args[*cur_arg + 1]) {
7267 if (err)
7268 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
7269 return ERR_ALERT | ERR_FATAL;
7270 }
7271
Frédéric Lécaille273f3212017-03-13 15:52:01 +01007272 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07007273 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
7274
Emeric Brunef42d922012-10-11 16:11:36 +02007275 return 0;
7276}
7277
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007278/* parse the "ssl-default-bind-options" keyword in global section */
7279static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
7280 struct proxy *defpx, const char *file, int line,
7281 char **err) {
7282 int i = 1;
7283
7284 if (*(args[i]) == 0) {
7285 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7286 return -1;
7287 }
7288 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007289 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007290 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Lukas Tribus53ae85c2017-05-04 15:45:40 +00007291 else if (!strcmp(args[i], "prefer-client-ciphers"))
7292 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007293 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7294 if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
7295 i++;
7296 else {
7297 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7298 return -1;
7299 }
7300 }
7301 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007302 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7303 return -1;
7304 }
7305 i++;
7306 }
7307 return 0;
7308}
7309
7310/* parse the "ssl-default-server-options" keyword in global section */
7311static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
7312 struct proxy *defpx, const char *file, int line,
7313 char **err) {
7314 int i = 1;
7315
7316 if (*(args[i]) == 0) {
7317 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7318 return -1;
7319 }
7320 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007321 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007322 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007323 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7324 if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
7325 i++;
7326 else {
7327 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7328 return -1;
7329 }
7330 }
7331 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007332 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7333 return -1;
7334 }
7335 i++;
7336 }
7337 return 0;
7338}
7339
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007340/* parse the "ca-base" / "crt-base" keywords in global section.
7341 * Returns <0 on alert, >0 on warning, 0 on success.
7342 */
7343static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
7344 struct proxy *defpx, const char *file, int line,
7345 char **err)
7346{
7347 char **target;
7348
Willy Tarreauef934602016-12-22 23:12:01 +01007349 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007350
7351 if (too_many_args(1, args, err, NULL))
7352 return -1;
7353
7354 if (*target) {
7355 memprintf(err, "'%s' already specified.", args[0]);
7356 return -1;
7357 }
7358
7359 if (*(args[1]) == 0) {
7360 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
7361 return -1;
7362 }
7363 *target = strdup(args[1]);
7364 return 0;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007365}
7366
7367/* parse the "ssl-mode-async" keyword in global section.
7368 * Returns <0 on alert, >0 on warning, 0 on success.
7369 */
7370static int ssl_parse_global_ssl_async(char **args, int section_type, struct proxy *curpx,
7371 struct proxy *defpx, const char *file, int line,
7372 char **err)
7373{
7374#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
7375 global_ssl.async = 1;
7376 return 0;
7377#else
7378 memprintf(err, "'%s': openssl library does not support async mode", args[0]);
7379 return -1;
7380#endif
7381}
7382
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007383#ifndef OPENSSL_NO_ENGINE
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007384static int ssl_check_async_engine_count(void) {
7385 int err_code = 0;
7386
Emeric Brun3854e012017-05-17 20:42:48 +02007387 if (global_ssl.async && (openssl_engines_initialized > 32)) {
7388 Alert("ssl-mode-async only supports a maximum of 32 engines.\n");
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007389 err_code = ERR_ABORT;
7390 }
7391 return err_code;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007392}
7393
Grant Zhang872f9c22017-01-21 01:10:18 +00007394/* parse the "ssl-engine" keyword in global section.
7395 * Returns <0 on alert, >0 on warning, 0 on success.
7396 */
7397static int ssl_parse_global_ssl_engine(char **args, int section_type, struct proxy *curpx,
7398 struct proxy *defpx, const char *file, int line,
7399 char **err)
7400{
7401 char *algo;
7402 int ret = -1;
7403
7404 if (*(args[1]) == 0) {
7405 memprintf(err, "global statement '%s' expects a valid engine name as an argument.", args[0]);
7406 return ret;
7407 }
7408
7409 if (*(args[2]) == 0) {
7410 /* if no list of algorithms is given, it defaults to ALL */
7411 algo = strdup("ALL");
7412 goto add_engine;
7413 }
7414
7415 /* otherwise the expected format is ssl-engine <engine_name> algo <list of algo> */
7416 if (strcmp(args[2], "algo") != 0) {
7417 memprintf(err, "global statement '%s' expects to have algo keyword.", args[0]);
7418 return ret;
7419 }
7420
7421 if (*(args[3]) == 0) {
7422 memprintf(err, "global statement '%s' expects algorithm names as an argument.", args[0]);
7423 return ret;
7424 }
7425 algo = strdup(args[3]);
7426
7427add_engine:
7428 if (ssl_init_single_engine(args[1], algo)==0) {
7429 openssl_engines_initialized++;
7430 ret = 0;
7431 }
7432 free(algo);
7433 return ret;
7434}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007435#endif
Grant Zhang872f9c22017-01-21 01:10:18 +00007436
Willy Tarreauf22e9682016-12-21 23:23:19 +01007437/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
7438 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
7439 */
7440static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
7441 struct proxy *defpx, const char *file, int line,
7442 char **err)
7443{
7444 char **target;
7445
Willy Tarreauef934602016-12-22 23:12:01 +01007446 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01007447
7448 if (too_many_args(1, args, err, NULL))
7449 return -1;
7450
7451 if (*(args[1]) == 0) {
7452 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
7453 return -1;
7454 }
7455
7456 free(*target);
7457 *target = strdup(args[1]);
7458 return 0;
7459}
7460
Willy Tarreau9ceda382016-12-21 23:13:03 +01007461/* parse various global tune.ssl settings consisting in positive integers.
7462 * Returns <0 on alert, >0 on warning, 0 on success.
7463 */
7464static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
7465 struct proxy *defpx, const char *file, int line,
7466 char **err)
7467{
7468 int *target;
7469
7470 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
7471 target = &global.tune.sslcachesize;
7472 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007473 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007474 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007475 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007476 else if (strcmp(args[0], "maxsslconn") == 0)
7477 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007478 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
7479 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007480 else {
7481 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
7482 return -1;
7483 }
7484
7485 if (too_many_args(1, args, err, NULL))
7486 return -1;
7487
7488 if (*(args[1]) == 0) {
7489 memprintf(err, "'%s' expects an integer argument.", args[0]);
7490 return -1;
7491 }
7492
7493 *target = atoi(args[1]);
7494 if (*target < 0) {
7495 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
7496 return -1;
7497 }
7498 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007499}
7500
7501static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
7502 struct proxy *defpx, const char *file, int line,
7503 char **err)
7504{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007505 int ret;
7506
7507 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
7508 if (ret != 0)
7509 return ret;
7510
7511 if (pool2_ssl_capture) {
7512 memprintf(err, "'%s' is already configured.", args[0]);
7513 return -1;
7514 }
7515
7516 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
7517 if (!pool2_ssl_capture) {
7518 memprintf(err, "Out of memory error.");
7519 return -1;
7520 }
7521 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007522}
7523
7524/* parse "ssl.force-private-cache".
7525 * Returns <0 on alert, >0 on warning, 0 on success.
7526 */
7527static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
7528 struct proxy *defpx, const char *file, int line,
7529 char **err)
7530{
7531 if (too_many_args(0, args, err, NULL))
7532 return -1;
7533
Willy Tarreauef934602016-12-22 23:12:01 +01007534 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007535 return 0;
7536}
7537
7538/* parse "ssl.lifetime".
7539 * Returns <0 on alert, >0 on warning, 0 on success.
7540 */
7541static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
7542 struct proxy *defpx, const char *file, int line,
7543 char **err)
7544{
7545 const char *res;
7546
7547 if (too_many_args(1, args, err, NULL))
7548 return -1;
7549
7550 if (*(args[1]) == 0) {
7551 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
7552 return -1;
7553 }
7554
Willy Tarreauef934602016-12-22 23:12:01 +01007555 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01007556 if (res) {
7557 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
7558 return -1;
7559 }
7560 return 0;
7561}
7562
7563#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01007564/* parse "ssl-dh-param-file".
7565 * Returns <0 on alert, >0 on warning, 0 on success.
7566 */
7567static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
7568 struct proxy *defpx, const char *file, int line,
7569 char **err)
7570{
7571 if (too_many_args(1, args, err, NULL))
7572 return -1;
7573
7574 if (*(args[1]) == 0) {
7575 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
7576 return -1;
7577 }
7578
7579 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
7580 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
7581 return -1;
7582 }
7583 return 0;
7584}
7585
Willy Tarreau9ceda382016-12-21 23:13:03 +01007586/* parse "ssl.default-dh-param".
7587 * Returns <0 on alert, >0 on warning, 0 on success.
7588 */
7589static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
7590 struct proxy *defpx, const char *file, int line,
7591 char **err)
7592{
7593 if (too_many_args(1, args, err, NULL))
7594 return -1;
7595
7596 if (*(args[1]) == 0) {
7597 memprintf(err, "'%s' expects an integer argument.", args[0]);
7598 return -1;
7599 }
7600
Willy Tarreauef934602016-12-22 23:12:01 +01007601 global_ssl.default_dh_param = atoi(args[1]);
7602 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01007603 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
7604 return -1;
7605 }
7606 return 0;
7607}
7608#endif
7609
7610
William Lallemand32af2032016-10-29 18:09:35 +02007611/* This function is used with TLS ticket keys management. It permits to browse
7612 * each reference. The variable <getnext> must contain the current node,
7613 * <end> point to the root node.
7614 */
7615#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7616static inline
7617struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
7618{
7619 struct tls_keys_ref *ref = getnext;
7620
7621 while (1) {
7622
7623 /* Get next list entry. */
7624 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
7625
7626 /* If the entry is the last of the list, return NULL. */
7627 if (&ref->list == end)
7628 return NULL;
7629
7630 return ref;
7631 }
7632}
7633
7634static inline
7635struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7636{
7637 int id;
7638 char *error;
7639
7640 /* If the reference starts by a '#', this is numeric id. */
7641 if (reference[0] == '#') {
7642 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7643 id = strtol(reference + 1, &error, 10);
7644 if (*error != '\0')
7645 return NULL;
7646
7647 /* Perform the unique id lookup. */
7648 return tlskeys_ref_lookupid(id);
7649 }
7650
7651 /* Perform the string lookup. */
7652 return tlskeys_ref_lookup(reference);
7653}
7654#endif
7655
7656
7657#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7658
7659static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7660
7661static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7662 return cli_io_handler_tlskeys_files(appctx);
7663}
7664
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007665/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7666 * (next index to be dumped), and cli.p0 (next key reference).
7667 */
William Lallemand32af2032016-10-29 18:09:35 +02007668static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7669
7670 struct stream_interface *si = appctx->owner;
7671
7672 switch (appctx->st2) {
7673 case STAT_ST_INIT:
7674 /* Display the column headers. If the message cannot be sent,
7675 * quit the fucntion with returning 0. The function is called
7676 * later and restart at the state "STAT_ST_INIT".
7677 */
7678 chunk_reset(&trash);
7679
7680 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7681 chunk_appendf(&trash, "# id secret\n");
7682 else
7683 chunk_appendf(&trash, "# id (file)\n");
7684
7685 if (bi_putchk(si_ic(si), &trash) == -1) {
7686 si_applet_cant_put(si);
7687 return 0;
7688 }
7689
William Lallemand32af2032016-10-29 18:09:35 +02007690 /* Now, we start the browsing of the references lists.
7691 * Note that the following call to LIST_ELEM return bad pointer. The only
7692 * available field of this pointer is <list>. It is used with the function
7693 * tlskeys_list_get_next() for retruning the first available entry
7694 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007695 if (appctx->ctx.cli.p0 == NULL) {
7696 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7697 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007698 }
7699
7700 appctx->st2 = STAT_ST_LIST;
7701 /* fall through */
7702
7703 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007704 while (appctx->ctx.cli.p0) {
7705 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7706 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007707
7708 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007709 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007710 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007711
7712 if (appctx->ctx.cli.i1 == 0)
7713 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7714
William Lallemand32af2032016-10-29 18:09:35 +02007715 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007716 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007717 struct chunk *t2 = get_trash_chunk();
7718
7719 chunk_reset(t2);
7720 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007721 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007722 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007723 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007724
7725 if (bi_putchk(si_ic(si), &trash) == -1) {
7726 /* let's try again later from this stream. We add ourselves into
7727 * this stream's users so that it can remove us upon termination.
7728 */
7729 si_applet_cant_put(si);
7730 return 0;
7731 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007732 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007733 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007734 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007735 }
7736 if (bi_putchk(si_ic(si), &trash) == -1) {
7737 /* let's try again later from this stream. We add ourselves into
7738 * this stream's users so that it can remove us upon termination.
7739 */
7740 si_applet_cant_put(si);
7741 return 0;
7742 }
7743
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007744 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007745 break;
7746
7747 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007748 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007749 }
7750
7751 appctx->st2 = STAT_ST_FIN;
7752 /* fall through */
7753
7754 default:
7755 appctx->st2 = STAT_ST_FIN;
7756 return 1;
7757 }
7758 return 0;
7759}
7760
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007761/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007762static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7763{
William Lallemand32af2032016-10-29 18:09:35 +02007764 /* no parameter, shows only file list */
7765 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007766 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007767 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007768 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007769 }
7770
7771 if (args[2][0] == '*') {
7772 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007773 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007774 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007775 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7776 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007777 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007778 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007779 return 1;
7780 }
7781 }
William Lallemand32af2032016-10-29 18:09:35 +02007782 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007783 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007784}
7785
William Lallemand32af2032016-10-29 18:09:35 +02007786static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7787{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007788 struct tls_keys_ref *ref;
7789
William Lallemand32af2032016-10-29 18:09:35 +02007790 /* Expect two parameters: the filename and the new new TLS key in encoding */
7791 if (!*args[3] || !*args[4]) {
7792 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 +01007793 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007794 return 1;
7795 }
7796
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007797 ref = tlskeys_ref_lookup_ref(args[3]);
7798 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007799 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007800 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007801 return 1;
7802 }
7803
7804 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7805 if (trash.len != sizeof(struct tls_sess_key)) {
7806 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007807 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007808 return 1;
7809 }
7810
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007811 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7812 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007813
7814 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007815 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007816 return 1;
7817
7818}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007819#endif
William Lallemand32af2032016-10-29 18:09:35 +02007820
7821static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7822{
7823#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7824 char *err = NULL;
7825
7826 /* Expect one parameter: the new response in base64 encoding */
7827 if (!*args[3]) {
7828 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007829 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007830 return 1;
7831 }
7832
7833 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7834 if (trash.len < 0) {
7835 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007836 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007837 return 1;
7838 }
7839
7840 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7841 if (err) {
7842 memprintf(&err, "%s.\n", err);
7843 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007844 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007845 }
7846 return 1;
7847 }
7848 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007849 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007850 return 1;
7851#else
7852 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 +01007853 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007854 return 1;
7855#endif
7856
7857}
7858
7859/* register cli keywords */
7860static struct cli_kw_list cli_kws = {{ },{
7861#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7862 { { "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 },
7863 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007864#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007865 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007866 { { NULL }, NULL, NULL, NULL }
7867}};
7868
7869
Willy Tarreau7875d092012-09-10 08:20:03 +02007870/* Note: must not be declared <const> as its list will be overwritten.
7871 * Please take care of keeping this list alphabetically sorted.
7872 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007873static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007874 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007875 { "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 +02007876 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7877 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007878 { "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 +02007879 { "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 +02007880 { "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 +02007881 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7882 { "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 +01007883 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007884 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007885 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7886 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7887 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7888 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7889 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7890 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7891 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7892 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007893 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007894 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7895 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007896 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007897 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7898 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7899 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7900 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7901 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7902 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7903 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007904 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007905 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007906 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007907 { "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 +01007908 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007909 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7910 { "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 +02007911 { "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 +02007912#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007913 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007914#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007915#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007916 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007917#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007918 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007919 { "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 +02007920 { "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 +01007921 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7922 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007923 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7924 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7925 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7926 { "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 +02007927 { NULL, NULL, 0, 0, 0 },
7928}};
7929
7930/* Note: must not be declared <const> as its list will be overwritten.
7931 * Please take care of keeping this list alphabetically sorted.
7932 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007933static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007934 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7935 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007936 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007937}};
7938
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007939/* Note: must not be declared <const> as its list will be overwritten.
7940 * Please take care of keeping this list alphabetically sorted, doing so helps
7941 * all code contributors.
7942 * Optional keywords are also declared with a NULL ->parse() function so that
7943 * the config parser can report an appropriate error when a known keyword was
7944 * not enabled.
7945 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007946static struct ssl_bind_kw ssl_bind_kws[] = {
7947 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7948 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7949 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7950 { "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 +01007951 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007952 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007953 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02007954 { "ssl-min-ver", ssl_bind_parse_tls_method_minmax,1 }, /* minimum version */
7955 { "ssl-max-ver", ssl_bind_parse_tls_method_minmax,1 }, /* maximum version */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007956 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7957 { NULL, NULL, 0 },
7958};
7959
Willy Tarreau51fb7652012-09-18 18:24:39 +02007960static struct bind_kw_list bind_kws = { "SSL", { }, {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007961 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7962 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7963 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
7964 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7965 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
7966 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7967 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7968 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7969 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7970 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
7971 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
7972 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7973 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
7974 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
7975 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
7976 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02007977 { "force-tlsv13", bind_parse_tls_method_options, 0 }, /* force TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007978 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
7979 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
7980 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
7981 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
7982 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02007983 { "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007984 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7985 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007986 { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
7987 { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007988 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7989 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7990 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7991 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
7992 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007993 { NULL, NULL, 0 },
7994}};
Emeric Brun46591952012-05-18 15:47:34 +02007995
Willy Tarreau92faadf2012-10-10 23:04:25 +02007996/* Note: must not be declared <const> as its list will be overwritten.
7997 * Please take care of keeping this list alphabetically sorted, doing so helps
7998 * all code contributors.
7999 * Optional keywords are also declared with a NULL ->parse() function so that
8000 * the config parser can report an appropriate error when a known keyword was
8001 * not enabled.
8002 */
8003static struct srv_kw_list srv_kws = { "SSL", { }, {
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02008004 { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
8005 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
8006 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
8007 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
8008 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
8009 { "force-sslv3", srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
8010 { "force-tlsv10", srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
8011 { "force-tlsv11", srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
8012 { "force-tlsv12", srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
8013 { "force-tlsv13", srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
8014 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
8015 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
8016 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
8017 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
8018 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
8019 { "no-sslv3", srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
8020 { "no-tlsv10", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
8021 { "no-tlsv11", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
8022 { "no-tlsv12", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
8023 { "no-tlsv13", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
8024 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
8025 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
8026 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
8027 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
8028 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
8029 { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1 }, /* minimum version */
8030 { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1 }, /* maximum version */
8031 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
8032 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
8033 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
8034 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02008035 { NULL, NULL, 0, 0 },
8036}};
8037
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008038static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01008039 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
8040 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01008041 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008042 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
8043 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01008044#ifndef OPENSSL_NO_DH
8045 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
8046#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008047 { CFG_GLOBAL, "ssl-mode-async", ssl_parse_global_ssl_async },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008048#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008049 { CFG_GLOBAL, "ssl-engine", ssl_parse_global_ssl_engine },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008050#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01008051 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
8052#ifndef OPENSSL_NO_DH
8053 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
8054#endif
8055 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
8056 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
8057 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
8058 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01008059 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01008060 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
8061 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008062 { 0, NULL, NULL },
8063}};
8064
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02008065/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01008066static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02008067 .snd_buf = ssl_sock_from_buf,
8068 .rcv_buf = ssl_sock_to_buf,
8069 .rcv_pipe = NULL,
8070 .snd_pipe = NULL,
8071 .shutr = NULL,
8072 .shutw = ssl_sock_shutw,
8073 .close = ssl_sock_close,
8074 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01008075 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01008076 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01008077 .prepare_srv = ssl_sock_prepare_srv_ctx,
8078 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8743f7e2016-12-04 18:44:29 +01008079 .get_alpn = ssl_sock_get_alpn,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01008080 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02008081};
8082
Daniel Jakots54ffb912015-11-06 20:02:41 +01008083#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008084
8085static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
8086{
8087 if (ptr) {
8088 chunk_destroy(ptr);
8089 free(ptr);
8090 }
8091}
8092
8093#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01008094static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
8095{
8096 pool_free2(pool2_ssl_capture, ptr);
8097}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008098
Emeric Brun46591952012-05-18 15:47:34 +02008099__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02008100static void __ssl_sock_init(void)
8101{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008102 char *ptr;
8103
Emeric Brun46591952012-05-18 15:47:34 +02008104 STACK_OF(SSL_COMP)* cm;
8105
Willy Tarreauef934602016-12-22 23:12:01 +01008106 if (global_ssl.listen_default_ciphers)
8107 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
8108 if (global_ssl.connect_default_ciphers)
8109 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01008110
Willy Tarreau13e14102016-12-22 20:25:26 +01008111 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02008112 SSL_library_init();
8113 cm = SSL_COMP_get_compression_methods();
8114 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01008115#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008116 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
8117#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01008118 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 +02008119 sample_register_fetches(&sample_fetch_keywords);
8120 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02008121 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02008122 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008123 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02008124 cli_register_kw(&cli_kws);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008125#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008126 ENGINE_load_builtin_engines();
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008127 hap_register_post_check(ssl_check_async_engine_count);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008128#endif
Willy Tarreaud1c57502016-12-22 22:46:15 +01008129#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
8130 hap_register_post_check(tlskeys_finalize_config);
8131#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008132
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008133 ptr = NULL;
8134 memprintf(&ptr, "Built with OpenSSL version : "
8135#ifdef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008136 "BoringSSL");
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008137#else /* OPENSSL_IS_BORINGSSL */
8138 OPENSSL_VERSION_TEXT
8139 "\nRunning on OpenSSL version : %s%s",
8140 SSLeay_version(SSLEAY_VERSION),
8141 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
8142#endif
8143 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
8144#if OPENSSL_VERSION_NUMBER < 0x00907000L
8145 "no (library version too old)"
8146#elif defined(OPENSSL_NO_TLSEXT)
8147 "no (disabled via OPENSSL_NO_TLSEXT)"
8148#else
8149 "yes"
8150#endif
8151 "", ptr);
8152
8153 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
8154#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
8155 "yes"
8156#else
8157#ifdef OPENSSL_NO_TLSEXT
8158 "no (because of OPENSSL_NO_TLSEXT)"
8159#else
8160 "no (version might be too old, 0.9.8f min needed)"
8161#endif
8162#endif
8163 "", ptr);
8164
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008165 memprintf(&ptr, "%s\nOpenSSL library supports : "
8166#if SSL_OP_NO_SSLv3
8167 "SSLv3 "
8168#endif
8169#if SSL_OP_NO_TLSv1
8170 "TLSv1.0 "
8171#endif
8172#if SSL_OP_NO_TLSv1_1
8173 "TLSv1.1 "
8174#endif
8175#if SSL_OP_NO_TLSv1_2
8176 "TLSv1.2 "
8177#endif
8178#if SSL_OP_NO_TLSv1_3
8179 "TLSv1.3"
8180#endif
8181 "", ptr);
8182
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008183 hap_register_build_opts(ptr, 1);
8184
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008185 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
8186 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02008187
8188#ifndef OPENSSL_NO_DH
8189 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
Grant Zhang872f9c22017-01-21 01:10:18 +00008190 hap_register_post_deinit(ssl_free_dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02008191#endif
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008192#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008193 hap_register_post_deinit(ssl_free_engines);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008194#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02008195 /* Load SSL string for the verbose & debug mode. */
8196 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02008197}
8198
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008199#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008200void ssl_free_engines(void) {
8201 struct ssl_engine_list *wl, *wlb;
8202 /* free up engine list */
8203 list_for_each_entry_safe(wl, wlb, &openssl_engines, list) {
8204 ENGINE_finish(wl->e);
8205 ENGINE_free(wl->e);
8206 LIST_DEL(&wl->list);
8207 free(wl);
8208 }
8209}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008210#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02008211
Remi Gacogned3a23c32015-05-28 16:39:47 +02008212#ifndef OPENSSL_NO_DH
Grant Zhang872f9c22017-01-21 01:10:18 +00008213void ssl_free_dh(void) {
8214 if (local_dh_1024) {
8215 DH_free(local_dh_1024);
8216 local_dh_1024 = NULL;
8217 }
8218 if (local_dh_2048) {
8219 DH_free(local_dh_2048);
8220 local_dh_2048 = NULL;
8221 }
8222 if (local_dh_4096) {
8223 DH_free(local_dh_4096);
8224 local_dh_4096 = NULL;
8225 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02008226 if (global_dh) {
8227 DH_free(global_dh);
8228 global_dh = NULL;
8229 }
Grant Zhang872f9c22017-01-21 01:10:18 +00008230}
8231#endif
8232
8233__attribute__((destructor))
8234static void __ssl_sock_deinit(void)
8235{
8236#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
8237 lru64_destroy(ssl_ctx_lru_tree);
Remi Gacogned3a23c32015-05-28 16:39:47 +02008238#endif
8239
8240 ERR_remove_state(0);
8241 ERR_free_strings();
8242
8243 EVP_cleanup();
8244
8245#if OPENSSL_VERSION_NUMBER >= 0x00907000L
8246 CRYPTO_cleanup_all_ex_data();
8247#endif
8248}
8249
8250
Emeric Brun46591952012-05-18 15:47:34 +02008251/*
8252 * Local variables:
8253 * c-indent-level: 8
8254 * c-basic-offset: 8
8255 * End:
8256 */