blob: 7b1a0c9bdcd05bcd69356931e87ad9ccac62f0e7 [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;
Emmanuel Hocdet15969292017-08-11 10:56:00 +02001583 SSL *tmp_ssl = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001584 X509_NAME *name;
1585 const EVP_MD *digest;
1586 X509V3_CTX ctx;
1587 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001588 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001589
Christopher Faulet48a83322017-07-28 16:56:09 +02001590 /* Get the private key of the default certificate and use it */
Emmanuel Hocdet15969292017-08-11 10:56:00 +02001591#if (OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined LIBRESSL_VERSION_NUMBER)
1592 pkey = SSL_CTX_get0_privatekey(bind_conf->default_ctx);
1593#else
1594 tmp_ssl = SSL_new(bind_conf->default_ctx);
1595 if (tmp_ssl)
1596 pkey = SSL_get_privatekey(tmp_ssl);
1597#endif
1598 if (!pkey)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001599 goto mkcert_error;
1600
1601 /* Create the certificate */
1602 if (!(newcrt = X509_new()))
1603 goto mkcert_error;
1604
1605 /* Set version number for the certificate (X509v3) and the serial
1606 * number */
1607 if (X509_set_version(newcrt, 2L) != 1)
1608 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001609 if (!serial)
1610 serial = now_ms;
1611 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001612
1613 /* Set duration for the certificate */
1614 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1615 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1616 goto mkcert_error;
1617
1618 /* set public key in the certificate */
1619 if (X509_set_pubkey(newcrt, pkey) != 1)
1620 goto mkcert_error;
1621
1622 /* Set issuer name from the CA */
1623 if (!(name = X509_get_subject_name(cacert)))
1624 goto mkcert_error;
1625 if (X509_set_issuer_name(newcrt, name) != 1)
1626 goto mkcert_error;
1627
1628 /* Set the subject name using the same, but the CN */
1629 name = X509_NAME_dup(name);
1630 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1631 (const unsigned char *)servername,
1632 -1, -1, 0) != 1) {
1633 X509_NAME_free(name);
1634 goto mkcert_error;
1635 }
1636 if (X509_set_subject_name(newcrt, name) != 1) {
1637 X509_NAME_free(name);
1638 goto mkcert_error;
1639 }
1640 X509_NAME_free(name);
1641
1642 /* Add x509v3 extensions as specified */
1643 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1644 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1645 X509_EXTENSION *ext;
1646
1647 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1648 goto mkcert_error;
1649 if (!X509_add_ext(newcrt, ext, -1)) {
1650 X509_EXTENSION_free(ext);
1651 goto mkcert_error;
1652 }
1653 X509_EXTENSION_free(ext);
1654 }
1655
1656 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001657
1658 key_type = EVP_PKEY_base_id(capkey);
1659
1660 if (key_type == EVP_PKEY_DSA)
1661 digest = EVP_sha1();
1662 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001663 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001664 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001665 digest = EVP_sha256();
1666 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001667#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001668 int nid;
1669
1670 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1671 goto mkcert_error;
1672 if (!(digest = EVP_get_digestbynid(nid)))
1673 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001674#else
1675 goto mkcert_error;
1676#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001677 }
1678
Christopher Faulet31af49d2015-06-09 17:29:50 +02001679 if (!(X509_sign(newcrt, capkey, digest)))
1680 goto mkcert_error;
1681
1682 /* Create and set the new SSL_CTX */
1683 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1684 goto mkcert_error;
1685 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1686 goto mkcert_error;
1687 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1688 goto mkcert_error;
1689 if (!SSL_CTX_check_private_key(ssl_ctx))
1690 goto mkcert_error;
1691
1692 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001693
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001694#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001695 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001696#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001697#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1698 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001699 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001700 EC_KEY *ecc;
1701 int nid;
1702
1703 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1704 goto end;
1705 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1706 goto end;
1707 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1708 EC_KEY_free(ecc);
1709 }
1710#endif
1711 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001712 return ssl_ctx;
1713
1714 mkcert_error:
Emmanuel Hocdet15969292017-08-11 10:56:00 +02001715 if (tmp_ssl) SSL_free(tmp_ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001716 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1717 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001718 return NULL;
1719}
1720
Christopher Faulet7969a332015-10-09 11:15:03 +02001721SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001722ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001723{
1724 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001725
1726 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001727}
1728
Christopher Faulet30548802015-06-11 13:39:32 +02001729/* Do a lookup for a certificate in the LRU cache used to store generated
1730 * certificates. */
1731SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001732ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001733{
1734 struct lru64 *lru = NULL;
1735
1736 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001737 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001738 if (lru && lru->domain)
1739 return (SSL_CTX *)lru->data;
1740 }
1741 return NULL;
1742}
1743
Christopher Fauletd2cab922015-07-28 16:03:47 +02001744/* Set a certificate int the LRU cache used to store generated
1745 * certificate. Return 0 on success, otherwise -1 */
1746int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001747ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001748{
1749 struct lru64 *lru = NULL;
1750
1751 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001752 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001753 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001754 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001755 if (lru->domain && lru->data)
1756 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001757 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001758 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001759 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001760 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001761}
1762
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001763/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001764unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001765ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001766{
1767 return XXH32(data, len, ssl_ctx_lru_seed);
1768}
1769
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001770/* Generate a cert and immediately assign it to the SSL session so that the cert's
1771 * refcount is maintained regardless of the cert's presence in the LRU cache.
1772 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001773static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001774ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001775{
1776 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001777 SSL_CTX *ssl_ctx = NULL;
1778 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001779 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001780
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001781 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001782 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001783 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001784 if (lru && lru->domain)
1785 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001786 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001787 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001788 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001789 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001790 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001791 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001792 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001793 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001794 SSL_set_SSL_CTX(ssl, ssl_ctx);
1795 /* No LRU cache, this CTX will be released as soon as the session dies */
1796 SSL_CTX_free(ssl_ctx);
1797 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001798 return ssl_ctx;
1799}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001800#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001801
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001802
1803#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1804#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1805#endif
1806
1807#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1808#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
1809#define SSL_renegotiate_pending(arg) 0
1810#endif
1811#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1812#define SSL_OP_SINGLE_ECDH_USE 0
1813#endif
1814#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1815#define SSL_OP_NO_TICKET 0
1816#endif
1817#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1818#define SSL_OP_NO_COMPRESSION 0
1819#endif
Emmanuel Hocdet23877ab2017-07-12 12:53:02 +02001820#ifdef OPENSSL_NO_SSL3 /* SSLv3 support removed */
1821#undef SSL_OP_NO_SSLv3
1822#define SSL_OP_NO_SSLv3 0
1823#endif
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001824#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1825#define SSL_OP_NO_TLSv1_1 0
1826#endif
1827#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1828#define SSL_OP_NO_TLSv1_2 0
1829#endif
1830#ifndef SSL_OP_NO_TLSv1_3 /* dev */
1831#define SSL_OP_NO_TLSv1_3 0
1832#endif
1833#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1834#define SSL_OP_SINGLE_DH_USE 0
1835#endif
1836#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1837#define SSL_OP_SINGLE_ECDH_USE 0
1838#endif
1839#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1840#define SSL_MODE_RELEASE_BUFFERS 0
1841#endif
1842#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1843#define SSL_MODE_SMALL_BUFFERS 0
1844#endif
1845
1846#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001847typedef enum { SET_CLIENT, SET_SERVER } set_context_func;
1848
1849static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001850{
Emmanuel Hocdet23877ab2017-07-12 12:53:02 +02001851#if SSL_OP_NO_SSLv3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001852 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, SSLv3_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001853 : SSL_CTX_set_ssl_version(ctx, SSLv3_client_method());
1854#endif
1855}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001856static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1857 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001858 : SSL_CTX_set_ssl_version(ctx, TLSv1_client_method());
1859}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001860static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001861#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001862 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001863 : SSL_CTX_set_ssl_version(ctx, TLSv1_1_client_method());
1864#endif
1865}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001866static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001867#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001868 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001869 : SSL_CTX_set_ssl_version(ctx, TLSv1_2_client_method());
1870#endif
1871}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001872/* TLS 1.2 is the last supported version in this context. */
1873static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {}
1874/* Unusable in this context. */
1875static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {}
1876static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {}
1877static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {}
1878static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {}
1879static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {}
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001880#else /* openssl >= 1.1.0 */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001881typedef enum { SET_MIN, SET_MAX } set_context_func;
1882
1883static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c) {
1884 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001885 : SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
1886}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001887static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {
1888 c == SET_MAX ? SSL_set_max_proto_version(ssl, SSL3_VERSION)
1889 : SSL_set_min_proto_version(ssl, SSL3_VERSION);
1890}
1891static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1892 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001893 : SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1894}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001895static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {
1896 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_VERSION)
1897 : SSL_set_min_proto_version(ssl, TLS1_VERSION);
1898}
1899static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
1900 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001901 : SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
1902}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001903static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {
1904 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_1_VERSION)
1905 : SSL_set_min_proto_version(ssl, TLS1_1_VERSION);
1906}
1907static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
1908 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001909 : SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
1910}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001911static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {
1912 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_2_VERSION)
1913 : SSL_set_min_proto_version(ssl, TLS1_2_VERSION);
1914}
1915static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001916#if SSL_OP_NO_TLSv1_3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001917 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001918 : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
1919#endif
1920}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001921static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {
1922#if SSL_OP_NO_TLSv1_3
1923 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_3_VERSION)
1924 : SSL_set_min_proto_version(ssl, TLS1_3_VERSION);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001925#endif
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001926}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001927#endif
1928static void ctx_set_None_func(SSL_CTX *ctx, set_context_func c) { }
1929static void ssl_set_None_func(SSL *ssl, set_context_func c) { }
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001930
1931static struct {
1932 int option;
1933 uint16_t flag;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001934 void (*ctx_set_version)(SSL_CTX *, set_context_func);
1935 void (*ssl_set_version)(SSL *, set_context_func);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001936 const char *name;
1937} methodVersions[] = {
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001938 {0, 0, ctx_set_None_func, ssl_set_None_func, "NONE"}, /* CONF_TLSV_NONE */
1939 {SSL_OP_NO_SSLv3, MC_SSL_O_NO_SSLV3, ctx_set_SSLv3_func, ssl_set_SSLv3_func, "SSLv3"}, /* CONF_SSLV3 */
1940 {SSL_OP_NO_TLSv1, MC_SSL_O_NO_TLSV10, ctx_set_TLSv10_func, ssl_set_TLSv10_func, "TLSv1.0"}, /* CONF_TLSV10 */
1941 {SSL_OP_NO_TLSv1_1, MC_SSL_O_NO_TLSV11, ctx_set_TLSv11_func, ssl_set_TLSv11_func, "TLSv1.1"}, /* CONF_TLSV11 */
1942 {SSL_OP_NO_TLSv1_2, MC_SSL_O_NO_TLSV12, ctx_set_TLSv12_func, ssl_set_TLSv12_func, "TLSv1.2"}, /* CONF_TLSV12 */
1943 {SSL_OP_NO_TLSv1_3, MC_SSL_O_NO_TLSV13, ctx_set_TLSv13_func, ssl_set_TLSv13_func, "TLSv1.3"}, /* CONF_TLSV13 */
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001944};
1945
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001946static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1947{
1948 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1949 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1950 SSL_set_SSL_CTX(ssl, ctx);
1951}
1952
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001953#ifdef OPENSSL_IS_BORINGSSL
1954
1955static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1956{
1957 (void)al; /* shut gcc stupid warning */
1958 (void)priv;
1959
1960 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1961 return SSL_TLSEXT_ERR_NOACK;
1962 return SSL_TLSEXT_ERR_OK;
1963}
1964
1965static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1966{
1967 struct connection *conn;
1968 struct bind_conf *s;
1969 const uint8_t *extension_data;
1970 size_t extension_len;
1971 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1972 const SSL_CIPHER *cipher;
1973 uint16_t cipher_suite;
1974 uint8_t name_type, hash, sign;
1975 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1976
1977 char *wildp = NULL;
1978 const uint8_t *servername;
1979 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1980 int i;
1981
1982 conn = SSL_get_app_data(ctx->ssl);
1983 s = objt_listener(conn->target)->bind_conf;
1984
1985 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1986 &extension_data, &extension_len)) {
1987 CBS_init(&extension, extension_data, extension_len);
1988
1989 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1990 || !CBS_get_u8(&server_name_list, &name_type)
1991 /* Although the server_name extension was intended to be extensible to
1992 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1993 * different name types will cause an error. Further, RFC 4366 originally
1994 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1995 * adding new name types is no longer feasible.
1996 *
1997 * Act as if the extensibility does not exist to simplify parsing. */
1998 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1999 || CBS_len(&server_name_list) != 0
2000 || CBS_len(&extension) != 0
2001 || name_type != TLSEXT_NAMETYPE_host_name
2002 || CBS_len(&host_name) == 0
2003 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
2004 || CBS_contains_zero_byte(&host_name)) {
2005 goto abort;
2006 }
2007 } else {
2008 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002009 if (!s->strict_sni) {
2010 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002011 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002012 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002013 goto abort;
2014 }
2015
2016 /* extract/check clientHello informations */
2017 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
2018 CBS_init(&extension, extension_data, extension_len);
2019
2020 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
2021 || CBS_len(&sig_algs) == 0
2022 || CBS_len(&extension) != 0) {
2023 goto abort;
2024 }
2025 if (CBS_len(&sig_algs) % 2 != 0) {
2026 goto abort;
2027 }
2028 while (CBS_len(&sig_algs) != 0) {
2029 if (!CBS_get_u8(&sig_algs, &hash)
2030 || !CBS_get_u8(&sig_algs, &sign)) {
2031 goto abort;
2032 }
2033 switch (sign) {
2034 case TLSEXT_signature_rsa:
2035 has_rsa = 1;
2036 break;
2037 case TLSEXT_signature_ecdsa:
2038 has_ecdsa_sig = 1;
2039 break;
2040 default:
2041 continue;
2042 }
2043 if (has_ecdsa_sig && has_rsa)
2044 break;
2045 }
2046 } else {
2047 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
2048 has_rsa = 1;
2049 }
2050 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
2051 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
2052
2053 while (CBS_len(&cipher_suites) != 0) {
2054 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
2055 goto abort;
2056 }
2057 cipher = SSL_get_cipher_by_value(cipher_suite);
2058 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
2059 has_ecdsa = 1;
2060 break;
2061 }
2062 }
2063 }
2064
2065 servername = CBS_data(&host_name);
2066 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
2067 trash.str[i] = tolower(servername[i]);
2068 if (!wildp && (trash.str[i] == '.'))
2069 wildp = &trash.str[i];
2070 }
2071 trash.str[i] = 0;
2072
2073 /* lookup in full qualified names */
2074 node = ebst_lookup(&s->sni_ctx, trash.str);
2075
2076 /* lookup a not neg filter */
2077 for (n = node; n; n = ebmb_next_dup(n)) {
2078 if (!container_of(n, struct sni_ctx, name)->neg) {
2079 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2080 case TLSEXT_signature_ecdsa:
2081 if (has_ecdsa) {
2082 node_ecdsa = n;
2083 goto find_one;
2084 }
2085 break;
2086 case TLSEXT_signature_rsa:
2087 if (has_rsa && !node_rsa) {
2088 node_rsa = n;
2089 if (!has_ecdsa)
2090 goto find_one;
2091 }
2092 break;
2093 default: /* TLSEXT_signature_anonymous */
2094 if (!node_anonymous)
2095 node_anonymous = n;
2096 break;
2097 }
2098 }
2099 }
2100 if (wildp) {
2101 /* lookup in wildcards names */
2102 node = ebst_lookup(&s->sni_w_ctx, wildp);
2103 for (n = node; n; n = ebmb_next_dup(n)) {
2104 if (!container_of(n, struct sni_ctx, name)->neg) {
2105 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2106 case TLSEXT_signature_ecdsa:
2107 if (has_ecdsa) {
2108 node_ecdsa = n;
2109 goto find_one;
2110 }
2111 break;
2112 case TLSEXT_signature_rsa:
2113 if (has_rsa && !node_rsa) {
2114 node_rsa = n;
2115 if (!has_ecdsa)
2116 goto find_one;
2117 }
2118 break;
2119 default: /* TLSEXT_signature_anonymous */
2120 if (!node_anonymous)
2121 node_anonymous = n;
2122 break;
2123 }
2124 }
2125 }
2126 }
2127 find_one:
2128 /* select by key_signature priority order */
2129 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
2130
2131 if (node) {
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02002132 int min, max;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002133 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002134 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02002135 min = container_of(node, struct sni_ctx, name)->conf->ssl_methods.min;
2136 if (min != s->ssl_methods.min)
2137 methodVersions[min].ssl_set_version(ctx->ssl, SET_MIN);
2138 max = container_of(node, struct sni_ctx, name)->conf->ssl_methods.max;
2139 if (max != s->ssl_methods.max)
2140 methodVersions[max].ssl_set_version(ctx->ssl, SET_MAX);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002141 return 1;
2142 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002143 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002144 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002145 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002146 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002147 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002148 abort:
2149 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
2150 conn->err_code = CO_ER_SSL_HANDSHAKE;
2151 return -1;
2152}
2153
2154#else /* OPENSSL_IS_BORINGSSL */
2155
Emeric Brunfc0421f2012-09-07 17:30:07 +02002156/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
2157 * warning when no match is found, which implies the default (first) cert
2158 * will keep being used.
2159 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002160static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002161{
2162 const char *servername;
2163 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002164 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002165 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002166 int i;
2167 (void)al; /* shut gcc stupid warning */
2168
2169 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002170 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002171#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02002172 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002173 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002174 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02002175 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02002176
Willy Tarreauf6721452015-07-07 18:04:38 +02002177 conn_get_to_addr(conn);
2178 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002179 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
2180 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02002181 if (ctx) {
2182 /* switch ctx */
2183 SSL_set_SSL_CTX(ssl, ctx);
2184 return SSL_TLSEXT_ERR_OK;
2185 }
Christopher Faulet30548802015-06-11 13:39:32 +02002186 }
2187 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002188#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002189 if (s->strict_sni)
2190 return SSL_TLSEXT_ERR_ALERT_FATAL;
2191 ssl_sock_switchctx_set(ssl, s->default_ctx);
2192 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002193 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002194
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002195 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002196 if (!servername[i])
2197 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002198 trash.str[i] = tolower(servername[i]);
2199 if (!wildp && (trash.str[i] == '.'))
2200 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002201 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002202 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002203
2204 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002205 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002206
2207 /* lookup a not neg filter */
2208 for (n = node; n; n = ebmb_next_dup(n)) {
2209 if (!container_of(n, struct sni_ctx, name)->neg) {
2210 node = n;
2211 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002212 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002213 }
2214 if (!node && wildp) {
2215 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002216 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002217 }
2218 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002219#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02002220 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002221 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02002222 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02002223 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02002224 return SSL_TLSEXT_ERR_OK;
2225 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002226#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002227 if (s->strict_sni)
2228 return SSL_TLSEXT_ERR_ALERT_FATAL;
2229 ssl_sock_switchctx_set(ssl, s->default_ctx);
2230 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002231 }
2232
2233 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002234 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002235 return SSL_TLSEXT_ERR_OK;
2236}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002237#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002238#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2239
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002240#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002241
2242static DH * ssl_get_dh_1024(void)
2243{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002244 static unsigned char dh1024_p[]={
2245 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
2246 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
2247 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
2248 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
2249 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
2250 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
2251 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
2252 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
2253 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
2254 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
2255 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
2256 };
2257 static unsigned char dh1024_g[]={
2258 0x02,
2259 };
2260
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002261 BIGNUM *p;
2262 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002263 DH *dh = DH_new();
2264 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002265 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
2266 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002267
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002268 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002269 DH_free(dh);
2270 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002271 } else {
2272 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002273 }
2274 }
2275 return dh;
2276}
2277
2278static DH *ssl_get_dh_2048(void)
2279{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002280 static unsigned char dh2048_p[]={
2281 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
2282 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
2283 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
2284 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
2285 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
2286 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
2287 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
2288 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
2289 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
2290 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
2291 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
2292 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
2293 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
2294 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
2295 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
2296 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
2297 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
2298 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
2299 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
2300 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
2301 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
2302 0xB7,0x1F,0x77,0xF3,
2303 };
2304 static unsigned char dh2048_g[]={
2305 0x02,
2306 };
2307
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002308 BIGNUM *p;
2309 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002310 DH *dh = DH_new();
2311 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002312 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
2313 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002314
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002315 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002316 DH_free(dh);
2317 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002318 } else {
2319 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002320 }
2321 }
2322 return dh;
2323}
2324
2325static DH *ssl_get_dh_4096(void)
2326{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002327 static unsigned char dh4096_p[]={
2328 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
2329 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
2330 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
2331 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
2332 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
2333 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
2334 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
2335 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
2336 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
2337 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
2338 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
2339 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
2340 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
2341 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
2342 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
2343 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
2344 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
2345 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
2346 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
2347 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
2348 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
2349 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
2350 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
2351 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
2352 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
2353 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
2354 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
2355 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
2356 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
2357 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
2358 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
2359 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
2360 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
2361 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
2362 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
2363 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
2364 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
2365 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
2366 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
2367 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
2368 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
2369 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
2370 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002371 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02002372 static unsigned char dh4096_g[]={
2373 0x02,
2374 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002375
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002376 BIGNUM *p;
2377 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002378 DH *dh = DH_new();
2379 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002380 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
2381 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002382
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002383 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002384 DH_free(dh);
2385 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002386 } else {
2387 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002388 }
2389 }
2390 return dh;
2391}
2392
2393/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01002394 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002395static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
2396{
2397 DH *dh = NULL;
2398 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002399 int type;
2400
2401 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002402
2403 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2404 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2405 */
2406 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2407 keylen = EVP_PKEY_bits(pkey);
2408 }
2409
Willy Tarreauef934602016-12-22 23:12:01 +01002410 if (keylen > global_ssl.default_dh_param) {
2411 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002412 }
2413
Remi Gacogned3a341a2015-05-29 16:26:17 +02002414 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002415 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002416 }
2417 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002418 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002419 }
2420 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002421 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002422 }
2423
2424 return dh;
2425}
2426
Remi Gacogne47783ef2015-05-29 15:53:22 +02002427static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002428{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002429 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002430 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002431
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002432 if (in == NULL)
2433 goto end;
2434
Remi Gacogne47783ef2015-05-29 15:53:22 +02002435 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002436 goto end;
2437
Remi Gacogne47783ef2015-05-29 15:53:22 +02002438 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2439
2440end:
2441 if (in)
2442 BIO_free(in);
2443
2444 return dh;
2445}
2446
2447int ssl_sock_load_global_dh_param_from_file(const char *filename)
2448{
2449 global_dh = ssl_sock_get_dh_from_file(filename);
2450
2451 if (global_dh) {
2452 return 0;
2453 }
2454
2455 return -1;
2456}
2457
2458/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2459 if an error occured, and 0 if parameter not found. */
2460int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2461{
2462 int ret = -1;
2463 DH *dh = ssl_sock_get_dh_from_file(file);
2464
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002465 if (dh) {
2466 ret = 1;
2467 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002468
2469 if (ssl_dh_ptr_index >= 0) {
2470 /* store a pointer to the DH params to avoid complaining about
2471 ssl-default-dh-param not being set for this SSL_CTX */
2472 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2473 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002474 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002475 else if (global_dh) {
2476 SSL_CTX_set_tmp_dh(ctx, global_dh);
2477 ret = 0; /* DH params not found */
2478 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002479 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002480 /* Clear openssl global errors stack */
2481 ERR_clear_error();
2482
Willy Tarreauef934602016-12-22 23:12:01 +01002483 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002484 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002485 if (local_dh_1024 == NULL)
2486 local_dh_1024 = ssl_get_dh_1024();
2487
Remi Gacogne8de54152014-07-15 11:36:40 +02002488 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002489 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002490
Remi Gacogne8de54152014-07-15 11:36:40 +02002491 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002492 }
2493 else {
2494 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2495 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002496
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002497 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002498 }
Emeric Brun644cde02012-12-14 11:21:13 +01002499
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002500end:
2501 if (dh)
2502 DH_free(dh);
2503
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002504 return ret;
2505}
2506#endif
2507
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002508static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2509 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002510{
2511 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002512 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002513 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002514
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002515 if (*name == '!') {
2516 neg = 1;
2517 name++;
2518 }
2519 if (*name == '*') {
2520 wild = 1;
2521 name++;
2522 }
2523 /* !* filter is a nop */
2524 if (neg && wild)
2525 return order;
2526 if (*name) {
2527 int j, len;
2528 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002529 for (j = 0; j < len && j < trash.size; j++)
2530 trash.str[j] = tolower(name[j]);
2531 if (j >= trash.size)
2532 return order;
2533 trash.str[j] = 0;
2534
2535 /* Check for duplicates. */
2536 if (wild)
2537 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2538 else
2539 node = ebst_lookup(&s->sni_ctx, trash.str);
2540 for (; node; node = ebmb_next_dup(node)) {
2541 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002542 if (sc->ctx == ctx && sc->conf == conf &&
2543 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002544 return order;
2545 }
2546
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002547 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002548 if (!sc)
2549 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002550 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002551 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002552 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002553 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002554 sc->order = order++;
2555 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002556 if (wild)
2557 ebst_insert(&s->sni_w_ctx, &sc->name);
2558 else
2559 ebst_insert(&s->sni_ctx, &sc->name);
2560 }
2561 return order;
2562}
2563
yanbzhu488a4d22015-12-01 15:16:07 -05002564
2565/* The following code is used for loading multiple crt files into
2566 * SSL_CTX's based on CN/SAN
2567 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002568#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002569/* This is used to preload the certifcate, private key
2570 * and Cert Chain of a file passed in via the crt
2571 * argument
2572 *
2573 * This way, we do not have to read the file multiple times
2574 */
2575struct cert_key_and_chain {
2576 X509 *cert;
2577 EVP_PKEY *key;
2578 unsigned int num_chain_certs;
2579 /* This is an array of X509 pointers */
2580 X509 **chain_certs;
2581};
2582
yanbzhu08ce6ab2015-12-02 13:01:29 -05002583#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2584
2585struct key_combo_ctx {
2586 SSL_CTX *ctx;
2587 int order;
2588};
2589
2590/* Map used for processing multiple keypairs for a single purpose
2591 *
2592 * This maps CN/SNI name to certificate type
2593 */
2594struct sni_keytype {
2595 int keytypes; /* BITMASK for keytypes */
2596 struct ebmb_node name; /* node holding the servername value */
2597};
2598
2599
yanbzhu488a4d22015-12-01 15:16:07 -05002600/* Frees the contents of a cert_key_and_chain
2601 */
2602static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2603{
2604 int i;
2605
2606 if (!ckch)
2607 return;
2608
2609 /* Free the certificate and set pointer to NULL */
2610 if (ckch->cert)
2611 X509_free(ckch->cert);
2612 ckch->cert = NULL;
2613
2614 /* Free the key and set pointer to NULL */
2615 if (ckch->key)
2616 EVP_PKEY_free(ckch->key);
2617 ckch->key = NULL;
2618
2619 /* Free each certificate in the chain */
2620 for (i = 0; i < ckch->num_chain_certs; i++) {
2621 if (ckch->chain_certs[i])
2622 X509_free(ckch->chain_certs[i]);
2623 }
2624
2625 /* Free the chain obj itself and set to NULL */
2626 if (ckch->num_chain_certs > 0) {
2627 free(ckch->chain_certs);
2628 ckch->num_chain_certs = 0;
2629 ckch->chain_certs = NULL;
2630 }
2631
2632}
2633
2634/* checks if a key and cert exists in the ckch
2635 */
2636static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2637{
2638 return (ckch->cert != NULL && ckch->key != NULL);
2639}
2640
2641
2642/* Loads the contents of a crt file (path) into a cert_key_and_chain
2643 * This allows us to carry the contents of the file without having to
2644 * read the file multiple times.
2645 *
2646 * returns:
2647 * 0 on Success
2648 * 1 on SSL Failure
2649 * 2 on file not found
2650 */
2651static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2652{
2653
2654 BIO *in;
2655 X509 *ca = NULL;
2656 int ret = 1;
2657
2658 ssl_sock_free_cert_key_and_chain_contents(ckch);
2659
2660 in = BIO_new(BIO_s_file());
2661 if (in == NULL)
2662 goto end;
2663
2664 if (BIO_read_filename(in, path) <= 0)
2665 goto end;
2666
yanbzhu488a4d22015-12-01 15:16:07 -05002667 /* Read Private Key */
2668 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2669 if (ckch->key == NULL) {
2670 memprintf(err, "%sunable to load private key from file '%s'.\n",
2671 err && *err ? *err : "", path);
2672 goto end;
2673 }
2674
Willy Tarreaubb137a82016-04-06 19:02:38 +02002675 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002676 if (BIO_reset(in) == -1) {
2677 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2678 err && *err ? *err : "", path);
2679 goto end;
2680 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002681
2682 /* Read Certificate */
2683 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2684 if (ckch->cert == NULL) {
2685 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2686 err && *err ? *err : "", path);
2687 goto end;
2688 }
2689
yanbzhu488a4d22015-12-01 15:16:07 -05002690 /* Read Certificate Chain */
2691 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2692 /* Grow the chain certs */
2693 ckch->num_chain_certs++;
2694 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2695
2696 /* use - 1 here since we just incremented it above */
2697 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2698 }
2699 ret = ERR_get_error();
2700 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2701 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2702 err && *err ? *err : "", path);
2703 ret = 1;
2704 goto end;
2705 }
2706
2707 ret = 0;
2708
2709end:
2710
2711 ERR_clear_error();
2712 if (in)
2713 BIO_free(in);
2714
2715 /* Something went wrong in one of the reads */
2716 if (ret != 0)
2717 ssl_sock_free_cert_key_and_chain_contents(ckch);
2718
2719 return ret;
2720}
2721
2722/* Loads the info in ckch into ctx
2723 * Currently, this does not process any information about ocsp, dhparams or
2724 * sctl
2725 * Returns
2726 * 0 on success
2727 * 1 on failure
2728 */
2729static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2730{
2731 int i = 0;
2732
2733 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2734 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2735 err && *err ? *err : "", path);
2736 return 1;
2737 }
2738
2739 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2740 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2741 err && *err ? *err : "", path);
2742 return 1;
2743 }
2744
yanbzhu488a4d22015-12-01 15:16:07 -05002745 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2746 for (i = 0; i < ckch->num_chain_certs; i++) {
2747 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002748 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2749 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002750 return 1;
2751 }
2752 }
2753
2754 if (SSL_CTX_check_private_key(ctx) <= 0) {
2755 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2756 err && *err ? *err : "", path);
2757 return 1;
2758 }
2759
2760 return 0;
2761}
2762
yanbzhu08ce6ab2015-12-02 13:01:29 -05002763
2764static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2765{
2766 struct sni_keytype *s_kt = NULL;
2767 struct ebmb_node *node;
2768 int i;
2769
2770 for (i = 0; i < trash.size; i++) {
2771 if (!str[i])
2772 break;
2773 trash.str[i] = tolower(str[i]);
2774 }
2775 trash.str[i] = 0;
2776 node = ebst_lookup(sni_keytypes, trash.str);
2777 if (!node) {
2778 /* CN not found in tree */
2779 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2780 /* Using memcpy here instead of strncpy.
2781 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2782 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2783 */
2784 memcpy(s_kt->name.key, trash.str, i+1);
2785 s_kt->keytypes = 0;
2786 ebst_insert(sni_keytypes, &s_kt->name);
2787 } else {
2788 /* CN found in tree */
2789 s_kt = container_of(node, struct sni_keytype, name);
2790 }
2791
2792 /* Mark that this CN has the keytype of key_index via keytypes mask */
2793 s_kt->keytypes |= 1<<key_index;
2794
2795}
2796
2797
2798/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2799 * If any are found, group these files into a set of SSL_CTX*
2800 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2801 *
2802 * This will allow the user to explictly group multiple cert/keys for a single purpose
2803 *
2804 * Returns
2805 * 0 on success
2806 * 1 on failure
2807 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002808static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2809 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002810{
2811 char fp[MAXPATHLEN+1] = {0};
2812 int n = 0;
2813 int i = 0;
2814 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2815 struct eb_root sni_keytypes_map = { {0} };
2816 struct ebmb_node *node;
2817 struct ebmb_node *next;
2818 /* Array of SSL_CTX pointers corresponding to each possible combo
2819 * of keytypes
2820 */
2821 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2822 int rv = 0;
2823 X509_NAME *xname = NULL;
2824 char *str = NULL;
2825#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2826 STACK_OF(GENERAL_NAME) *names = NULL;
2827#endif
2828
2829 /* Load all possible certs and keys */
2830 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2831 struct stat buf;
2832
2833 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2834 if (stat(fp, &buf) == 0) {
2835 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2836 rv = 1;
2837 goto end;
2838 }
2839 }
2840 }
2841
2842 /* Process each ckch and update keytypes for each CN/SAN
2843 * for example, if CN/SAN www.a.com is associated with
2844 * certs with keytype 0 and 2, then at the end of the loop,
2845 * www.a.com will have:
2846 * keyindex = 0 | 1 | 4 = 5
2847 */
2848 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2849
2850 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2851 continue;
2852
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002853 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002854 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002855 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2856 } else {
2857 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2858 * so the line that contains logic is marked via comments
2859 */
2860 xname = X509_get_subject_name(certs_and_keys[n].cert);
2861 i = -1;
2862 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2863 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002864 ASN1_STRING *value;
2865 value = X509_NAME_ENTRY_get_data(entry);
2866 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002867 /* Important line is here */
2868 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002869
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002870 OPENSSL_free(str);
2871 str = NULL;
2872 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002873 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002874
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002875 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002876#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002877 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2878 if (names) {
2879 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2880 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002881
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002882 if (name->type == GEN_DNS) {
2883 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2884 /* Important line is here */
2885 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002886
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002887 OPENSSL_free(str);
2888 str = NULL;
2889 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002890 }
2891 }
2892 }
2893 }
2894#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2895 }
2896
2897 /* If no files found, return error */
2898 if (eb_is_empty(&sni_keytypes_map)) {
2899 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2900 err && *err ? *err : "", path);
2901 rv = 1;
2902 goto end;
2903 }
2904
2905 /* We now have a map of CN/SAN to keytypes that are loaded in
2906 * Iterate through the map to create the SSL_CTX's (if needed)
2907 * and add each CTX to the SNI tree
2908 *
2909 * Some math here:
2910 * There are 2^n - 1 possibile combinations, each unique
2911 * combination is denoted by the key in the map. Each key
2912 * has a value between 1 and 2^n - 1. Conveniently, the array
2913 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2914 * entry in the array to correspond to the unique combo (key)
2915 * associated with i. This unique key combo (i) will be associated
2916 * with combos[i-1]
2917 */
2918
2919 node = ebmb_first(&sni_keytypes_map);
2920 while (node) {
2921 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002922 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002923
2924 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2925 i = container_of(node, struct sni_keytype, name)->keytypes;
2926 cur_ctx = key_combos[i-1].ctx;
2927
2928 if (cur_ctx == NULL) {
2929 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002930 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002931 if (cur_ctx == NULL) {
2932 memprintf(err, "%sunable to allocate SSL context.\n",
2933 err && *err ? *err : "");
2934 rv = 1;
2935 goto end;
2936 }
2937
yanbzhube2774d2015-12-10 15:07:30 -05002938 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002939 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2940 if (i & (1<<n)) {
2941 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002942 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2943 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002944 SSL_CTX_free(cur_ctx);
2945 rv = 1;
2946 goto end;
2947 }
yanbzhube2774d2015-12-10 15:07:30 -05002948
2949#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2950 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002951 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002952 if (err)
2953 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 +00002954 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002955 SSL_CTX_free(cur_ctx);
2956 rv = 1;
2957 goto end;
2958 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02002959#elif (defined OPENSSL_IS_BORINGSSL)
2960 ssl_sock_set_ocsp_response_from_file(cur_ctx, cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002961#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002962 }
2963 }
2964
2965 /* Load DH params into the ctx to support DHE keys */
2966#ifndef OPENSSL_NO_DH
2967 if (ssl_dh_ptr_index >= 0)
2968 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2969
2970 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2971 if (rv < 0) {
2972 if (err)
2973 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2974 *err ? *err : "", path);
2975 rv = 1;
2976 goto end;
2977 }
2978#endif
2979
2980 /* Update key_combos */
2981 key_combos[i-1].ctx = cur_ctx;
2982 }
2983
2984 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002985 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2986 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002987 node = ebmb_next(node);
2988 }
2989
2990
2991 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2992 if (!bind_conf->default_ctx) {
2993 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2994 if (key_combos[i].ctx) {
2995 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002996 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002997 break;
2998 }
2999 }
3000 }
3001
3002end:
3003
3004 if (names)
3005 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
3006
3007 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
3008 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
3009
3010 node = ebmb_first(&sni_keytypes_map);
3011 while (node) {
3012 next = ebmb_next(node);
3013 ebmb_delete(node);
3014 node = next;
3015 }
3016
3017 return rv;
3018}
3019#else
3020/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003021static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3022 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05003023{
3024 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3025 err && *err ? *err : "", path, strerror(errno));
3026 return 1;
3027}
3028
yanbzhu488a4d22015-12-01 15:16:07 -05003029#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
3030
Emeric Brunfc0421f2012-09-07 17:30:07 +02003031/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
3032 * an early error happens and the caller must call SSL_CTX_free() by itelf.
3033 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003034static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
3035 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003036{
3037 BIO *in;
3038 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003039 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003040 int ret = -1;
3041 int order = 0;
3042 X509_NAME *xname;
3043 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003044 pem_password_cb *passwd_cb;
3045 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003046 EVP_PKEY *pkey;
3047 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003048
Emeric Brunfc0421f2012-09-07 17:30:07 +02003049#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3050 STACK_OF(GENERAL_NAME) *names;
3051#endif
3052
3053 in = BIO_new(BIO_s_file());
3054 if (in == NULL)
3055 goto end;
3056
3057 if (BIO_read_filename(in, file) <= 0)
3058 goto end;
3059
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003060
3061 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
3062 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
3063
3064 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003065 if (x == NULL)
3066 goto end;
3067
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003068 pkey = X509_get_pubkey(x);
3069 if (pkey) {
3070 switch(EVP_PKEY_base_id(pkey)) {
3071 case EVP_PKEY_RSA:
3072 key_sig = TLSEXT_signature_rsa;
3073 break;
3074 case EVP_PKEY_EC:
3075 key_sig = TLSEXT_signature_ecdsa;
3076 break;
3077 }
3078 EVP_PKEY_free(pkey);
3079 }
3080
Emeric Brun50bcecc2013-04-22 13:05:23 +02003081 if (fcount) {
3082 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003083 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003084 }
3085 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003086#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003087 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
3088 if (names) {
3089 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
3090 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
3091 if (name->type == GEN_DNS) {
3092 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003093 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003094 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003095 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003096 }
3097 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003098 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003099 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003100#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003101 xname = X509_get_subject_name(x);
3102 i = -1;
3103 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
3104 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003105 ASN1_STRING *value;
3106
3107 value = X509_NAME_ENTRY_get_data(entry);
3108 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003109 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003110 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003111 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003112 }
3113 }
3114
3115 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
3116 if (!SSL_CTX_use_certificate(ctx, x))
3117 goto end;
3118
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003119#ifdef SSL_CTX_clear_extra_chain_certs
3120 SSL_CTX_clear_extra_chain_certs(ctx);
3121#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02003122 if (ctx->extra_certs != NULL) {
3123 sk_X509_pop_free(ctx->extra_certs, X509_free);
3124 ctx->extra_certs = NULL;
3125 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003126#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003127
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003128 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003129 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
3130 X509_free(ca);
3131 goto end;
3132 }
3133 }
3134
3135 err = ERR_get_error();
3136 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
3137 /* we successfully reached the last cert in the file */
3138 ret = 1;
3139 }
3140 ERR_clear_error();
3141
3142end:
3143 if (x)
3144 X509_free(x);
3145
3146 if (in)
3147 BIO_free(in);
3148
3149 return ret;
3150}
3151
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003152static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3153 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003154{
3155 int ret;
3156 SSL_CTX *ctx;
3157
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003158 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02003159 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003160 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
3161 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003162 return 1;
3163 }
3164
3165 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003166 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
3167 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003168 SSL_CTX_free(ctx);
3169 return 1;
3170 }
3171
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003172 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003173 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003174 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
3175 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003176 if (ret < 0) /* serious error, must do that ourselves */
3177 SSL_CTX_free(ctx);
3178 return 1;
3179 }
Emeric Brun61694ab2012-10-26 13:35:33 +02003180
3181 if (SSL_CTX_check_private_key(ctx) <= 0) {
3182 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3183 err && *err ? *err : "", path);
3184 return 1;
3185 }
3186
Emeric Brunfc0421f2012-09-07 17:30:07 +02003187 /* we must not free the SSL_CTX anymore below, since it's already in
3188 * the tree, so it will be discovered and cleaned in time.
3189 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003190#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02003191 /* store a NULL pointer to indicate we have not yet loaded
3192 a custom DH param file */
3193 if (ssl_dh_ptr_index >= 0) {
3194 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
3195 }
3196
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003197 ret = ssl_sock_load_dh_params(ctx, path);
3198 if (ret < 0) {
3199 if (err)
3200 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
3201 *err ? *err : "", path);
3202 return 1;
3203 }
3204#endif
3205
Lukas Tribuse4e30f72014-12-09 16:32:51 +01003206#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02003207 ret = ssl_sock_load_ocsp(ctx, path);
3208 if (ret < 0) {
3209 if (err)
3210 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",
3211 *err ? *err : "", path);
3212 return 1;
3213 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02003214#elif (defined OPENSSL_IS_BORINGSSL)
3215 ssl_sock_set_ocsp_response_from_file(ctx, path);
Emeric Brun4147b2e2014-06-16 18:36:30 +02003216#endif
3217
Daniel Jakots54ffb912015-11-06 20:02:41 +01003218#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01003219 if (sctl_ex_index >= 0) {
3220 ret = ssl_sock_load_sctl(ctx, path);
3221 if (ret < 0) {
3222 if (err)
3223 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
3224 *err ? *err : "", path);
3225 return 1;
3226 }
3227 }
3228#endif
3229
Emeric Brunfc0421f2012-09-07 17:30:07 +02003230#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003231 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003232 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
3233 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02003234 return 1;
3235 }
3236#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003237 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003238 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003239 bind_conf->default_ssl_conf = ssl_conf;
3240 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003241
3242 return 0;
3243}
3244
Willy Tarreau03209342016-12-22 17:08:28 +01003245int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003246{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003247 struct dirent **de_list;
3248 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003249 DIR *dir;
3250 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01003251 char *end;
3252 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02003253 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05003254#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3255 int is_bundle;
3256 int j;
3257#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003258
yanbzhu08ce6ab2015-12-02 13:01:29 -05003259 if (stat(path, &buf) == 0) {
3260 dir = opendir(path);
3261 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003262 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003263
yanbzhu08ce6ab2015-12-02 13:01:29 -05003264 /* strip trailing slashes, including first one */
3265 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
3266 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003267
yanbzhu08ce6ab2015-12-02 13:01:29 -05003268 n = scandir(path, &de_list, 0, alphasort);
3269 if (n < 0) {
3270 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
3271 err && *err ? *err : "", path, strerror(errno));
3272 cfgerr++;
3273 }
3274 else {
3275 for (i = 0; i < n; i++) {
3276 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02003277
yanbzhu08ce6ab2015-12-02 13:01:29 -05003278 end = strrchr(de->d_name, '.');
3279 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
3280 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003281
yanbzhu08ce6ab2015-12-02 13:01:29 -05003282 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
3283 if (stat(fp, &buf) != 0) {
3284 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3285 err && *err ? *err : "", fp, strerror(errno));
3286 cfgerr++;
3287 goto ignore_entry;
3288 }
3289 if (!S_ISREG(buf.st_mode))
3290 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05003291
3292#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3293 is_bundle = 0;
3294 /* Check if current entry in directory is part of a multi-cert bundle */
3295
3296 if (end) {
3297 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
3298 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
3299 is_bundle = 1;
3300 break;
3301 }
3302 }
3303
3304 if (is_bundle) {
3305 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
3306 int dp_len;
3307
3308 dp_len = end - de->d_name;
3309 snprintf(dp, dp_len + 1, "%s", de->d_name);
3310
3311 /* increment i and free de until we get to a non-bundle cert
3312 * Note here that we look at de_list[i + 1] before freeing de
3313 * this is important since ignore_entry will free de
3314 */
3315 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
3316 free(de);
3317 i++;
3318 de = de_list[i];
3319 }
3320
3321 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003322 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05003323
3324 /* Successfully processed the bundle */
3325 goto ignore_entry;
3326 }
3327 }
3328
3329#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003330 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003331ignore_entry:
3332 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003333 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003334 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003335 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003336 closedir(dir);
3337 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003338 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003339
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003340 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003341
Emeric Brunfc0421f2012-09-07 17:30:07 +02003342 return cfgerr;
3343}
3344
Thierry Fournier383085f2013-01-24 14:15:43 +01003345/* Make sure openssl opens /dev/urandom before the chroot. The work is only
3346 * done once. Zero is returned if the operation fails. No error is returned
3347 * if the random is said as not implemented, because we expect that openssl
3348 * will use another method once needed.
3349 */
3350static int ssl_initialize_random()
3351{
3352 unsigned char random;
3353 static int random_initialized = 0;
3354
3355 if (!random_initialized && RAND_bytes(&random, 1) != 0)
3356 random_initialized = 1;
3357
3358 return random_initialized;
3359}
3360
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003361/* release ssl bind conf */
3362void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003363{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003364 if (conf) {
3365#ifdef OPENSSL_NPN_NEGOTIATED
3366 free(conf->npn_str);
3367 conf->npn_str = NULL;
3368#endif
3369#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
3370 free(conf->alpn_str);
3371 conf->alpn_str = NULL;
3372#endif
3373 free(conf->ca_file);
3374 conf->ca_file = NULL;
3375 free(conf->crl_file);
3376 conf->crl_file = NULL;
3377 free(conf->ciphers);
3378 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003379 free(conf->curves);
3380 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003381 free(conf->ecdhe);
3382 conf->ecdhe = NULL;
3383 }
3384}
3385
3386int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
3387{
3388 char thisline[CRT_LINESIZE];
3389 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003390 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05003391 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003392 int linenum = 0;
3393 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003394
Willy Tarreauad1731d2013-04-02 17:35:58 +02003395 if ((f = fopen(file, "r")) == NULL) {
3396 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003397 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003398 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003399
3400 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003401 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003402 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003403 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003404 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003405 char *crt_path;
3406 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003407
3408 linenum++;
3409 end = line + strlen(line);
3410 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3411 /* Check if we reached the limit and the last char is not \n.
3412 * Watch out for the last line without the terminating '\n'!
3413 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003414 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3415 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003416 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003417 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003418 }
3419
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003420 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003421 newarg = 1;
3422 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003423 if (*line == '#' || *line == '\n' || *line == '\r') {
3424 /* end of string, end of loop */
3425 *line = 0;
3426 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003427 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003428 newarg = 1;
3429 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003430 } else if (*line == '[') {
3431 if (ssl_b) {
3432 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3433 cfgerr = 1;
3434 break;
3435 }
3436 if (!arg) {
3437 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3438 cfgerr = 1;
3439 break;
3440 }
3441 ssl_b = arg;
3442 newarg = 1;
3443 *line = 0;
3444 } else if (*line == ']') {
3445 if (ssl_e) {
3446 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003447 cfgerr = 1;
3448 break;
3449 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003450 if (!ssl_b) {
3451 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3452 cfgerr = 1;
3453 break;
3454 }
3455 ssl_e = arg;
3456 newarg = 1;
3457 *line = 0;
3458 } else if (newarg) {
3459 if (arg == MAX_CRT_ARGS) {
3460 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3461 cfgerr = 1;
3462 break;
3463 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003464 newarg = 0;
3465 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003466 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003467 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003468 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003469 if (cfgerr)
3470 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003471 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003472
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003473 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003474 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003475 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003476
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003477 crt_path = args[0];
3478 if (*crt_path != '/' && global_ssl.crt_base) {
3479 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3480 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3481 crt_path, linenum, file);
3482 cfgerr = 1;
3483 break;
3484 }
3485 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3486 crt_path = path;
3487 }
3488
3489 ssl_conf = calloc(1, sizeof *ssl_conf);
3490 cur_arg = ssl_b ? ssl_b : 1;
3491 while (cur_arg < ssl_e) {
3492 newarg = 0;
3493 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3494 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3495 newarg = 1;
3496 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3497 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3498 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3499 args[cur_arg], linenum, file);
3500 cfgerr = 1;
3501 }
3502 cur_arg += 1 + ssl_bind_kws[i].skip;
3503 break;
3504 }
3505 }
3506 if (!cfgerr && !newarg) {
3507 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3508 args[cur_arg], linenum, file);
3509 cfgerr = 1;
3510 break;
3511 }
3512 }
3513 if (cfgerr) {
3514 ssl_sock_free_ssl_conf(ssl_conf);
3515 free(ssl_conf);
3516 ssl_conf = NULL;
3517 break;
3518 }
3519
3520 if (stat(crt_path, &buf) == 0) {
3521 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3522 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003523 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003524 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3525 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003526 }
3527
Willy Tarreauad1731d2013-04-02 17:35:58 +02003528 if (cfgerr) {
3529 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003530 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003531 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003532 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003533 fclose(f);
3534 return cfgerr;
3535}
3536
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003537/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003538static int
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003539ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003540{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003541 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003542 long options =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003543 SSL_OP_ALL | /* all known workarounds for bugs */
3544 SSL_OP_NO_SSLv2 |
3545 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003546 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003547 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003548 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3549 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003550 long mode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003551 SSL_MODE_ENABLE_PARTIAL_WRITE |
3552 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003553 SSL_MODE_RELEASE_BUFFERS |
3554 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003555 struct tls_version_filter *conf_ssl_methods = &bind_conf->ssl_methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003556 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003557 int flags = MC_SSL_O_ALL;
3558 int cfgerr = 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003559
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003560 ctx = SSL_CTX_new(SSLv23_server_method());
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003561 bind_conf->initial_ctx = ctx;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003562
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003563 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
3564 Warning("Proxy '%s': no-sslv3/no-tlsv1x are ignored for bind '%s' at [%s:%d]. "
3565 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
3566 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3567 else
3568 flags = conf_ssl_methods->flags;
3569
Emmanuel Hocdetbd695fe2017-05-15 15:53:41 +02003570 min = conf_ssl_methods->min;
3571 max = conf_ssl_methods->max;
3572 /* start with TLSv10 to remove SSLv3 per default */
3573 if (!min && (!max || max >= CONF_TLSV10))
3574 min = CONF_TLSV10;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003575 /* Real min and max should be determinate with configuration and openssl's capabilities */
Emmanuel Hocdetbd695fe2017-05-15 15:53:41 +02003576 if (min)
3577 flags |= (methodVersions[min].flag - 1);
3578 if (max)
3579 flags |= ~((methodVersions[max].flag << 1) - 1);
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003580 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003581 min = max = CONF_TLSV_NONE;
3582 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003583 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003584 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003585 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003586 if (min) {
3587 if (hole) {
3588 Warning("Proxy '%s': SSL/TLS versions range not contiguous for bind '%s' at [%s:%d]. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003589 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003590 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line,
3591 methodVersions[hole].name);
3592 hole = 0;
3593 }
3594 max = i;
3595 }
3596 else {
3597 min = max = i;
3598 }
3599 }
3600 else {
3601 if (min)
3602 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003603 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003604 if (!min) {
3605 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003606 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003607 cfgerr += 1;
3608 }
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003609 /* save real min/max in bind_conf */
3610 conf_ssl_methods->min = min;
3611 conf_ssl_methods->max = max;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003612
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003613#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3614 /* Keep force-xxx implementation as it is in older haproxy. It's a
3615 precautionary measure to avoid any suprise with older openssl version. */
3616 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003617 methodVersions[min].ctx_set_version(ctx, SET_SERVER);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003618 else
3619 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3620 if (flags & methodVersions[i].flag)
3621 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003622#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003623 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003624 methodVersions[min].ctx_set_version(ctx, SET_MIN);
3625 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003626#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003627
3628 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3629 options |= SSL_OP_NO_TICKET;
3630 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
3631 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
3632 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00003633
3634#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
3635 if (global_ssl.async)
3636 mode |= SSL_MODE_ASYNC;
3637#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003638 SSL_CTX_set_mode(ctx, mode);
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003639 if (global_ssl.life_time)
3640 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003641
3642#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3643#ifdef OPENSSL_IS_BORINGSSL
3644 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3645 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3646#else
3647 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3648 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3649#endif
3650#endif
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003651 return cfgerr;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003652}
3653
3654int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3655{
3656 struct proxy *curproxy = bind_conf->frontend;
3657 int cfgerr = 0;
3658 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003659 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003660 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003661 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003662
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02003663 if (ssl_conf) {
3664 struct tls_version_filter *conf_ssl_methods = &ssl_conf->ssl_methods;
3665 int i, min, max;
3666 int flags = MC_SSL_O_ALL;
3667
3668 /* Real min and max should be determinate with configuration and openssl's capabilities */
3669 min = conf_ssl_methods->min ? conf_ssl_methods->min : bind_conf->ssl_methods.min;
3670 max = conf_ssl_methods->max ? conf_ssl_methods->max : bind_conf->ssl_methods.max;
3671 if (min)
3672 flags |= (methodVersions[min].flag - 1);
3673 if (max)
3674 flags |= ~((methodVersions[max].flag << 1) - 1);
3675 min = max = CONF_TLSV_NONE;
3676 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3677 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
3678 if (min)
3679 max = i;
3680 else
3681 min = max = i;
3682 }
3683 /* save real min/max */
3684 conf_ssl_methods->min = min;
3685 conf_ssl_methods->max = max;
3686 if (!min) {
3687 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
3688 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3689 cfgerr += 1;
3690 }
3691 }
3692
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003693 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003694 case SSL_SOCK_VERIFY_NONE:
3695 verify = SSL_VERIFY_NONE;
3696 break;
3697 case SSL_SOCK_VERIFY_OPTIONAL:
3698 verify = SSL_VERIFY_PEER;
3699 break;
3700 case SSL_SOCK_VERIFY_REQUIRED:
3701 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3702 break;
3703 }
3704 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3705 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003706 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3707 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3708 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003709 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003710 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003711 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003712 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003713 cfgerr++;
3714 }
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02003715 if (!((ssl_conf && ssl_conf->no_ca_names) || bind_conf->ssl_conf.no_ca_names)) {
3716 /* set CA names for client cert request, function returns void */
3717 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
3718 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003719 }
Emeric Brun850efd52014-01-29 12:24:34 +01003720 else {
3721 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3722 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3723 cfgerr++;
3724 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003725#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003726 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003727 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3728
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003729 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003730 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003731 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003732 cfgerr++;
3733 }
Emeric Brun561e5742012-10-02 15:20:55 +02003734 else {
3735 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3736 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003737 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003738#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003739 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003740 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003741#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003742 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003743 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3744 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3745 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3746 cfgerr++;
3747 }
3748 }
3749#endif
3750
Emeric Brunfc0421f2012-09-07 17:30:07 +02003751 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003752 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3753 if (conf_ciphers &&
3754 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003755 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 +01003756 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003757 cfgerr++;
3758 }
3759
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003760#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003761 /* If tune.ssl.default-dh-param has not been set,
3762 neither has ssl-default-dh-file and no static DH
3763 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003764 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003765 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003766 (ssl_dh_ptr_index == -1 ||
3767 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003768 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3769 const SSL_CIPHER * cipher = NULL;
3770 char cipher_description[128];
3771 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3772 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3773 which is not ephemeral DH. */
3774 const char dhe_description[] = " Kx=DH ";
3775 const char dhe_export_description[] = " Kx=DH(";
3776 int idx = 0;
3777 int dhe_found = 0;
3778 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003779
Remi Gacogne23d5d372014-10-10 17:04:26 +02003780 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003781
Remi Gacogne23d5d372014-10-10 17:04:26 +02003782 if (ssl) {
3783 ciphers = SSL_get_ciphers(ssl);
3784
3785 if (ciphers) {
3786 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3787 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3788 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3789 if (strstr(cipher_description, dhe_description) != NULL ||
3790 strstr(cipher_description, dhe_export_description) != NULL) {
3791 dhe_found = 1;
3792 break;
3793 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003794 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003795 }
3796 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003797 SSL_free(ssl);
3798 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003799 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003800
Lukas Tribus90132722014-08-18 00:56:33 +02003801 if (dhe_found) {
3802 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 +02003803 }
3804
Willy Tarreauef934602016-12-22 23:12:01 +01003805 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003806 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003807
Willy Tarreauef934602016-12-22 23:12:01 +01003808 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003809 if (local_dh_1024 == NULL) {
3810 local_dh_1024 = ssl_get_dh_1024();
3811 }
Willy Tarreauef934602016-12-22 23:12:01 +01003812 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003813 if (local_dh_2048 == NULL) {
3814 local_dh_2048 = ssl_get_dh_2048();
3815 }
Willy Tarreauef934602016-12-22 23:12:01 +01003816 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003817 if (local_dh_4096 == NULL) {
3818 local_dh_4096 = ssl_get_dh_4096();
3819 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003820 }
3821 }
3822 }
3823#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003824
Emeric Brunfc0421f2012-09-07 17:30:07 +02003825 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003826#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003827 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003828#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003829
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003830#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003831 ssl_conf_cur = NULL;
3832 if (ssl_conf && ssl_conf->npn_str)
3833 ssl_conf_cur = ssl_conf;
3834 else if (bind_conf->ssl_conf.npn_str)
3835 ssl_conf_cur = &bind_conf->ssl_conf;
3836 if (ssl_conf_cur)
3837 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003838#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003839#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003840 ssl_conf_cur = NULL;
3841 if (ssl_conf && ssl_conf->alpn_str)
3842 ssl_conf_cur = ssl_conf;
3843 else if (bind_conf->ssl_conf.alpn_str)
3844 ssl_conf_cur = &bind_conf->ssl_conf;
3845 if (ssl_conf_cur)
3846 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003847#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003848#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3849 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3850 if (conf_curves) {
3851 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3852 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3853 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3854 cfgerr++;
3855 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003856#if defined(SSL_CTX_set_ecdh_auto)
3857 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3858#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003859 }
3860#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003861#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003862 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003863 int i;
3864 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003865 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3866 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003867
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003868 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003869 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3870 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 +01003871 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003872 cfgerr++;
3873 }
3874 else {
3875 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3876 EC_KEY_free(ecdh);
3877 }
3878 }
3879#endif
3880
Emeric Brunfc0421f2012-09-07 17:30:07 +02003881 return cfgerr;
3882}
3883
Evan Broderbe554312013-06-27 00:05:25 -07003884static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3885{
3886 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3887 size_t prefixlen, suffixlen;
3888
3889 /* Trivial case */
3890 if (strcmp(pattern, hostname) == 0)
3891 return 1;
3892
Evan Broderbe554312013-06-27 00:05:25 -07003893 /* The rest of this logic is based on RFC 6125, section 6.4.3
3894 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3895
Emeric Bruna848dae2013-10-08 11:27:28 +02003896 pattern_wildcard = NULL;
3897 pattern_left_label_end = pattern;
3898 while (*pattern_left_label_end != '.') {
3899 switch (*pattern_left_label_end) {
3900 case 0:
3901 /* End of label not found */
3902 return 0;
3903 case '*':
3904 /* If there is more than one wildcards */
3905 if (pattern_wildcard)
3906 return 0;
3907 pattern_wildcard = pattern_left_label_end;
3908 break;
3909 }
3910 pattern_left_label_end++;
3911 }
3912
3913 /* If it's not trivial and there is no wildcard, it can't
3914 * match */
3915 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003916 return 0;
3917
3918 /* Make sure all labels match except the leftmost */
3919 hostname_left_label_end = strchr(hostname, '.');
3920 if (!hostname_left_label_end
3921 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3922 return 0;
3923
3924 /* Make sure the leftmost label of the hostname is long enough
3925 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003926 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003927 return 0;
3928
3929 /* Finally compare the string on either side of the
3930 * wildcard */
3931 prefixlen = pattern_wildcard - pattern;
3932 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003933 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3934 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003935 return 0;
3936
3937 return 1;
3938}
3939
3940static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3941{
3942 SSL *ssl;
3943 struct connection *conn;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003944 const char *servername;
Willy Tarreau71d058c2017-07-26 20:09:56 +02003945 const char *sni;
Evan Broderbe554312013-06-27 00:05:25 -07003946
3947 int depth;
3948 X509 *cert;
3949 STACK_OF(GENERAL_NAME) *alt_names;
3950 int i;
3951 X509_NAME *cert_subject;
3952 char *str;
3953
3954 if (ok == 0)
3955 return ok;
3956
3957 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003958 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003959
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003960 /* We're checking if the provided hostnames match the desired one. The
3961 * desired hostname comes from the SNI we presented if any, or if not
3962 * provided then it may have been explicitly stated using a "verifyhost"
3963 * directive. If neither is set, we don't care about the name so the
3964 * verification is OK.
Willy Tarreau2ab88672017-07-05 18:23:03 +02003965 */
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003966 servername = SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau71d058c2017-07-26 20:09:56 +02003967 sni = servername;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003968 if (!servername) {
Willy Tarreauad92a9a2017-07-28 11:38:41 +02003969 servername = objt_server(conn->target)->ssl_ctx.verify_host;
Willy Tarreau2ab88672017-07-05 18:23:03 +02003970 if (!servername)
3971 return ok;
3972 }
Evan Broderbe554312013-06-27 00:05:25 -07003973
3974 /* We only need to verify the CN on the actual server cert,
3975 * not the indirect CAs */
3976 depth = X509_STORE_CTX_get_error_depth(ctx);
3977 if (depth != 0)
3978 return ok;
3979
3980 /* At this point, the cert is *not* OK unless we can find a
3981 * hostname match */
3982 ok = 0;
3983
3984 cert = X509_STORE_CTX_get_current_cert(ctx);
3985 /* It seems like this might happen if verify peer isn't set */
3986 if (!cert)
3987 return ok;
3988
3989 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3990 if (alt_names) {
3991 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3992 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3993 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003994#if OPENSSL_VERSION_NUMBER < 0x00907000L
3995 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3996#else
Evan Broderbe554312013-06-27 00:05:25 -07003997 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003998#endif
Evan Broderbe554312013-06-27 00:05:25 -07003999 ok = ssl_sock_srv_hostcheck(str, servername);
4000 OPENSSL_free(str);
4001 }
4002 }
4003 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02004004 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07004005 }
4006
4007 cert_subject = X509_get_subject_name(cert);
4008 i = -1;
4009 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
4010 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004011 ASN1_STRING *value;
4012 value = X509_NAME_ENTRY_get_data(entry);
4013 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07004014 ok = ssl_sock_srv_hostcheck(str, servername);
4015 OPENSSL_free(str);
4016 }
4017 }
4018
Willy Tarreau71d058c2017-07-26 20:09:56 +02004019 /* report the mismatch and indicate if SNI was used or not */
4020 if (!ok && !conn->err_code)
4021 conn->err_code = sni ? CO_ER_SSL_MISMATCH_SNI : CO_ER_SSL_MISMATCH;
Evan Broderbe554312013-06-27 00:05:25 -07004022 return ok;
4023}
4024
Emeric Brun94324a42012-10-11 14:00:19 +02004025/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01004026int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02004027{
Willy Tarreau03209342016-12-22 17:08:28 +01004028 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02004029 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02004030 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02004031 SSL_OP_ALL | /* all known workarounds for bugs */
4032 SSL_OP_NO_SSLv2 |
4033 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02004034 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02004035 SSL_MODE_ENABLE_PARTIAL_WRITE |
4036 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01004037 SSL_MODE_RELEASE_BUFFERS |
4038 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01004039 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004040 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004041 struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004042 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004043 int flags = MC_SSL_O_ALL;
Emeric Brun94324a42012-10-11 14:00:19 +02004044
Thierry Fournier383085f2013-01-24 14:15:43 +01004045 /* Make sure openssl opens /dev/urandom before the chroot */
4046 if (!ssl_initialize_random()) {
4047 Alert("OpenSSL random data generator initialization failed.\n");
4048 cfgerr++;
4049 }
4050
Willy Tarreaufce03112015-01-15 21:32:40 +01004051 /* Automatic memory computations need to know we use SSL there */
4052 global.ssl_used_backend = 1;
4053
4054 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02004055 srv->ssl_ctx.reused_sess = NULL;
4056 if (srv->use_ssl)
4057 srv->xprt = &ssl_sock;
4058 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01004059 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02004060
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004061 ctx = SSL_CTX_new(SSLv23_client_method());
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004062 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02004063 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
4064 proxy_type_str(curproxy), curproxy->id,
4065 srv->id);
4066 cfgerr++;
4067 return cfgerr;
4068 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004069
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004070 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
4071 Warning("config : %s '%s': no-sslv3/no-tlsv1x are ignored for server '%s'. "
4072 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
4073 proxy_type_str(curproxy), curproxy->id, srv->id);
4074 else
4075 flags = conf_ssl_methods->flags;
4076
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004077 /* Real min and max should be determinate with configuration and openssl's capabilities */
4078 if (conf_ssl_methods->min)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004079 flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004080 if (conf_ssl_methods->max)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004081 flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004082
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004083 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004084 min = max = CONF_TLSV_NONE;
4085 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004086 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004087 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004088 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004089 if (min) {
4090 if (hole) {
4091 Warning("config : %s '%s': SSL/TLS versions range not contiguous for server '%s'. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02004092 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004093 proxy_type_str(curproxy), curproxy->id, srv->id,
4094 methodVersions[hole].name);
4095 hole = 0;
4096 }
4097 max = i;
4098 }
4099 else {
4100 min = max = i;
4101 }
4102 }
4103 else {
4104 if (min)
4105 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004106 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004107 if (!min) {
4108 Alert("config : %s '%s': all SSL/TLS versions are disabled for server '%s'.\n",
4109 proxy_type_str(curproxy), curproxy->id, srv->id);
4110 cfgerr += 1;
4111 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004112
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004113#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
4114 /* Keep force-xxx implementation as it is in older haproxy. It's a
4115 precautionary measure to avoid any suprise with older openssl version. */
4116 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004117 methodVersions[min].ctx_set_version(ctx, SET_CLIENT);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004118 else
4119 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
4120 if (flags & methodVersions[i].flag)
4121 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004122#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004123 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004124 methodVersions[min].ctx_set_version(ctx, SET_MIN);
4125 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004126#endif
4127
4128 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
4129 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004130 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004131
4132#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4133 if (global_ssl.async)
4134 mode |= SSL_MODE_ASYNC;
4135#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004136 SSL_CTX_set_mode(ctx, mode);
4137 srv->ssl_ctx.ctx = ctx;
4138
Emeric Bruna7aa3092012-10-26 12:58:00 +02004139 if (srv->ssl_ctx.client_crt) {
4140 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
4141 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
4142 proxy_type_str(curproxy), curproxy->id,
4143 srv->id, srv->ssl_ctx.client_crt);
4144 cfgerr++;
4145 }
4146 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
4147 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
4148 proxy_type_str(curproxy), curproxy->id,
4149 srv->id, srv->ssl_ctx.client_crt);
4150 cfgerr++;
4151 }
4152 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
4153 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
4154 proxy_type_str(curproxy), curproxy->id,
4155 srv->id, srv->ssl_ctx.client_crt);
4156 cfgerr++;
4157 }
4158 }
Emeric Brun94324a42012-10-11 14:00:19 +02004159
Emeric Brun850efd52014-01-29 12:24:34 +01004160 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
4161 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01004162 switch (srv->ssl_ctx.verify) {
4163 case SSL_SOCK_VERIFY_NONE:
4164 verify = SSL_VERIFY_NONE;
4165 break;
4166 case SSL_SOCK_VERIFY_REQUIRED:
4167 verify = SSL_VERIFY_PEER;
4168 break;
4169 }
Evan Broderbe554312013-06-27 00:05:25 -07004170 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01004171 verify,
Willy Tarreau2ab88672017-07-05 18:23:03 +02004172 (srv->ssl_ctx.verify_host || (verify & SSL_VERIFY_PEER)) ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01004173 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02004174 if (srv->ssl_ctx.ca_file) {
4175 /* load CAfile to verify */
4176 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004177 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004178 curproxy->id, srv->id,
4179 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
4180 cfgerr++;
4181 }
4182 }
Emeric Brun850efd52014-01-29 12:24:34 +01004183 else {
4184 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004185 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 +01004186 curproxy->id, srv->id,
4187 srv->conf.file, srv->conf.line);
4188 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004189 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01004190 curproxy->id, srv->id,
4191 srv->conf.file, srv->conf.line);
4192 cfgerr++;
4193 }
Emeric Brunef42d922012-10-11 16:11:36 +02004194#ifdef X509_V_FLAG_CRL_CHECK
4195 if (srv->ssl_ctx.crl_file) {
4196 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
4197
4198 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004199 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004200 curproxy->id, srv->id,
4201 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
4202 cfgerr++;
4203 }
4204 else {
4205 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
4206 }
4207 }
4208#endif
4209 }
4210
Emeric Brun94324a42012-10-11 14:00:19 +02004211 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
4212 if (srv->ssl_ctx.ciphers &&
4213 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
4214 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
4215 curproxy->id, srv->id,
4216 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
4217 cfgerr++;
4218 }
4219
4220 return cfgerr;
4221}
4222
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004223/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004224 * be NULL, in which case nothing is done. Returns the number of errors
4225 * encountered.
4226 */
Willy Tarreau03209342016-12-22 17:08:28 +01004227int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004228{
4229 struct ebmb_node *node;
4230 struct sni_ctx *sni;
4231 int err = 0;
4232
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004233 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004234 return 0;
4235
Willy Tarreaufce03112015-01-15 21:32:40 +01004236 /* Automatic memory computations need to know we use SSL there */
4237 global.ssl_used_frontend = 1;
4238
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004239 /* Make sure openssl opens /dev/urandom before the chroot */
4240 if (!ssl_initialize_random()) {
4241 Alert("OpenSSL random data generator initialization failed.\n");
4242 err++;
4243 }
4244 /* Create initial_ctx used to start the ssl connection before do switchctx */
4245 if (!bind_conf->initial_ctx) {
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004246 err += ssl_sock_initial_ctx(bind_conf);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004247 /* It should not be necessary to call this function, but it's
4248 necessary first to check and move all initialisation related
4249 to initial_ctx in ssl_sock_initial_ctx. */
4250 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
4251 }
Emeric Brun0bed9942014-10-30 19:25:24 +01004252 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004253 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01004254
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004255 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004256 while (node) {
4257 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004258 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4259 /* only initialize the CTX on its first occurrence and
4260 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004261 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004262 node = ebmb_next(node);
4263 }
4264
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004265 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004266 while (node) {
4267 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004268 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4269 /* only initialize the CTX on its first occurrence and
4270 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004271 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004272 node = ebmb_next(node);
4273 }
4274 return err;
4275}
4276
Willy Tarreau55d37912016-12-21 23:38:39 +01004277/* Prepares all the contexts for a bind_conf and allocates the shared SSL
4278 * context if needed. Returns < 0 on error, 0 on success. The warnings and
4279 * alerts are directly emitted since the rest of the stack does it below.
4280 */
4281int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
4282{
4283 struct proxy *px = bind_conf->frontend;
4284 int alloc_ctx;
4285 int err;
4286
4287 if (!bind_conf->is_ssl) {
4288 if (bind_conf->default_ctx) {
4289 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
4290 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4291 }
4292 return 0;
4293 }
4294 if (!bind_conf->default_ctx) {
Emmanuel Hocdetaa0d6372017-08-09 11:24:25 +02004295 if (bind_conf->strict_sni && !bind_conf->generate_certs) {
4296 Warning("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d], ssl connections will fail (use 'crt').\n",
4297 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4298 }
4299 else {
4300 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
4301 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4302 return -1;
4303 }
Willy Tarreau55d37912016-12-21 23:38:39 +01004304 }
4305
Willy Tarreauef934602016-12-22 23:12:01 +01004306 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01004307 if (alloc_ctx < 0) {
4308 if (alloc_ctx == SHCTX_E_INIT_LOCK)
4309 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");
4310 else
4311 Alert("Unable to allocate SSL session cache.\n");
4312 return -1;
4313 }
4314
4315 err = 0;
4316 /* initialize all certificate contexts */
4317 err += ssl_sock_prepare_all_ctx(bind_conf);
4318
4319 /* initialize CA variables if the certificates generation is enabled */
4320 err += ssl_sock_load_ca(bind_conf);
4321
4322 return -err;
4323}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02004324
4325/* release ssl context allocated for servers. */
4326void ssl_sock_free_srv_ctx(struct server *srv)
4327{
4328 if (srv->ssl_ctx.ctx)
4329 SSL_CTX_free(srv->ssl_ctx.ctx);
4330}
4331
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004332/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004333 * be NULL, in which case nothing is done. The default_ctx is nullified too.
4334 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004335void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004336{
4337 struct ebmb_node *node, *back;
4338 struct sni_ctx *sni;
4339
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004340 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004341 return;
4342
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004343 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004344 while (node) {
4345 sni = ebmb_entry(node, struct sni_ctx, name);
4346 back = ebmb_next(node);
4347 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004348 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004349 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004350 ssl_sock_free_ssl_conf(sni->conf);
4351 free(sni->conf);
4352 sni->conf = NULL;
4353 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004354 free(sni);
4355 node = back;
4356 }
4357
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004358 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004359 while (node) {
4360 sni = ebmb_entry(node, struct sni_ctx, name);
4361 back = ebmb_next(node);
4362 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004363 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004364 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004365 ssl_sock_free_ssl_conf(sni->conf);
4366 free(sni->conf);
4367 sni->conf = NULL;
4368 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004369 free(sni);
4370 node = back;
4371 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004372 SSL_CTX_free(bind_conf->initial_ctx);
4373 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004374 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004375 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02004376}
4377
Willy Tarreau795cdab2016-12-22 17:30:54 +01004378/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
4379void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
4380{
4381 ssl_sock_free_ca(bind_conf);
4382 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004383 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004384 free(bind_conf->ca_sign_file);
4385 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004386 if (bind_conf->keys_ref) {
4387 free(bind_conf->keys_ref->filename);
4388 free(bind_conf->keys_ref->tlskeys);
4389 LIST_DEL(&bind_conf->keys_ref->list);
4390 free(bind_conf->keys_ref);
4391 }
4392 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004393 bind_conf->ca_sign_pass = NULL;
4394 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004395}
4396
Christopher Faulet31af49d2015-06-09 17:29:50 +02004397/* Load CA cert file and private key used to generate certificates */
4398int
Willy Tarreau03209342016-12-22 17:08:28 +01004399ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02004400{
Willy Tarreau03209342016-12-22 17:08:28 +01004401 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004402 FILE *fp;
4403 X509 *cacert = NULL;
4404 EVP_PKEY *capkey = NULL;
4405 int err = 0;
4406
4407 if (!bind_conf || !bind_conf->generate_certs)
4408 return err;
4409
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004410#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01004411 if (global_ssl.ctx_cache)
4412 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02004413 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02004414#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02004415
Christopher Faulet31af49d2015-06-09 17:29:50 +02004416 if (!bind_conf->ca_sign_file) {
4417 Alert("Proxy '%s': cannot enable certificate generation, "
4418 "no CA certificate File configured at [%s:%d].\n",
4419 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004420 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004421 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004422
4423 /* read in the CA certificate */
4424 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
4425 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4426 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004427 goto load_error;
4428 }
4429 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
4430 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4431 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004432 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004433 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004434 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004435 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
4436 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
4437 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004438 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004439 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004440
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004441 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004442 bind_conf->ca_sign_cert = cacert;
4443 bind_conf->ca_sign_pkey = capkey;
4444 return err;
4445
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004446 read_error:
4447 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004448 if (capkey) EVP_PKEY_free(capkey);
4449 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004450 load_error:
4451 bind_conf->generate_certs = 0;
4452 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004453 return err;
4454}
4455
4456/* Release CA cert and private key used to generate certificated */
4457void
4458ssl_sock_free_ca(struct bind_conf *bind_conf)
4459{
4460 if (!bind_conf)
4461 return;
4462
4463 if (bind_conf->ca_sign_pkey)
4464 EVP_PKEY_free(bind_conf->ca_sign_pkey);
4465 if (bind_conf->ca_sign_cert)
4466 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01004467 bind_conf->ca_sign_pkey = NULL;
4468 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004469}
4470
Emeric Brun46591952012-05-18 15:47:34 +02004471/*
4472 * This function is called if SSL * context is not yet allocated. The function
4473 * is designed to be called before any other data-layer operation and sets the
4474 * handshake flag on the connection. It is safe to call it multiple times.
4475 * It returns 0 on success and -1 in error case.
4476 */
4477static int ssl_sock_init(struct connection *conn)
4478{
4479 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004480 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004481 return 0;
4482
Willy Tarreau3c728722014-01-23 13:50:42 +01004483 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004484 return 0;
4485
Willy Tarreau20879a02012-12-03 16:32:10 +01004486 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4487 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004488 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004489 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004490
Emeric Brun46591952012-05-18 15:47:34 +02004491 /* If it is in client mode initiate SSL session
4492 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004493 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004494 int may_retry = 1;
4495
4496 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004497 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004498 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004499 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004500 if (may_retry--) {
4501 pool_gc2();
4502 goto retry_connect;
4503 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004504 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004505 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004506 }
Emeric Brun46591952012-05-18 15:47:34 +02004507
Emeric Brun46591952012-05-18 15:47:34 +02004508 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004509 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4510 SSL_free(conn->xprt_ctx);
4511 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004512 if (may_retry--) {
4513 pool_gc2();
4514 goto retry_connect;
4515 }
Emeric Brun55476152014-11-12 17:35:37 +01004516 conn->err_code = CO_ER_SSL_NO_MEM;
4517 return -1;
4518 }
Emeric Brun46591952012-05-18 15:47:34 +02004519
Evan Broderbe554312013-06-27 00:05:25 -07004520 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004521 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4522 SSL_free(conn->xprt_ctx);
4523 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004524 if (may_retry--) {
4525 pool_gc2();
4526 goto retry_connect;
4527 }
Emeric Brun55476152014-11-12 17:35:37 +01004528 conn->err_code = CO_ER_SSL_NO_MEM;
4529 return -1;
4530 }
4531
4532 SSL_set_connect_state(conn->xprt_ctx);
4533 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4534 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4535 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4536 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4537 }
4538 }
Evan Broderbe554312013-06-27 00:05:25 -07004539
Emeric Brun46591952012-05-18 15:47:34 +02004540 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004541 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004542
4543 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004544 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004545 return 0;
4546 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004547 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004548 int may_retry = 1;
4549
4550 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004551 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004552 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004553 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004554 if (may_retry--) {
4555 pool_gc2();
4556 goto retry_accept;
4557 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004558 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004559 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004560 }
Emeric Brun46591952012-05-18 15:47:34 +02004561
Emeric Brun46591952012-05-18 15:47:34 +02004562 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004563 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4564 SSL_free(conn->xprt_ctx);
4565 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004566 if (may_retry--) {
4567 pool_gc2();
4568 goto retry_accept;
4569 }
Emeric Brun55476152014-11-12 17:35:37 +01004570 conn->err_code = CO_ER_SSL_NO_MEM;
4571 return -1;
4572 }
Emeric Brun46591952012-05-18 15:47:34 +02004573
Emeric Brune1f38db2012-09-03 20:36:47 +02004574 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004575 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4576 SSL_free(conn->xprt_ctx);
4577 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004578 if (may_retry--) {
4579 pool_gc2();
4580 goto retry_accept;
4581 }
Emeric Brun55476152014-11-12 17:35:37 +01004582 conn->err_code = CO_ER_SSL_NO_MEM;
4583 return -1;
4584 }
4585
4586 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004587
Emeric Brun46591952012-05-18 15:47:34 +02004588 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004589 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004590
4591 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004592 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004593 return 0;
4594 }
4595 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004596 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004597 return -1;
4598}
4599
4600
4601/* This is the callback which is used when an SSL handshake is pending. It
4602 * updates the FD status if it wants some polling before being called again.
4603 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4604 * otherwise it returns non-zero and removes itself from the connection's
4605 * flags (the bit is provided in <flag> by the caller).
4606 */
4607int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4608{
4609 int ret;
4610
Willy Tarreau3c728722014-01-23 13:50:42 +01004611 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004612 return 0;
4613
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004614 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004615 goto out_error;
4616
Emeric Brun674b7432012-11-08 19:21:55 +01004617 /* If we use SSL_do_handshake to process a reneg initiated by
4618 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4619 * Usually SSL_write and SSL_read are used and process implicitly
4620 * the reneg handshake.
4621 * Here we use SSL_peek as a workaround for reneg.
4622 */
4623 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4624 char c;
4625
4626 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4627 if (ret <= 0) {
4628 /* handshake may have not been completed, let's find why */
4629 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004630
Emeric Brun674b7432012-11-08 19:21:55 +01004631 if (ret == SSL_ERROR_WANT_WRITE) {
4632 /* SSL handshake needs to write, L4 connection may not be ready */
4633 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004634 __conn_sock_want_send(conn);
4635 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004636 return 0;
4637 }
4638 else if (ret == SSL_ERROR_WANT_READ) {
4639 /* handshake may have been completed but we have
4640 * no more data to read.
4641 */
4642 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4643 ret = 1;
4644 goto reneg_ok;
4645 }
4646 /* SSL handshake needs to read, L4 connection is ready */
4647 if (conn->flags & CO_FL_WAIT_L4_CONN)
4648 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4649 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004650 __conn_sock_want_recv(conn);
4651 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004652 return 0;
4653 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004654#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4655 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004656 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004657 return 0;
4658 }
4659#endif
Emeric Brun674b7432012-11-08 19:21:55 +01004660 else if (ret == SSL_ERROR_SYSCALL) {
4661 /* if errno is null, then connection was successfully established */
4662 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4663 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004664 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004665#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4666 conn->err_code = CO_ER_SSL_HANDSHAKE;
4667#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004668 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004669#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004670 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4671 empty_handshake = state == TLS_ST_BEFORE;
4672#else
4673 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4674#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004675 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004676 if (!errno) {
4677 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4678 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4679 else
4680 conn->err_code = CO_ER_SSL_EMPTY;
4681 }
4682 else {
4683 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4684 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4685 else
4686 conn->err_code = CO_ER_SSL_ABORT;
4687 }
4688 }
4689 else {
4690 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4691 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004692 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004693 conn->err_code = CO_ER_SSL_HANDSHAKE;
4694 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004695#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004696 }
Emeric Brun674b7432012-11-08 19:21:55 +01004697 goto out_error;
4698 }
4699 else {
4700 /* Fail on all other handshake errors */
4701 /* Note: OpenSSL may leave unread bytes in the socket's
4702 * buffer, causing an RST to be emitted upon close() on
4703 * TCP sockets. We first try to drain possibly pending
4704 * data to avoid this as much as possible.
4705 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004706 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004707 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004708 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4709 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004710 goto out_error;
4711 }
4712 }
4713 /* read some data: consider handshake completed */
4714 goto reneg_ok;
4715 }
4716
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004717 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004718 if (ret != 1) {
4719 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004720 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004721
4722 if (ret == SSL_ERROR_WANT_WRITE) {
4723 /* SSL handshake needs to write, L4 connection may not be ready */
4724 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004725 __conn_sock_want_send(conn);
4726 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004727 return 0;
4728 }
4729 else if (ret == SSL_ERROR_WANT_READ) {
4730 /* SSL handshake needs to read, L4 connection is ready */
4731 if (conn->flags & CO_FL_WAIT_L4_CONN)
4732 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4733 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004734 __conn_sock_want_recv(conn);
4735 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004736 return 0;
4737 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004738#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4739 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004740 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004741 return 0;
4742 }
4743#endif
Willy Tarreau89230192012-09-28 20:22:13 +02004744 else if (ret == SSL_ERROR_SYSCALL) {
4745 /* if errno is null, then connection was successfully established */
4746 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4747 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004748 if (!conn->err_code) {
4749#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4750 conn->err_code = CO_ER_SSL_HANDSHAKE;
4751#else
4752 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004753#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004754 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4755 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004756#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004757 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004758#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004759 if (empty_handshake) {
4760 if (!errno) {
4761 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4762 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4763 else
4764 conn->err_code = CO_ER_SSL_EMPTY;
4765 }
4766 else {
4767 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4768 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4769 else
4770 conn->err_code = CO_ER_SSL_ABORT;
4771 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004772 }
4773 else {
4774 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4775 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4776 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004777 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004778 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004779#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004780 }
Willy Tarreau89230192012-09-28 20:22:13 +02004781 goto out_error;
4782 }
Emeric Brun46591952012-05-18 15:47:34 +02004783 else {
4784 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004785 /* Note: OpenSSL may leave unread bytes in the socket's
4786 * buffer, causing an RST to be emitted upon close() on
4787 * TCP sockets. We first try to drain possibly pending
4788 * data to avoid this as much as possible.
4789 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004790 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004791 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004792 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4793 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004794 goto out_error;
4795 }
4796 }
4797
Emeric Brun674b7432012-11-08 19:21:55 +01004798reneg_ok:
Emeric Brunb5e42a82017-06-06 12:35:14 +00004799
4800#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4801 /* ASYNC engine API doesn't support moving read/write
4802 * buffers. So we disable ASYNC mode right after
4803 * the handshake to avoid buffer oveflows.
4804 */
4805 if (global_ssl.async)
4806 SSL_clear_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4807#endif
Emeric Brun46591952012-05-18 15:47:34 +02004808 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004809 if (!SSL_session_reused(conn->xprt_ctx)) {
4810 if (objt_server(conn->target)) {
4811 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4812 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4813 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4814
Emeric Brun46591952012-05-18 15:47:34 +02004815 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004816 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004817 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004818 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4819 }
Emeric Brun46591952012-05-18 15:47:34 +02004820
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004821 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4822 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004823 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004824 else {
4825 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4826 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4827 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4828 }
Emeric Brun46591952012-05-18 15:47:34 +02004829 }
4830
4831 /* The connection is now established at both layers, it's time to leave */
4832 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4833 return 1;
4834
4835 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004836 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004837 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004838 ERR_clear_error();
4839
Emeric Brun9fa89732012-10-04 17:09:56 +02004840 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004841 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4842 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4843 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004844 }
4845
Emeric Brun46591952012-05-18 15:47:34 +02004846 /* Fail on all other handshake errors */
4847 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004848 if (!conn->err_code)
4849 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004850 return 0;
4851}
4852
4853/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004854 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004855 * buffer wraps, in which case a second call may be performed. The connection's
4856 * flags are updated with whatever special event is detected (error, read0,
4857 * empty). The caller is responsible for taking care of those events and
4858 * avoiding the call if inappropriate. The function does not call the
4859 * connection's polling update function, so the caller is responsible for this.
4860 */
4861static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4862{
4863 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004864 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004865
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004866 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004867 goto out_error;
4868
4869 if (conn->flags & CO_FL_HANDSHAKE)
4870 /* a handshake was requested */
4871 return 0;
4872
Willy Tarreauabf08d92014-01-14 11:31:27 +01004873 /* let's realign the buffer to optimize I/O */
4874 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004875 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004876
4877 /* read the largest possible block. For this, we perform only one call
4878 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4879 * in which case we accept to do it once again. A new attempt is made on
4880 * EINTR too.
4881 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004882 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004883 /* first check if we have some room after p+i */
4884 try = buf->data + buf->size - (buf->p + buf->i);
4885 /* otherwise continue between data and p-o */
4886 if (try <= 0) {
4887 try = buf->p - (buf->data + buf->o);
4888 if (try <= 0)
4889 break;
4890 }
4891 if (try > count)
4892 try = count;
4893
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004894 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004895 if (conn->flags & CO_FL_ERROR) {
4896 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004897 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004898 }
Emeric Brun46591952012-05-18 15:47:34 +02004899 if (ret > 0) {
4900 buf->i += ret;
4901 done += ret;
Emeric Brun46591952012-05-18 15:47:34 +02004902 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004903 }
4904 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004905 ret = SSL_get_error(conn->xprt_ctx, ret);
4906 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004907 /* error on protocol or underlying transport */
4908 if ((ret != SSL_ERROR_SYSCALL)
4909 || (errno && (errno != EAGAIN)))
4910 conn->flags |= CO_FL_ERROR;
4911
Emeric Brun644cde02012-12-14 11:21:13 +01004912 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004913 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004914 ERR_clear_error();
4915 }
Emeric Brun46591952012-05-18 15:47:34 +02004916 goto read0;
4917 }
4918 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004919 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004920 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004921 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004922 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004923 __conn_sock_want_send(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00004924#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4925 /* Async mode can be re-enabled, because we're leaving data state.*/
4926 if (global_ssl.async)
4927 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4928#endif
Emeric Brun46591952012-05-18 15:47:34 +02004929 break;
4930 }
4931 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004932 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4933 /* handshake is running, and it may need to re-enable read */
4934 conn->flags |= CO_FL_SSL_WAIT_HS;
4935 __conn_sock_want_recv(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00004936#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4937 /* Async mode can be re-enabled, because we're leaving data state.*/
4938 if (global_ssl.async)
4939 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
4940#endif
Emeric Brun282a76a2012-11-08 18:02:56 +01004941 break;
4942 }
Emeric Brun46591952012-05-18 15:47:34 +02004943 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004944 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004945 break;
4946 }
4947 /* otherwise it's a real error */
4948 goto out_error;
4949 }
4950 }
4951 return done;
4952
4953 read0:
4954 conn_sock_read0(conn);
4955 return done;
4956 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004957 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004958 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004959 ERR_clear_error();
4960
Emeric Brun46591952012-05-18 15:47:34 +02004961 conn->flags |= CO_FL_ERROR;
4962 return done;
4963}
4964
4965
4966/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004967 * <flags> may contain some CO_SFL_* flags to hint the system about other
4968 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004969 * Only one call to send() is performed, unless the buffer wraps, in which case
4970 * a second call may be performed. The connection's flags are updated with
4971 * whatever special event is detected (error, empty). The caller is responsible
4972 * for taking care of those events and avoiding the call if inappropriate. The
4973 * function does not call the connection's polling update function, so the caller
4974 * is responsible for this.
4975 */
4976static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4977{
4978 int ret, try, done;
4979
4980 done = 0;
4981
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004982 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004983 goto out_error;
4984
4985 if (conn->flags & CO_FL_HANDSHAKE)
4986 /* a handshake was requested */
4987 return 0;
4988
4989 /* send the largest possible block. For this we perform only one call
4990 * to send() unless the buffer wraps and we exactly fill the first hunk,
4991 * in which case we accept to do it once again.
4992 */
4993 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004994 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004995
Willy Tarreau7bed9452014-02-02 02:00:24 +01004996 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004997 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004998 global_ssl.max_record && try > global_ssl.max_record) {
4999 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01005000 }
5001 else {
5002 /* we need to keep the information about the fact that
5003 * we're not limiting the upcoming send(), because if it
5004 * fails, we'll have to retry with at least as many data.
5005 */
5006 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
5007 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01005008
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005009 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01005010
Emeric Brune1f38db2012-09-03 20:36:47 +02005011 if (conn->flags & CO_FL_ERROR) {
5012 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01005013 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02005014 }
Emeric Brun46591952012-05-18 15:47:34 +02005015 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01005016 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
5017
Emeric Brun46591952012-05-18 15:47:34 +02005018 buf->o -= ret;
5019 done += ret;
5020
Willy Tarreau5fb38032012-12-16 19:39:09 +01005021 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02005022 /* optimize data alignment in the buffer */
5023 buf->p = buf->data;
5024
5025 /* if the system buffer is full, don't insist */
5026 if (ret < try)
5027 break;
5028 }
5029 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005030 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005031
Emeric Brun46591952012-05-18 15:47:34 +02005032 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01005033 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
5034 /* handshake is running, and it may need to re-enable write */
5035 conn->flags |= CO_FL_SSL_WAIT_HS;
5036 __conn_sock_want_send(conn);
Emeric Brunb5e42a82017-06-06 12:35:14 +00005037#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
5038 /* Async mode can be re-enabled, because we're leaving data state.*/
5039 if (global_ssl.async)
5040 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
5041#endif
Emeric Brun282a76a2012-11-08 18:02:56 +01005042 break;
5043 }
Emeric Brun46591952012-05-18 15:47:34 +02005044 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01005045 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02005046 break;
5047 }
5048 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01005049 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02005050 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01005051 __conn_sock_want_recv(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005052#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brunb5e42a82017-06-06 12:35:14 +00005053 /* Async mode can be re-enabled, because we're leaving data state.*/
5054 if (global_ssl.async)
5055 SSL_set_mode(conn->xprt_ctx, SSL_MODE_ASYNC);
5056#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005057 break;
5058 }
Emeric Brun46591952012-05-18 15:47:34 +02005059 goto out_error;
5060 }
5061 }
5062 return done;
5063
5064 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01005065 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005066 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005067 ERR_clear_error();
5068
Emeric Brun46591952012-05-18 15:47:34 +02005069 conn->flags |= CO_FL_ERROR;
5070 return done;
5071}
5072
Emeric Brun46591952012-05-18 15:47:34 +02005073static void ssl_sock_close(struct connection *conn) {
5074
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005075 if (conn->xprt_ctx) {
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005076#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brun3854e012017-05-17 20:42:48 +02005077 if (global_ssl.async) {
5078 OSSL_ASYNC_FD all_fd[32], afd;
5079 size_t num_all_fds = 0;
5080 int i;
5081
5082 SSL_get_all_async_fds(conn->xprt_ctx, NULL, &num_all_fds);
5083 if (num_all_fds > 32) {
5084 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
5085 return;
5086 }
5087
5088 SSL_get_all_async_fds(conn->xprt_ctx, all_fd, &num_all_fds);
5089
5090 /* If an async job is pending, we must try to
5091 to catch the end using polling before calling
5092 SSL_free */
5093 if (num_all_fds && SSL_waiting_for_async(conn->xprt_ctx)) {
5094 for (i=0 ; i < num_all_fds ; i++) {
5095 /* switch on an handler designed to
5096 * handle the SSL_free
5097 */
5098 afd = all_fd[i];
5099 fdtab[afd].iocb = ssl_async_fd_free;
5100 fdtab[afd].owner = conn->xprt_ctx;
5101 fd_want_recv(afd);
Emeric Brunce9e01c2017-05-31 10:02:53 +00005102 /* To ensure that the fd cache won't be used
5103 * and we'll catch a real RD event.
5104 */
5105 fd_cant_recv(afd);
Emeric Brun3854e012017-05-17 20:42:48 +02005106 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005107 conn->xprt_ctx = NULL;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005108 jobs++;
5109 return;
5110 }
Emeric Brun3854e012017-05-17 20:42:48 +02005111 /* Else we can remove the fds from the fdtab
5112 * and call SSL_free.
5113 * note: we do a fd_remove and not a delete
5114 * because the fd is owned by the engine.
5115 * the engine is responsible to close
5116 */
5117 for (i=0 ; i < num_all_fds ; i++)
5118 fd_remove(all_fd[i]);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005119 }
5120#endif
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005121 SSL_free(conn->xprt_ctx);
5122 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02005123 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02005124 }
Emeric Brun46591952012-05-18 15:47:34 +02005125}
5126
5127/* This function tries to perform a clean shutdown on an SSL connection, and in
5128 * any case, flags the connection as reusable if no handshake was in progress.
5129 */
5130static void ssl_sock_shutw(struct connection *conn, int clean)
5131{
5132 if (conn->flags & CO_FL_HANDSHAKE)
5133 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005134 if (!clean)
5135 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01005136 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02005137 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005138 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01005139 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005140 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005141 ERR_clear_error();
5142 }
Emeric Brun46591952012-05-18 15:47:34 +02005143}
5144
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02005145/* used for logging, may be changed for a sample fetch later */
5146const char *ssl_sock_get_cipher_name(struct connection *conn)
5147{
5148 if (!conn->xprt && !conn->xprt_ctx)
5149 return NULL;
5150 return SSL_get_cipher_name(conn->xprt_ctx);
5151}
5152
5153/* used for logging, may be changed for a sample fetch later */
5154const char *ssl_sock_get_proto_version(struct connection *conn)
5155{
5156 if (!conn->xprt && !conn->xprt_ctx)
5157 return NULL;
5158 return SSL_get_version(conn->xprt_ctx);
5159}
5160
Willy Tarreau8d598402012-10-22 17:58:39 +02005161/* Extract a serial from a cert, and copy it to a chunk.
5162 * Returns 1 if serial is found and copied, 0 if no serial found and
5163 * -1 if output is not large enough.
5164 */
5165static int
5166ssl_sock_get_serial(X509 *crt, struct chunk *out)
5167{
5168 ASN1_INTEGER *serial;
5169
5170 serial = X509_get_serialNumber(crt);
5171 if (!serial)
5172 return 0;
5173
5174 if (out->size < serial->length)
5175 return -1;
5176
5177 memcpy(out->str, serial->data, serial->length);
5178 out->len = serial->length;
5179 return 1;
5180}
5181
Emeric Brun43e79582014-10-29 19:03:26 +01005182/* Extract a cert to der, and copy it to a chunk.
5183 * Returns 1 if cert is found and copied, 0 on der convertion failure and
5184 * -1 if output is not large enough.
5185 */
5186static int
5187ssl_sock_crt2der(X509 *crt, struct chunk *out)
5188{
5189 int len;
5190 unsigned char *p = (unsigned char *)out->str;;
5191
5192 len =i2d_X509(crt, NULL);
5193 if (len <= 0)
5194 return 1;
5195
5196 if (out->size < len)
5197 return -1;
5198
5199 i2d_X509(crt,&p);
5200 out->len = len;
5201 return 1;
5202}
5203
Emeric Brunce5ad802012-10-22 14:11:22 +02005204
5205/* Copy Date in ASN1_UTCTIME format in struct chunk out.
5206 * Returns 1 if serial is found and copied, 0 if no valid time found
5207 * and -1 if output is not large enough.
5208 */
5209static int
5210ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
5211{
5212 if (tm->type == V_ASN1_GENERALIZEDTIME) {
5213 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
5214
5215 if (gentm->length < 12)
5216 return 0;
5217 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
5218 return 0;
5219 if (out->size < gentm->length-2)
5220 return -1;
5221
5222 memcpy(out->str, gentm->data+2, gentm->length-2);
5223 out->len = gentm->length-2;
5224 return 1;
5225 }
5226 else if (tm->type == V_ASN1_UTCTIME) {
5227 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
5228
5229 if (utctm->length < 10)
5230 return 0;
5231 if (utctm->data[0] >= 0x35)
5232 return 0;
5233 if (out->size < utctm->length)
5234 return -1;
5235
5236 memcpy(out->str, utctm->data, utctm->length);
5237 out->len = utctm->length;
5238 return 1;
5239 }
5240
5241 return 0;
5242}
5243
Emeric Brun87855892012-10-17 17:39:35 +02005244/* Extract an entry from a X509_NAME and copy its value to an output chunk.
5245 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
5246 */
5247static int
5248ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
5249{
5250 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005251 ASN1_OBJECT *obj;
5252 ASN1_STRING *data;
5253 const unsigned char *data_ptr;
5254 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005255 int i, j, n;
5256 int cur = 0;
5257 const char *s;
5258 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005259 int name_count;
5260
5261 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005262
5263 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005264 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02005265 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005266 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02005267 else
5268 j = i;
5269
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005270 ne = X509_NAME_get_entry(a, j);
5271 obj = X509_NAME_ENTRY_get_object(ne);
5272 data = X509_NAME_ENTRY_get_data(ne);
5273 data_ptr = ASN1_STRING_get0_data(data);
5274 data_len = ASN1_STRING_length(data);
5275 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005276 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005277 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005278 s = tmp;
5279 }
5280
5281 if (chunk_strcasecmp(entry, s) != 0)
5282 continue;
5283
5284 if (pos < 0)
5285 cur--;
5286 else
5287 cur++;
5288
5289 if (cur != pos)
5290 continue;
5291
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005292 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02005293 return -1;
5294
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005295 memcpy(out->str, data_ptr, data_len);
5296 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005297 return 1;
5298 }
5299
5300 return 0;
5301
5302}
5303
5304/* Extract and format full DN from a X509_NAME and copy result into a chunk
5305 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
5306 */
5307static int
5308ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
5309{
5310 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005311 ASN1_OBJECT *obj;
5312 ASN1_STRING *data;
5313 const unsigned char *data_ptr;
5314 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005315 int i, n, ln;
5316 int l = 0;
5317 const char *s;
5318 char *p;
5319 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005320 int name_count;
5321
5322
5323 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005324
5325 out->len = 0;
5326 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005327 for (i = 0; i < name_count; i++) {
5328 ne = X509_NAME_get_entry(a, i);
5329 obj = X509_NAME_ENTRY_get_object(ne);
5330 data = X509_NAME_ENTRY_get_data(ne);
5331 data_ptr = ASN1_STRING_get0_data(data);
5332 data_len = ASN1_STRING_length(data);
5333 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005334 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005335 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005336 s = tmp;
5337 }
5338 ln = strlen(s);
5339
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005340 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005341 if (l > out->size)
5342 return -1;
5343 out->len = l;
5344
5345 *(p++)='/';
5346 memcpy(p, s, ln);
5347 p += ln;
5348 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005349 memcpy(p, data_ptr, data_len);
5350 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005351 }
5352
5353 if (!out->len)
5354 return 0;
5355
5356 return 1;
5357}
5358
David Safb76832014-05-08 23:42:08 -04005359char *ssl_sock_get_version(struct connection *conn)
5360{
5361 if (!ssl_sock_is_ssl(conn))
5362 return NULL;
5363
5364 return (char *)SSL_get_version(conn->xprt_ctx);
5365}
5366
Willy Tarreau119a4082016-12-22 21:58:38 +01005367/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
5368 * to disable SNI.
5369 */
Willy Tarreau63076412015-07-10 11:33:32 +02005370void ssl_sock_set_servername(struct connection *conn, const char *hostname)
5371{
5372#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01005373 char *prev_name;
5374
Willy Tarreau63076412015-07-10 11:33:32 +02005375 if (!ssl_sock_is_ssl(conn))
5376 return;
5377
Willy Tarreau119a4082016-12-22 21:58:38 +01005378 /* if the SNI changes, we must destroy the reusable context so that a
5379 * new connection will present a new SNI. As an optimization we could
5380 * later imagine having a small cache of ssl_ctx to hold a few SNI per
5381 * server.
5382 */
5383 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5384 if ((!prev_name && hostname) ||
5385 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
5386 SSL_set_session(conn->xprt_ctx, NULL);
5387
Willy Tarreau63076412015-07-10 11:33:32 +02005388 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
5389#endif
5390}
5391
Emeric Brun0abf8362014-06-24 18:26:41 +02005392/* Extract peer certificate's common name into the chunk dest
5393 * Returns
5394 * the len of the extracted common name
5395 * or 0 if no CN found in DN
5396 * or -1 on error case (i.e. no peer certificate)
5397 */
5398int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04005399{
5400 X509 *crt = NULL;
5401 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04005402 const char find_cn[] = "CN";
5403 const struct chunk find_cn_chunk = {
5404 .str = (char *)&find_cn,
5405 .len = sizeof(find_cn)-1
5406 };
Emeric Brun0abf8362014-06-24 18:26:41 +02005407 int result = -1;
David Safb76832014-05-08 23:42:08 -04005408
5409 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02005410 goto out;
David Safb76832014-05-08 23:42:08 -04005411
5412 /* SSL_get_peer_certificate, it increase X509 * ref count */
5413 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5414 if (!crt)
5415 goto out;
5416
5417 name = X509_get_subject_name(crt);
5418 if (!name)
5419 goto out;
David Safb76832014-05-08 23:42:08 -04005420
Emeric Brun0abf8362014-06-24 18:26:41 +02005421 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
5422out:
David Safb76832014-05-08 23:42:08 -04005423 if (crt)
5424 X509_free(crt);
5425
5426 return result;
5427}
5428
Dave McCowan328fb582014-07-30 10:39:13 -04005429/* returns 1 if client passed a certificate for this session, 0 if not */
5430int ssl_sock_get_cert_used_sess(struct connection *conn)
5431{
5432 X509 *crt = NULL;
5433
5434 if (!ssl_sock_is_ssl(conn))
5435 return 0;
5436
5437 /* SSL_get_peer_certificate, it increase X509 * ref count */
5438 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5439 if (!crt)
5440 return 0;
5441
5442 X509_free(crt);
5443 return 1;
5444}
5445
5446/* returns 1 if client passed a certificate for this connection, 0 if not */
5447int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04005448{
5449 if (!ssl_sock_is_ssl(conn))
5450 return 0;
5451
5452 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
5453}
5454
5455/* returns result from SSL verify */
5456unsigned int ssl_sock_get_verify_result(struct connection *conn)
5457{
5458 if (!ssl_sock_is_ssl(conn))
5459 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
5460
5461 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
5462}
5463
Willy Tarreau8743f7e2016-12-04 18:44:29 +01005464/* Returns the application layer protocol name in <str> and <len> when known.
5465 * Zero is returned if the protocol name was not found, otherwise non-zero is
5466 * returned. The string is allocated in the SSL context and doesn't have to be
5467 * freed by the caller. NPN is also checked if available since older versions
5468 * of openssl (1.0.1) which are more common in field only support this one.
5469 */
5470static int ssl_sock_get_alpn(const struct connection *conn, const char **str, int *len)
5471{
5472 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5473 return 0;
5474
5475 *str = NULL;
5476
5477#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
5478 SSL_get0_alpn_selected(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
5479 if (*str)
5480 return 1;
5481#endif
5482#ifdef OPENSSL_NPN_NEGOTIATED
5483 SSL_get0_next_proto_negotiated(conn->xprt_ctx, (const unsigned char **)str, (unsigned *)len);
5484 if (*str)
5485 return 1;
5486#endif
5487 return 0;
5488}
5489
Willy Tarreau7875d092012-09-10 08:20:03 +02005490/***** Below are some sample fetching functions for ACL/patterns *****/
5491
Emeric Brune64aef12012-09-21 13:15:06 +02005492/* boolean, returns true if client cert was present */
5493static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005494smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02005495{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005496 struct connection *conn;
5497
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005498 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005499 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02005500 return 0;
5501
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005502 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02005503 smp->flags |= SMP_F_MAY_CHANGE;
5504 return 0;
5505 }
5506
5507 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005508 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005509 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02005510
5511 return 1;
5512}
5513
Emeric Brun43e79582014-10-29 19:03:26 +01005514/* binary, returns a certificate in a binary chunk (der/raw).
5515 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5516 * should be use.
5517 */
5518static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005519smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01005520{
5521 int cert_peer = (kw[4] == 'c') ? 1 : 0;
5522 X509 *crt = NULL;
5523 int ret = 0;
5524 struct chunk *smp_trash;
5525 struct connection *conn;
5526
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005527 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01005528 if (!conn || conn->xprt != &ssl_sock)
5529 return 0;
5530
5531 if (!(conn->flags & CO_FL_CONNECTED)) {
5532 smp->flags |= SMP_F_MAY_CHANGE;
5533 return 0;
5534 }
5535
5536 if (cert_peer)
5537 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5538 else
5539 crt = SSL_get_certificate(conn->xprt_ctx);
5540
5541 if (!crt)
5542 goto out;
5543
5544 smp_trash = get_trash_chunk();
5545 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
5546 goto out;
5547
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005548 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005549 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01005550 ret = 1;
5551out:
5552 /* SSL_get_peer_certificate, it increase X509 * ref count */
5553 if (cert_peer && crt)
5554 X509_free(crt);
5555 return ret;
5556}
5557
Emeric Brunba841a12014-04-30 17:05:08 +02005558/* binary, returns serial of certificate in a binary chunk.
5559 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5560 * should be use.
5561 */
Willy Tarreau8d598402012-10-22 17:58:39 +02005562static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005563smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02005564{
Emeric Brunba841a12014-04-30 17:05:08 +02005565 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02005566 X509 *crt = NULL;
5567 int ret = 0;
5568 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005569 struct connection *conn;
5570
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005571 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005572 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02005573 return 0;
5574
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005575 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02005576 smp->flags |= SMP_F_MAY_CHANGE;
5577 return 0;
5578 }
5579
Emeric Brunba841a12014-04-30 17:05:08 +02005580 if (cert_peer)
5581 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5582 else
5583 crt = SSL_get_certificate(conn->xprt_ctx);
5584
Willy Tarreau8d598402012-10-22 17:58:39 +02005585 if (!crt)
5586 goto out;
5587
Willy Tarreau47ca5452012-12-23 20:22:19 +01005588 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005589 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5590 goto out;
5591
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005592 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005593 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005594 ret = 1;
5595out:
Emeric Brunba841a12014-04-30 17:05:08 +02005596 /* SSL_get_peer_certificate, it increase X509 * ref count */
5597 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005598 X509_free(crt);
5599 return ret;
5600}
Emeric Brune64aef12012-09-21 13:15:06 +02005601
Emeric Brunba841a12014-04-30 17:05:08 +02005602/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5603 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5604 * should be use.
5605 */
James Votha051b4a2013-05-14 20:37:59 +02005606static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005607smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005608{
Emeric Brunba841a12014-04-30 17:05:08 +02005609 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005610 X509 *crt = NULL;
5611 const EVP_MD *digest;
5612 int ret = 0;
5613 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005614 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005615
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005616 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005617 if (!conn || conn->xprt != &ssl_sock)
5618 return 0;
5619
5620 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005621 smp->flags |= SMP_F_MAY_CHANGE;
5622 return 0;
5623 }
5624
Emeric Brunba841a12014-04-30 17:05:08 +02005625 if (cert_peer)
5626 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5627 else
5628 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005629 if (!crt)
5630 goto out;
5631
5632 smp_trash = get_trash_chunk();
5633 digest = EVP_sha1();
5634 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5635
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005636 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005637 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005638 ret = 1;
5639out:
Emeric Brunba841a12014-04-30 17:05:08 +02005640 /* SSL_get_peer_certificate, it increase X509 * ref count */
5641 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005642 X509_free(crt);
5643 return ret;
5644}
5645
Emeric Brunba841a12014-04-30 17:05:08 +02005646/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5647 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5648 * should be use.
5649 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005650static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005651smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005652{
Emeric Brunba841a12014-04-30 17:05:08 +02005653 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005654 X509 *crt = NULL;
5655 int ret = 0;
5656 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005657 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005658
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005659 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005660 if (!conn || conn->xprt != &ssl_sock)
5661 return 0;
5662
5663 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005664 smp->flags |= SMP_F_MAY_CHANGE;
5665 return 0;
5666 }
5667
Emeric Brunba841a12014-04-30 17:05:08 +02005668 if (cert_peer)
5669 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5670 else
5671 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005672 if (!crt)
5673 goto out;
5674
Willy Tarreau47ca5452012-12-23 20:22:19 +01005675 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005676 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5677 goto out;
5678
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005679 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005680 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005681 ret = 1;
5682out:
Emeric Brunba841a12014-04-30 17:05:08 +02005683 /* SSL_get_peer_certificate, it increase X509 * ref count */
5684 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005685 X509_free(crt);
5686 return ret;
5687}
5688
Emeric Brunba841a12014-04-30 17:05:08 +02005689/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5690 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5691 * should be use.
5692 */
Emeric Brun87855892012-10-17 17:39:35 +02005693static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005694smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005695{
Emeric Brunba841a12014-04-30 17:05:08 +02005696 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005697 X509 *crt = NULL;
5698 X509_NAME *name;
5699 int ret = 0;
5700 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005701 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005702
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005703 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005704 if (!conn || conn->xprt != &ssl_sock)
5705 return 0;
5706
5707 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005708 smp->flags |= SMP_F_MAY_CHANGE;
5709 return 0;
5710 }
5711
Emeric Brunba841a12014-04-30 17:05:08 +02005712 if (cert_peer)
5713 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5714 else
5715 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005716 if (!crt)
5717 goto out;
5718
5719 name = X509_get_issuer_name(crt);
5720 if (!name)
5721 goto out;
5722
Willy Tarreau47ca5452012-12-23 20:22:19 +01005723 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005724 if (args && args[0].type == ARGT_STR) {
5725 int pos = 1;
5726
5727 if (args[1].type == ARGT_SINT)
5728 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005729
5730 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5731 goto out;
5732 }
5733 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5734 goto out;
5735
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005736 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005737 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005738 ret = 1;
5739out:
Emeric Brunba841a12014-04-30 17:05:08 +02005740 /* SSL_get_peer_certificate, it increase X509 * ref count */
5741 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005742 X509_free(crt);
5743 return ret;
5744}
5745
Emeric Brunba841a12014-04-30 17:05:08 +02005746/* string, returns notbefore date in ASN1_UTCTIME format.
5747 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5748 * should be use.
5749 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005750static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005751smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005752{
Emeric Brunba841a12014-04-30 17:05:08 +02005753 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005754 X509 *crt = NULL;
5755 int ret = 0;
5756 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005757 struct connection *conn;
5758
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005759 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005760 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005761 return 0;
5762
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005763 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005764 smp->flags |= SMP_F_MAY_CHANGE;
5765 return 0;
5766 }
5767
Emeric Brunba841a12014-04-30 17:05:08 +02005768 if (cert_peer)
5769 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5770 else
5771 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005772 if (!crt)
5773 goto out;
5774
Willy Tarreau47ca5452012-12-23 20:22:19 +01005775 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005776 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5777 goto out;
5778
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005779 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005780 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005781 ret = 1;
5782out:
Emeric Brunba841a12014-04-30 17:05:08 +02005783 /* SSL_get_peer_certificate, it increase X509 * ref count */
5784 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005785 X509_free(crt);
5786 return ret;
5787}
5788
Emeric Brunba841a12014-04-30 17:05:08 +02005789/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5790 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5791 * should be use.
5792 */
Emeric Brun87855892012-10-17 17:39:35 +02005793static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005794smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005795{
Emeric Brunba841a12014-04-30 17:05:08 +02005796 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005797 X509 *crt = NULL;
5798 X509_NAME *name;
5799 int ret = 0;
5800 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005801 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005802
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005803 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005804 if (!conn || conn->xprt != &ssl_sock)
5805 return 0;
5806
5807 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005808 smp->flags |= SMP_F_MAY_CHANGE;
5809 return 0;
5810 }
5811
Emeric Brunba841a12014-04-30 17:05:08 +02005812 if (cert_peer)
5813 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5814 else
5815 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005816 if (!crt)
5817 goto out;
5818
5819 name = X509_get_subject_name(crt);
5820 if (!name)
5821 goto out;
5822
Willy Tarreau47ca5452012-12-23 20:22:19 +01005823 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005824 if (args && args[0].type == ARGT_STR) {
5825 int pos = 1;
5826
5827 if (args[1].type == ARGT_SINT)
5828 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005829
5830 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5831 goto out;
5832 }
5833 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5834 goto out;
5835
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005836 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005837 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005838 ret = 1;
5839out:
Emeric Brunba841a12014-04-30 17:05:08 +02005840 /* SSL_get_peer_certificate, it increase X509 * ref count */
5841 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005842 X509_free(crt);
5843 return ret;
5844}
Emeric Brun9143d372012-12-20 15:44:16 +01005845
5846/* integer, returns true if current session use a client certificate */
5847static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005848smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005849{
5850 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005851 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005852
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005853 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005854 if (!conn || conn->xprt != &ssl_sock)
5855 return 0;
5856
5857 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005858 smp->flags |= SMP_F_MAY_CHANGE;
5859 return 0;
5860 }
5861
5862 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005863 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005864 if (crt) {
5865 X509_free(crt);
5866 }
5867
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005868 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005869 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005870 return 1;
5871}
5872
Emeric Brunba841a12014-04-30 17:05:08 +02005873/* integer, returns the certificate version
5874 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5875 * should be use.
5876 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005877static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005878smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005879{
Emeric Brunba841a12014-04-30 17:05:08 +02005880 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005881 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005882 struct connection *conn;
5883
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005884 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005885 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005886 return 0;
5887
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005888 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005889 smp->flags |= SMP_F_MAY_CHANGE;
5890 return 0;
5891 }
5892
Emeric Brunba841a12014-04-30 17:05:08 +02005893 if (cert_peer)
5894 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5895 else
5896 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005897 if (!crt)
5898 return 0;
5899
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005900 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005901 /* SSL_get_peer_certificate increase X509 * ref count */
5902 if (cert_peer)
5903 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005904 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005905
5906 return 1;
5907}
5908
Emeric Brunba841a12014-04-30 17:05:08 +02005909/* string, returns the certificate's signature algorithm.
5910 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5911 * should be use.
5912 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005913static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005914smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005915{
Emeric Brunba841a12014-04-30 17:05:08 +02005916 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005917 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005918 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005919 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005920 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005921
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005922 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005923 if (!conn || conn->xprt != &ssl_sock)
5924 return 0;
5925
5926 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005927 smp->flags |= SMP_F_MAY_CHANGE;
5928 return 0;
5929 }
5930
Emeric Brunba841a12014-04-30 17:05:08 +02005931 if (cert_peer)
5932 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5933 else
5934 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005935 if (!crt)
5936 return 0;
5937
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005938 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5939 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005940
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005941 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5942 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005943 /* SSL_get_peer_certificate increase X509 * ref count */
5944 if (cert_peer)
5945 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005946 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005947 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005948
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005949 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005950 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005951 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005952 /* SSL_get_peer_certificate increase X509 * ref count */
5953 if (cert_peer)
5954 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005955
5956 return 1;
5957}
5958
Emeric Brunba841a12014-04-30 17:05:08 +02005959/* string, returns the certificate's key algorithm.
5960 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5961 * should be use.
5962 */
Emeric Brun521a0112012-10-22 12:22:55 +02005963static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005964smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005965{
Emeric Brunba841a12014-04-30 17:05:08 +02005966 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005967 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005968 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005969 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005970 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005971
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005972 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005973 if (!conn || conn->xprt != &ssl_sock)
5974 return 0;
5975
5976 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005977 smp->flags |= SMP_F_MAY_CHANGE;
5978 return 0;
5979 }
5980
Emeric Brunba841a12014-04-30 17:05:08 +02005981 if (cert_peer)
5982 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5983 else
5984 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005985 if (!crt)
5986 return 0;
5987
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005988 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5989 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005990
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005991 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5992 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005993 /* SSL_get_peer_certificate increase X509 * ref count */
5994 if (cert_peer)
5995 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005996 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005997 }
Emeric Brun521a0112012-10-22 12:22:55 +02005998
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005999 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006000 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006001 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02006002 if (cert_peer)
6003 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02006004
6005 return 1;
6006}
6007
Emeric Brun645ae792014-04-30 14:21:06 +02006008/* boolean, returns true if front conn. transport layer is SSL.
6009 * This function is also usable on backend conn if the fetch keyword 5th
6010 * char is 'b'.
6011 */
Willy Tarreau7875d092012-09-10 08:20:03 +02006012static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006013smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006014{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006015 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6016 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006017
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006018 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006019 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02006020 return 1;
6021}
6022
Emeric Brun2525b6b2012-10-18 15:59:43 +02006023/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02006024static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006025smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006026{
6027#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006028 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006029
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006030 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006031 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006032 conn->xprt_ctx &&
6033 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02006034 return 1;
6035#else
6036 return 0;
6037#endif
6038}
6039
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02006040/* boolean, returns true if client session has been resumed */
6041static int
6042smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
6043{
6044 struct connection *conn = objt_conn(smp->sess->origin);
6045
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006046 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006047 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02006048 conn->xprt_ctx &&
6049 SSL_session_reused(conn->xprt_ctx);
6050 return 1;
6051}
6052
Emeric Brun645ae792014-04-30 14:21:06 +02006053/* string, returns the used cipher if front conn. transport layer is SSL.
6054 * This function is also usable on backend conn if the fetch keyword 5th
6055 * char is 'b'.
6056 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006057static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006058smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006059{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006060 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6061 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02006062
Willy Tarreaube508f12016-03-10 11:47:01 +01006063 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006064 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02006065 return 0;
6066
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006067 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
6068 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006069 return 0;
6070
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006071 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006072 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006073 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006074
6075 return 1;
6076}
6077
Emeric Brun645ae792014-04-30 14:21:06 +02006078/* integer, returns the algoritm's keysize if front conn. transport layer
6079 * is SSL.
6080 * This function is also usable on backend conn if the fetch keyword 5th
6081 * char is 'b'.
6082 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006083static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006084smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006085{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006086 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6087 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006088
Willy Tarreaue237fe12016-03-10 17:05:28 +01006089 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01006090
Emeric Brun589fcad2012-10-16 14:13:26 +02006091 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006092 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02006093 return 0;
6094
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006095 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006096 return 0;
6097
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006098 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006099 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02006100
6101 return 1;
6102}
6103
Emeric Brun645ae792014-04-30 14:21:06 +02006104/* integer, returns the used keysize if front conn. transport layer is SSL.
6105 * This function is also usable on backend conn if the fetch keyword 5th
6106 * char is 'b'.
6107 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006108static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006109smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006110{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006111 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6112 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006113
Emeric Brun589fcad2012-10-16 14:13:26 +02006114 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006115 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6116 return 0;
6117
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006118 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
6119 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02006120 return 0;
6121
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006122 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02006123
6124 return 1;
6125}
6126
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006127#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02006128static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006129smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +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 Tarreaua33c6542012-10-15 13:19:06 +02006135
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006136 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006137 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6138 return 0;
6139
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006140 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006141 SSL_get0_next_proto_negotiated(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 Tarreaua33c6542012-10-15 13:19:06 +02006143
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006144 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02006145 return 0;
6146
6147 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02006148}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006149#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02006150
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006151#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006152static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006153smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02006154{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006155 struct connection *conn;
6156
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006157 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006158 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02006159
Willy Tarreaue26bf052015-05-12 10:30:12 +02006160 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006161 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02006162 return 0;
6163
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006164 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006165 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006166 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02006167
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006168 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02006169 return 0;
6170
6171 return 1;
6172}
6173#endif
6174
Emeric Brun645ae792014-04-30 14:21:06 +02006175/* string, returns the used protocol if front conn. transport layer is SSL.
6176 * This function is also usable on backend conn if the fetch keyword 5th
6177 * char is 'b'.
6178 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02006179static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006180smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006181{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006182 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6183 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006184
Emeric Brun589fcad2012-10-16 14:13:26 +02006185 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006186 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6187 return 0;
6188
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006189 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
6190 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006191 return 0;
6192
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006193 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006194 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006195 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006196
6197 return 1;
6198}
6199
Willy Tarreau87b09662015-04-03 00:22:06 +02006200/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02006201 * This function is also usable on backend conn if the fetch keyword 5th
6202 * char is 'b'.
6203 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006204static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006205smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02006206{
6207#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006208 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6209 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02006210
Willy Tarreaue237fe12016-03-10 17:05:28 +01006211 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01006212
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006213 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006214 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02006215
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006216 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6217 return 0;
6218
Willy Tarreau192252e2015-04-04 01:47:55 +02006219 ssl_sess = SSL_get_session(conn->xprt_ctx);
6220 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02006221 return 0;
6222
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006223 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
6224 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02006225 return 0;
6226
6227 return 1;
6228#else
6229 return 0;
6230#endif
6231}
6232
6233static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006234smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006235{
6236#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006237 struct connection *conn;
6238
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006239 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006240 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02006241
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006242 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006243 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6244 return 0;
6245
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006246 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
6247 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02006248 return 0;
6249
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006250 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02006251 return 1;
6252#else
6253 return 0;
6254#endif
6255}
6256
David Sc1ad52e2014-04-08 18:48:47 -04006257static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006258smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
6259{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006260 struct connection *conn;
6261 struct ssl_capture *capture;
6262
6263 conn = objt_conn(smp->sess->origin);
6264 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6265 return 0;
6266
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006267 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006268 if (!capture)
6269 return 0;
6270
6271 smp->flags = SMP_F_CONST;
6272 smp->data.type = SMP_T_BIN;
6273 smp->data.u.str.str = capture->ciphersuite;
6274 smp->data.u.str.len = capture->ciphersuite_len;
6275 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006276}
6277
6278static int
6279smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
6280{
6281 struct chunk *data;
6282
6283 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6284 return 0;
6285
6286 data = get_trash_chunk();
6287 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
6288 smp->data.type = SMP_T_BIN;
6289 smp->data.u.str = *data;
6290 return 1;
6291}
6292
6293static int
6294smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
6295{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006296 struct connection *conn;
6297 struct ssl_capture *capture;
6298
6299 conn = objt_conn(smp->sess->origin);
6300 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6301 return 0;
6302
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006303 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006304 if (!capture)
6305 return 0;
6306
6307 smp->data.type = SMP_T_SINT;
6308 smp->data.u.sint = capture->xxh64;
6309 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006310}
6311
6312static int
6313smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
6314{
6315#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
6316 struct chunk *data;
6317 SSL_CIPHER cipher;
6318 int i;
6319 const char *str;
6320 unsigned char *bin;
6321
6322 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6323 return 0;
6324
6325 /* The cipher algorith must not be SSL_SSLV2, because this
6326 * SSL version seems to not have the same cipher encoding,
6327 * and it is not supported by OpenSSL. Unfortunately, the
6328 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
6329 * with standard defines. We just set the variable to 0,
6330 * ensure that the match with SSL_SSLV2 fails.
6331 */
6332 cipher.algorithm_ssl = 0;
6333
6334 data = get_trash_chunk();
6335 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
6336 bin = (unsigned char *)smp->data.u.str.str + i;
6337 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
6338 str = SSL_CIPHER_standard_name(&cipher);
6339 if (!str || strcmp(str, "UNKNOWN") == 0)
6340 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
6341 else
6342 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
6343 }
6344 smp->data.type = SMP_T_STR;
6345 smp->data.u.str = *data;
6346 return 1;
6347#else
6348 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
6349#endif
6350}
6351
6352static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006353smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04006354{
6355#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006356 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6357 smp->strm ? smp->strm->si[1].end : NULL);
6358
David Sc1ad52e2014-04-08 18:48:47 -04006359 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04006360 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04006361
6362 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04006363 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6364 return 0;
6365
6366 if (!(conn->flags & CO_FL_CONNECTED)) {
6367 smp->flags |= SMP_F_MAY_CHANGE;
6368 return 0;
6369 }
6370
6371 finished_trash = get_trash_chunk();
6372 if (!SSL_session_reused(conn->xprt_ctx))
6373 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6374 else
6375 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6376
6377 if (!finished_len)
6378 return 0;
6379
Emeric Brunb73a9b02014-04-30 18:49:19 +02006380 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006381 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006382 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04006383
6384 return 1;
6385#else
6386 return 0;
6387#endif
6388}
6389
Emeric Brun2525b6b2012-10-18 15:59:43 +02006390/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006391static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006392smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006393{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006394 struct connection *conn;
6395
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006396 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006397 if (!conn || conn->xprt != &ssl_sock)
6398 return 0;
6399
6400 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006401 smp->flags = SMP_F_MAY_CHANGE;
6402 return 0;
6403 }
6404
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006405 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006406 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006407 smp->flags = 0;
6408
6409 return 1;
6410}
6411
Emeric Brun2525b6b2012-10-18 15:59:43 +02006412/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006413static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006414smp_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 +02006415{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006416 struct connection *conn;
6417
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006418 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006419 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02006420 return 0;
6421
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006422 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006423 smp->flags = SMP_F_MAY_CHANGE;
6424 return 0;
6425 }
6426
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006427 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006428 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006429 smp->flags = 0;
6430
6431 return 1;
6432}
6433
Emeric Brun2525b6b2012-10-18 15:59:43 +02006434/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02006435static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006436smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006437{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006438 struct connection *conn;
6439
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006440 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006441 if (!conn || conn->xprt != &ssl_sock)
6442 return 0;
6443
6444 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006445 smp->flags = SMP_F_MAY_CHANGE;
6446 return 0;
6447 }
6448
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006449 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006450 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006451 smp->flags = 0;
6452
6453 return 1;
6454}
6455
Emeric Brun2525b6b2012-10-18 15:59:43 +02006456/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006457static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006458smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006459{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006460 struct connection *conn;
6461
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006462 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006463 if (!conn || conn->xprt != &ssl_sock)
6464 return 0;
6465
6466 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006467 smp->flags = SMP_F_MAY_CHANGE;
6468 return 0;
6469 }
6470
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006471 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006472 return 0;
6473
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006474 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006475 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006476 smp->flags = 0;
6477
6478 return 1;
6479}
6480
Emeric Brunfb510ea2012-10-05 12:00:26 +02006481/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006482static 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 +02006483{
6484 if (!*args[cur_arg + 1]) {
6485 if (err)
6486 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6487 return ERR_ALERT | ERR_FATAL;
6488 }
6489
Willy Tarreauef934602016-12-22 23:12:01 +01006490 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6491 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006492 else
6493 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006494
Emeric Brund94b3fe2012-09-20 18:23:56 +02006495 return 0;
6496}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006497static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6498{
6499 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
6500}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006501
Christopher Faulet31af49d2015-06-09 17:29:50 +02006502/* parse the "ca-sign-file" bind keyword */
6503static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6504{
6505 if (!*args[cur_arg + 1]) {
6506 if (err)
6507 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6508 return ERR_ALERT | ERR_FATAL;
6509 }
6510
Willy Tarreauef934602016-12-22 23:12:01 +01006511 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6512 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02006513 else
6514 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
6515
6516 return 0;
6517}
6518
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006519/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006520static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6521{
6522 if (!*args[cur_arg + 1]) {
6523 if (err)
6524 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
6525 return ERR_ALERT | ERR_FATAL;
6526 }
6527 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
6528 return 0;
6529}
6530
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006531/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006532static 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 +02006533{
6534 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006535 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006536 return ERR_ALERT | ERR_FATAL;
6537 }
6538
Emeric Brun76d88952012-10-05 15:47:31 +02006539 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02006540 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006541 return 0;
6542}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006543static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6544{
6545 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
6546}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006547/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006548static 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 +02006549{
Willy Tarreau38011032013-08-13 16:59:39 +02006550 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02006551
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006552 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006553 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006554 return ERR_ALERT | ERR_FATAL;
6555 }
6556
Willy Tarreauef934602016-12-22 23:12:01 +01006557 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
6558 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02006559 memprintf(err, "'%s' : path too long", args[cur_arg]);
6560 return ERR_ALERT | ERR_FATAL;
6561 }
Willy Tarreauef934602016-12-22 23:12:01 +01006562 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01006563 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02006564 return ERR_ALERT | ERR_FATAL;
6565
6566 return 0;
6567 }
6568
Willy Tarreau03209342016-12-22 17:08:28 +01006569 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006570 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006571
6572 return 0;
6573}
6574
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006575/* parse the "crt-list" bind keyword */
6576static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6577{
6578 if (!*args[cur_arg + 1]) {
6579 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
6580 return ERR_ALERT | ERR_FATAL;
6581 }
6582
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006583 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006584 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006585 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006586 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006587
6588 return 0;
6589}
6590
Emeric Brunfb510ea2012-10-05 12:00:26 +02006591/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006592static 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 +02006593{
Emeric Brun051cdab2012-10-02 19:25:50 +02006594#ifndef X509_V_FLAG_CRL_CHECK
6595 if (err)
6596 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6597 return ERR_ALERT | ERR_FATAL;
6598#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006599 if (!*args[cur_arg + 1]) {
6600 if (err)
6601 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6602 return ERR_ALERT | ERR_FATAL;
6603 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006604
Willy Tarreauef934602016-12-22 23:12:01 +01006605 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6606 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006607 else
6608 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006609
Emeric Brun2b58d042012-09-20 17:10:03 +02006610 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006611#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006612}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006613static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6614{
6615 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6616}
Emeric Brun2b58d042012-09-20 17:10:03 +02006617
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006618/* parse the "curves" bind keyword keyword */
6619static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6620{
6621#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6622 if (!*args[cur_arg + 1]) {
6623 if (err)
6624 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6625 return ERR_ALERT | ERR_FATAL;
6626 }
6627 conf->curves = strdup(args[cur_arg + 1]);
6628 return 0;
6629#else
6630 if (err)
6631 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6632 return ERR_ALERT | ERR_FATAL;
6633#endif
6634}
6635static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6636{
6637 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6638}
6639
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006640/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006641static 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 +02006642{
6643#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6644 if (err)
6645 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6646 return ERR_ALERT | ERR_FATAL;
6647#elif defined(OPENSSL_NO_ECDH)
6648 if (err)
6649 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6650 return ERR_ALERT | ERR_FATAL;
6651#else
6652 if (!*args[cur_arg + 1]) {
6653 if (err)
6654 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6655 return ERR_ALERT | ERR_FATAL;
6656 }
6657
6658 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006659
6660 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006661#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006662}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006663static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6664{
6665 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6666}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006667
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006668/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006669static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6670{
6671 int code;
6672 char *p = args[cur_arg + 1];
6673 unsigned long long *ignerr = &conf->crt_ignerr;
6674
6675 if (!*p) {
6676 if (err)
6677 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6678 return ERR_ALERT | ERR_FATAL;
6679 }
6680
6681 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6682 ignerr = &conf->ca_ignerr;
6683
6684 if (strcmp(p, "all") == 0) {
6685 *ignerr = ~0ULL;
6686 return 0;
6687 }
6688
6689 while (p) {
6690 code = atoi(p);
6691 if ((code <= 0) || (code > 63)) {
6692 if (err)
6693 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6694 args[cur_arg], code, args[cur_arg + 1]);
6695 return ERR_ALERT | ERR_FATAL;
6696 }
6697 *ignerr |= 1ULL << code;
6698 p = strchr(p, ',');
6699 if (p)
6700 p++;
6701 }
6702
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006703 return 0;
6704}
6705
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006706/* parse tls_method_options "no-xxx" and "force-xxx" */
6707static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006708{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006709 uint16_t v;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006710 char *p;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006711 p = strchr(arg, '-');
6712 if (!p)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006713 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006714 p++;
6715 if (!strcmp(p, "sslv3"))
6716 v = CONF_SSLV3;
6717 else if (!strcmp(p, "tlsv10"))
6718 v = CONF_TLSV10;
6719 else if (!strcmp(p, "tlsv11"))
6720 v = CONF_TLSV11;
6721 else if (!strcmp(p, "tlsv12"))
6722 v = CONF_TLSV12;
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02006723 else if (!strcmp(p, "tlsv13"))
6724 v = CONF_TLSV13;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006725 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006726 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006727 if (!strncmp(arg, "no-", 3))
6728 methods->flags |= methodVersions[v].flag;
6729 else if (!strncmp(arg, "force-", 6))
6730 methods->min = methods->max = v;
6731 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006732 goto fail;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006733 return 0;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006734 fail:
6735 if (err)
6736 memprintf(err, "'%s' : option not implemented", arg);
6737 return ERR_ALERT | ERR_FATAL;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006738}
6739
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006740static 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 +02006741{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006742 return parse_tls_method_options(args[cur_arg], &conf->ssl_methods, err);
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006743}
6744
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006745static 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 +02006746{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006747 return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
6748}
6749
6750/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
6751static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
6752{
6753 uint16_t i, v = 0;
6754 char *argv = args[cur_arg + 1];
6755 if (!*argv) {
6756 if (err)
6757 memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
6758 return ERR_ALERT | ERR_FATAL;
6759 }
6760 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
6761 if (!strcmp(argv, methodVersions[i].name))
6762 v = i;
6763 if (!v) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006764 if (err)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006765 memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006766 return ERR_ALERT | ERR_FATAL;
6767 }
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006768 if (!strcmp("ssl-min-ver", args[cur_arg]))
6769 methods->min = v;
6770 else if (!strcmp("ssl-max-ver", args[cur_arg]))
6771 methods->max = v;
6772 else {
6773 if (err)
6774 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
6775 return ERR_ALERT | ERR_FATAL;
6776 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006777 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006778}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006779
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02006780static int ssl_bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6781{
6782#if !defined(OPENSSL_IS_BORINGSSL)
6783 Warning("crt-list: ssl-min-ver and ssl-max-ver are not supported with this Openssl version (skipped).\n");
6784#endif
6785 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6786}
6787
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006788static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6789{
6790 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6791}
6792
6793static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6794{
6795 return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
6796}
6797
Emeric Brun2d0c4822012-10-02 13:45:20 +02006798/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006799static 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 +02006800{
Emeric Brun89675492012-10-05 13:48:26 +02006801 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006802 return 0;
6803}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006804
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006805/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006806static 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 +02006807{
6808#ifdef OPENSSL_NPN_NEGOTIATED
6809 char *p1, *p2;
6810
6811 if (!*args[cur_arg + 1]) {
6812 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6813 return ERR_ALERT | ERR_FATAL;
6814 }
6815
6816 free(conf->npn_str);
6817
Willy Tarreau3724da12016-02-12 17:11:12 +01006818 /* the NPN string is built as a suite of (<len> <name>)*,
6819 * so we reuse each comma to store the next <len> and need
6820 * one more for the end of the string.
6821 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006822 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006823 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006824 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6825
6826 /* replace commas with the name length */
6827 p1 = conf->npn_str;
6828 p2 = p1 + 1;
6829 while (1) {
6830 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6831 if (!p2)
6832 p2 = p1 + 1 + strlen(p1 + 1);
6833
6834 if (p2 - (p1 + 1) > 255) {
6835 *p2 = '\0';
6836 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6837 return ERR_ALERT | ERR_FATAL;
6838 }
6839
6840 *p1 = p2 - (p1 + 1);
6841 p1 = p2;
6842
6843 if (!*p2)
6844 break;
6845
6846 *(p2++) = '\0';
6847 }
6848 return 0;
6849#else
6850 if (err)
6851 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6852 return ERR_ALERT | ERR_FATAL;
6853#endif
6854}
6855
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006856static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6857{
6858 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6859}
6860
Willy Tarreauab861d32013-04-02 02:30:41 +02006861/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006862static 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 +02006863{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006864#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006865 char *p1, *p2;
6866
6867 if (!*args[cur_arg + 1]) {
6868 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6869 return ERR_ALERT | ERR_FATAL;
6870 }
6871
6872 free(conf->alpn_str);
6873
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006874 /* the ALPN string is built as a suite of (<len> <name>)*,
6875 * so we reuse each comma to store the next <len> and need
6876 * one more for the end of the string.
6877 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006878 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006879 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006880 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6881
6882 /* replace commas with the name length */
6883 p1 = conf->alpn_str;
6884 p2 = p1 + 1;
6885 while (1) {
6886 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6887 if (!p2)
6888 p2 = p1 + 1 + strlen(p1 + 1);
6889
6890 if (p2 - (p1 + 1) > 255) {
6891 *p2 = '\0';
6892 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6893 return ERR_ALERT | ERR_FATAL;
6894 }
6895
6896 *p1 = p2 - (p1 + 1);
6897 p1 = p2;
6898
6899 if (!*p2)
6900 break;
6901
6902 *(p2++) = '\0';
6903 }
6904 return 0;
6905#else
6906 if (err)
6907 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6908 return ERR_ALERT | ERR_FATAL;
6909#endif
6910}
6911
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006912static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6913{
6914 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6915}
6916
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006917/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006918static 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 +02006919{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006920 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006921 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006922
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006923 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6924 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006925 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006926 conf->ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
6927 if (!conf->ssl_methods.min)
6928 conf->ssl_methods.min = global_ssl.listen_default_sslmethods.min;
6929 if (!conf->ssl_methods.max)
6930 conf->ssl_methods.max = global_ssl.listen_default_sslmethods.max;
Emeric Brun76d88952012-10-05 15:47:31 +02006931
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006932 return 0;
6933}
6934
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006935/* parse the "prefer-client-ciphers" bind keyword */
6936static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6937{
6938 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
6939 return 0;
6940}
6941
Christopher Faulet31af49d2015-06-09 17:29:50 +02006942/* parse the "generate-certificates" bind keyword */
6943static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6944{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006945#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006946 conf->generate_certs = 1;
6947#else
6948 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6949 err && *err ? *err : "");
6950#endif
6951 return 0;
6952}
6953
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006954/* parse the "strict-sni" bind keyword */
6955static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6956{
6957 conf->strict_sni = 1;
6958 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006959}
6960
6961/* parse the "tls-ticket-keys" bind keyword */
6962static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6963{
6964#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6965 FILE *f;
6966 int i = 0;
6967 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006968 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006969
6970 if (!*args[cur_arg + 1]) {
6971 if (err)
6972 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6973 return ERR_ALERT | ERR_FATAL;
6974 }
6975
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006976 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6977 if(keys_ref) {
6978 conf->keys_ref = keys_ref;
6979 return 0;
6980 }
6981
Vincent Bernat02779b62016-04-03 13:48:43 +02006982 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006983 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006984
6985 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6986 if (err)
6987 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6988 return ERR_ALERT | ERR_FATAL;
6989 }
6990
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006991 keys_ref->filename = strdup(args[cur_arg + 1]);
6992
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006993 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6994 int len = strlen(thisline);
6995 /* Strip newline characters from the end */
6996 if(thisline[len - 1] == '\n')
6997 thisline[--len] = 0;
6998
6999 if(thisline[len - 1] == '\r')
7000 thisline[--len] = 0;
7001
Nenad Merdanovic146defa2015-05-09 08:46:00 +02007002 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 +01007003 if (err)
7004 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02007005 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007006 return ERR_ALERT | ERR_FATAL;
7007 }
7008 i++;
7009 }
7010
7011 if (i < TLS_TICKETS_NO) {
7012 if (err)
7013 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 +02007014 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007015 return ERR_ALERT | ERR_FATAL;
7016 }
7017
7018 fclose(f);
7019
7020 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01007021 i -= 2;
7022 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02007023 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02007024 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007025
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02007026 LIST_ADD(&tlskeys_reference, &keys_ref->list);
7027
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007028 return 0;
7029#else
7030 if (err)
7031 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
7032 return ERR_ALERT | ERR_FATAL;
7033#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01007034}
7035
Emeric Brund94b3fe2012-09-20 18:23:56 +02007036/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007037static 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 +02007038{
7039 if (!*args[cur_arg + 1]) {
7040 if (err)
7041 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
7042 return ERR_ALERT | ERR_FATAL;
7043 }
7044
7045 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007046 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007047 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007048 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007049 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007050 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02007051 else {
7052 if (err)
7053 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
7054 args[cur_arg], args[cur_arg + 1]);
7055 return ERR_ALERT | ERR_FATAL;
7056 }
7057
7058 return 0;
7059}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007060static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
7061{
7062 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
7063}
Emeric Brund94b3fe2012-09-20 18:23:56 +02007064
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02007065/* parse the "no-ca-names" bind keyword */
7066static int ssl_bind_parse_no_ca_names(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
7067{
7068 conf->no_ca_names = 1;
7069 return 0;
7070}
7071static int bind_parse_no_ca_names(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
7072{
7073 return ssl_bind_parse_no_ca_names(args, cur_arg, px, &conf->ssl_conf, err);
7074}
7075
Willy Tarreau92faadf2012-10-10 23:04:25 +02007076/************** "server" keywords ****************/
7077
Emeric Brunef42d922012-10-11 16:11:36 +02007078/* parse the "ca-file" server keyword */
7079static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7080{
7081 if (!*args[*cur_arg + 1]) {
7082 if (err)
7083 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
7084 return ERR_ALERT | ERR_FATAL;
7085 }
7086
Willy Tarreauef934602016-12-22 23:12:01 +01007087 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
7088 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02007089 else
7090 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
7091
7092 return 0;
7093}
7094
Willy Tarreau92faadf2012-10-10 23:04:25 +02007095/* parse the "check-ssl" server keyword */
7096static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7097{
7098 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007099 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7100 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
7101 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007102 newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
7103 if (!newsrv->ssl_ctx.methods.min)
7104 newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
7105 if (!newsrv->ssl_ctx.methods.max)
7106 newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
7107
Willy Tarreau92faadf2012-10-10 23:04:25 +02007108 return 0;
7109}
7110
7111/* parse the "ciphers" server keyword */
7112static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7113{
7114 if (!*args[*cur_arg + 1]) {
7115 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
7116 return ERR_ALERT | ERR_FATAL;
7117 }
7118
7119 free(newsrv->ssl_ctx.ciphers);
7120 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
7121 return 0;
7122}
7123
Emeric Brunef42d922012-10-11 16:11:36 +02007124/* parse the "crl-file" server keyword */
7125static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7126{
7127#ifndef X509_V_FLAG_CRL_CHECK
7128 if (err)
7129 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
7130 return ERR_ALERT | ERR_FATAL;
7131#else
7132 if (!*args[*cur_arg + 1]) {
7133 if (err)
7134 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
7135 return ERR_ALERT | ERR_FATAL;
7136 }
7137
Willy Tarreauef934602016-12-22 23:12:01 +01007138 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
7139 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02007140 else
7141 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
7142
7143 return 0;
7144#endif
7145}
7146
Emeric Bruna7aa3092012-10-26 12:58:00 +02007147/* parse the "crt" server keyword */
7148static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7149{
7150 if (!*args[*cur_arg + 1]) {
7151 if (err)
7152 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
7153 return ERR_ALERT | ERR_FATAL;
7154 }
7155
Willy Tarreauef934602016-12-22 23:12:01 +01007156 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
7157 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02007158 else
7159 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
7160
7161 return 0;
7162}
Emeric Brunef42d922012-10-11 16:11:36 +02007163
Frédéric Lécaille340ae602017-03-13 10:38:04 +01007164/* parse the "no-check-ssl" server keyword */
7165static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7166{
7167 newsrv->check.use_ssl = 0;
7168 free(newsrv->ssl_ctx.ciphers);
7169 newsrv->ssl_ctx.ciphers = NULL;
7170 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
7171 return 0;
7172}
7173
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01007174/* parse the "no-send-proxy-v2-ssl" server keyword */
7175static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7176{
7177 newsrv->pp_opts &= ~SRV_PP_V2;
7178 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7179 return 0;
7180}
7181
7182/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
7183static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7184{
7185 newsrv->pp_opts &= ~SRV_PP_V2;
7186 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7187 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
7188 return 0;
7189}
7190
Frédéric Lécaillee381d762017-03-13 11:54:17 +01007191/* parse the "no-ssl" server keyword */
7192static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7193{
7194 newsrv->use_ssl = 0;
7195 free(newsrv->ssl_ctx.ciphers);
7196 newsrv->ssl_ctx.ciphers = NULL;
7197 return 0;
7198}
7199
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007200/* parse the "no-ssl-reuse" server keyword */
7201static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7202{
7203 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
7204 return 0;
7205}
7206
Emeric Brunf9c5c472012-10-11 15:28:34 +02007207/* parse the "no-tls-tickets" server keyword */
7208static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7209{
7210 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
7211 return 0;
7212}
David Safb76832014-05-08 23:42:08 -04007213/* parse the "send-proxy-v2-ssl" server keyword */
7214static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7215{
7216 newsrv->pp_opts |= SRV_PP_V2;
7217 newsrv->pp_opts |= SRV_PP_V2_SSL;
7218 return 0;
7219}
7220
7221/* parse the "send-proxy-v2-ssl-cn" server keyword */
7222static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7223{
7224 newsrv->pp_opts |= SRV_PP_V2;
7225 newsrv->pp_opts |= SRV_PP_V2_SSL;
7226 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
7227 return 0;
7228}
Emeric Brunf9c5c472012-10-11 15:28:34 +02007229
Willy Tarreau732eac42015-07-09 11:40:25 +02007230/* parse the "sni" server keyword */
7231static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7232{
7233#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
7234 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
7235 return ERR_ALERT | ERR_FATAL;
7236#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007237 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02007238
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007239 arg = args[*cur_arg + 1];
7240 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02007241 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
7242 return ERR_ALERT | ERR_FATAL;
7243 }
7244
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007245 free(newsrv->sni_expr);
7246 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02007247
Willy Tarreau732eac42015-07-09 11:40:25 +02007248 return 0;
7249#endif
7250}
7251
Willy Tarreau92faadf2012-10-10 23:04:25 +02007252/* parse the "ssl" server keyword */
7253static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7254{
7255 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007256 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7257 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007258 return 0;
7259}
7260
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007261/* parse the "ssl-reuse" server keyword */
7262static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7263{
7264 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
7265 return 0;
7266}
7267
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007268/* parse the "tls-tickets" server keyword */
7269static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7270{
7271 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
7272 return 0;
7273}
7274
Emeric Brunef42d922012-10-11 16:11:36 +02007275/* parse the "verify" server keyword */
7276static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7277{
7278 if (!*args[*cur_arg + 1]) {
7279 if (err)
7280 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
7281 return ERR_ALERT | ERR_FATAL;
7282 }
7283
7284 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007285 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02007286 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007287 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02007288 else {
7289 if (err)
7290 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
7291 args[*cur_arg], args[*cur_arg + 1]);
7292 return ERR_ALERT | ERR_FATAL;
7293 }
7294
Evan Broderbe554312013-06-27 00:05:25 -07007295 return 0;
7296}
7297
7298/* parse the "verifyhost" server keyword */
7299static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7300{
7301 if (!*args[*cur_arg + 1]) {
7302 if (err)
7303 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
7304 return ERR_ALERT | ERR_FATAL;
7305 }
7306
Frédéric Lécaille273f3212017-03-13 15:52:01 +01007307 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07007308 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
7309
Emeric Brunef42d922012-10-11 16:11:36 +02007310 return 0;
7311}
7312
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007313/* parse the "ssl-default-bind-options" keyword in global section */
7314static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
7315 struct proxy *defpx, const char *file, int line,
7316 char **err) {
7317 int i = 1;
7318
7319 if (*(args[i]) == 0) {
7320 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7321 return -1;
7322 }
7323 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007324 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007325 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Lukas Tribus53ae85c2017-05-04 15:45:40 +00007326 else if (!strcmp(args[i], "prefer-client-ciphers"))
7327 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007328 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7329 if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
7330 i++;
7331 else {
7332 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7333 return -1;
7334 }
7335 }
7336 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007337 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7338 return -1;
7339 }
7340 i++;
7341 }
7342 return 0;
7343}
7344
7345/* parse the "ssl-default-server-options" keyword in global section */
7346static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
7347 struct proxy *defpx, const char *file, int line,
7348 char **err) {
7349 int i = 1;
7350
7351 if (*(args[i]) == 0) {
7352 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7353 return -1;
7354 }
7355 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007356 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007357 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007358 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7359 if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
7360 i++;
7361 else {
7362 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7363 return -1;
7364 }
7365 }
7366 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007367 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7368 return -1;
7369 }
7370 i++;
7371 }
7372 return 0;
7373}
7374
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007375/* parse the "ca-base" / "crt-base" keywords in global section.
7376 * Returns <0 on alert, >0 on warning, 0 on success.
7377 */
7378static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
7379 struct proxy *defpx, const char *file, int line,
7380 char **err)
7381{
7382 char **target;
7383
Willy Tarreauef934602016-12-22 23:12:01 +01007384 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007385
7386 if (too_many_args(1, args, err, NULL))
7387 return -1;
7388
7389 if (*target) {
7390 memprintf(err, "'%s' already specified.", args[0]);
7391 return -1;
7392 }
7393
7394 if (*(args[1]) == 0) {
7395 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
7396 return -1;
7397 }
7398 *target = strdup(args[1]);
7399 return 0;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007400}
7401
7402/* parse the "ssl-mode-async" keyword in global section.
7403 * Returns <0 on alert, >0 on warning, 0 on success.
7404 */
7405static int ssl_parse_global_ssl_async(char **args, int section_type, struct proxy *curpx,
7406 struct proxy *defpx, const char *file, int line,
7407 char **err)
7408{
7409#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
7410 global_ssl.async = 1;
7411 return 0;
7412#else
7413 memprintf(err, "'%s': openssl library does not support async mode", args[0]);
7414 return -1;
7415#endif
7416}
7417
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007418#ifndef OPENSSL_NO_ENGINE
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007419static int ssl_check_async_engine_count(void) {
7420 int err_code = 0;
7421
Emeric Brun3854e012017-05-17 20:42:48 +02007422 if (global_ssl.async && (openssl_engines_initialized > 32)) {
7423 Alert("ssl-mode-async only supports a maximum of 32 engines.\n");
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007424 err_code = ERR_ABORT;
7425 }
7426 return err_code;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007427}
7428
Grant Zhang872f9c22017-01-21 01:10:18 +00007429/* parse the "ssl-engine" keyword in global section.
7430 * Returns <0 on alert, >0 on warning, 0 on success.
7431 */
7432static int ssl_parse_global_ssl_engine(char **args, int section_type, struct proxy *curpx,
7433 struct proxy *defpx, const char *file, int line,
7434 char **err)
7435{
7436 char *algo;
7437 int ret = -1;
7438
7439 if (*(args[1]) == 0) {
7440 memprintf(err, "global statement '%s' expects a valid engine name as an argument.", args[0]);
7441 return ret;
7442 }
7443
7444 if (*(args[2]) == 0) {
7445 /* if no list of algorithms is given, it defaults to ALL */
7446 algo = strdup("ALL");
7447 goto add_engine;
7448 }
7449
7450 /* otherwise the expected format is ssl-engine <engine_name> algo <list of algo> */
7451 if (strcmp(args[2], "algo") != 0) {
7452 memprintf(err, "global statement '%s' expects to have algo keyword.", args[0]);
7453 return ret;
7454 }
7455
7456 if (*(args[3]) == 0) {
7457 memprintf(err, "global statement '%s' expects algorithm names as an argument.", args[0]);
7458 return ret;
7459 }
7460 algo = strdup(args[3]);
7461
7462add_engine:
7463 if (ssl_init_single_engine(args[1], algo)==0) {
7464 openssl_engines_initialized++;
7465 ret = 0;
7466 }
7467 free(algo);
7468 return ret;
7469}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007470#endif
Grant Zhang872f9c22017-01-21 01:10:18 +00007471
Willy Tarreauf22e9682016-12-21 23:23:19 +01007472/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
7473 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
7474 */
7475static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
7476 struct proxy *defpx, const char *file, int line,
7477 char **err)
7478{
7479 char **target;
7480
Willy Tarreauef934602016-12-22 23:12:01 +01007481 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01007482
7483 if (too_many_args(1, args, err, NULL))
7484 return -1;
7485
7486 if (*(args[1]) == 0) {
7487 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
7488 return -1;
7489 }
7490
7491 free(*target);
7492 *target = strdup(args[1]);
7493 return 0;
7494}
7495
Willy Tarreau9ceda382016-12-21 23:13:03 +01007496/* parse various global tune.ssl settings consisting in positive integers.
7497 * Returns <0 on alert, >0 on warning, 0 on success.
7498 */
7499static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
7500 struct proxy *defpx, const char *file, int line,
7501 char **err)
7502{
7503 int *target;
7504
7505 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
7506 target = &global.tune.sslcachesize;
7507 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007508 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007509 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007510 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007511 else if (strcmp(args[0], "maxsslconn") == 0)
7512 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007513 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
7514 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007515 else {
7516 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
7517 return -1;
7518 }
7519
7520 if (too_many_args(1, args, err, NULL))
7521 return -1;
7522
7523 if (*(args[1]) == 0) {
7524 memprintf(err, "'%s' expects an integer argument.", args[0]);
7525 return -1;
7526 }
7527
7528 *target = atoi(args[1]);
7529 if (*target < 0) {
7530 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
7531 return -1;
7532 }
7533 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007534}
7535
7536static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
7537 struct proxy *defpx, const char *file, int line,
7538 char **err)
7539{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007540 int ret;
7541
7542 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
7543 if (ret != 0)
7544 return ret;
7545
7546 if (pool2_ssl_capture) {
7547 memprintf(err, "'%s' is already configured.", args[0]);
7548 return -1;
7549 }
7550
7551 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
7552 if (!pool2_ssl_capture) {
7553 memprintf(err, "Out of memory error.");
7554 return -1;
7555 }
7556 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007557}
7558
7559/* parse "ssl.force-private-cache".
7560 * Returns <0 on alert, >0 on warning, 0 on success.
7561 */
7562static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
7563 struct proxy *defpx, const char *file, int line,
7564 char **err)
7565{
7566 if (too_many_args(0, args, err, NULL))
7567 return -1;
7568
Willy Tarreauef934602016-12-22 23:12:01 +01007569 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007570 return 0;
7571}
7572
7573/* parse "ssl.lifetime".
7574 * Returns <0 on alert, >0 on warning, 0 on success.
7575 */
7576static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
7577 struct proxy *defpx, const char *file, int line,
7578 char **err)
7579{
7580 const char *res;
7581
7582 if (too_many_args(1, args, err, NULL))
7583 return -1;
7584
7585 if (*(args[1]) == 0) {
7586 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
7587 return -1;
7588 }
7589
Willy Tarreauef934602016-12-22 23:12:01 +01007590 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01007591 if (res) {
7592 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
7593 return -1;
7594 }
7595 return 0;
7596}
7597
7598#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01007599/* parse "ssl-dh-param-file".
7600 * Returns <0 on alert, >0 on warning, 0 on success.
7601 */
7602static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
7603 struct proxy *defpx, const char *file, int line,
7604 char **err)
7605{
7606 if (too_many_args(1, args, err, NULL))
7607 return -1;
7608
7609 if (*(args[1]) == 0) {
7610 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
7611 return -1;
7612 }
7613
7614 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
7615 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
7616 return -1;
7617 }
7618 return 0;
7619}
7620
Willy Tarreau9ceda382016-12-21 23:13:03 +01007621/* parse "ssl.default-dh-param".
7622 * Returns <0 on alert, >0 on warning, 0 on success.
7623 */
7624static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
7625 struct proxy *defpx, const char *file, int line,
7626 char **err)
7627{
7628 if (too_many_args(1, args, err, NULL))
7629 return -1;
7630
7631 if (*(args[1]) == 0) {
7632 memprintf(err, "'%s' expects an integer argument.", args[0]);
7633 return -1;
7634 }
7635
Willy Tarreauef934602016-12-22 23:12:01 +01007636 global_ssl.default_dh_param = atoi(args[1]);
7637 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01007638 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
7639 return -1;
7640 }
7641 return 0;
7642}
7643#endif
7644
7645
William Lallemand32af2032016-10-29 18:09:35 +02007646/* This function is used with TLS ticket keys management. It permits to browse
7647 * each reference. The variable <getnext> must contain the current node,
7648 * <end> point to the root node.
7649 */
7650#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7651static inline
7652struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
7653{
7654 struct tls_keys_ref *ref = getnext;
7655
7656 while (1) {
7657
7658 /* Get next list entry. */
7659 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
7660
7661 /* If the entry is the last of the list, return NULL. */
7662 if (&ref->list == end)
7663 return NULL;
7664
7665 return ref;
7666 }
7667}
7668
7669static inline
7670struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7671{
7672 int id;
7673 char *error;
7674
7675 /* If the reference starts by a '#', this is numeric id. */
7676 if (reference[0] == '#') {
7677 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7678 id = strtol(reference + 1, &error, 10);
7679 if (*error != '\0')
7680 return NULL;
7681
7682 /* Perform the unique id lookup. */
7683 return tlskeys_ref_lookupid(id);
7684 }
7685
7686 /* Perform the string lookup. */
7687 return tlskeys_ref_lookup(reference);
7688}
7689#endif
7690
7691
7692#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7693
7694static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7695
7696static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7697 return cli_io_handler_tlskeys_files(appctx);
7698}
7699
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007700/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7701 * (next index to be dumped), and cli.p0 (next key reference).
7702 */
William Lallemand32af2032016-10-29 18:09:35 +02007703static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7704
7705 struct stream_interface *si = appctx->owner;
7706
7707 switch (appctx->st2) {
7708 case STAT_ST_INIT:
7709 /* Display the column headers. If the message cannot be sent,
7710 * quit the fucntion with returning 0. The function is called
7711 * later and restart at the state "STAT_ST_INIT".
7712 */
7713 chunk_reset(&trash);
7714
7715 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7716 chunk_appendf(&trash, "# id secret\n");
7717 else
7718 chunk_appendf(&trash, "# id (file)\n");
7719
7720 if (bi_putchk(si_ic(si), &trash) == -1) {
7721 si_applet_cant_put(si);
7722 return 0;
7723 }
7724
William Lallemand32af2032016-10-29 18:09:35 +02007725 /* Now, we start the browsing of the references lists.
7726 * Note that the following call to LIST_ELEM return bad pointer. The only
7727 * available field of this pointer is <list>. It is used with the function
7728 * tlskeys_list_get_next() for retruning the first available entry
7729 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007730 if (appctx->ctx.cli.p0 == NULL) {
7731 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7732 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007733 }
7734
7735 appctx->st2 = STAT_ST_LIST;
7736 /* fall through */
7737
7738 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007739 while (appctx->ctx.cli.p0) {
7740 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7741 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007742
7743 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007744 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007745 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007746
7747 if (appctx->ctx.cli.i1 == 0)
7748 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7749
William Lallemand32af2032016-10-29 18:09:35 +02007750 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007751 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007752 struct chunk *t2 = get_trash_chunk();
7753
7754 chunk_reset(t2);
7755 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007756 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007757 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007758 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007759
7760 if (bi_putchk(si_ic(si), &trash) == -1) {
7761 /* let's try again later from this stream. We add ourselves into
7762 * this stream's users so that it can remove us upon termination.
7763 */
7764 si_applet_cant_put(si);
7765 return 0;
7766 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007767 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007768 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007769 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007770 }
7771 if (bi_putchk(si_ic(si), &trash) == -1) {
7772 /* let's try again later from this stream. We add ourselves into
7773 * this stream's users so that it can remove us upon termination.
7774 */
7775 si_applet_cant_put(si);
7776 return 0;
7777 }
7778
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007779 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007780 break;
7781
7782 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007783 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007784 }
7785
7786 appctx->st2 = STAT_ST_FIN;
7787 /* fall through */
7788
7789 default:
7790 appctx->st2 = STAT_ST_FIN;
7791 return 1;
7792 }
7793 return 0;
7794}
7795
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007796/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007797static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7798{
William Lallemand32af2032016-10-29 18:09:35 +02007799 /* no parameter, shows only file list */
7800 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007801 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007802 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007803 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007804 }
7805
7806 if (args[2][0] == '*') {
7807 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007808 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007809 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007810 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7811 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007812 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007813 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007814 return 1;
7815 }
7816 }
William Lallemand32af2032016-10-29 18:09:35 +02007817 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007818 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007819}
7820
William Lallemand32af2032016-10-29 18:09:35 +02007821static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7822{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007823 struct tls_keys_ref *ref;
7824
William Lallemand32af2032016-10-29 18:09:35 +02007825 /* Expect two parameters: the filename and the new new TLS key in encoding */
7826 if (!*args[3] || !*args[4]) {
7827 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 +01007828 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007829 return 1;
7830 }
7831
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007832 ref = tlskeys_ref_lookup_ref(args[3]);
7833 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007834 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007835 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007836 return 1;
7837 }
7838
7839 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7840 if (trash.len != sizeof(struct tls_sess_key)) {
7841 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007842 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007843 return 1;
7844 }
7845
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007846 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7847 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007848
7849 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007850 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007851 return 1;
7852
7853}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007854#endif
William Lallemand32af2032016-10-29 18:09:35 +02007855
7856static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7857{
7858#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7859 char *err = NULL;
7860
7861 /* Expect one parameter: the new response in base64 encoding */
7862 if (!*args[3]) {
7863 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007864 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007865 return 1;
7866 }
7867
7868 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7869 if (trash.len < 0) {
7870 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007871 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007872 return 1;
7873 }
7874
7875 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7876 if (err) {
7877 memprintf(&err, "%s.\n", err);
7878 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007879 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007880 }
7881 return 1;
7882 }
7883 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007884 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007885 return 1;
7886#else
7887 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 +01007888 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007889 return 1;
7890#endif
7891
7892}
7893
7894/* register cli keywords */
7895static struct cli_kw_list cli_kws = {{ },{
7896#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7897 { { "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 },
7898 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007899#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007900 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007901 { { NULL }, NULL, NULL, NULL }
7902}};
7903
7904
Willy Tarreau7875d092012-09-10 08:20:03 +02007905/* Note: must not be declared <const> as its list will be overwritten.
7906 * Please take care of keeping this list alphabetically sorted.
7907 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007908static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007909 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007910 { "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 +02007911 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7912 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007913 { "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 +02007914 { "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 +02007915 { "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 +02007916 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7917 { "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 +01007918 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007919 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007920 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7921 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7922 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7923 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7924 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7925 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7926 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7927 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007928 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007929 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7930 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007931 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007932 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7933 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7934 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7935 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7936 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7937 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7938 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007939 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007940 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007941 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007942 { "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 +01007943 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007944 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7945 { "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 +02007946 { "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 +02007947#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007948 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007949#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007950#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007951 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007952#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007953 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007954 { "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 +02007955 { "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 +01007956 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7957 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007958 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7959 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7960 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7961 { "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 +02007962 { NULL, NULL, 0, 0, 0 },
7963}};
7964
7965/* Note: must not be declared <const> as its list will be overwritten.
7966 * Please take care of keeping this list alphabetically sorted.
7967 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007968static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007969 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7970 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007971 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007972}};
7973
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007974/* Note: must not be declared <const> as its list will be overwritten.
7975 * Please take care of keeping this list alphabetically sorted, doing so helps
7976 * all code contributors.
7977 * Optional keywords are also declared with a NULL ->parse() function so that
7978 * the config parser can report an appropriate error when a known keyword was
7979 * not enabled.
7980 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007981static struct ssl_bind_kw ssl_bind_kws[] = {
7982 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7983 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7984 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7985 { "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 +01007986 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007987 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02007988 { "no-ca-names", ssl_bind_parse_no_ca_names, 0 }, /* do not send ca names to clients (ca_file related) */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007989 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
Emmanuel Hocdetdf701a22017-05-18 12:46:50 +02007990 { "ssl-min-ver", ssl_bind_parse_tls_method_minmax,1 }, /* minimum version */
7991 { "ssl-max-ver", ssl_bind_parse_tls_method_minmax,1 }, /* maximum version */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007992 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7993 { NULL, NULL, 0 },
7994};
7995
Willy Tarreau51fb7652012-09-18 18:24:39 +02007996static struct bind_kw_list bind_kws = { "SSL", { }, {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007997 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7998 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7999 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
8000 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
8001 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
8002 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
8003 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
8004 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
8005 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
8006 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
8007 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
8008 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
8009 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
8010 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
8011 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
8012 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02008013 { "force-tlsv13", bind_parse_tls_method_options, 0 }, /* force TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008014 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Emmanuel Hocdet174dfe52017-07-28 15:01:05 +02008015 { "no-ca-names", bind_parse_no_ca_names, 0 }, /* do not send ca names to clients (ca_file related) */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008016 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
8017 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
8018 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
8019 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02008020 { "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008021 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
8022 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02008023 { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
8024 { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02008025 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
8026 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
8027 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
8028 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
8029 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02008030 { NULL, NULL, 0 },
8031}};
Emeric Brun46591952012-05-18 15:47:34 +02008032
Willy Tarreau92faadf2012-10-10 23:04:25 +02008033/* Note: must not be declared <const> as its list will be overwritten.
8034 * Please take care of keeping this list alphabetically sorted, doing so helps
8035 * all code contributors.
8036 * Optional keywords are also declared with a NULL ->parse() function so that
8037 * the config parser can report an appropriate error when a known keyword was
8038 * not enabled.
8039 */
8040static struct srv_kw_list srv_kws = { "SSL", { }, {
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02008041 { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
8042 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
8043 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
8044 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
8045 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
8046 { "force-sslv3", srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
8047 { "force-tlsv10", srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
8048 { "force-tlsv11", srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
8049 { "force-tlsv12", srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
8050 { "force-tlsv13", srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
8051 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
8052 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
8053 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
8054 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
8055 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
8056 { "no-sslv3", srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
8057 { "no-tlsv10", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
8058 { "no-tlsv11", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
8059 { "no-tlsv12", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
8060 { "no-tlsv13", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
8061 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
8062 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
8063 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
8064 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
8065 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
8066 { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1 }, /* minimum version */
8067 { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1 }, /* maximum version */
8068 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
8069 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
8070 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
8071 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02008072 { NULL, NULL, 0, 0 },
8073}};
8074
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008075static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01008076 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
8077 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01008078 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008079 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
8080 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01008081#ifndef OPENSSL_NO_DH
8082 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
8083#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008084 { CFG_GLOBAL, "ssl-mode-async", ssl_parse_global_ssl_async },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008085#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008086 { CFG_GLOBAL, "ssl-engine", ssl_parse_global_ssl_engine },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008087#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01008088 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
8089#ifndef OPENSSL_NO_DH
8090 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
8091#endif
8092 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
8093 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
8094 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
8095 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01008096 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01008097 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
8098 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008099 { 0, NULL, NULL },
8100}};
8101
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02008102/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01008103static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02008104 .snd_buf = ssl_sock_from_buf,
8105 .rcv_buf = ssl_sock_to_buf,
8106 .rcv_pipe = NULL,
8107 .snd_pipe = NULL,
8108 .shutr = NULL,
8109 .shutw = ssl_sock_shutw,
8110 .close = ssl_sock_close,
8111 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01008112 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01008113 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01008114 .prepare_srv = ssl_sock_prepare_srv_ctx,
8115 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8743f7e2016-12-04 18:44:29 +01008116 .get_alpn = ssl_sock_get_alpn,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01008117 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02008118};
8119
Daniel Jakots54ffb912015-11-06 20:02:41 +01008120#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008121
8122static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
8123{
8124 if (ptr) {
8125 chunk_destroy(ptr);
8126 free(ptr);
8127 }
8128}
8129
8130#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01008131static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
8132{
8133 pool_free2(pool2_ssl_capture, ptr);
8134}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008135
Emeric Brun46591952012-05-18 15:47:34 +02008136__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02008137static void __ssl_sock_init(void)
8138{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008139 char *ptr;
Emmanuel Hocdetf80bc242017-07-12 14:25:38 +02008140 int i;
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008141
Emeric Brun46591952012-05-18 15:47:34 +02008142 STACK_OF(SSL_COMP)* cm;
8143
Willy Tarreauef934602016-12-22 23:12:01 +01008144 if (global_ssl.listen_default_ciphers)
8145 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
8146 if (global_ssl.connect_default_ciphers)
8147 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01008148
Willy Tarreau13e14102016-12-22 20:25:26 +01008149 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02008150 SSL_library_init();
8151 cm = SSL_COMP_get_compression_methods();
8152 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01008153#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01008154 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
8155#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01008156 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 +02008157 sample_register_fetches(&sample_fetch_keywords);
8158 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02008159 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02008160 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008161 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02008162 cli_register_kw(&cli_kws);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008163#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008164 ENGINE_load_builtin_engines();
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008165 hap_register_post_check(ssl_check_async_engine_count);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008166#endif
Willy Tarreaud1c57502016-12-22 22:46:15 +01008167#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
8168 hap_register_post_check(tlskeys_finalize_config);
8169#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008170
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008171 ptr = NULL;
8172 memprintf(&ptr, "Built with OpenSSL version : "
8173#ifdef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008174 "BoringSSL");
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008175#else /* OPENSSL_IS_BORINGSSL */
8176 OPENSSL_VERSION_TEXT
8177 "\nRunning on OpenSSL version : %s%s",
8178 SSLeay_version(SSLEAY_VERSION),
8179 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
8180#endif
8181 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
8182#if OPENSSL_VERSION_NUMBER < 0x00907000L
8183 "no (library version too old)"
8184#elif defined(OPENSSL_NO_TLSEXT)
8185 "no (disabled via OPENSSL_NO_TLSEXT)"
8186#else
8187 "yes"
8188#endif
8189 "", ptr);
8190
8191 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
8192#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
8193 "yes"
8194#else
8195#ifdef OPENSSL_NO_TLSEXT
8196 "no (because of OPENSSL_NO_TLSEXT)"
8197#else
8198 "no (version might be too old, 0.9.8f min needed)"
8199#endif
8200#endif
8201 "", ptr);
8202
Emmanuel Hocdetf80bc242017-07-12 14:25:38 +02008203 memprintf(&ptr, "%s\nOpenSSL library supports :", ptr);
8204 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
8205 if (methodVersions[i].option)
8206 memprintf(&ptr, "%s %s", ptr, methodVersions[i].name);
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008207
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008208 hap_register_build_opts(ptr, 1);
8209
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008210 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
8211 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02008212
8213#ifndef OPENSSL_NO_DH
8214 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
Grant Zhang872f9c22017-01-21 01:10:18 +00008215 hap_register_post_deinit(ssl_free_dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02008216#endif
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008217#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008218 hap_register_post_deinit(ssl_free_engines);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008219#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02008220 /* Load SSL string for the verbose & debug mode. */
8221 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02008222}
8223
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008224#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008225void ssl_free_engines(void) {
8226 struct ssl_engine_list *wl, *wlb;
8227 /* free up engine list */
8228 list_for_each_entry_safe(wl, wlb, &openssl_engines, list) {
8229 ENGINE_finish(wl->e);
8230 ENGINE_free(wl->e);
8231 LIST_DEL(&wl->list);
8232 free(wl);
8233 }
8234}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008235#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02008236
Remi Gacogned3a23c32015-05-28 16:39:47 +02008237#ifndef OPENSSL_NO_DH
Grant Zhang872f9c22017-01-21 01:10:18 +00008238void ssl_free_dh(void) {
8239 if (local_dh_1024) {
8240 DH_free(local_dh_1024);
8241 local_dh_1024 = NULL;
8242 }
8243 if (local_dh_2048) {
8244 DH_free(local_dh_2048);
8245 local_dh_2048 = NULL;
8246 }
8247 if (local_dh_4096) {
8248 DH_free(local_dh_4096);
8249 local_dh_4096 = NULL;
8250 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02008251 if (global_dh) {
8252 DH_free(global_dh);
8253 global_dh = NULL;
8254 }
Grant Zhang872f9c22017-01-21 01:10:18 +00008255}
8256#endif
8257
8258__attribute__((destructor))
8259static void __ssl_sock_deinit(void)
8260{
8261#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
8262 lru64_destroy(ssl_ctx_lru_tree);
Remi Gacogned3a23c32015-05-28 16:39:47 +02008263#endif
8264
8265 ERR_remove_state(0);
8266 ERR_free_strings();
8267
8268 EVP_cleanup();
8269
8270#if OPENSSL_VERSION_NUMBER >= 0x00907000L
8271 CRYPTO_cleanup_all_ex_data();
8272#endif
8273}
8274
8275
Emeric Brun46591952012-05-18 15:47:34 +02008276/*
8277 * Local variables:
8278 * c-indent-level: 8
8279 * c-basic-offset: 8
8280 * End:
8281 */