blob: 67fa2aebbff209af8863816e78d96be20adff1ab [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;
372 int conn_fd = conn->t.sock.fd;
373
Emeric Brun3854e012017-05-17 20:42:48 +0200374 /* fd is an async enfine fd, we must stop
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000375 * to poll this fd until it is requested
376 */
377 fd_cant_recv(fd);
378
379 /* crypto engine is available, let's notify the associated
380 * connection that it can pursue its processing.
381 */
382 conn_fd_handler(conn_fd);
383}
384
Emeric Brun3854e012017-05-17 20:42:48 +0200385/*
386 * openssl async delayed SSL_free handler
387 */
388static void ssl_async_fd_free(int fd)
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000389{
390 SSL *ssl = fdtab[fd].owner;
Emeric Brun3854e012017-05-17 20:42:48 +0200391 OSSL_ASYNC_FD all_fd[32];
392 size_t num_all_fds = 0;
393 int i;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000394
Emeric Brun3854e012017-05-17 20:42:48 +0200395 /* We suppose that the async job for a same SSL *
396 * are serialized. So if we are awake it is
397 * because the running job has just finished
398 * and we can remove all async fds safely
399 */
400 SSL_get_all_async_fds(ssl, NULL, &num_all_fds);
401 if (num_all_fds > 32) {
402 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
403 return;
404 }
405
406 SSL_get_all_async_fds(ssl, all_fd, &num_all_fds);
407 for (i=0 ; i < num_all_fds ; i++)
408 fd_remove(all_fd[i]);
409
410 /* Now we can safely call SSL_free, no more pending job in engines */
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000411 SSL_free(ssl);
412 sslconns--;
413 jobs--;
414}
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000415/*
Emeric Brun3854e012017-05-17 20:42:48 +0200416 * function used to manage a returned SSL_ERROR_WANT_ASYNC
417 * and enable/disable polling for async fds
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000418 */
Emeric Brun3854e012017-05-17 20:42:48 +0200419static void inline ssl_async_process_fds(struct connection *conn, SSL *ssl)
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000420{
Emeric Brun3854e012017-05-17 20:42:48 +0200421 OSSL_ASYNC_FD add_fd[32], afd;
422 OSSL_ASYNC_FD del_fd[32];
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000423 size_t num_add_fds = 0;
424 size_t num_del_fds = 0;
Emeric Brun3854e012017-05-17 20:42:48 +0200425 int i;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000426
427 SSL_get_changed_async_fds(ssl, NULL, &num_add_fds, NULL,
428 &num_del_fds);
Emeric Brun3854e012017-05-17 20:42:48 +0200429 if (num_add_fds > 32 || num_del_fds > 32) {
430 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 +0000431 return;
432 }
433
Emeric Brun3854e012017-05-17 20:42:48 +0200434 SSL_get_changed_async_fds(ssl, add_fd, &num_add_fds, del_fd, &num_del_fds);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000435
Emeric Brun3854e012017-05-17 20:42:48 +0200436 /* We remove unused fds from the fdtab */
437 for (i=0 ; i < num_del_fds ; i++)
438 fd_remove(del_fd[i]);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000439
Emeric Brun3854e012017-05-17 20:42:48 +0200440 /* We add new fds to the fdtab */
441 for (i=0 ; i < num_add_fds ; i++) {
442 afd = add_fd[i];
443 fdtab[afd].owner = conn;
444 fdtab[afd].iocb = ssl_async_fd_handler;
445 fd_insert(afd);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000446 }
447
Emeric Brun3854e012017-05-17 20:42:48 +0200448 num_add_fds = 0;
449 SSL_get_all_async_fds(ssl, NULL, &num_add_fds);
450 if (num_add_fds > 32) {
451 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
452 return;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000453 }
Emeric Brun3854e012017-05-17 20:42:48 +0200454
455 /* We activate the polling for all known async fds */
456 SSL_get_all_async_fds(ssl, add_fd, &num_add_fds);
457 for (i=0 ; i < num_add_fds ; i++)
458 fd_want_recv(add_fd[i]);
459
460 /* We must also prevent the conn_handler
461 * to be called until a read event was
462 * polled on an async fd
463 */
464 __conn_sock_stop_both(conn);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +0000465}
466#endif
467
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200468/*
469 * This function returns the number of seconds elapsed
470 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
471 * date presented un ASN1_GENERALIZEDTIME.
472 *
473 * In parsing error case, it returns -1.
474 */
475static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
476{
477 long epoch;
478 char *p, *end;
479 const unsigned short month_offset[12] = {
480 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
481 };
482 int year, month;
483
484 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
485
486 p = (char *)d->data;
487 end = p + d->length;
488
489 if (end - p < 4) return -1;
490 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
491 p += 4;
492 if (end - p < 2) return -1;
493 month = 10 * (p[0] - '0') + p[1] - '0';
494 if (month < 1 || month > 12) return -1;
495 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
496 We consider leap years and the current month (<marsh or not) */
497 epoch = ( ((year - 1970) * 365)
498 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
499 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
500 + month_offset[month-1]
501 ) * 24 * 60 * 60;
502 p += 2;
503 if (end - p < 2) return -1;
504 /* Add the number of seconds of completed days of current month */
505 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
506 p += 2;
507 if (end - p < 2) return -1;
508 /* Add the completed hours of the current day */
509 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
510 p += 2;
511 if (end - p < 2) return -1;
512 /* Add the completed minutes of the current hour */
513 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
514 p += 2;
515 if (p == end) return -1;
516 /* Test if there is available seconds */
517 if (p[0] < '0' || p[0] > '9')
518 goto nosec;
519 if (end - p < 2) return -1;
520 /* Add the seconds of the current minute */
521 epoch += 10 * (p[0] - '0') + p[1] - '0';
522 p += 2;
523 if (p == end) return -1;
524 /* Ignore seconds float part if present */
525 if (p[0] == '.') {
526 do {
527 if (++p == end) return -1;
528 } while (p[0] >= '0' && p[0] <= '9');
529 }
530
531nosec:
532 if (p[0] == 'Z') {
533 if (end - p != 1) return -1;
534 return epoch;
535 }
536 else if (p[0] == '+') {
537 if (end - p != 5) return -1;
538 /* Apply timezone offset */
539 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
540 }
541 else if (p[0] == '-') {
542 if (end - p != 5) return -1;
543 /* Apply timezone offset */
544 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
545 }
546
547 return -1;
548}
549
Emeric Brun1d3865b2014-06-20 15:37:32 +0200550static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200551
552/* This function starts to check if the OCSP response (in DER format) contained
553 * in chunk 'ocsp_response' is valid (else exits on error).
554 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
555 * contained in the OCSP Response and exits on error if no match.
556 * If it's a valid OCSP Response:
557 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
558 * pointed by 'ocsp'.
559 * If 'ocsp' is NULL, the function looks up into the OCSP response's
560 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
561 * from the response) and exits on error if not found. Finally, If an OCSP response is
562 * already present in the container, it will be overwritten.
563 *
564 * Note: OCSP response containing more than one OCSP Single response is not
565 * considered valid.
566 *
567 * Returns 0 on success, 1 in error case.
568 */
569static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
570{
571 OCSP_RESPONSE *resp;
572 OCSP_BASICRESP *bs = NULL;
573 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200574 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200575 unsigned char *p = (unsigned char *)ocsp_response->str;
576 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200577 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200578 int reason;
579 int ret = 1;
580
581 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
582 if (!resp) {
583 memprintf(err, "Unable to parse OCSP response");
584 goto out;
585 }
586
587 rc = OCSP_response_status(resp);
588 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
589 memprintf(err, "OCSP response status not successful");
590 goto out;
591 }
592
593 bs = OCSP_response_get1_basic(resp);
594 if (!bs) {
595 memprintf(err, "Failed to get basic response from OCSP Response");
596 goto out;
597 }
598
599 count_sr = OCSP_resp_count(bs);
600 if (count_sr > 1) {
601 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
602 goto out;
603 }
604
605 sr = OCSP_resp_get0(bs, 0);
606 if (!sr) {
607 memprintf(err, "Failed to get OCSP single response");
608 goto out;
609 }
610
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200611 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
612
Emeric Brun4147b2e2014-06-16 18:36:30 +0200613 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
614 if (rc != V_OCSP_CERTSTATUS_GOOD) {
615 memprintf(err, "OCSP single response: certificate status not good");
616 goto out;
617 }
618
Emeric Brun13a6b482014-06-20 15:44:34 +0200619 if (!nextupd) {
620 memprintf(err, "OCSP single response: missing nextupdate");
621 goto out;
622 }
623
Emeric Brunc8b27b62014-06-19 14:16:17 +0200624 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200625 if (!rc) {
626 memprintf(err, "OCSP single response: no longer valid.");
627 goto out;
628 }
629
630 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200631 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200632 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
633 goto out;
634 }
635 }
636
637 if (!ocsp) {
638 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
639 unsigned char *p;
640
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200641 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200642 if (!rc) {
643 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
644 goto out;
645 }
646
647 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
648 memprintf(err, "OCSP single response: Certificate ID too long");
649 goto out;
650 }
651
652 p = key;
653 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200654 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200655 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
656 if (!ocsp) {
657 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
658 goto out;
659 }
660 }
661
662 /* According to comments on "chunk_dup", the
663 previous chunk buffer will be freed */
664 if (!chunk_dup(&ocsp->response, ocsp_response)) {
665 memprintf(err, "OCSP response: Memory allocation error");
666 goto out;
667 }
668
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200669 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
670
Emeric Brun4147b2e2014-06-16 18:36:30 +0200671 ret = 0;
672out:
Janusz Dziemidowicz8d710492017-03-08 16:59:41 +0100673 ERR_clear_error();
674
Emeric Brun4147b2e2014-06-16 18:36:30 +0200675 if (bs)
676 OCSP_BASICRESP_free(bs);
677
678 if (resp)
679 OCSP_RESPONSE_free(resp);
680
681 return ret;
682}
683/*
684 * External function use to update the OCSP response in the OCSP response's
685 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
686 * to update in DER format.
687 *
688 * Returns 0 on success, 1 in error case.
689 */
690int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
691{
692 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
693}
694
695/*
696 * This function load the OCSP Resonse in DER format contained in file at
697 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
698 *
699 * Returns 0 on success, 1 in error case.
700 */
701static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
702{
703 int fd = -1;
704 int r = 0;
705 int ret = 1;
706
707 fd = open(ocsp_path, O_RDONLY);
708 if (fd == -1) {
709 memprintf(err, "Error opening OCSP response file");
710 goto end;
711 }
712
713 trash.len = 0;
714 while (trash.len < trash.size) {
715 r = read(fd, trash.str + trash.len, trash.size - trash.len);
716 if (r < 0) {
717 if (errno == EINTR)
718 continue;
719
720 memprintf(err, "Error reading OCSP response from file");
721 goto end;
722 }
723 else if (r == 0) {
724 break;
725 }
726 trash.len += r;
727 }
728
729 close(fd);
730 fd = -1;
731
732 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
733end:
734 if (fd != -1)
735 close(fd);
736
737 return ret;
738}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100739#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200740
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100741#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
742static 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)
743{
744 struct tls_sess_key *keys;
745 struct connection *conn;
746 int head;
747 int i;
748
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200749 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200750 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
751 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100752
753 if (enc) {
754 memcpy(key_name, keys[head].name, 16);
755
756 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
757 return -1;
758
759 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
760 return -1;
761
762 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
763
764 return 1;
765 } else {
766 for (i = 0; i < TLS_TICKETS_NO; i++) {
767 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
768 goto found;
769 }
770 return 0;
771
772 found:
773 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
774 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
775 return -1;
776 /* 2 for key renewal, 1 if current key is still valid */
777 return i ? 2 : 1;
778 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200779}
780
781struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
782{
783 struct tls_keys_ref *ref;
784
785 list_for_each_entry(ref, &tlskeys_reference, list)
786 if (ref->filename && strcmp(filename, ref->filename) == 0)
787 return ref;
788 return NULL;
789}
790
791struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
792{
793 struct tls_keys_ref *ref;
794
795 list_for_each_entry(ref, &tlskeys_reference, list)
796 if (ref->unique_id == unique_id)
797 return ref;
798 return NULL;
799}
800
801int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
802 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
803
804 if(!ref) {
805 memprintf(err, "Unable to locate the referenced filename: %s", filename);
806 return 1;
807 }
808
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530809 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
810 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200811
812 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100813}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200814
815/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100816 * automatic ids. It's called just after the basic checks. It returns
817 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200818 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100819static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200820{
821 int i = 0;
822 struct tls_keys_ref *ref, *ref2, *ref3;
823 struct list tkr = LIST_HEAD_INIT(tkr);
824
825 list_for_each_entry(ref, &tlskeys_reference, list) {
826 if (ref->unique_id == -1) {
827 /* Look for the first free id. */
828 while (1) {
829 list_for_each_entry(ref2, &tlskeys_reference, list) {
830 if (ref2->unique_id == i) {
831 i++;
832 break;
833 }
834 }
835 if (&ref2->list == &tlskeys_reference)
836 break;
837 }
838
839 /* Uses the unique id and increment it for the next entry. */
840 ref->unique_id = i;
841 i++;
842 }
843 }
844
845 /* This sort the reference list by id. */
846 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
847 LIST_DEL(&ref->list);
848 list_for_each_entry(ref3, &tkr, list) {
849 if (ref->unique_id < ref3->unique_id) {
850 LIST_ADDQ(&ref3->list, &ref->list);
851 break;
852 }
853 }
854 if (&ref3->list == &tkr)
855 LIST_ADDQ(&tkr, &ref->list);
856 }
857
858 /* swap root */
859 LIST_ADD(&tkr, &tlskeys_reference);
860 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100861 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200862}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100863#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
864
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100865#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500866int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
867{
868 switch (evp_keytype) {
869 case EVP_PKEY_RSA:
870 return 2;
871 case EVP_PKEY_DSA:
872 return 0;
873 case EVP_PKEY_EC:
874 return 1;
875 }
876
877 return -1;
878}
879
Emeric Brun4147b2e2014-06-16 18:36:30 +0200880/*
881 * Callback used to set OCSP status extension content in server hello.
882 */
883int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
884{
yanbzhube2774d2015-12-10 15:07:30 -0500885 struct certificate_ocsp *ocsp;
886 struct ocsp_cbk_arg *ocsp_arg;
887 char *ssl_buf;
888 EVP_PKEY *ssl_pkey;
889 int key_type;
890 int index;
891
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200892 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500893
894 ssl_pkey = SSL_get_privatekey(ssl);
895 if (!ssl_pkey)
896 return SSL_TLSEXT_ERR_NOACK;
897
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200898 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500899
900 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
901 ocsp = ocsp_arg->s_ocsp;
902 else {
903 /* For multiple certs per context, we have to find the correct OCSP response based on
904 * the certificate type
905 */
906 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
907
908 if (index < 0)
909 return SSL_TLSEXT_ERR_NOACK;
910
911 ocsp = ocsp_arg->m_ocsp[index];
912
913 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200914
915 if (!ocsp ||
916 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200917 !ocsp->response.len ||
918 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200919 return SSL_TLSEXT_ERR_NOACK;
920
921 ssl_buf = OPENSSL_malloc(ocsp->response.len);
922 if (!ssl_buf)
923 return SSL_TLSEXT_ERR_NOACK;
924
925 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
926 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
927
928 return SSL_TLSEXT_ERR_OK;
929}
930
931/*
932 * This function enables the handling of OCSP status extension on 'ctx' if a
933 * file name 'cert_path' suffixed using ".ocsp" is present.
934 * To enable OCSP status extension, the issuer's certificate is mandatory.
935 * It should be present in the certificate's extra chain builded from file
936 * 'cert_path'. If not found, the issuer certificate is loaded from a file
937 * named 'cert_path' suffixed using '.issuer'.
938 *
939 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
940 * response. If file is empty or content is not a valid OCSP response,
941 * OCSP status extension is enabled but OCSP response is ignored (a warning
942 * is displayed).
943 *
944 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
945 * succesfully enabled, or -1 in other error case.
946 */
947static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
948{
949
950 BIO *in = NULL;
951 X509 *x, *xi = NULL, *issuer = NULL;
952 STACK_OF(X509) *chain = NULL;
953 OCSP_CERTID *cid = NULL;
954 SSL *ssl;
955 char ocsp_path[MAXPATHLEN+1];
956 int i, ret = -1;
957 struct stat st;
958 struct certificate_ocsp *ocsp = NULL, *iocsp;
959 char *warn = NULL;
960 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200961 pem_password_cb *passwd_cb;
962 void *passwd_cb_userdata;
963 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200964
965 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
966
967 if (stat(ocsp_path, &st))
968 return 1;
969
970 ssl = SSL_new(ctx);
971 if (!ssl)
972 goto out;
973
974 x = SSL_get_certificate(ssl);
975 if (!x)
976 goto out;
977
978 /* Try to lookup for issuer in certificate extra chain */
979#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
980 SSL_CTX_get_extra_chain_certs(ctx, &chain);
981#else
982 chain = ctx->extra_certs;
983#endif
984 for (i = 0; i < sk_X509_num(chain); i++) {
985 issuer = sk_X509_value(chain, i);
986 if (X509_check_issued(issuer, x) == X509_V_OK)
987 break;
988 else
989 issuer = NULL;
990 }
991
992 /* If not found try to load issuer from a suffixed file */
993 if (!issuer) {
994 char issuer_path[MAXPATHLEN+1];
995
996 in = BIO_new(BIO_s_file());
997 if (!in)
998 goto out;
999
1000 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
1001 if (BIO_read_filename(in, issuer_path) <= 0)
1002 goto out;
1003
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001004 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
1005 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
1006
1007 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +02001008 if (!xi)
1009 goto out;
1010
1011 if (X509_check_issued(xi, x) != X509_V_OK)
1012 goto out;
1013
1014 issuer = xi;
1015 }
1016
1017 cid = OCSP_cert_to_id(0, x, issuer);
1018 if (!cid)
1019 goto out;
1020
1021 i = i2d_OCSP_CERTID(cid, NULL);
1022 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
1023 goto out;
1024
Vincent Bernat02779b62016-04-03 13:48:43 +02001025 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +02001026 if (!ocsp)
1027 goto out;
1028
1029 p = ocsp->key_data;
1030 i2d_OCSP_CERTID(cid, &p);
1031
1032 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
1033 if (iocsp == ocsp)
1034 ocsp = NULL;
1035
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001036#ifndef SSL_CTX_get_tlsext_status_cb
1037# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
1038 *cb = (void (*) (void))ctx->tlsext_status_cb;
1039#endif
1040 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
1041
1042 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +02001043 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001044 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -05001045
1046 cb_arg->is_single = 1;
1047 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001048
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001049 pkey = X509_get_pubkey(x);
1050 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
1051 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -05001052
1053 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
1054 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
1055 } else {
1056 /*
1057 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
1058 * Update that cb_arg with the new cert's staple
1059 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001060 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -05001061 struct certificate_ocsp *tmp_ocsp;
1062 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001063 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001064 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001065
1066#ifdef SSL_CTX_get_tlsext_status_arg
1067 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
1068#else
1069 cb_arg = ctx->tlsext_status_arg;
1070#endif
yanbzhube2774d2015-12-10 15:07:30 -05001071
1072 /*
1073 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
1074 * the order of operations below matter, take care when changing it
1075 */
1076 tmp_ocsp = cb_arg->s_ocsp;
1077 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
1078 cb_arg->s_ocsp = NULL;
1079 cb_arg->m_ocsp[index] = tmp_ocsp;
1080 cb_arg->is_single = 0;
1081 cb_arg->single_kt = 0;
1082
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +01001083 pkey = X509_get_pubkey(x);
1084 key_type = EVP_PKEY_base_id(pkey);
1085 EVP_PKEY_free(pkey);
1086
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001087 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -05001088 if (index >= 0 && !cb_arg->m_ocsp[index])
1089 cb_arg->m_ocsp[index] = iocsp;
1090
1091 }
Emeric Brun4147b2e2014-06-16 18:36:30 +02001092
1093 ret = 0;
1094
1095 warn = NULL;
1096 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
1097 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
1098 Warning("%s.\n", warn);
1099 }
1100
1101out:
1102 if (ssl)
1103 SSL_free(ssl);
1104
1105 if (in)
1106 BIO_free(in);
1107
1108 if (xi)
1109 X509_free(xi);
1110
1111 if (cid)
1112 OCSP_CERTID_free(cid);
1113
1114 if (ocsp)
1115 free(ocsp);
1116
1117 if (warn)
1118 free(warn);
1119
1120
1121 return ret;
1122}
1123
1124#endif
1125
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02001126#ifdef OPENSSL_IS_BORINGSSL
1127static int ssl_sock_set_ocsp_response_from_file(SSL_CTX *ctx, const char *cert_path)
1128{
1129 char ocsp_path[MAXPATHLEN+1];
1130 struct stat st;
1131 int fd = -1, r = 0;
1132
1133 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
1134 if (stat(ocsp_path, &st))
1135 return 0;
1136
1137 fd = open(ocsp_path, O_RDONLY);
1138 if (fd == -1) {
1139 Warning("Error opening OCSP response file %s.\n", ocsp_path);
1140 return -1;
1141 }
1142
1143 trash.len = 0;
1144 while (trash.len < trash.size) {
1145 r = read(fd, trash.str + trash.len, trash.size - trash.len);
1146 if (r < 0) {
1147 if (errno == EINTR)
1148 continue;
1149 Warning("Error reading OCSP response from file %s.\n", ocsp_path);
1150 close(fd);
1151 return -1;
1152 }
1153 else if (r == 0) {
1154 break;
1155 }
1156 trash.len += r;
1157 }
1158 close(fd);
1159 return SSL_CTX_set_ocsp_response(ctx, (const uint8_t *)trash.str, trash.len);
1160}
1161#endif
1162
Daniel Jakots54ffb912015-11-06 20:02:41 +01001163#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001164
1165#define CT_EXTENSION_TYPE 18
1166
1167static int sctl_ex_index = -1;
1168
1169/*
1170 * Try to parse Signed Certificate Timestamp List structure. This function
1171 * makes only basic test if the data seems like SCTL. No signature validation
1172 * is performed.
1173 */
1174static int ssl_sock_parse_sctl(struct chunk *sctl)
1175{
1176 int ret = 1;
1177 int len, pos, sct_len;
1178 unsigned char *data;
1179
1180 if (sctl->len < 2)
1181 goto out;
1182
1183 data = (unsigned char *)sctl->str;
1184 len = (data[0] << 8) | data[1];
1185
1186 if (len + 2 != sctl->len)
1187 goto out;
1188
1189 data = data + 2;
1190 pos = 0;
1191 while (pos < len) {
1192 if (len - pos < 2)
1193 goto out;
1194
1195 sct_len = (data[pos] << 8) | data[pos + 1];
1196 if (pos + sct_len + 2 > len)
1197 goto out;
1198
1199 pos += sct_len + 2;
1200 }
1201
1202 ret = 0;
1203
1204out:
1205 return ret;
1206}
1207
1208static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
1209{
1210 int fd = -1;
1211 int r = 0;
1212 int ret = 1;
1213
1214 *sctl = NULL;
1215
1216 fd = open(sctl_path, O_RDONLY);
1217 if (fd == -1)
1218 goto end;
1219
1220 trash.len = 0;
1221 while (trash.len < trash.size) {
1222 r = read(fd, trash.str + trash.len, trash.size - trash.len);
1223 if (r < 0) {
1224 if (errno == EINTR)
1225 continue;
1226
1227 goto end;
1228 }
1229 else if (r == 0) {
1230 break;
1231 }
1232 trash.len += r;
1233 }
1234
1235 ret = ssl_sock_parse_sctl(&trash);
1236 if (ret)
1237 goto end;
1238
Vincent Bernat02779b62016-04-03 13:48:43 +02001239 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001240 if (!chunk_dup(*sctl, &trash)) {
1241 free(*sctl);
1242 *sctl = NULL;
1243 goto end;
1244 }
1245
1246end:
1247 if (fd != -1)
1248 close(fd);
1249
1250 return ret;
1251}
1252
1253int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1254{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001255 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001256
1257 *out = (unsigned char *)sctl->str;
1258 *outlen = sctl->len;
1259
1260 return 1;
1261}
1262
1263int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1264{
1265 return 1;
1266}
1267
1268static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1269{
1270 char sctl_path[MAXPATHLEN+1];
1271 int ret = -1;
1272 struct stat st;
1273 struct chunk *sctl = NULL;
1274
1275 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1276
1277 if (stat(sctl_path, &st))
1278 return 1;
1279
1280 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1281 goto out;
1282
1283 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1284 free(sctl);
1285 goto out;
1286 }
1287
1288 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1289
1290 ret = 0;
1291
1292out:
1293 return ret;
1294}
1295
1296#endif
1297
Emeric Brune1f38db2012-09-03 20:36:47 +02001298void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1299{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001300 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001301 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001302 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001303
1304 if (where & SSL_CB_HANDSHAKE_START) {
1305 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001306 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001307 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001308 conn->err_code = CO_ER_SSL_RENEG;
1309 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001310 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001311
1312 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1313 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1314 /* Long certificate chains optimz
1315 If write and read bios are differents, we
1316 consider that the buffering was activated,
1317 so we rise the output buffer size from 4k
1318 to 16k */
1319 write_bio = SSL_get_wbio(ssl);
1320 if (write_bio != SSL_get_rbio(ssl)) {
1321 BIO_set_write_buffer_size(write_bio, 16384);
1322 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1323 }
1324 }
1325 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001326}
1327
Emeric Brune64aef12012-09-21 13:15:06 +02001328/* Callback is called for each certificate of the chain during a verify
1329 ok is set to 1 if preverify detect no error on current certificate.
1330 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001331int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001332{
1333 SSL *ssl;
1334 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001335 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001336
1337 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001338 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001339
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001340 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001341
Emeric Brun81c00f02012-09-21 14:31:21 +02001342 if (ok) /* no errors */
1343 return ok;
1344
1345 depth = X509_STORE_CTX_get_error_depth(x_store);
1346 err = X509_STORE_CTX_get_error(x_store);
1347
1348 /* check if CA error needs to be ignored */
1349 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001350 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1351 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1352 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001353 }
1354
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001355 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001356 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001357 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001358 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001359 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001360
Willy Tarreau20879a02012-12-03 16:32:10 +01001361 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001362 return 0;
1363 }
1364
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001365 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1366 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001367
Emeric Brun81c00f02012-09-21 14:31:21 +02001368 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001369 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001370 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001371 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001372 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001373 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001374
Willy Tarreau20879a02012-12-03 16:32:10 +01001375 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001376 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001377}
1378
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001379static inline
1380void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001381 const void *buf, size_t len, SSL *ssl)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001382{
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001383 struct ssl_capture *capture;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001384 unsigned char *msg;
1385 unsigned char *end;
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001386 size_t rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001387
1388 /* This function is called for "from client" and "to server"
1389 * connections. The combination of write_p == 0 and content_type == 22
1390 * is only avalaible during "from client" connection.
1391 */
1392
1393 /* "write_p" is set to 0 is the bytes are received messages,
1394 * otherwise it is set to 1.
1395 */
1396 if (write_p != 0)
1397 return;
1398
1399 /* content_type contains the type of message received or sent
1400 * according with the SSL/TLS protocol spec. This message is
1401 * encoded with one byte. The value 256 (two bytes) is used
1402 * for designing the SSL/TLS record layer. According with the
1403 * rfc6101, the expected message (other than 256) are:
1404 * - change_cipher_spec(20)
1405 * - alert(21)
1406 * - handshake(22)
1407 * - application_data(23)
1408 * - (255)
1409 * We are interessed by the handshake and specially the client
1410 * hello.
1411 */
1412 if (content_type != 22)
1413 return;
1414
1415 /* The message length is at least 4 bytes, containing the
1416 * message type and the message length.
1417 */
1418 if (len < 4)
1419 return;
1420
1421 /* First byte of the handshake message id the type of
1422 * message. The konwn types are:
1423 * - hello_request(0)
1424 * - client_hello(1)
1425 * - server_hello(2)
1426 * - certificate(11)
1427 * - server_key_exchange (12)
1428 * - certificate_request(13)
1429 * - server_hello_done(14)
1430 * We are interested by the client hello.
1431 */
1432 msg = (unsigned char *)buf;
1433 if (msg[0] != 1)
1434 return;
1435
1436 /* Next three bytes are the length of the message. The total length
1437 * must be this decoded length + 4. If the length given as argument
1438 * is not the same, we abort the protocol dissector.
1439 */
1440 rec_len = (msg[1] << 16) + (msg[2] << 8) + msg[3];
1441 if (len < rec_len + 4)
1442 return;
1443 msg += 4;
1444 end = msg + rec_len;
1445 if (end < msg)
1446 return;
1447
1448 /* Expect 2 bytes for protocol version (1 byte for major and 1 byte
1449 * for minor, the random, composed by 4 bytes for the unix time and
1450 * 28 bytes for unix payload, and them 1 byte for the session id. So
1451 * we jump 1 + 1 + 4 + 28 + 1 bytes.
1452 */
1453 msg += 1 + 1 + 4 + 28 + 1;
1454 if (msg > end)
1455 return;
1456
1457 /* Next two bytes are the ciphersuite length. */
1458 if (msg + 2 > end)
1459 return;
1460 rec_len = (msg[0] << 8) + msg[1];
1461 msg += 2;
1462 if (msg + rec_len > end || msg + rec_len < msg)
1463 return;
1464
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001465 capture = pool_alloc_dirty(pool2_ssl_capture);
1466 if (!capture)
1467 return;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001468 /* Compute the xxh64 of the ciphersuite. */
1469 capture->xxh64 = XXH64(msg, rec_len, 0);
1470
1471 /* Capture the ciphersuite. */
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001472 capture->ciphersuite_len = (global_ssl.capture_cipherlist < rec_len) ?
1473 global_ssl.capture_cipherlist : rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001474 memcpy(capture->ciphersuite, msg, capture->ciphersuite_len);
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001475
1476 SSL_set_ex_data(ssl, ssl_capture_ptr_index, capture);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001477}
1478
Emeric Brun29f037d2014-04-25 19:05:36 +02001479/* Callback is called for ssl protocol analyse */
1480void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1481{
Emeric Brun29f037d2014-04-25 19:05:36 +02001482#ifdef TLS1_RT_HEARTBEAT
1483 /* test heartbeat received (write_p is set to 0
1484 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001485 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001486 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001487 const unsigned char *p = buf;
1488 unsigned int payload;
1489
Emeric Brun29f037d2014-04-25 19:05:36 +02001490 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001491
1492 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1493 if (*p != TLS1_HB_REQUEST)
1494 return;
1495
Willy Tarreauaeed6722014-04-25 23:59:58 +02001496 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001497 goto kill_it;
1498
1499 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001500 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001501 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001502 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001503 /* We have a clear heartbleed attack (CVE-2014-0160), the
1504 * advertised payload is larger than the advertised packet
1505 * length, so we have garbage in the buffer between the
1506 * payload and the end of the buffer (p+len). We can't know
1507 * if the SSL stack is patched, and we don't know if we can
1508 * safely wipe out the area between p+3+len and payload.
1509 * So instead, we prevent the response from being sent by
1510 * setting the max_send_fragment to 0 and we report an SSL
1511 * error, which will kill this connection. It will be reported
1512 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001513 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1514 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001515 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001516 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1517 return;
1518 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001519#endif
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001520 if (global_ssl.capture_cipherlist > 0)
1521 ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
Emeric Brun29f037d2014-04-25 19:05:36 +02001522}
1523
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001524#ifdef OPENSSL_NPN_NEGOTIATED
1525/* This callback is used so that the server advertises the list of
1526 * negociable protocols for NPN.
1527 */
1528static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1529 unsigned int *len, void *arg)
1530{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001531 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001532
1533 *data = (const unsigned char *)conf->npn_str;
1534 *len = conf->npn_len;
1535 return SSL_TLSEXT_ERR_OK;
1536}
1537#endif
1538
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001539#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001540/* This callback is used so that the server advertises the list of
1541 * negociable protocols for ALPN.
1542 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001543static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1544 unsigned char *outlen,
1545 const unsigned char *server,
1546 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001547{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001548 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001549
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001550 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1551 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1552 return SSL_TLSEXT_ERR_NOACK;
1553 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001554 return SSL_TLSEXT_ERR_OK;
1555}
1556#endif
1557
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001558#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001559#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001560
Christopher Faulet30548802015-06-11 13:39:32 +02001561/* Create a X509 certificate with the specified servername and serial. This
1562 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001563static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001564ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001565{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001566 static unsigned int serial = 0;
1567
Christopher Faulet7969a332015-10-09 11:15:03 +02001568 X509 *cacert = bind_conf->ca_sign_cert;
1569 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001570 SSL_CTX *ssl_ctx = NULL;
1571 X509 *newcrt = NULL;
1572 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001573 X509_NAME *name;
1574 const EVP_MD *digest;
1575 X509V3_CTX ctx;
1576 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001577 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001578
Christopher Faulet7969a332015-10-09 11:15:03 +02001579 /* Get the private key of the defautl certificate and use it */
1580 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001581 goto mkcert_error;
1582
1583 /* Create the certificate */
1584 if (!(newcrt = X509_new()))
1585 goto mkcert_error;
1586
1587 /* Set version number for the certificate (X509v3) and the serial
1588 * number */
1589 if (X509_set_version(newcrt, 2L) != 1)
1590 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001591 if (!serial)
1592 serial = now_ms;
1593 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001594
1595 /* Set duration for the certificate */
1596 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1597 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1598 goto mkcert_error;
1599
1600 /* set public key in the certificate */
1601 if (X509_set_pubkey(newcrt, pkey) != 1)
1602 goto mkcert_error;
1603
1604 /* Set issuer name from the CA */
1605 if (!(name = X509_get_subject_name(cacert)))
1606 goto mkcert_error;
1607 if (X509_set_issuer_name(newcrt, name) != 1)
1608 goto mkcert_error;
1609
1610 /* Set the subject name using the same, but the CN */
1611 name = X509_NAME_dup(name);
1612 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1613 (const unsigned char *)servername,
1614 -1, -1, 0) != 1) {
1615 X509_NAME_free(name);
1616 goto mkcert_error;
1617 }
1618 if (X509_set_subject_name(newcrt, name) != 1) {
1619 X509_NAME_free(name);
1620 goto mkcert_error;
1621 }
1622 X509_NAME_free(name);
1623
1624 /* Add x509v3 extensions as specified */
1625 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1626 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1627 X509_EXTENSION *ext;
1628
1629 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1630 goto mkcert_error;
1631 if (!X509_add_ext(newcrt, ext, -1)) {
1632 X509_EXTENSION_free(ext);
1633 goto mkcert_error;
1634 }
1635 X509_EXTENSION_free(ext);
1636 }
1637
1638 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001639
1640 key_type = EVP_PKEY_base_id(capkey);
1641
1642 if (key_type == EVP_PKEY_DSA)
1643 digest = EVP_sha1();
1644 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001645 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001646 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001647 digest = EVP_sha256();
1648 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001649#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001650 int nid;
1651
1652 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1653 goto mkcert_error;
1654 if (!(digest = EVP_get_digestbynid(nid)))
1655 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001656#else
1657 goto mkcert_error;
1658#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001659 }
1660
Christopher Faulet31af49d2015-06-09 17:29:50 +02001661 if (!(X509_sign(newcrt, capkey, digest)))
1662 goto mkcert_error;
1663
1664 /* Create and set the new SSL_CTX */
1665 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1666 goto mkcert_error;
1667 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1668 goto mkcert_error;
1669 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1670 goto mkcert_error;
1671 if (!SSL_CTX_check_private_key(ssl_ctx))
1672 goto mkcert_error;
1673
1674 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001675
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001676#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001677 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001678#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001679#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1680 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001681 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001682 EC_KEY *ecc;
1683 int nid;
1684
1685 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1686 goto end;
1687 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1688 goto end;
1689 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1690 EC_KEY_free(ecc);
1691 }
1692#endif
1693 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001694 return ssl_ctx;
1695
1696 mkcert_error:
1697 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1698 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001699 return NULL;
1700}
1701
Christopher Faulet7969a332015-10-09 11:15:03 +02001702SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001703ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001704{
1705 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001706
1707 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001708}
1709
Christopher Faulet30548802015-06-11 13:39:32 +02001710/* Do a lookup for a certificate in the LRU cache used to store generated
1711 * certificates. */
1712SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001713ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001714{
1715 struct lru64 *lru = NULL;
1716
1717 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001718 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001719 if (lru && lru->domain)
1720 return (SSL_CTX *)lru->data;
1721 }
1722 return NULL;
1723}
1724
Christopher Fauletd2cab922015-07-28 16:03:47 +02001725/* Set a certificate int the LRU cache used to store generated
1726 * certificate. Return 0 on success, otherwise -1 */
1727int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001728ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001729{
1730 struct lru64 *lru = NULL;
1731
1732 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001733 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001734 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001735 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001736 if (lru->domain && lru->data)
1737 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001738 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001739 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001740 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001741 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001742}
1743
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001744/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001745unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001746ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001747{
1748 return XXH32(data, len, ssl_ctx_lru_seed);
1749}
1750
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001751/* Generate a cert and immediately assign it to the SSL session so that the cert's
1752 * refcount is maintained regardless of the cert's presence in the LRU cache.
1753 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001754static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001755ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001756{
1757 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001758 SSL_CTX *ssl_ctx = NULL;
1759 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001760 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001761
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001762 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001763 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001764 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001765 if (lru && lru->domain)
1766 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001767 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001768 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001769 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001770 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001771 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001772 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001773 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001774 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001775 SSL_set_SSL_CTX(ssl, ssl_ctx);
1776 /* No LRU cache, this CTX will be released as soon as the session dies */
1777 SSL_CTX_free(ssl_ctx);
1778 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001779 return ssl_ctx;
1780}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001781#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001782
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001783
1784#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1785#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1786#endif
1787
1788#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1789#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
1790#define SSL_renegotiate_pending(arg) 0
1791#endif
1792#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1793#define SSL_OP_SINGLE_ECDH_USE 0
1794#endif
1795#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1796#define SSL_OP_NO_TICKET 0
1797#endif
1798#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1799#define SSL_OP_NO_COMPRESSION 0
1800#endif
1801#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1802#define SSL_OP_NO_TLSv1_1 0
1803#endif
1804#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1805#define SSL_OP_NO_TLSv1_2 0
1806#endif
1807#ifndef SSL_OP_NO_TLSv1_3 /* dev */
1808#define SSL_OP_NO_TLSv1_3 0
1809#endif
1810#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1811#define SSL_OP_SINGLE_DH_USE 0
1812#endif
1813#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1814#define SSL_OP_SINGLE_ECDH_USE 0
1815#endif
1816#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1817#define SSL_MODE_RELEASE_BUFFERS 0
1818#endif
1819#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1820#define SSL_MODE_SMALL_BUFFERS 0
1821#endif
1822
1823#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001824typedef enum { SET_CLIENT, SET_SERVER } set_context_func;
1825
1826static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001827{
1828#if SSL_OP_NO_SSLv3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001829 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, SSLv3_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001830 : SSL_CTX_set_ssl_version(ctx, SSLv3_client_method());
1831#endif
1832}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001833static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1834 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001835 : SSL_CTX_set_ssl_version(ctx, TLSv1_client_method());
1836}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001837static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001838#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001839 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001840 : SSL_CTX_set_ssl_version(ctx, TLSv1_1_client_method());
1841#endif
1842}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001843static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001844#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001845 c == SET_SERVER ? SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method())
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001846 : SSL_CTX_set_ssl_version(ctx, TLSv1_2_client_method());
1847#endif
1848}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001849/* TLS 1.2 is the last supported version in this context. */
1850static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {}
1851/* Unusable in this context. */
1852static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {}
1853static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {}
1854static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {}
1855static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {}
1856static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {}
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001857#else /* openssl >= 1.1.0 */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001858typedef enum { SET_MIN, SET_MAX } set_context_func;
1859
1860static void ctx_set_SSLv3_func(SSL_CTX *ctx, set_context_func c) {
1861 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001862 : SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
1863}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001864static void ssl_set_SSLv3_func(SSL *ssl, set_context_func c) {
1865 c == SET_MAX ? SSL_set_max_proto_version(ssl, SSL3_VERSION)
1866 : SSL_set_min_proto_version(ssl, SSL3_VERSION);
1867}
1868static void ctx_set_TLSv10_func(SSL_CTX *ctx, set_context_func c) {
1869 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001870 : SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1871}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001872static void ssl_set_TLSv10_func(SSL *ssl, set_context_func c) {
1873 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_VERSION)
1874 : SSL_set_min_proto_version(ssl, TLS1_VERSION);
1875}
1876static void ctx_set_TLSv11_func(SSL_CTX *ctx, set_context_func c) {
1877 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001878 : SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
1879}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001880static void ssl_set_TLSv11_func(SSL *ssl, set_context_func c) {
1881 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_1_VERSION)
1882 : SSL_set_min_proto_version(ssl, TLS1_1_VERSION);
1883}
1884static void ctx_set_TLSv12_func(SSL_CTX *ctx, set_context_func c) {
1885 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001886 : SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
1887}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001888static void ssl_set_TLSv12_func(SSL *ssl, set_context_func c) {
1889 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_2_VERSION)
1890 : SSL_set_min_proto_version(ssl, TLS1_2_VERSION);
1891}
1892static void ctx_set_TLSv13_func(SSL_CTX *ctx, set_context_func c) {
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001893#if SSL_OP_NO_TLSv1_3
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001894 c == SET_MAX ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION)
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001895 : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
1896#endif
1897}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001898static void ssl_set_TLSv13_func(SSL *ssl, set_context_func c) {
1899#if SSL_OP_NO_TLSv1_3
1900 c == SET_MAX ? SSL_set_max_proto_version(ssl, TLS1_3_VERSION)
1901 : SSL_set_min_proto_version(ssl, TLS1_3_VERSION);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001902#endif
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001903}
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001904#endif
1905static void ctx_set_None_func(SSL_CTX *ctx, set_context_func c) { }
1906static void ssl_set_None_func(SSL *ssl, set_context_func c) { }
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001907
1908static struct {
1909 int option;
1910 uint16_t flag;
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001911 void (*ctx_set_version)(SSL_CTX *, set_context_func);
1912 void (*ssl_set_version)(SSL *, set_context_func);
Emmanuel Hocdetecb0e232017-05-18 11:56:58 +02001913 const char *name;
1914} methodVersions[] = {
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02001915 {0, 0, ctx_set_None_func, ssl_set_None_func, "NONE"}, /* CONF_TLSV_NONE */
1916 {SSL_OP_NO_SSLv3, MC_SSL_O_NO_SSLV3, ctx_set_SSLv3_func, ssl_set_SSLv3_func, "SSLv3"}, /* CONF_SSLV3 */
1917 {SSL_OP_NO_TLSv1, MC_SSL_O_NO_TLSV10, ctx_set_TLSv10_func, ssl_set_TLSv10_func, "TLSv1.0"}, /* CONF_TLSV10 */
1918 {SSL_OP_NO_TLSv1_1, MC_SSL_O_NO_TLSV11, ctx_set_TLSv11_func, ssl_set_TLSv11_func, "TLSv1.1"}, /* CONF_TLSV11 */
1919 {SSL_OP_NO_TLSv1_2, MC_SSL_O_NO_TLSV12, ctx_set_TLSv12_func, ssl_set_TLSv12_func, "TLSv1.2"}, /* CONF_TLSV12 */
1920 {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 +02001921};
1922
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001923static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1924{
1925 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1926 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1927 SSL_set_SSL_CTX(ssl, ctx);
1928}
1929
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001930#ifdef OPENSSL_IS_BORINGSSL
1931
1932static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1933{
1934 (void)al; /* shut gcc stupid warning */
1935 (void)priv;
1936
1937 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1938 return SSL_TLSEXT_ERR_NOACK;
1939 return SSL_TLSEXT_ERR_OK;
1940}
1941
1942static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1943{
1944 struct connection *conn;
1945 struct bind_conf *s;
1946 const uint8_t *extension_data;
1947 size_t extension_len;
1948 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1949 const SSL_CIPHER *cipher;
1950 uint16_t cipher_suite;
1951 uint8_t name_type, hash, sign;
1952 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1953
1954 char *wildp = NULL;
1955 const uint8_t *servername;
1956 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1957 int i;
1958
1959 conn = SSL_get_app_data(ctx->ssl);
1960 s = objt_listener(conn->target)->bind_conf;
1961
1962 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1963 &extension_data, &extension_len)) {
1964 CBS_init(&extension, extension_data, extension_len);
1965
1966 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1967 || !CBS_get_u8(&server_name_list, &name_type)
1968 /* Although the server_name extension was intended to be extensible to
1969 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1970 * different name types will cause an error. Further, RFC 4366 originally
1971 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1972 * adding new name types is no longer feasible.
1973 *
1974 * Act as if the extensibility does not exist to simplify parsing. */
1975 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1976 || CBS_len(&server_name_list) != 0
1977 || CBS_len(&extension) != 0
1978 || name_type != TLSEXT_NAMETYPE_host_name
1979 || CBS_len(&host_name) == 0
1980 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1981 || CBS_contains_zero_byte(&host_name)) {
1982 goto abort;
1983 }
1984 } else {
1985 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001986 if (!s->strict_sni) {
1987 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001988 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001989 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001990 goto abort;
1991 }
1992
1993 /* extract/check clientHello informations */
1994 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
1995 CBS_init(&extension, extension_data, extension_len);
1996
1997 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
1998 || CBS_len(&sig_algs) == 0
1999 || CBS_len(&extension) != 0) {
2000 goto abort;
2001 }
2002 if (CBS_len(&sig_algs) % 2 != 0) {
2003 goto abort;
2004 }
2005 while (CBS_len(&sig_algs) != 0) {
2006 if (!CBS_get_u8(&sig_algs, &hash)
2007 || !CBS_get_u8(&sig_algs, &sign)) {
2008 goto abort;
2009 }
2010 switch (sign) {
2011 case TLSEXT_signature_rsa:
2012 has_rsa = 1;
2013 break;
2014 case TLSEXT_signature_ecdsa:
2015 has_ecdsa_sig = 1;
2016 break;
2017 default:
2018 continue;
2019 }
2020 if (has_ecdsa_sig && has_rsa)
2021 break;
2022 }
2023 } else {
2024 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
2025 has_rsa = 1;
2026 }
2027 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
2028 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
2029
2030 while (CBS_len(&cipher_suites) != 0) {
2031 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
2032 goto abort;
2033 }
2034 cipher = SSL_get_cipher_by_value(cipher_suite);
2035 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
2036 has_ecdsa = 1;
2037 break;
2038 }
2039 }
2040 }
2041
2042 servername = CBS_data(&host_name);
2043 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
2044 trash.str[i] = tolower(servername[i]);
2045 if (!wildp && (trash.str[i] == '.'))
2046 wildp = &trash.str[i];
2047 }
2048 trash.str[i] = 0;
2049
2050 /* lookup in full qualified names */
2051 node = ebst_lookup(&s->sni_ctx, trash.str);
2052
2053 /* lookup a not neg filter */
2054 for (n = node; n; n = ebmb_next_dup(n)) {
2055 if (!container_of(n, struct sni_ctx, name)->neg) {
2056 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2057 case TLSEXT_signature_ecdsa:
2058 if (has_ecdsa) {
2059 node_ecdsa = n;
2060 goto find_one;
2061 }
2062 break;
2063 case TLSEXT_signature_rsa:
2064 if (has_rsa && !node_rsa) {
2065 node_rsa = n;
2066 if (!has_ecdsa)
2067 goto find_one;
2068 }
2069 break;
2070 default: /* TLSEXT_signature_anonymous */
2071 if (!node_anonymous)
2072 node_anonymous = n;
2073 break;
2074 }
2075 }
2076 }
2077 if (wildp) {
2078 /* lookup in wildcards names */
2079 node = ebst_lookup(&s->sni_w_ctx, wildp);
2080 for (n = node; n; n = ebmb_next_dup(n)) {
2081 if (!container_of(n, struct sni_ctx, name)->neg) {
2082 switch(container_of(n, struct sni_ctx, name)->key_sig) {
2083 case TLSEXT_signature_ecdsa:
2084 if (has_ecdsa) {
2085 node_ecdsa = n;
2086 goto find_one;
2087 }
2088 break;
2089 case TLSEXT_signature_rsa:
2090 if (has_rsa && !node_rsa) {
2091 node_rsa = n;
2092 if (!has_ecdsa)
2093 goto find_one;
2094 }
2095 break;
2096 default: /* TLSEXT_signature_anonymous */
2097 if (!node_anonymous)
2098 node_anonymous = n;
2099 break;
2100 }
2101 }
2102 }
2103 }
2104 find_one:
2105 /* select by key_signature priority order */
2106 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
2107
2108 if (node) {
2109 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002110 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002111 return 1;
2112 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002113 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002114 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002115 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002116 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002117 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002118 abort:
2119 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
2120 conn->err_code = CO_ER_SSL_HANDSHAKE;
2121 return -1;
2122}
2123
2124#else /* OPENSSL_IS_BORINGSSL */
2125
Emeric Brunfc0421f2012-09-07 17:30:07 +02002126/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
2127 * warning when no match is found, which implies the default (first) cert
2128 * will keep being used.
2129 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002130static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002131{
2132 const char *servername;
2133 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002134 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002135 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002136 int i;
2137 (void)al; /* shut gcc stupid warning */
2138
2139 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002140 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002141#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02002142 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002143 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002144 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02002145 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02002146
Willy Tarreauf6721452015-07-07 18:04:38 +02002147 conn_get_to_addr(conn);
2148 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01002149 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
2150 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02002151 if (ctx) {
2152 /* switch ctx */
2153 SSL_set_SSL_CTX(ssl, ctx);
2154 return SSL_TLSEXT_ERR_OK;
2155 }
Christopher Faulet30548802015-06-11 13:39:32 +02002156 }
2157 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002158#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002159 if (s->strict_sni)
2160 return SSL_TLSEXT_ERR_ALERT_FATAL;
2161 ssl_sock_switchctx_set(ssl, s->default_ctx);
2162 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002163 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002164
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002165 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002166 if (!servername[i])
2167 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002168 trash.str[i] = tolower(servername[i]);
2169 if (!wildp && (trash.str[i] == '.'))
2170 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002171 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002172 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002173
2174 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01002175 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002176
2177 /* lookup a not neg filter */
2178 for (n = node; n; n = ebmb_next_dup(n)) {
2179 if (!container_of(n, struct sni_ctx, name)->neg) {
2180 node = n;
2181 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01002182 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002183 }
2184 if (!node && wildp) {
2185 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002186 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002187 }
2188 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002189#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02002190 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002191 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02002192 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02002193 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02002194 return SSL_TLSEXT_ERR_OK;
2195 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01002196#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002197 if (s->strict_sni)
2198 return SSL_TLSEXT_ERR_ALERT_FATAL;
2199 ssl_sock_switchctx_set(ssl, s->default_ctx);
2200 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002201 }
2202
2203 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01002204 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002205 return SSL_TLSEXT_ERR_OK;
2206}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002207#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02002208#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2209
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002210#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002211
2212static DH * ssl_get_dh_1024(void)
2213{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002214 static unsigned char dh1024_p[]={
2215 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
2216 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
2217 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
2218 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
2219 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
2220 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
2221 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
2222 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
2223 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
2224 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
2225 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
2226 };
2227 static unsigned char dh1024_g[]={
2228 0x02,
2229 };
2230
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002231 BIGNUM *p;
2232 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002233 DH *dh = DH_new();
2234 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002235 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
2236 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002237
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002238 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002239 DH_free(dh);
2240 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002241 } else {
2242 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002243 }
2244 }
2245 return dh;
2246}
2247
2248static DH *ssl_get_dh_2048(void)
2249{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002250 static unsigned char dh2048_p[]={
2251 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
2252 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
2253 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
2254 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
2255 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
2256 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
2257 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
2258 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
2259 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
2260 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
2261 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
2262 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
2263 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
2264 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
2265 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
2266 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
2267 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
2268 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
2269 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
2270 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
2271 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
2272 0xB7,0x1F,0x77,0xF3,
2273 };
2274 static unsigned char dh2048_g[]={
2275 0x02,
2276 };
2277
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002278 BIGNUM *p;
2279 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002280 DH *dh = DH_new();
2281 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002282 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
2283 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002284
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002285 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002286 DH_free(dh);
2287 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002288 } else {
2289 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002290 }
2291 }
2292 return dh;
2293}
2294
2295static DH *ssl_get_dh_4096(void)
2296{
Remi Gacogned3a341a2015-05-29 16:26:17 +02002297 static unsigned char dh4096_p[]={
2298 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
2299 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
2300 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
2301 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
2302 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
2303 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
2304 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
2305 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
2306 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
2307 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
2308 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
2309 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
2310 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
2311 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
2312 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
2313 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
2314 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
2315 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
2316 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
2317 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
2318 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
2319 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
2320 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
2321 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
2322 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
2323 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
2324 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
2325 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
2326 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
2327 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
2328 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
2329 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
2330 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
2331 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
2332 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
2333 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
2334 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
2335 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
2336 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
2337 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
2338 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
2339 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
2340 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002341 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02002342 static unsigned char dh4096_g[]={
2343 0x02,
2344 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002345
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002346 BIGNUM *p;
2347 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002348 DH *dh = DH_new();
2349 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002350 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
2351 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002352
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002353 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002354 DH_free(dh);
2355 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002356 } else {
2357 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002358 }
2359 }
2360 return dh;
2361}
2362
2363/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01002364 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002365static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
2366{
2367 DH *dh = NULL;
2368 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002369 int type;
2370
2371 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002372
2373 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2374 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2375 */
2376 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2377 keylen = EVP_PKEY_bits(pkey);
2378 }
2379
Willy Tarreauef934602016-12-22 23:12:01 +01002380 if (keylen > global_ssl.default_dh_param) {
2381 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002382 }
2383
Remi Gacogned3a341a2015-05-29 16:26:17 +02002384 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002385 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002386 }
2387 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002388 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002389 }
2390 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002391 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002392 }
2393
2394 return dh;
2395}
2396
Remi Gacogne47783ef2015-05-29 15:53:22 +02002397static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002398{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002399 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002400 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002401
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002402 if (in == NULL)
2403 goto end;
2404
Remi Gacogne47783ef2015-05-29 15:53:22 +02002405 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002406 goto end;
2407
Remi Gacogne47783ef2015-05-29 15:53:22 +02002408 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2409
2410end:
2411 if (in)
2412 BIO_free(in);
2413
2414 return dh;
2415}
2416
2417int ssl_sock_load_global_dh_param_from_file(const char *filename)
2418{
2419 global_dh = ssl_sock_get_dh_from_file(filename);
2420
2421 if (global_dh) {
2422 return 0;
2423 }
2424
2425 return -1;
2426}
2427
2428/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2429 if an error occured, and 0 if parameter not found. */
2430int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2431{
2432 int ret = -1;
2433 DH *dh = ssl_sock_get_dh_from_file(file);
2434
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002435 if (dh) {
2436 ret = 1;
2437 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002438
2439 if (ssl_dh_ptr_index >= 0) {
2440 /* store a pointer to the DH params to avoid complaining about
2441 ssl-default-dh-param not being set for this SSL_CTX */
2442 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2443 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002444 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002445 else if (global_dh) {
2446 SSL_CTX_set_tmp_dh(ctx, global_dh);
2447 ret = 0; /* DH params not found */
2448 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002449 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002450 /* Clear openssl global errors stack */
2451 ERR_clear_error();
2452
Willy Tarreauef934602016-12-22 23:12:01 +01002453 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002454 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002455 if (local_dh_1024 == NULL)
2456 local_dh_1024 = ssl_get_dh_1024();
2457
Remi Gacogne8de54152014-07-15 11:36:40 +02002458 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002459 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002460
Remi Gacogne8de54152014-07-15 11:36:40 +02002461 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002462 }
2463 else {
2464 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2465 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002466
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002467 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002468 }
Emeric Brun644cde02012-12-14 11:21:13 +01002469
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002470end:
2471 if (dh)
2472 DH_free(dh);
2473
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002474 return ret;
2475}
2476#endif
2477
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002478static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2479 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002480{
2481 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002482 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002483 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002484
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002485 if (*name == '!') {
2486 neg = 1;
2487 name++;
2488 }
2489 if (*name == '*') {
2490 wild = 1;
2491 name++;
2492 }
2493 /* !* filter is a nop */
2494 if (neg && wild)
2495 return order;
2496 if (*name) {
2497 int j, len;
2498 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002499 for (j = 0; j < len && j < trash.size; j++)
2500 trash.str[j] = tolower(name[j]);
2501 if (j >= trash.size)
2502 return order;
2503 trash.str[j] = 0;
2504
2505 /* Check for duplicates. */
2506 if (wild)
2507 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2508 else
2509 node = ebst_lookup(&s->sni_ctx, trash.str);
2510 for (; node; node = ebmb_next_dup(node)) {
2511 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002512 if (sc->ctx == ctx && sc->conf == conf &&
2513 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002514 return order;
2515 }
2516
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002517 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002518 if (!sc)
2519 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002520 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002521 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002522 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002523 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002524 sc->order = order++;
2525 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002526 if (wild)
2527 ebst_insert(&s->sni_w_ctx, &sc->name);
2528 else
2529 ebst_insert(&s->sni_ctx, &sc->name);
2530 }
2531 return order;
2532}
2533
yanbzhu488a4d22015-12-01 15:16:07 -05002534
2535/* The following code is used for loading multiple crt files into
2536 * SSL_CTX's based on CN/SAN
2537 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002538#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002539/* This is used to preload the certifcate, private key
2540 * and Cert Chain of a file passed in via the crt
2541 * argument
2542 *
2543 * This way, we do not have to read the file multiple times
2544 */
2545struct cert_key_and_chain {
2546 X509 *cert;
2547 EVP_PKEY *key;
2548 unsigned int num_chain_certs;
2549 /* This is an array of X509 pointers */
2550 X509 **chain_certs;
2551};
2552
yanbzhu08ce6ab2015-12-02 13:01:29 -05002553#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2554
2555struct key_combo_ctx {
2556 SSL_CTX *ctx;
2557 int order;
2558};
2559
2560/* Map used for processing multiple keypairs for a single purpose
2561 *
2562 * This maps CN/SNI name to certificate type
2563 */
2564struct sni_keytype {
2565 int keytypes; /* BITMASK for keytypes */
2566 struct ebmb_node name; /* node holding the servername value */
2567};
2568
2569
yanbzhu488a4d22015-12-01 15:16:07 -05002570/* Frees the contents of a cert_key_and_chain
2571 */
2572static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2573{
2574 int i;
2575
2576 if (!ckch)
2577 return;
2578
2579 /* Free the certificate and set pointer to NULL */
2580 if (ckch->cert)
2581 X509_free(ckch->cert);
2582 ckch->cert = NULL;
2583
2584 /* Free the key and set pointer to NULL */
2585 if (ckch->key)
2586 EVP_PKEY_free(ckch->key);
2587 ckch->key = NULL;
2588
2589 /* Free each certificate in the chain */
2590 for (i = 0; i < ckch->num_chain_certs; i++) {
2591 if (ckch->chain_certs[i])
2592 X509_free(ckch->chain_certs[i]);
2593 }
2594
2595 /* Free the chain obj itself and set to NULL */
2596 if (ckch->num_chain_certs > 0) {
2597 free(ckch->chain_certs);
2598 ckch->num_chain_certs = 0;
2599 ckch->chain_certs = NULL;
2600 }
2601
2602}
2603
2604/* checks if a key and cert exists in the ckch
2605 */
2606static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2607{
2608 return (ckch->cert != NULL && ckch->key != NULL);
2609}
2610
2611
2612/* Loads the contents of a crt file (path) into a cert_key_and_chain
2613 * This allows us to carry the contents of the file without having to
2614 * read the file multiple times.
2615 *
2616 * returns:
2617 * 0 on Success
2618 * 1 on SSL Failure
2619 * 2 on file not found
2620 */
2621static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2622{
2623
2624 BIO *in;
2625 X509 *ca = NULL;
2626 int ret = 1;
2627
2628 ssl_sock_free_cert_key_and_chain_contents(ckch);
2629
2630 in = BIO_new(BIO_s_file());
2631 if (in == NULL)
2632 goto end;
2633
2634 if (BIO_read_filename(in, path) <= 0)
2635 goto end;
2636
yanbzhu488a4d22015-12-01 15:16:07 -05002637 /* Read Private Key */
2638 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2639 if (ckch->key == NULL) {
2640 memprintf(err, "%sunable to load private key from file '%s'.\n",
2641 err && *err ? *err : "", path);
2642 goto end;
2643 }
2644
Willy Tarreaubb137a82016-04-06 19:02:38 +02002645 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002646 if (BIO_reset(in) == -1) {
2647 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2648 err && *err ? *err : "", path);
2649 goto end;
2650 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002651
2652 /* Read Certificate */
2653 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2654 if (ckch->cert == NULL) {
2655 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2656 err && *err ? *err : "", path);
2657 goto end;
2658 }
2659
yanbzhu488a4d22015-12-01 15:16:07 -05002660 /* Read Certificate Chain */
2661 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2662 /* Grow the chain certs */
2663 ckch->num_chain_certs++;
2664 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2665
2666 /* use - 1 here since we just incremented it above */
2667 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2668 }
2669 ret = ERR_get_error();
2670 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2671 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2672 err && *err ? *err : "", path);
2673 ret = 1;
2674 goto end;
2675 }
2676
2677 ret = 0;
2678
2679end:
2680
2681 ERR_clear_error();
2682 if (in)
2683 BIO_free(in);
2684
2685 /* Something went wrong in one of the reads */
2686 if (ret != 0)
2687 ssl_sock_free_cert_key_and_chain_contents(ckch);
2688
2689 return ret;
2690}
2691
2692/* Loads the info in ckch into ctx
2693 * Currently, this does not process any information about ocsp, dhparams or
2694 * sctl
2695 * Returns
2696 * 0 on success
2697 * 1 on failure
2698 */
2699static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2700{
2701 int i = 0;
2702
2703 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2704 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2705 err && *err ? *err : "", path);
2706 return 1;
2707 }
2708
2709 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2710 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2711 err && *err ? *err : "", path);
2712 return 1;
2713 }
2714
yanbzhu488a4d22015-12-01 15:16:07 -05002715 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2716 for (i = 0; i < ckch->num_chain_certs; i++) {
2717 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002718 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2719 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002720 return 1;
2721 }
2722 }
2723
2724 if (SSL_CTX_check_private_key(ctx) <= 0) {
2725 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2726 err && *err ? *err : "", path);
2727 return 1;
2728 }
2729
2730 return 0;
2731}
2732
yanbzhu08ce6ab2015-12-02 13:01:29 -05002733
2734static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2735{
2736 struct sni_keytype *s_kt = NULL;
2737 struct ebmb_node *node;
2738 int i;
2739
2740 for (i = 0; i < trash.size; i++) {
2741 if (!str[i])
2742 break;
2743 trash.str[i] = tolower(str[i]);
2744 }
2745 trash.str[i] = 0;
2746 node = ebst_lookup(sni_keytypes, trash.str);
2747 if (!node) {
2748 /* CN not found in tree */
2749 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2750 /* Using memcpy here instead of strncpy.
2751 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2752 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2753 */
2754 memcpy(s_kt->name.key, trash.str, i+1);
2755 s_kt->keytypes = 0;
2756 ebst_insert(sni_keytypes, &s_kt->name);
2757 } else {
2758 /* CN found in tree */
2759 s_kt = container_of(node, struct sni_keytype, name);
2760 }
2761
2762 /* Mark that this CN has the keytype of key_index via keytypes mask */
2763 s_kt->keytypes |= 1<<key_index;
2764
2765}
2766
2767
2768/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2769 * If any are found, group these files into a set of SSL_CTX*
2770 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2771 *
2772 * This will allow the user to explictly group multiple cert/keys for a single purpose
2773 *
2774 * Returns
2775 * 0 on success
2776 * 1 on failure
2777 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002778static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2779 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002780{
2781 char fp[MAXPATHLEN+1] = {0};
2782 int n = 0;
2783 int i = 0;
2784 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2785 struct eb_root sni_keytypes_map = { {0} };
2786 struct ebmb_node *node;
2787 struct ebmb_node *next;
2788 /* Array of SSL_CTX pointers corresponding to each possible combo
2789 * of keytypes
2790 */
2791 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2792 int rv = 0;
2793 X509_NAME *xname = NULL;
2794 char *str = NULL;
2795#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2796 STACK_OF(GENERAL_NAME) *names = NULL;
2797#endif
2798
2799 /* Load all possible certs and keys */
2800 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2801 struct stat buf;
2802
2803 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2804 if (stat(fp, &buf) == 0) {
2805 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2806 rv = 1;
2807 goto end;
2808 }
2809 }
2810 }
2811
2812 /* Process each ckch and update keytypes for each CN/SAN
2813 * for example, if CN/SAN www.a.com is associated with
2814 * certs with keytype 0 and 2, then at the end of the loop,
2815 * www.a.com will have:
2816 * keyindex = 0 | 1 | 4 = 5
2817 */
2818 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2819
2820 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2821 continue;
2822
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002823 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002824 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002825 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2826 } else {
2827 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2828 * so the line that contains logic is marked via comments
2829 */
2830 xname = X509_get_subject_name(certs_and_keys[n].cert);
2831 i = -1;
2832 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2833 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002834 ASN1_STRING *value;
2835 value = X509_NAME_ENTRY_get_data(entry);
2836 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002837 /* Important line is here */
2838 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002839
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002840 OPENSSL_free(str);
2841 str = NULL;
2842 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002843 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002844
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002845 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002846#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002847 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2848 if (names) {
2849 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2850 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002851
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002852 if (name->type == GEN_DNS) {
2853 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2854 /* Important line is here */
2855 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002856
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002857 OPENSSL_free(str);
2858 str = NULL;
2859 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002860 }
2861 }
2862 }
2863 }
2864#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2865 }
2866
2867 /* If no files found, return error */
2868 if (eb_is_empty(&sni_keytypes_map)) {
2869 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2870 err && *err ? *err : "", path);
2871 rv = 1;
2872 goto end;
2873 }
2874
2875 /* We now have a map of CN/SAN to keytypes that are loaded in
2876 * Iterate through the map to create the SSL_CTX's (if needed)
2877 * and add each CTX to the SNI tree
2878 *
2879 * Some math here:
2880 * There are 2^n - 1 possibile combinations, each unique
2881 * combination is denoted by the key in the map. Each key
2882 * has a value between 1 and 2^n - 1. Conveniently, the array
2883 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2884 * entry in the array to correspond to the unique combo (key)
2885 * associated with i. This unique key combo (i) will be associated
2886 * with combos[i-1]
2887 */
2888
2889 node = ebmb_first(&sni_keytypes_map);
2890 while (node) {
2891 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002892 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002893
2894 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2895 i = container_of(node, struct sni_keytype, name)->keytypes;
2896 cur_ctx = key_combos[i-1].ctx;
2897
2898 if (cur_ctx == NULL) {
2899 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002900 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002901 if (cur_ctx == NULL) {
2902 memprintf(err, "%sunable to allocate SSL context.\n",
2903 err && *err ? *err : "");
2904 rv = 1;
2905 goto end;
2906 }
2907
yanbzhube2774d2015-12-10 15:07:30 -05002908 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002909 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2910 if (i & (1<<n)) {
2911 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002912 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2913 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002914 SSL_CTX_free(cur_ctx);
2915 rv = 1;
2916 goto end;
2917 }
yanbzhube2774d2015-12-10 15:07:30 -05002918
2919#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2920 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002921 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002922 if (err)
2923 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 +00002924 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002925 SSL_CTX_free(cur_ctx);
2926 rv = 1;
2927 goto end;
2928 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02002929#elif (defined OPENSSL_IS_BORINGSSL)
2930 ssl_sock_set_ocsp_response_from_file(cur_ctx, cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002931#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002932 }
2933 }
2934
2935 /* Load DH params into the ctx to support DHE keys */
2936#ifndef OPENSSL_NO_DH
2937 if (ssl_dh_ptr_index >= 0)
2938 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2939
2940 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2941 if (rv < 0) {
2942 if (err)
2943 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2944 *err ? *err : "", path);
2945 rv = 1;
2946 goto end;
2947 }
2948#endif
2949
2950 /* Update key_combos */
2951 key_combos[i-1].ctx = cur_ctx;
2952 }
2953
2954 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002955 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2956 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002957 node = ebmb_next(node);
2958 }
2959
2960
2961 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2962 if (!bind_conf->default_ctx) {
2963 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2964 if (key_combos[i].ctx) {
2965 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002966 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002967 break;
2968 }
2969 }
2970 }
2971
2972end:
2973
2974 if (names)
2975 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2976
2977 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2978 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2979
2980 node = ebmb_first(&sni_keytypes_map);
2981 while (node) {
2982 next = ebmb_next(node);
2983 ebmb_delete(node);
2984 node = next;
2985 }
2986
2987 return rv;
2988}
2989#else
2990/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002991static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2992 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002993{
2994 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2995 err && *err ? *err : "", path, strerror(errno));
2996 return 1;
2997}
2998
yanbzhu488a4d22015-12-01 15:16:07 -05002999#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
3000
Emeric Brunfc0421f2012-09-07 17:30:07 +02003001/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
3002 * an early error happens and the caller must call SSL_CTX_free() by itelf.
3003 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003004static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
3005 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003006{
3007 BIO *in;
3008 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003009 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003010 int ret = -1;
3011 int order = 0;
3012 X509_NAME *xname;
3013 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003014 pem_password_cb *passwd_cb;
3015 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003016 EVP_PKEY *pkey;
3017 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003018
Emeric Brunfc0421f2012-09-07 17:30:07 +02003019#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3020 STACK_OF(GENERAL_NAME) *names;
3021#endif
3022
3023 in = BIO_new(BIO_s_file());
3024 if (in == NULL)
3025 goto end;
3026
3027 if (BIO_read_filename(in, file) <= 0)
3028 goto end;
3029
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003030
3031 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
3032 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
3033
3034 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003035 if (x == NULL)
3036 goto end;
3037
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003038 pkey = X509_get_pubkey(x);
3039 if (pkey) {
3040 switch(EVP_PKEY_base_id(pkey)) {
3041 case EVP_PKEY_RSA:
3042 key_sig = TLSEXT_signature_rsa;
3043 break;
3044 case EVP_PKEY_EC:
3045 key_sig = TLSEXT_signature_ecdsa;
3046 break;
3047 }
3048 EVP_PKEY_free(pkey);
3049 }
3050
Emeric Brun50bcecc2013-04-22 13:05:23 +02003051 if (fcount) {
3052 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003053 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003054 }
3055 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003056#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003057 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
3058 if (names) {
3059 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
3060 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
3061 if (name->type == GEN_DNS) {
3062 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003063 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003064 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003065 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003066 }
3067 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003068 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003069 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003070#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003071 xname = X509_get_subject_name(x);
3072 i = -1;
3073 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
3074 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003075 ASN1_STRING *value;
3076
3077 value = X509_NAME_ENTRY_get_data(entry);
3078 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003079 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003080 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003081 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003082 }
3083 }
3084
3085 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
3086 if (!SSL_CTX_use_certificate(ctx, x))
3087 goto end;
3088
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003089#ifdef SSL_CTX_clear_extra_chain_certs
3090 SSL_CTX_clear_extra_chain_certs(ctx);
3091#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02003092 if (ctx->extra_certs != NULL) {
3093 sk_X509_pop_free(ctx->extra_certs, X509_free);
3094 ctx->extra_certs = NULL;
3095 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003096#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003097
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003098 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003099 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
3100 X509_free(ca);
3101 goto end;
3102 }
3103 }
3104
3105 err = ERR_get_error();
3106 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
3107 /* we successfully reached the last cert in the file */
3108 ret = 1;
3109 }
3110 ERR_clear_error();
3111
3112end:
3113 if (x)
3114 X509_free(x);
3115
3116 if (in)
3117 BIO_free(in);
3118
3119 return ret;
3120}
3121
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003122static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
3123 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003124{
3125 int ret;
3126 SSL_CTX *ctx;
3127
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003128 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02003129 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003130 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
3131 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003132 return 1;
3133 }
3134
3135 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003136 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
3137 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003138 SSL_CTX_free(ctx);
3139 return 1;
3140 }
3141
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003142 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003143 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003144 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
3145 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003146 if (ret < 0) /* serious error, must do that ourselves */
3147 SSL_CTX_free(ctx);
3148 return 1;
3149 }
Emeric Brun61694ab2012-10-26 13:35:33 +02003150
3151 if (SSL_CTX_check_private_key(ctx) <= 0) {
3152 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3153 err && *err ? *err : "", path);
3154 return 1;
3155 }
3156
Emeric Brunfc0421f2012-09-07 17:30:07 +02003157 /* we must not free the SSL_CTX anymore below, since it's already in
3158 * the tree, so it will be discovered and cleaned in time.
3159 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003160#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02003161 /* store a NULL pointer to indicate we have not yet loaded
3162 a custom DH param file */
3163 if (ssl_dh_ptr_index >= 0) {
3164 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
3165 }
3166
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003167 ret = ssl_sock_load_dh_params(ctx, path);
3168 if (ret < 0) {
3169 if (err)
3170 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
3171 *err ? *err : "", path);
3172 return 1;
3173 }
3174#endif
3175
Lukas Tribuse4e30f72014-12-09 16:32:51 +01003176#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02003177 ret = ssl_sock_load_ocsp(ctx, path);
3178 if (ret < 0) {
3179 if (err)
3180 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",
3181 *err ? *err : "", path);
3182 return 1;
3183 }
Emmanuel Hocdet2c32d8f2017-05-22 14:58:00 +02003184#elif (defined OPENSSL_IS_BORINGSSL)
3185 ssl_sock_set_ocsp_response_from_file(ctx, path);
Emeric Brun4147b2e2014-06-16 18:36:30 +02003186#endif
3187
Daniel Jakots54ffb912015-11-06 20:02:41 +01003188#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01003189 if (sctl_ex_index >= 0) {
3190 ret = ssl_sock_load_sctl(ctx, path);
3191 if (ret < 0) {
3192 if (err)
3193 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
3194 *err ? *err : "", path);
3195 return 1;
3196 }
3197 }
3198#endif
3199
Emeric Brunfc0421f2012-09-07 17:30:07 +02003200#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003201 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003202 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
3203 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02003204 return 1;
3205 }
3206#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003207 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003208 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003209 bind_conf->default_ssl_conf = ssl_conf;
3210 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003211
3212 return 0;
3213}
3214
Willy Tarreau03209342016-12-22 17:08:28 +01003215int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003216{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003217 struct dirent **de_list;
3218 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003219 DIR *dir;
3220 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01003221 char *end;
3222 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02003223 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05003224#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3225 int is_bundle;
3226 int j;
3227#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003228
yanbzhu08ce6ab2015-12-02 13:01:29 -05003229 if (stat(path, &buf) == 0) {
3230 dir = opendir(path);
3231 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003232 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003233
yanbzhu08ce6ab2015-12-02 13:01:29 -05003234 /* strip trailing slashes, including first one */
3235 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
3236 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003237
yanbzhu08ce6ab2015-12-02 13:01:29 -05003238 n = scandir(path, &de_list, 0, alphasort);
3239 if (n < 0) {
3240 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
3241 err && *err ? *err : "", path, strerror(errno));
3242 cfgerr++;
3243 }
3244 else {
3245 for (i = 0; i < n; i++) {
3246 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02003247
yanbzhu08ce6ab2015-12-02 13:01:29 -05003248 end = strrchr(de->d_name, '.');
3249 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
3250 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003251
yanbzhu08ce6ab2015-12-02 13:01:29 -05003252 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
3253 if (stat(fp, &buf) != 0) {
3254 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
3255 err && *err ? *err : "", fp, strerror(errno));
3256 cfgerr++;
3257 goto ignore_entry;
3258 }
3259 if (!S_ISREG(buf.st_mode))
3260 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05003261
3262#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3263 is_bundle = 0;
3264 /* Check if current entry in directory is part of a multi-cert bundle */
3265
3266 if (end) {
3267 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
3268 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
3269 is_bundle = 1;
3270 break;
3271 }
3272 }
3273
3274 if (is_bundle) {
3275 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
3276 int dp_len;
3277
3278 dp_len = end - de->d_name;
3279 snprintf(dp, dp_len + 1, "%s", de->d_name);
3280
3281 /* increment i and free de until we get to a non-bundle cert
3282 * Note here that we look at de_list[i + 1] before freeing de
3283 * this is important since ignore_entry will free de
3284 */
3285 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
3286 free(de);
3287 i++;
3288 de = de_list[i];
3289 }
3290
3291 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003292 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05003293
3294 /* Successfully processed the bundle */
3295 goto ignore_entry;
3296 }
3297 }
3298
3299#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003300 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003301ignore_entry:
3302 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01003303 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003304 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003305 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003306 closedir(dir);
3307 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003308 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05003309
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003310 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05003311
Emeric Brunfc0421f2012-09-07 17:30:07 +02003312 return cfgerr;
3313}
3314
Thierry Fournier383085f2013-01-24 14:15:43 +01003315/* Make sure openssl opens /dev/urandom before the chroot. The work is only
3316 * done once. Zero is returned if the operation fails. No error is returned
3317 * if the random is said as not implemented, because we expect that openssl
3318 * will use another method once needed.
3319 */
3320static int ssl_initialize_random()
3321{
3322 unsigned char random;
3323 static int random_initialized = 0;
3324
3325 if (!random_initialized && RAND_bytes(&random, 1) != 0)
3326 random_initialized = 1;
3327
3328 return random_initialized;
3329}
3330
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003331/* release ssl bind conf */
3332void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003333{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003334 if (conf) {
3335#ifdef OPENSSL_NPN_NEGOTIATED
3336 free(conf->npn_str);
3337 conf->npn_str = NULL;
3338#endif
3339#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
3340 free(conf->alpn_str);
3341 conf->alpn_str = NULL;
3342#endif
3343 free(conf->ca_file);
3344 conf->ca_file = NULL;
3345 free(conf->crl_file);
3346 conf->crl_file = NULL;
3347 free(conf->ciphers);
3348 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003349 free(conf->curves);
3350 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003351 free(conf->ecdhe);
3352 conf->ecdhe = NULL;
3353 }
3354}
3355
3356int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
3357{
3358 char thisline[CRT_LINESIZE];
3359 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003360 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05003361 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003362 int linenum = 0;
3363 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003364
Willy Tarreauad1731d2013-04-02 17:35:58 +02003365 if ((f = fopen(file, "r")) == NULL) {
3366 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003367 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003368 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003369
3370 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003371 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003372 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003373 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003374 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003375 char *crt_path;
3376 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003377
3378 linenum++;
3379 end = line + strlen(line);
3380 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3381 /* Check if we reached the limit and the last char is not \n.
3382 * Watch out for the last line without the terminating '\n'!
3383 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003384 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3385 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003386 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003387 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003388 }
3389
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003390 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003391 newarg = 1;
3392 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003393 if (*line == '#' || *line == '\n' || *line == '\r') {
3394 /* end of string, end of loop */
3395 *line = 0;
3396 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003397 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003398 newarg = 1;
3399 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003400 } else if (*line == '[') {
3401 if (ssl_b) {
3402 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3403 cfgerr = 1;
3404 break;
3405 }
3406 if (!arg) {
3407 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3408 cfgerr = 1;
3409 break;
3410 }
3411 ssl_b = arg;
3412 newarg = 1;
3413 *line = 0;
3414 } else if (*line == ']') {
3415 if (ssl_e) {
3416 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003417 cfgerr = 1;
3418 break;
3419 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003420 if (!ssl_b) {
3421 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3422 cfgerr = 1;
3423 break;
3424 }
3425 ssl_e = arg;
3426 newarg = 1;
3427 *line = 0;
3428 } else if (newarg) {
3429 if (arg == MAX_CRT_ARGS) {
3430 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3431 cfgerr = 1;
3432 break;
3433 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003434 newarg = 0;
3435 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003436 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003437 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003438 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003439 if (cfgerr)
3440 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003441 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003442
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003443 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003444 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003445 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003446
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003447 crt_path = args[0];
3448 if (*crt_path != '/' && global_ssl.crt_base) {
3449 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3450 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3451 crt_path, linenum, file);
3452 cfgerr = 1;
3453 break;
3454 }
3455 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3456 crt_path = path;
3457 }
3458
3459 ssl_conf = calloc(1, sizeof *ssl_conf);
3460 cur_arg = ssl_b ? ssl_b : 1;
3461 while (cur_arg < ssl_e) {
3462 newarg = 0;
3463 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3464 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3465 newarg = 1;
3466 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3467 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3468 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3469 args[cur_arg], linenum, file);
3470 cfgerr = 1;
3471 }
3472 cur_arg += 1 + ssl_bind_kws[i].skip;
3473 break;
3474 }
3475 }
3476 if (!cfgerr && !newarg) {
3477 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3478 args[cur_arg], linenum, file);
3479 cfgerr = 1;
3480 break;
3481 }
3482 }
3483 if (cfgerr) {
3484 ssl_sock_free_ssl_conf(ssl_conf);
3485 free(ssl_conf);
3486 ssl_conf = NULL;
3487 break;
3488 }
3489
3490 if (stat(crt_path, &buf) == 0) {
3491 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3492 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003493 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003494 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3495 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003496 }
3497
Willy Tarreauad1731d2013-04-02 17:35:58 +02003498 if (cfgerr) {
3499 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003500 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003501 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003502 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003503 fclose(f);
3504 return cfgerr;
3505}
3506
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003507/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003508static int
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003509ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003510{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003511 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003512 long options =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003513 SSL_OP_ALL | /* all known workarounds for bugs */
3514 SSL_OP_NO_SSLv2 |
3515 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003516 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003517 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003518 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3519 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003520 long mode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003521 SSL_MODE_ENABLE_PARTIAL_WRITE |
3522 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003523 SSL_MODE_RELEASE_BUFFERS |
3524 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003525 struct tls_version_filter *conf_ssl_methods = &bind_conf->ssl_methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003526 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003527 int flags = MC_SSL_O_ALL;
3528 int cfgerr = 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003529
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003530 ctx = SSL_CTX_new(SSLv23_server_method());
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003531 bind_conf->initial_ctx = ctx;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003532
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003533 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
3534 Warning("Proxy '%s': no-sslv3/no-tlsv1x are ignored for bind '%s' at [%s:%d]. "
3535 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
3536 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3537 else
3538 flags = conf_ssl_methods->flags;
3539
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003540 /* Real min and max should be determinate with configuration and openssl's capabilities */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003541 if (conf_ssl_methods->min)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003542 flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003543 if (conf_ssl_methods->max)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003544 flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003545
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003546 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003547 min = max = CONF_TLSV_NONE;
3548 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003549 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003550 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003551 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003552 if (min) {
3553 if (hole) {
3554 Warning("Proxy '%s': SSL/TLS versions range not contiguous for bind '%s' at [%s:%d]. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003555 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003556 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line,
3557 methodVersions[hole].name);
3558 hole = 0;
3559 }
3560 max = i;
3561 }
3562 else {
3563 min = max = i;
3564 }
3565 }
3566 else {
3567 if (min)
3568 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003569 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003570 if (!min) {
3571 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003572 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003573 cfgerr += 1;
3574 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003575
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003576#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3577 /* Keep force-xxx implementation as it is in older haproxy. It's a
3578 precautionary measure to avoid any suprise with older openssl version. */
3579 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003580 methodVersions[min].ctx_set_version(ctx, SET_SERVER);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003581 else
3582 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3583 if (flags & methodVersions[i].flag)
3584 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003585#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003586 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003587 methodVersions[min].ctx_set_version(ctx, SET_MIN);
3588 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003589#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003590
3591 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3592 options |= SSL_OP_NO_TICKET;
3593 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
3594 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
3595 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00003596
3597#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
3598 if (global_ssl.async)
3599 mode |= SSL_MODE_ASYNC;
3600#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003601 SSL_CTX_set_mode(ctx, mode);
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003602 if (global_ssl.life_time)
3603 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003604
3605#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3606#ifdef OPENSSL_IS_BORINGSSL
3607 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3608 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3609#else
3610 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3611 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3612#endif
3613#endif
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003614 return cfgerr;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003615}
3616
3617int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3618{
3619 struct proxy *curproxy = bind_conf->frontend;
3620 int cfgerr = 0;
3621 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003622 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003623 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003624 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003625
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003626 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003627 case SSL_SOCK_VERIFY_NONE:
3628 verify = SSL_VERIFY_NONE;
3629 break;
3630 case SSL_SOCK_VERIFY_OPTIONAL:
3631 verify = SSL_VERIFY_PEER;
3632 break;
3633 case SSL_SOCK_VERIFY_REQUIRED:
3634 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3635 break;
3636 }
3637 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3638 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003639 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3640 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3641 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003642 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003643 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003644 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003645 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003646 cfgerr++;
3647 }
3648 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003649 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003650 }
Emeric Brun850efd52014-01-29 12:24:34 +01003651 else {
3652 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3653 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3654 cfgerr++;
3655 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003656#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003657 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003658 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3659
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003660 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003661 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003662 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003663 cfgerr++;
3664 }
Emeric Brun561e5742012-10-02 15:20:55 +02003665 else {
3666 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3667 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003668 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003669#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003670 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003671 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003672#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003673 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003674 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3675 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3676 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3677 cfgerr++;
3678 }
3679 }
3680#endif
3681
Emeric Brunfc0421f2012-09-07 17:30:07 +02003682 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003683 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3684 if (conf_ciphers &&
3685 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003686 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 +01003687 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003688 cfgerr++;
3689 }
3690
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003691#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003692 /* If tune.ssl.default-dh-param has not been set,
3693 neither has ssl-default-dh-file and no static DH
3694 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003695 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003696 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003697 (ssl_dh_ptr_index == -1 ||
3698 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003699 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3700 const SSL_CIPHER * cipher = NULL;
3701 char cipher_description[128];
3702 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3703 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3704 which is not ephemeral DH. */
3705 const char dhe_description[] = " Kx=DH ";
3706 const char dhe_export_description[] = " Kx=DH(";
3707 int idx = 0;
3708 int dhe_found = 0;
3709 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003710
Remi Gacogne23d5d372014-10-10 17:04:26 +02003711 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003712
Remi Gacogne23d5d372014-10-10 17:04:26 +02003713 if (ssl) {
3714 ciphers = SSL_get_ciphers(ssl);
3715
3716 if (ciphers) {
3717 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3718 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3719 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3720 if (strstr(cipher_description, dhe_description) != NULL ||
3721 strstr(cipher_description, dhe_export_description) != NULL) {
3722 dhe_found = 1;
3723 break;
3724 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003725 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003726 }
3727 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003728 SSL_free(ssl);
3729 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003730 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003731
Lukas Tribus90132722014-08-18 00:56:33 +02003732 if (dhe_found) {
3733 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 +02003734 }
3735
Willy Tarreauef934602016-12-22 23:12:01 +01003736 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003737 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003738
Willy Tarreauef934602016-12-22 23:12:01 +01003739 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003740 if (local_dh_1024 == NULL) {
3741 local_dh_1024 = ssl_get_dh_1024();
3742 }
Willy Tarreauef934602016-12-22 23:12:01 +01003743 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003744 if (local_dh_2048 == NULL) {
3745 local_dh_2048 = ssl_get_dh_2048();
3746 }
Willy Tarreauef934602016-12-22 23:12:01 +01003747 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003748 if (local_dh_4096 == NULL) {
3749 local_dh_4096 = ssl_get_dh_4096();
3750 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003751 }
3752 }
3753 }
3754#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003755
Emeric Brunfc0421f2012-09-07 17:30:07 +02003756 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003757#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003758 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003759#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003760
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003761#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003762 ssl_conf_cur = NULL;
3763 if (ssl_conf && ssl_conf->npn_str)
3764 ssl_conf_cur = ssl_conf;
3765 else if (bind_conf->ssl_conf.npn_str)
3766 ssl_conf_cur = &bind_conf->ssl_conf;
3767 if (ssl_conf_cur)
3768 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003769#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003770#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003771 ssl_conf_cur = NULL;
3772 if (ssl_conf && ssl_conf->alpn_str)
3773 ssl_conf_cur = ssl_conf;
3774 else if (bind_conf->ssl_conf.alpn_str)
3775 ssl_conf_cur = &bind_conf->ssl_conf;
3776 if (ssl_conf_cur)
3777 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003778#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003779#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3780 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3781 if (conf_curves) {
3782 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3783 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3784 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3785 cfgerr++;
3786 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003787#if defined(SSL_CTX_set_ecdh_auto)
3788 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3789#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003790 }
3791#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003792#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003793 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003794 int i;
3795 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003796 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3797 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003798
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003799 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003800 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3801 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 +01003802 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003803 cfgerr++;
3804 }
3805 else {
3806 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3807 EC_KEY_free(ecdh);
3808 }
3809 }
3810#endif
3811
Emeric Brunfc0421f2012-09-07 17:30:07 +02003812 return cfgerr;
3813}
3814
Evan Broderbe554312013-06-27 00:05:25 -07003815static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3816{
3817 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3818 size_t prefixlen, suffixlen;
3819
3820 /* Trivial case */
3821 if (strcmp(pattern, hostname) == 0)
3822 return 1;
3823
Evan Broderbe554312013-06-27 00:05:25 -07003824 /* The rest of this logic is based on RFC 6125, section 6.4.3
3825 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3826
Emeric Bruna848dae2013-10-08 11:27:28 +02003827 pattern_wildcard = NULL;
3828 pattern_left_label_end = pattern;
3829 while (*pattern_left_label_end != '.') {
3830 switch (*pattern_left_label_end) {
3831 case 0:
3832 /* End of label not found */
3833 return 0;
3834 case '*':
3835 /* If there is more than one wildcards */
3836 if (pattern_wildcard)
3837 return 0;
3838 pattern_wildcard = pattern_left_label_end;
3839 break;
3840 }
3841 pattern_left_label_end++;
3842 }
3843
3844 /* If it's not trivial and there is no wildcard, it can't
3845 * match */
3846 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003847 return 0;
3848
3849 /* Make sure all labels match except the leftmost */
3850 hostname_left_label_end = strchr(hostname, '.');
3851 if (!hostname_left_label_end
3852 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3853 return 0;
3854
3855 /* Make sure the leftmost label of the hostname is long enough
3856 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003857 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003858 return 0;
3859
3860 /* Finally compare the string on either side of the
3861 * wildcard */
3862 prefixlen = pattern_wildcard - pattern;
3863 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003864 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3865 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003866 return 0;
3867
3868 return 1;
3869}
3870
3871static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3872{
3873 SSL *ssl;
3874 struct connection *conn;
3875 char *servername;
3876
3877 int depth;
3878 X509 *cert;
3879 STACK_OF(GENERAL_NAME) *alt_names;
3880 int i;
3881 X509_NAME *cert_subject;
3882 char *str;
3883
3884 if (ok == 0)
3885 return ok;
3886
3887 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003888 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003889
3890 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3891
3892 /* We only need to verify the CN on the actual server cert,
3893 * not the indirect CAs */
3894 depth = X509_STORE_CTX_get_error_depth(ctx);
3895 if (depth != 0)
3896 return ok;
3897
3898 /* At this point, the cert is *not* OK unless we can find a
3899 * hostname match */
3900 ok = 0;
3901
3902 cert = X509_STORE_CTX_get_current_cert(ctx);
3903 /* It seems like this might happen if verify peer isn't set */
3904 if (!cert)
3905 return ok;
3906
3907 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3908 if (alt_names) {
3909 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3910 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3911 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003912#if OPENSSL_VERSION_NUMBER < 0x00907000L
3913 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3914#else
Evan Broderbe554312013-06-27 00:05:25 -07003915 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003916#endif
Evan Broderbe554312013-06-27 00:05:25 -07003917 ok = ssl_sock_srv_hostcheck(str, servername);
3918 OPENSSL_free(str);
3919 }
3920 }
3921 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003922 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003923 }
3924
3925 cert_subject = X509_get_subject_name(cert);
3926 i = -1;
3927 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3928 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003929 ASN1_STRING *value;
3930 value = X509_NAME_ENTRY_get_data(entry);
3931 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003932 ok = ssl_sock_srv_hostcheck(str, servername);
3933 OPENSSL_free(str);
3934 }
3935 }
3936
3937 return ok;
3938}
3939
Emeric Brun94324a42012-10-11 14:00:19 +02003940/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003941int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003942{
Willy Tarreau03209342016-12-22 17:08:28 +01003943 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003944 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003945 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003946 SSL_OP_ALL | /* all known workarounds for bugs */
3947 SSL_OP_NO_SSLv2 |
3948 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003949 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003950 SSL_MODE_ENABLE_PARTIAL_WRITE |
3951 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003952 SSL_MODE_RELEASE_BUFFERS |
3953 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003954 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003955 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003956 struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003957 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003958 int flags = MC_SSL_O_ALL;
Emeric Brun94324a42012-10-11 14:00:19 +02003959
Thierry Fournier383085f2013-01-24 14:15:43 +01003960 /* Make sure openssl opens /dev/urandom before the chroot */
3961 if (!ssl_initialize_random()) {
3962 Alert("OpenSSL random data generator initialization failed.\n");
3963 cfgerr++;
3964 }
3965
Willy Tarreaufce03112015-01-15 21:32:40 +01003966 /* Automatic memory computations need to know we use SSL there */
3967 global.ssl_used_backend = 1;
3968
3969 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003970 srv->ssl_ctx.reused_sess = NULL;
3971 if (srv->use_ssl)
3972 srv->xprt = &ssl_sock;
3973 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003974 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003975
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003976 ctx = SSL_CTX_new(SSLv23_client_method());
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003977 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02003978 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3979 proxy_type_str(curproxy), curproxy->id,
3980 srv->id);
3981 cfgerr++;
3982 return cfgerr;
3983 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003984
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003985 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
3986 Warning("config : %s '%s': no-sslv3/no-tlsv1x are ignored for server '%s'. "
3987 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
3988 proxy_type_str(curproxy), curproxy->id, srv->id);
3989 else
3990 flags = conf_ssl_methods->flags;
3991
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003992 /* Real min and max should be determinate with configuration and openssl's capabilities */
3993 if (conf_ssl_methods->min)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003994 flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003995 if (conf_ssl_methods->max)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003996 flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003997
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02003998 /* find min, max and holes */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003999 min = max = CONF_TLSV_NONE;
4000 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004001 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004002 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004003 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004004 if (min) {
4005 if (hole) {
4006 Warning("config : %s '%s': SSL/TLS versions range not contiguous for server '%s'. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02004007 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004008 proxy_type_str(curproxy), curproxy->id, srv->id,
4009 methodVersions[hole].name);
4010 hole = 0;
4011 }
4012 max = i;
4013 }
4014 else {
4015 min = max = i;
4016 }
4017 }
4018 else {
4019 if (min)
4020 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004021 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004022 if (!min) {
4023 Alert("config : %s '%s': all SSL/TLS versions are disabled for server '%s'.\n",
4024 proxy_type_str(curproxy), curproxy->id, srv->id);
4025 cfgerr += 1;
4026 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004027
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004028#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
4029 /* Keep force-xxx implementation as it is in older haproxy. It's a
4030 precautionary measure to avoid any suprise with older openssl version. */
4031 if (min == max)
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004032 methodVersions[min].ctx_set_version(ctx, SET_CLIENT);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004033 else
4034 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
4035 if (flags & methodVersions[i].flag)
4036 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004037#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02004038 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet4aa615f2017-05-18 12:33:19 +02004039 methodVersions[min].ctx_set_version(ctx, SET_MIN);
4040 methodVersions[max].ctx_set_version(ctx, SET_MAX);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02004041#endif
4042
4043 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
4044 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004045 SSL_CTX_set_options(ctx, options);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004046
4047#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4048 if (global_ssl.async)
4049 mode |= SSL_MODE_ASYNC;
4050#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01004051 SSL_CTX_set_mode(ctx, mode);
4052 srv->ssl_ctx.ctx = ctx;
4053
Emeric Bruna7aa3092012-10-26 12:58:00 +02004054 if (srv->ssl_ctx.client_crt) {
4055 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
4056 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
4057 proxy_type_str(curproxy), curproxy->id,
4058 srv->id, srv->ssl_ctx.client_crt);
4059 cfgerr++;
4060 }
4061 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
4062 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
4063 proxy_type_str(curproxy), curproxy->id,
4064 srv->id, srv->ssl_ctx.client_crt);
4065 cfgerr++;
4066 }
4067 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
4068 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
4069 proxy_type_str(curproxy), curproxy->id,
4070 srv->id, srv->ssl_ctx.client_crt);
4071 cfgerr++;
4072 }
4073 }
Emeric Brun94324a42012-10-11 14:00:19 +02004074
Emeric Brun850efd52014-01-29 12:24:34 +01004075 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
4076 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01004077 switch (srv->ssl_ctx.verify) {
4078 case SSL_SOCK_VERIFY_NONE:
4079 verify = SSL_VERIFY_NONE;
4080 break;
4081 case SSL_SOCK_VERIFY_REQUIRED:
4082 verify = SSL_VERIFY_PEER;
4083 break;
4084 }
Evan Broderbe554312013-06-27 00:05:25 -07004085 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01004086 verify,
Evan Broderbe554312013-06-27 00:05:25 -07004087 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01004088 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02004089 if (srv->ssl_ctx.ca_file) {
4090 /* load CAfile to verify */
4091 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004092 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004093 curproxy->id, srv->id,
4094 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
4095 cfgerr++;
4096 }
4097 }
Emeric Brun850efd52014-01-29 12:24:34 +01004098 else {
4099 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004100 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 +01004101 curproxy->id, srv->id,
4102 srv->conf.file, srv->conf.line);
4103 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004104 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01004105 curproxy->id, srv->id,
4106 srv->conf.file, srv->conf.line);
4107 cfgerr++;
4108 }
Emeric Brunef42d922012-10-11 16:11:36 +02004109#ifdef X509_V_FLAG_CRL_CHECK
4110 if (srv->ssl_ctx.crl_file) {
4111 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
4112
4113 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01004114 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02004115 curproxy->id, srv->id,
4116 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
4117 cfgerr++;
4118 }
4119 else {
4120 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
4121 }
4122 }
4123#endif
4124 }
4125
Emeric Brun94324a42012-10-11 14:00:19 +02004126 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
4127 if (srv->ssl_ctx.ciphers &&
4128 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
4129 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
4130 curproxy->id, srv->id,
4131 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
4132 cfgerr++;
4133 }
4134
4135 return cfgerr;
4136}
4137
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004138/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004139 * be NULL, in which case nothing is done. Returns the number of errors
4140 * encountered.
4141 */
Willy Tarreau03209342016-12-22 17:08:28 +01004142int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004143{
4144 struct ebmb_node *node;
4145 struct sni_ctx *sni;
4146 int err = 0;
4147
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004148 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004149 return 0;
4150
Willy Tarreaufce03112015-01-15 21:32:40 +01004151 /* Automatic memory computations need to know we use SSL there */
4152 global.ssl_used_frontend = 1;
4153
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004154 /* Make sure openssl opens /dev/urandom before the chroot */
4155 if (!ssl_initialize_random()) {
4156 Alert("OpenSSL random data generator initialization failed.\n");
4157 err++;
4158 }
4159 /* Create initial_ctx used to start the ssl connection before do switchctx */
4160 if (!bind_conf->initial_ctx) {
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02004161 err += ssl_sock_initial_ctx(bind_conf);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004162 /* It should not be necessary to call this function, but it's
4163 necessary first to check and move all initialisation related
4164 to initial_ctx in ssl_sock_initial_ctx. */
4165 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
4166 }
Emeric Brun0bed9942014-10-30 19:25:24 +01004167 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004168 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01004169
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004170 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004171 while (node) {
4172 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004173 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4174 /* only initialize the CTX on its first occurrence and
4175 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004176 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004177 node = ebmb_next(node);
4178 }
4179
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004180 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004181 while (node) {
4182 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01004183 if (!sni->order && sni->ctx != bind_conf->default_ctx)
4184 /* only initialize the CTX on its first occurrence and
4185 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004186 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004187 node = ebmb_next(node);
4188 }
4189 return err;
4190}
4191
Willy Tarreau55d37912016-12-21 23:38:39 +01004192/* Prepares all the contexts for a bind_conf and allocates the shared SSL
4193 * context if needed. Returns < 0 on error, 0 on success. The warnings and
4194 * alerts are directly emitted since the rest of the stack does it below.
4195 */
4196int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
4197{
4198 struct proxy *px = bind_conf->frontend;
4199 int alloc_ctx;
4200 int err;
4201
4202 if (!bind_conf->is_ssl) {
4203 if (bind_conf->default_ctx) {
4204 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
4205 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4206 }
4207 return 0;
4208 }
4209 if (!bind_conf->default_ctx) {
4210 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
4211 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
4212 return -1;
4213 }
4214
Willy Tarreauef934602016-12-22 23:12:01 +01004215 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01004216 if (alloc_ctx < 0) {
4217 if (alloc_ctx == SHCTX_E_INIT_LOCK)
4218 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");
4219 else
4220 Alert("Unable to allocate SSL session cache.\n");
4221 return -1;
4222 }
4223
4224 err = 0;
4225 /* initialize all certificate contexts */
4226 err += ssl_sock_prepare_all_ctx(bind_conf);
4227
4228 /* initialize CA variables if the certificates generation is enabled */
4229 err += ssl_sock_load_ca(bind_conf);
4230
4231 return -err;
4232}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02004233
4234/* release ssl context allocated for servers. */
4235void ssl_sock_free_srv_ctx(struct server *srv)
4236{
4237 if (srv->ssl_ctx.ctx)
4238 SSL_CTX_free(srv->ssl_ctx.ctx);
4239}
4240
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004241/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02004242 * be NULL, in which case nothing is done. The default_ctx is nullified too.
4243 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004244void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004245{
4246 struct ebmb_node *node, *back;
4247 struct sni_ctx *sni;
4248
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004249 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004250 return;
4251
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004252 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004253 while (node) {
4254 sni = ebmb_entry(node, struct sni_ctx, name);
4255 back = ebmb_next(node);
4256 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004257 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004258 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004259 ssl_sock_free_ssl_conf(sni->conf);
4260 free(sni->conf);
4261 sni->conf = NULL;
4262 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004263 free(sni);
4264 node = back;
4265 }
4266
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004267 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004268 while (node) {
4269 sni = ebmb_entry(node, struct sni_ctx, name);
4270 back = ebmb_next(node);
4271 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004272 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004273 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004274 ssl_sock_free_ssl_conf(sni->conf);
4275 free(sni->conf);
4276 sni->conf = NULL;
4277 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004278 free(sni);
4279 node = back;
4280 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004281 SSL_CTX_free(bind_conf->initial_ctx);
4282 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004283 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004284 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02004285}
4286
Willy Tarreau795cdab2016-12-22 17:30:54 +01004287/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
4288void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
4289{
4290 ssl_sock_free_ca(bind_conf);
4291 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004292 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004293 free(bind_conf->ca_sign_file);
4294 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004295 if (bind_conf->keys_ref) {
4296 free(bind_conf->keys_ref->filename);
4297 free(bind_conf->keys_ref->tlskeys);
4298 LIST_DEL(&bind_conf->keys_ref->list);
4299 free(bind_conf->keys_ref);
4300 }
4301 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004302 bind_conf->ca_sign_pass = NULL;
4303 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004304}
4305
Christopher Faulet31af49d2015-06-09 17:29:50 +02004306/* Load CA cert file and private key used to generate certificates */
4307int
Willy Tarreau03209342016-12-22 17:08:28 +01004308ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02004309{
Willy Tarreau03209342016-12-22 17:08:28 +01004310 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004311 FILE *fp;
4312 X509 *cacert = NULL;
4313 EVP_PKEY *capkey = NULL;
4314 int err = 0;
4315
4316 if (!bind_conf || !bind_conf->generate_certs)
4317 return err;
4318
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004319#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01004320 if (global_ssl.ctx_cache)
4321 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02004322 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02004323#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02004324
Christopher Faulet31af49d2015-06-09 17:29:50 +02004325 if (!bind_conf->ca_sign_file) {
4326 Alert("Proxy '%s': cannot enable certificate generation, "
4327 "no CA certificate File configured at [%s:%d].\n",
4328 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004329 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004330 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004331
4332 /* read in the CA certificate */
4333 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
4334 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4335 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004336 goto load_error;
4337 }
4338 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
4339 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4340 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004341 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004342 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004343 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004344 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
4345 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
4346 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004347 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004348 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004349
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004350 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004351 bind_conf->ca_sign_cert = cacert;
4352 bind_conf->ca_sign_pkey = capkey;
4353 return err;
4354
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004355 read_error:
4356 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004357 if (capkey) EVP_PKEY_free(capkey);
4358 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004359 load_error:
4360 bind_conf->generate_certs = 0;
4361 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004362 return err;
4363}
4364
4365/* Release CA cert and private key used to generate certificated */
4366void
4367ssl_sock_free_ca(struct bind_conf *bind_conf)
4368{
4369 if (!bind_conf)
4370 return;
4371
4372 if (bind_conf->ca_sign_pkey)
4373 EVP_PKEY_free(bind_conf->ca_sign_pkey);
4374 if (bind_conf->ca_sign_cert)
4375 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01004376 bind_conf->ca_sign_pkey = NULL;
4377 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004378}
4379
Emeric Brun46591952012-05-18 15:47:34 +02004380/*
4381 * This function is called if SSL * context is not yet allocated. The function
4382 * is designed to be called before any other data-layer operation and sets the
4383 * handshake flag on the connection. It is safe to call it multiple times.
4384 * It returns 0 on success and -1 in error case.
4385 */
4386static int ssl_sock_init(struct connection *conn)
4387{
4388 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004389 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004390 return 0;
4391
Willy Tarreau3c728722014-01-23 13:50:42 +01004392 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004393 return 0;
4394
Willy Tarreau20879a02012-12-03 16:32:10 +01004395 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4396 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004397 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004398 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004399
Emeric Brun46591952012-05-18 15:47:34 +02004400 /* If it is in client mode initiate SSL session
4401 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004402 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004403 int may_retry = 1;
4404
4405 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004406 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004407 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004408 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004409 if (may_retry--) {
4410 pool_gc2();
4411 goto retry_connect;
4412 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004413 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004414 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004415 }
Emeric Brun46591952012-05-18 15:47:34 +02004416
Emeric Brun46591952012-05-18 15:47:34 +02004417 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004418 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4419 SSL_free(conn->xprt_ctx);
4420 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004421 if (may_retry--) {
4422 pool_gc2();
4423 goto retry_connect;
4424 }
Emeric Brun55476152014-11-12 17:35:37 +01004425 conn->err_code = CO_ER_SSL_NO_MEM;
4426 return -1;
4427 }
Emeric Brun46591952012-05-18 15:47:34 +02004428
Evan Broderbe554312013-06-27 00:05:25 -07004429 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004430 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4431 SSL_free(conn->xprt_ctx);
4432 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004433 if (may_retry--) {
4434 pool_gc2();
4435 goto retry_connect;
4436 }
Emeric Brun55476152014-11-12 17:35:37 +01004437 conn->err_code = CO_ER_SSL_NO_MEM;
4438 return -1;
4439 }
4440
4441 SSL_set_connect_state(conn->xprt_ctx);
4442 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4443 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4444 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4445 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4446 }
4447 }
Evan Broderbe554312013-06-27 00:05:25 -07004448
Emeric Brun46591952012-05-18 15:47:34 +02004449 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004450 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004451
4452 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004453 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004454 return 0;
4455 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004456 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004457 int may_retry = 1;
4458
4459 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004460 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004461 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004462 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004463 if (may_retry--) {
4464 pool_gc2();
4465 goto retry_accept;
4466 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004467 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004468 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004469 }
Emeric Brun46591952012-05-18 15:47:34 +02004470
Emeric Brun46591952012-05-18 15:47:34 +02004471 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004472 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4473 SSL_free(conn->xprt_ctx);
4474 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004475 if (may_retry--) {
4476 pool_gc2();
4477 goto retry_accept;
4478 }
Emeric Brun55476152014-11-12 17:35:37 +01004479 conn->err_code = CO_ER_SSL_NO_MEM;
4480 return -1;
4481 }
Emeric Brun46591952012-05-18 15:47:34 +02004482
Emeric Brune1f38db2012-09-03 20:36:47 +02004483 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004484 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4485 SSL_free(conn->xprt_ctx);
4486 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004487 if (may_retry--) {
4488 pool_gc2();
4489 goto retry_accept;
4490 }
Emeric Brun55476152014-11-12 17:35:37 +01004491 conn->err_code = CO_ER_SSL_NO_MEM;
4492 return -1;
4493 }
4494
4495 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004496
Emeric Brun46591952012-05-18 15:47:34 +02004497 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004498 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004499
4500 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004501 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004502 return 0;
4503 }
4504 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004505 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004506 return -1;
4507}
4508
4509
4510/* This is the callback which is used when an SSL handshake is pending. It
4511 * updates the FD status if it wants some polling before being called again.
4512 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4513 * otherwise it returns non-zero and removes itself from the connection's
4514 * flags (the bit is provided in <flag> by the caller).
4515 */
4516int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4517{
4518 int ret;
4519
Willy Tarreau3c728722014-01-23 13:50:42 +01004520 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004521 return 0;
4522
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004523 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004524 goto out_error;
4525
Emeric Brun674b7432012-11-08 19:21:55 +01004526 /* If we use SSL_do_handshake to process a reneg initiated by
4527 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4528 * Usually SSL_write and SSL_read are used and process implicitly
4529 * the reneg handshake.
4530 * Here we use SSL_peek as a workaround for reneg.
4531 */
4532 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4533 char c;
4534
4535 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4536 if (ret <= 0) {
4537 /* handshake may have not been completed, let's find why */
4538 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004539
Emeric Brun674b7432012-11-08 19:21:55 +01004540 if (ret == SSL_ERROR_WANT_WRITE) {
4541 /* SSL handshake needs to write, L4 connection may not be ready */
4542 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004543 __conn_sock_want_send(conn);
4544 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004545 return 0;
4546 }
4547 else if (ret == SSL_ERROR_WANT_READ) {
4548 /* handshake may have been completed but we have
4549 * no more data to read.
4550 */
4551 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4552 ret = 1;
4553 goto reneg_ok;
4554 }
4555 /* SSL handshake needs to read, L4 connection is ready */
4556 if (conn->flags & CO_FL_WAIT_L4_CONN)
4557 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4558 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004559 __conn_sock_want_recv(conn);
4560 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004561 return 0;
4562 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004563#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4564 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004565 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004566 return 0;
4567 }
4568#endif
Emeric Brun674b7432012-11-08 19:21:55 +01004569 else if (ret == SSL_ERROR_SYSCALL) {
4570 /* if errno is null, then connection was successfully established */
4571 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4572 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004573 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004574#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4575 conn->err_code = CO_ER_SSL_HANDSHAKE;
4576#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004577 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004578#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004579 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4580 empty_handshake = state == TLS_ST_BEFORE;
4581#else
4582 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4583#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004584 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004585 if (!errno) {
4586 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4587 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4588 else
4589 conn->err_code = CO_ER_SSL_EMPTY;
4590 }
4591 else {
4592 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4593 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4594 else
4595 conn->err_code = CO_ER_SSL_ABORT;
4596 }
4597 }
4598 else {
4599 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4600 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004601 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004602 conn->err_code = CO_ER_SSL_HANDSHAKE;
4603 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004604#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004605 }
Emeric Brun674b7432012-11-08 19:21:55 +01004606 goto out_error;
4607 }
4608 else {
4609 /* Fail on all other handshake errors */
4610 /* Note: OpenSSL may leave unread bytes in the socket's
4611 * buffer, causing an RST to be emitted upon close() on
4612 * TCP sockets. We first try to drain possibly pending
4613 * data to avoid this as much as possible.
4614 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004615 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004616 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004617 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4618 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004619 goto out_error;
4620 }
4621 }
4622 /* read some data: consider handshake completed */
4623 goto reneg_ok;
4624 }
4625
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004626 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004627 if (ret != 1) {
4628 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004629 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004630
4631 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 Brun46591952012-05-18 15:47:34 +02004636 return 0;
4637 }
4638 else if (ret == SSL_ERROR_WANT_READ) {
4639 /* SSL handshake needs to read, L4 connection is ready */
4640 if (conn->flags & CO_FL_WAIT_L4_CONN)
4641 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4642 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004643 __conn_sock_want_recv(conn);
4644 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004645 return 0;
4646 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004647#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4648 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004649 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004650 return 0;
4651 }
4652#endif
Willy Tarreau89230192012-09-28 20:22:13 +02004653 else if (ret == SSL_ERROR_SYSCALL) {
4654 /* if errno is null, then connection was successfully established */
4655 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4656 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004657 if (!conn->err_code) {
4658#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4659 conn->err_code = CO_ER_SSL_HANDSHAKE;
4660#else
4661 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004662#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004663 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4664 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004665#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004666 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004667#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004668 if (empty_handshake) {
4669 if (!errno) {
4670 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4671 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4672 else
4673 conn->err_code = CO_ER_SSL_EMPTY;
4674 }
4675 else {
4676 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4677 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4678 else
4679 conn->err_code = CO_ER_SSL_ABORT;
4680 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004681 }
4682 else {
4683 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4684 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4685 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004686 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004687 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004688#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004689 }
Willy Tarreau89230192012-09-28 20:22:13 +02004690 goto out_error;
4691 }
Emeric Brun46591952012-05-18 15:47:34 +02004692 else {
4693 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004694 /* Note: OpenSSL may leave unread bytes in the socket's
4695 * buffer, causing an RST to be emitted upon close() on
4696 * TCP sockets. We first try to drain possibly pending
4697 * data to avoid this as much as possible.
4698 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004699 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004700 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004701 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4702 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004703 goto out_error;
4704 }
4705 }
4706
Emeric Brun674b7432012-11-08 19:21:55 +01004707reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004708 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004709 if (!SSL_session_reused(conn->xprt_ctx)) {
4710 if (objt_server(conn->target)) {
4711 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4712 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4713 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4714
Emeric Brun46591952012-05-18 15:47:34 +02004715 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004716 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004717 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004718 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4719 }
Emeric Brun46591952012-05-18 15:47:34 +02004720
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004721 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4722 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004723 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004724 else {
4725 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4726 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4727 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4728 }
Emeric Brun46591952012-05-18 15:47:34 +02004729 }
4730
4731 /* The connection is now established at both layers, it's time to leave */
4732 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4733 return 1;
4734
4735 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004736 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004737 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004738 ERR_clear_error();
4739
Emeric Brun9fa89732012-10-04 17:09:56 +02004740 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004741 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4742 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4743 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004744 }
4745
Emeric Brun46591952012-05-18 15:47:34 +02004746 /* Fail on all other handshake errors */
4747 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004748 if (!conn->err_code)
4749 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004750 return 0;
4751}
4752
4753/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004754 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004755 * buffer wraps, in which case a second call may be performed. The connection's
4756 * flags are updated with whatever special event is detected (error, read0,
4757 * empty). The caller is responsible for taking care of those events and
4758 * avoiding the call if inappropriate. The function does not call the
4759 * connection's polling update function, so the caller is responsible for this.
4760 */
4761static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4762{
4763 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004764 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004765
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004766 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004767 goto out_error;
4768
4769 if (conn->flags & CO_FL_HANDSHAKE)
4770 /* a handshake was requested */
4771 return 0;
4772
Willy Tarreauabf08d92014-01-14 11:31:27 +01004773 /* let's realign the buffer to optimize I/O */
4774 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004775 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004776
4777 /* read the largest possible block. For this, we perform only one call
4778 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4779 * in which case we accept to do it once again. A new attempt is made on
4780 * EINTR too.
4781 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004782 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004783 /* first check if we have some room after p+i */
4784 try = buf->data + buf->size - (buf->p + buf->i);
4785 /* otherwise continue between data and p-o */
4786 if (try <= 0) {
4787 try = buf->p - (buf->data + buf->o);
4788 if (try <= 0)
4789 break;
4790 }
4791 if (try > count)
4792 try = count;
4793
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004794 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004795 if (conn->flags & CO_FL_ERROR) {
4796 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004797 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004798 }
Emeric Brun46591952012-05-18 15:47:34 +02004799 if (ret > 0) {
4800 buf->i += ret;
4801 done += ret;
4802 if (ret < try)
4803 break;
4804 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004805 }
4806 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004807 ret = SSL_get_error(conn->xprt_ctx, ret);
4808 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004809 /* error on protocol or underlying transport */
4810 if ((ret != SSL_ERROR_SYSCALL)
4811 || (errno && (errno != EAGAIN)))
4812 conn->flags |= CO_FL_ERROR;
4813
Emeric Brun644cde02012-12-14 11:21:13 +01004814 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004815 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004816 ERR_clear_error();
4817 }
Emeric Brun46591952012-05-18 15:47:34 +02004818 goto read0;
4819 }
4820 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004821 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004822 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004823 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004824 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004825 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004826 break;
4827 }
4828 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004829 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4830 /* handshake is running, and it may need to re-enable read */
4831 conn->flags |= CO_FL_SSL_WAIT_HS;
4832 __conn_sock_want_recv(conn);
4833 break;
4834 }
Emeric Brun46591952012-05-18 15:47:34 +02004835 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004836 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004837 break;
4838 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004839#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4840 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004841 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004842 break;
4843 }
4844#endif
Emeric Brun46591952012-05-18 15:47:34 +02004845 /* otherwise it's a real error */
4846 goto out_error;
4847 }
4848 }
4849 return done;
4850
4851 read0:
4852 conn_sock_read0(conn);
4853 return done;
4854 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004855 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004856 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004857 ERR_clear_error();
4858
Emeric Brun46591952012-05-18 15:47:34 +02004859 conn->flags |= CO_FL_ERROR;
4860 return done;
4861}
4862
4863
4864/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004865 * <flags> may contain some CO_SFL_* flags to hint the system about other
4866 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004867 * Only one call to send() is performed, unless the buffer wraps, in which case
4868 * a second call may be performed. The connection's flags are updated with
4869 * whatever special event is detected (error, empty). The caller is responsible
4870 * for taking care of those events and avoiding the call if inappropriate. The
4871 * function does not call the connection's polling update function, so the caller
4872 * is responsible for this.
4873 */
4874static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4875{
4876 int ret, try, done;
4877
4878 done = 0;
4879
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004880 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004881 goto out_error;
4882
4883 if (conn->flags & CO_FL_HANDSHAKE)
4884 /* a handshake was requested */
4885 return 0;
4886
4887 /* send the largest possible block. For this we perform only one call
4888 * to send() unless the buffer wraps and we exactly fill the first hunk,
4889 * in which case we accept to do it once again.
4890 */
4891 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004892 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004893
Willy Tarreau7bed9452014-02-02 02:00:24 +01004894 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004895 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004896 global_ssl.max_record && try > global_ssl.max_record) {
4897 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004898 }
4899 else {
4900 /* we need to keep the information about the fact that
4901 * we're not limiting the upcoming send(), because if it
4902 * fails, we'll have to retry with at least as many data.
4903 */
4904 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4905 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004906
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004907 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004908
Emeric Brune1f38db2012-09-03 20:36:47 +02004909 if (conn->flags & CO_FL_ERROR) {
4910 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004911 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004912 }
Emeric Brun46591952012-05-18 15:47:34 +02004913 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004914 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4915
Emeric Brun46591952012-05-18 15:47:34 +02004916 buf->o -= ret;
4917 done += ret;
4918
Willy Tarreau5fb38032012-12-16 19:39:09 +01004919 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004920 /* optimize data alignment in the buffer */
4921 buf->p = buf->data;
4922
4923 /* if the system buffer is full, don't insist */
4924 if (ret < try)
4925 break;
4926 }
4927 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004928 ret = SSL_get_error(conn->xprt_ctx, ret);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004929
Emeric Brun46591952012-05-18 15:47:34 +02004930 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004931 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4932 /* handshake is running, and it may need to re-enable write */
4933 conn->flags |= CO_FL_SSL_WAIT_HS;
4934 __conn_sock_want_send(conn);
4935 break;
4936 }
Emeric Brun46591952012-05-18 15:47:34 +02004937 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004938 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004939 break;
4940 }
4941 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004942 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004943 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004944 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004945 break;
4946 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004947#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
4948 else if (ret == SSL_ERROR_WANT_ASYNC) {
Emeric Brun3854e012017-05-17 20:42:48 +02004949 ssl_async_process_fds(conn, conn->xprt_ctx);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004950 break;
4951 }
4952#endif
Emeric Brun46591952012-05-18 15:47:34 +02004953 goto out_error;
4954 }
4955 }
4956 return done;
4957
4958 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004959 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004960 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004961 ERR_clear_error();
4962
Emeric Brun46591952012-05-18 15:47:34 +02004963 conn->flags |= CO_FL_ERROR;
4964 return done;
4965}
4966
Emeric Brun46591952012-05-18 15:47:34 +02004967static void ssl_sock_close(struct connection *conn) {
4968
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004969 if (conn->xprt_ctx) {
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004970#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
Emeric Brun3854e012017-05-17 20:42:48 +02004971 if (global_ssl.async) {
4972 OSSL_ASYNC_FD all_fd[32], afd;
4973 size_t num_all_fds = 0;
4974 int i;
4975
4976 SSL_get_all_async_fds(conn->xprt_ctx, NULL, &num_all_fds);
4977 if (num_all_fds > 32) {
4978 send_log(NULL, LOG_EMERG, "haproxy: openssl returns too many async fds. It seems a bug. Process may crash\n");
4979 return;
4980 }
4981
4982 SSL_get_all_async_fds(conn->xprt_ctx, all_fd, &num_all_fds);
4983
4984 /* If an async job is pending, we must try to
4985 to catch the end using polling before calling
4986 SSL_free */
4987 if (num_all_fds && SSL_waiting_for_async(conn->xprt_ctx)) {
4988 for (i=0 ; i < num_all_fds ; i++) {
4989 /* switch on an handler designed to
4990 * handle the SSL_free
4991 */
4992 afd = all_fd[i];
4993 fdtab[afd].iocb = ssl_async_fd_free;
4994 fdtab[afd].owner = conn->xprt_ctx;
4995 fd_want_recv(afd);
4996 }
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004997 conn->xprt_ctx = NULL;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00004998 jobs++;
4999 return;
5000 }
Emeric Brun3854e012017-05-17 20:42:48 +02005001 /* Else we can remove the fds from the fdtab
5002 * and call SSL_free.
5003 * note: we do a fd_remove and not a delete
5004 * because the fd is owned by the engine.
5005 * the engine is responsible to close
5006 */
5007 for (i=0 ; i < num_all_fds ; i++)
5008 fd_remove(all_fd[i]);
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00005009 }
5010#endif
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005011 SSL_free(conn->xprt_ctx);
5012 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02005013 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02005014 }
Emeric Brun46591952012-05-18 15:47:34 +02005015}
5016
5017/* This function tries to perform a clean shutdown on an SSL connection, and in
5018 * any case, flags the connection as reusable if no handshake was in progress.
5019 */
5020static void ssl_sock_shutw(struct connection *conn, int clean)
5021{
5022 if (conn->flags & CO_FL_HANDSHAKE)
5023 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005024 if (!clean)
5025 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01005026 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02005027 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01005028 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01005029 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02005030 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01005031 ERR_clear_error();
5032 }
Emeric Brun46591952012-05-18 15:47:34 +02005033}
5034
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02005035/* used for logging, may be changed for a sample fetch later */
5036const char *ssl_sock_get_cipher_name(struct connection *conn)
5037{
5038 if (!conn->xprt && !conn->xprt_ctx)
5039 return NULL;
5040 return SSL_get_cipher_name(conn->xprt_ctx);
5041}
5042
5043/* used for logging, may be changed for a sample fetch later */
5044const char *ssl_sock_get_proto_version(struct connection *conn)
5045{
5046 if (!conn->xprt && !conn->xprt_ctx)
5047 return NULL;
5048 return SSL_get_version(conn->xprt_ctx);
5049}
5050
Willy Tarreau8d598402012-10-22 17:58:39 +02005051/* Extract a serial from a cert, and copy it to a chunk.
5052 * Returns 1 if serial is found and copied, 0 if no serial found and
5053 * -1 if output is not large enough.
5054 */
5055static int
5056ssl_sock_get_serial(X509 *crt, struct chunk *out)
5057{
5058 ASN1_INTEGER *serial;
5059
5060 serial = X509_get_serialNumber(crt);
5061 if (!serial)
5062 return 0;
5063
5064 if (out->size < serial->length)
5065 return -1;
5066
5067 memcpy(out->str, serial->data, serial->length);
5068 out->len = serial->length;
5069 return 1;
5070}
5071
Emeric Brun43e79582014-10-29 19:03:26 +01005072/* Extract a cert to der, and copy it to a chunk.
5073 * Returns 1 if cert is found and copied, 0 on der convertion failure and
5074 * -1 if output is not large enough.
5075 */
5076static int
5077ssl_sock_crt2der(X509 *crt, struct chunk *out)
5078{
5079 int len;
5080 unsigned char *p = (unsigned char *)out->str;;
5081
5082 len =i2d_X509(crt, NULL);
5083 if (len <= 0)
5084 return 1;
5085
5086 if (out->size < len)
5087 return -1;
5088
5089 i2d_X509(crt,&p);
5090 out->len = len;
5091 return 1;
5092}
5093
Emeric Brunce5ad802012-10-22 14:11:22 +02005094
5095/* Copy Date in ASN1_UTCTIME format in struct chunk out.
5096 * Returns 1 if serial is found and copied, 0 if no valid time found
5097 * and -1 if output is not large enough.
5098 */
5099static int
5100ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
5101{
5102 if (tm->type == V_ASN1_GENERALIZEDTIME) {
5103 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
5104
5105 if (gentm->length < 12)
5106 return 0;
5107 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
5108 return 0;
5109 if (out->size < gentm->length-2)
5110 return -1;
5111
5112 memcpy(out->str, gentm->data+2, gentm->length-2);
5113 out->len = gentm->length-2;
5114 return 1;
5115 }
5116 else if (tm->type == V_ASN1_UTCTIME) {
5117 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
5118
5119 if (utctm->length < 10)
5120 return 0;
5121 if (utctm->data[0] >= 0x35)
5122 return 0;
5123 if (out->size < utctm->length)
5124 return -1;
5125
5126 memcpy(out->str, utctm->data, utctm->length);
5127 out->len = utctm->length;
5128 return 1;
5129 }
5130
5131 return 0;
5132}
5133
Emeric Brun87855892012-10-17 17:39:35 +02005134/* Extract an entry from a X509_NAME and copy its value to an output chunk.
5135 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
5136 */
5137static int
5138ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
5139{
5140 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005141 ASN1_OBJECT *obj;
5142 ASN1_STRING *data;
5143 const unsigned char *data_ptr;
5144 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005145 int i, j, n;
5146 int cur = 0;
5147 const char *s;
5148 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005149 int name_count;
5150
5151 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005152
5153 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005154 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02005155 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005156 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02005157 else
5158 j = i;
5159
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005160 ne = X509_NAME_get_entry(a, j);
5161 obj = X509_NAME_ENTRY_get_object(ne);
5162 data = X509_NAME_ENTRY_get_data(ne);
5163 data_ptr = ASN1_STRING_get0_data(data);
5164 data_len = ASN1_STRING_length(data);
5165 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005166 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005167 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005168 s = tmp;
5169 }
5170
5171 if (chunk_strcasecmp(entry, s) != 0)
5172 continue;
5173
5174 if (pos < 0)
5175 cur--;
5176 else
5177 cur++;
5178
5179 if (cur != pos)
5180 continue;
5181
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005182 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02005183 return -1;
5184
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005185 memcpy(out->str, data_ptr, data_len);
5186 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005187 return 1;
5188 }
5189
5190 return 0;
5191
5192}
5193
5194/* Extract and format full DN from a X509_NAME and copy result into a chunk
5195 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
5196 */
5197static int
5198ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
5199{
5200 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005201 ASN1_OBJECT *obj;
5202 ASN1_STRING *data;
5203 const unsigned char *data_ptr;
5204 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005205 int i, n, ln;
5206 int l = 0;
5207 const char *s;
5208 char *p;
5209 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005210 int name_count;
5211
5212
5213 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02005214
5215 out->len = 0;
5216 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005217 for (i = 0; i < name_count; i++) {
5218 ne = X509_NAME_get_entry(a, i);
5219 obj = X509_NAME_ENTRY_get_object(ne);
5220 data = X509_NAME_ENTRY_get_data(ne);
5221 data_ptr = ASN1_STRING_get0_data(data);
5222 data_len = ASN1_STRING_length(data);
5223 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02005224 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005225 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02005226 s = tmp;
5227 }
5228 ln = strlen(s);
5229
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005230 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005231 if (l > out->size)
5232 return -1;
5233 out->len = l;
5234
5235 *(p++)='/';
5236 memcpy(p, s, ln);
5237 p += ln;
5238 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005239 memcpy(p, data_ptr, data_len);
5240 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02005241 }
5242
5243 if (!out->len)
5244 return 0;
5245
5246 return 1;
5247}
5248
David Safb76832014-05-08 23:42:08 -04005249char *ssl_sock_get_version(struct connection *conn)
5250{
5251 if (!ssl_sock_is_ssl(conn))
5252 return NULL;
5253
5254 return (char *)SSL_get_version(conn->xprt_ctx);
5255}
5256
Willy Tarreau119a4082016-12-22 21:58:38 +01005257/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
5258 * to disable SNI.
5259 */
Willy Tarreau63076412015-07-10 11:33:32 +02005260void ssl_sock_set_servername(struct connection *conn, const char *hostname)
5261{
5262#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01005263 char *prev_name;
5264
Willy Tarreau63076412015-07-10 11:33:32 +02005265 if (!ssl_sock_is_ssl(conn))
5266 return;
5267
Willy Tarreau119a4082016-12-22 21:58:38 +01005268 /* if the SNI changes, we must destroy the reusable context so that a
5269 * new connection will present a new SNI. As an optimization we could
5270 * later imagine having a small cache of ssl_ctx to hold a few SNI per
5271 * server.
5272 */
5273 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5274 if ((!prev_name && hostname) ||
5275 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
5276 SSL_set_session(conn->xprt_ctx, NULL);
5277
Willy Tarreau63076412015-07-10 11:33:32 +02005278 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
5279#endif
5280}
5281
Emeric Brun0abf8362014-06-24 18:26:41 +02005282/* Extract peer certificate's common name into the chunk dest
5283 * Returns
5284 * the len of the extracted common name
5285 * or 0 if no CN found in DN
5286 * or -1 on error case (i.e. no peer certificate)
5287 */
5288int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04005289{
5290 X509 *crt = NULL;
5291 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04005292 const char find_cn[] = "CN";
5293 const struct chunk find_cn_chunk = {
5294 .str = (char *)&find_cn,
5295 .len = sizeof(find_cn)-1
5296 };
Emeric Brun0abf8362014-06-24 18:26:41 +02005297 int result = -1;
David Safb76832014-05-08 23:42:08 -04005298
5299 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02005300 goto out;
David Safb76832014-05-08 23:42:08 -04005301
5302 /* SSL_get_peer_certificate, it increase X509 * ref count */
5303 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5304 if (!crt)
5305 goto out;
5306
5307 name = X509_get_subject_name(crt);
5308 if (!name)
5309 goto out;
David Safb76832014-05-08 23:42:08 -04005310
Emeric Brun0abf8362014-06-24 18:26:41 +02005311 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
5312out:
David Safb76832014-05-08 23:42:08 -04005313 if (crt)
5314 X509_free(crt);
5315
5316 return result;
5317}
5318
Dave McCowan328fb582014-07-30 10:39:13 -04005319/* returns 1 if client passed a certificate for this session, 0 if not */
5320int ssl_sock_get_cert_used_sess(struct connection *conn)
5321{
5322 X509 *crt = NULL;
5323
5324 if (!ssl_sock_is_ssl(conn))
5325 return 0;
5326
5327 /* SSL_get_peer_certificate, it increase X509 * ref count */
5328 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5329 if (!crt)
5330 return 0;
5331
5332 X509_free(crt);
5333 return 1;
5334}
5335
5336/* returns 1 if client passed a certificate for this connection, 0 if not */
5337int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04005338{
5339 if (!ssl_sock_is_ssl(conn))
5340 return 0;
5341
5342 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
5343}
5344
5345/* returns result from SSL verify */
5346unsigned int ssl_sock_get_verify_result(struct connection *conn)
5347{
5348 if (!ssl_sock_is_ssl(conn))
5349 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
5350
5351 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
5352}
5353
Willy Tarreau7875d092012-09-10 08:20:03 +02005354/***** Below are some sample fetching functions for ACL/patterns *****/
5355
Emeric Brune64aef12012-09-21 13:15:06 +02005356/* boolean, returns true if client cert was present */
5357static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005358smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02005359{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005360 struct connection *conn;
5361
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005362 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005363 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02005364 return 0;
5365
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005366 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02005367 smp->flags |= SMP_F_MAY_CHANGE;
5368 return 0;
5369 }
5370
5371 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005372 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005373 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02005374
5375 return 1;
5376}
5377
Emeric Brun43e79582014-10-29 19:03:26 +01005378/* binary, returns a certificate in a binary chunk (der/raw).
5379 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5380 * should be use.
5381 */
5382static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005383smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01005384{
5385 int cert_peer = (kw[4] == 'c') ? 1 : 0;
5386 X509 *crt = NULL;
5387 int ret = 0;
5388 struct chunk *smp_trash;
5389 struct connection *conn;
5390
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005391 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01005392 if (!conn || conn->xprt != &ssl_sock)
5393 return 0;
5394
5395 if (!(conn->flags & CO_FL_CONNECTED)) {
5396 smp->flags |= SMP_F_MAY_CHANGE;
5397 return 0;
5398 }
5399
5400 if (cert_peer)
5401 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5402 else
5403 crt = SSL_get_certificate(conn->xprt_ctx);
5404
5405 if (!crt)
5406 goto out;
5407
5408 smp_trash = get_trash_chunk();
5409 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
5410 goto out;
5411
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005412 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005413 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01005414 ret = 1;
5415out:
5416 /* SSL_get_peer_certificate, it increase X509 * ref count */
5417 if (cert_peer && crt)
5418 X509_free(crt);
5419 return ret;
5420}
5421
Emeric Brunba841a12014-04-30 17:05:08 +02005422/* binary, returns serial of certificate in a binary chunk.
5423 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5424 * should be use.
5425 */
Willy Tarreau8d598402012-10-22 17:58:39 +02005426static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005427smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02005428{
Emeric Brunba841a12014-04-30 17:05:08 +02005429 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02005430 X509 *crt = NULL;
5431 int ret = 0;
5432 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005433 struct connection *conn;
5434
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005435 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005436 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02005437 return 0;
5438
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005439 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02005440 smp->flags |= SMP_F_MAY_CHANGE;
5441 return 0;
5442 }
5443
Emeric Brunba841a12014-04-30 17:05:08 +02005444 if (cert_peer)
5445 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5446 else
5447 crt = SSL_get_certificate(conn->xprt_ctx);
5448
Willy Tarreau8d598402012-10-22 17:58:39 +02005449 if (!crt)
5450 goto out;
5451
Willy Tarreau47ca5452012-12-23 20:22:19 +01005452 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005453 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5454 goto out;
5455
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005456 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005457 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005458 ret = 1;
5459out:
Emeric Brunba841a12014-04-30 17:05:08 +02005460 /* SSL_get_peer_certificate, it increase X509 * ref count */
5461 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005462 X509_free(crt);
5463 return ret;
5464}
Emeric Brune64aef12012-09-21 13:15:06 +02005465
Emeric Brunba841a12014-04-30 17:05:08 +02005466/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5467 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5468 * should be use.
5469 */
James Votha051b4a2013-05-14 20:37:59 +02005470static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005471smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005472{
Emeric Brunba841a12014-04-30 17:05:08 +02005473 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005474 X509 *crt = NULL;
5475 const EVP_MD *digest;
5476 int ret = 0;
5477 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005478 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005479
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005480 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005481 if (!conn || conn->xprt != &ssl_sock)
5482 return 0;
5483
5484 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005485 smp->flags |= SMP_F_MAY_CHANGE;
5486 return 0;
5487 }
5488
Emeric Brunba841a12014-04-30 17:05:08 +02005489 if (cert_peer)
5490 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5491 else
5492 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005493 if (!crt)
5494 goto out;
5495
5496 smp_trash = get_trash_chunk();
5497 digest = EVP_sha1();
5498 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5499
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005500 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005501 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005502 ret = 1;
5503out:
Emeric Brunba841a12014-04-30 17:05:08 +02005504 /* SSL_get_peer_certificate, it increase X509 * ref count */
5505 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005506 X509_free(crt);
5507 return ret;
5508}
5509
Emeric Brunba841a12014-04-30 17:05:08 +02005510/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5511 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5512 * should be use.
5513 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005514static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005515smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005516{
Emeric Brunba841a12014-04-30 17:05:08 +02005517 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005518 X509 *crt = NULL;
5519 int ret = 0;
5520 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005521 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005522
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005523 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005524 if (!conn || conn->xprt != &ssl_sock)
5525 return 0;
5526
5527 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005528 smp->flags |= SMP_F_MAY_CHANGE;
5529 return 0;
5530 }
5531
Emeric Brunba841a12014-04-30 17:05:08 +02005532 if (cert_peer)
5533 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5534 else
5535 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005536 if (!crt)
5537 goto out;
5538
Willy Tarreau47ca5452012-12-23 20:22:19 +01005539 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005540 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5541 goto out;
5542
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005543 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005544 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005545 ret = 1;
5546out:
Emeric Brunba841a12014-04-30 17:05:08 +02005547 /* SSL_get_peer_certificate, it increase X509 * ref count */
5548 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005549 X509_free(crt);
5550 return ret;
5551}
5552
Emeric Brunba841a12014-04-30 17:05:08 +02005553/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5554 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5555 * should be use.
5556 */
Emeric Brun87855892012-10-17 17:39:35 +02005557static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005558smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005559{
Emeric Brunba841a12014-04-30 17:05:08 +02005560 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005561 X509 *crt = NULL;
5562 X509_NAME *name;
5563 int ret = 0;
5564 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005565 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005566
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005567 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005568 if (!conn || conn->xprt != &ssl_sock)
5569 return 0;
5570
5571 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005572 smp->flags |= SMP_F_MAY_CHANGE;
5573 return 0;
5574 }
5575
Emeric Brunba841a12014-04-30 17:05:08 +02005576 if (cert_peer)
5577 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5578 else
5579 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005580 if (!crt)
5581 goto out;
5582
5583 name = X509_get_issuer_name(crt);
5584 if (!name)
5585 goto out;
5586
Willy Tarreau47ca5452012-12-23 20:22:19 +01005587 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005588 if (args && args[0].type == ARGT_STR) {
5589 int pos = 1;
5590
5591 if (args[1].type == ARGT_SINT)
5592 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005593
5594 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5595 goto out;
5596 }
5597 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5598 goto out;
5599
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005600 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005601 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005602 ret = 1;
5603out:
Emeric Brunba841a12014-04-30 17:05:08 +02005604 /* SSL_get_peer_certificate, it increase X509 * ref count */
5605 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005606 X509_free(crt);
5607 return ret;
5608}
5609
Emeric Brunba841a12014-04-30 17:05:08 +02005610/* string, returns notbefore date in ASN1_UTCTIME format.
5611 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5612 * should be use.
5613 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005614static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005615smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005616{
Emeric Brunba841a12014-04-30 17:05:08 +02005617 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005618 X509 *crt = NULL;
5619 int ret = 0;
5620 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005621 struct connection *conn;
5622
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005623 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005624 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005625 return 0;
5626
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005627 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005628 smp->flags |= SMP_F_MAY_CHANGE;
5629 return 0;
5630 }
5631
Emeric Brunba841a12014-04-30 17:05:08 +02005632 if (cert_peer)
5633 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5634 else
5635 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005636 if (!crt)
5637 goto out;
5638
Willy Tarreau47ca5452012-12-23 20:22:19 +01005639 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005640 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5641 goto out;
5642
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005643 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005644 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005645 ret = 1;
5646out:
Emeric Brunba841a12014-04-30 17:05:08 +02005647 /* SSL_get_peer_certificate, it increase X509 * ref count */
5648 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005649 X509_free(crt);
5650 return ret;
5651}
5652
Emeric Brunba841a12014-04-30 17:05:08 +02005653/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5654 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5655 * should be use.
5656 */
Emeric Brun87855892012-10-17 17:39:35 +02005657static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005658smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005659{
Emeric Brunba841a12014-04-30 17:05:08 +02005660 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005661 X509 *crt = NULL;
5662 X509_NAME *name;
5663 int ret = 0;
5664 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005665 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005666
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005667 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005668 if (!conn || conn->xprt != &ssl_sock)
5669 return 0;
5670
5671 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005672 smp->flags |= SMP_F_MAY_CHANGE;
5673 return 0;
5674 }
5675
Emeric Brunba841a12014-04-30 17:05:08 +02005676 if (cert_peer)
5677 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5678 else
5679 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005680 if (!crt)
5681 goto out;
5682
5683 name = X509_get_subject_name(crt);
5684 if (!name)
5685 goto out;
5686
Willy Tarreau47ca5452012-12-23 20:22:19 +01005687 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005688 if (args && args[0].type == ARGT_STR) {
5689 int pos = 1;
5690
5691 if (args[1].type == ARGT_SINT)
5692 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005693
5694 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5695 goto out;
5696 }
5697 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5698 goto out;
5699
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005700 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005701 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005702 ret = 1;
5703out:
Emeric Brunba841a12014-04-30 17:05:08 +02005704 /* SSL_get_peer_certificate, it increase X509 * ref count */
5705 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005706 X509_free(crt);
5707 return ret;
5708}
Emeric Brun9143d372012-12-20 15:44:16 +01005709
5710/* integer, returns true if current session use a client certificate */
5711static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005712smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005713{
5714 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005715 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005716
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005717 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005718 if (!conn || conn->xprt != &ssl_sock)
5719 return 0;
5720
5721 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005722 smp->flags |= SMP_F_MAY_CHANGE;
5723 return 0;
5724 }
5725
5726 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005727 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005728 if (crt) {
5729 X509_free(crt);
5730 }
5731
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005732 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005733 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005734 return 1;
5735}
5736
Emeric Brunba841a12014-04-30 17:05:08 +02005737/* integer, returns the certificate version
5738 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5739 * should be use.
5740 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005741static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005742smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005743{
Emeric Brunba841a12014-04-30 17:05:08 +02005744 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005745 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005746 struct connection *conn;
5747
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005748 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005749 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005750 return 0;
5751
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005752 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005753 smp->flags |= SMP_F_MAY_CHANGE;
5754 return 0;
5755 }
5756
Emeric Brunba841a12014-04-30 17:05:08 +02005757 if (cert_peer)
5758 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5759 else
5760 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005761 if (!crt)
5762 return 0;
5763
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005764 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005765 /* SSL_get_peer_certificate increase X509 * ref count */
5766 if (cert_peer)
5767 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005768 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005769
5770 return 1;
5771}
5772
Emeric Brunba841a12014-04-30 17:05:08 +02005773/* string, returns the certificate's signature algorithm.
5774 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5775 * should be use.
5776 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005777static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005778smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005779{
Emeric Brunba841a12014-04-30 17:05:08 +02005780 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005781 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005782 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005783 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005784 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005785
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005786 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005787 if (!conn || conn->xprt != &ssl_sock)
5788 return 0;
5789
5790 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005791 smp->flags |= SMP_F_MAY_CHANGE;
5792 return 0;
5793 }
5794
Emeric Brunba841a12014-04-30 17:05:08 +02005795 if (cert_peer)
5796 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5797 else
5798 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005799 if (!crt)
5800 return 0;
5801
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005802 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5803 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005804
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005805 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5806 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005807 /* SSL_get_peer_certificate increase X509 * ref count */
5808 if (cert_peer)
5809 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005810 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005811 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005812
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005813 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005814 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005815 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005816 /* SSL_get_peer_certificate increase X509 * ref count */
5817 if (cert_peer)
5818 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005819
5820 return 1;
5821}
5822
Emeric Brunba841a12014-04-30 17:05:08 +02005823/* string, returns the certificate's key algorithm.
5824 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5825 * should be use.
5826 */
Emeric Brun521a0112012-10-22 12:22:55 +02005827static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005828smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005829{
Emeric Brunba841a12014-04-30 17:05:08 +02005830 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005831 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005832 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005833 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005834 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005835
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005836 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005837 if (!conn || conn->xprt != &ssl_sock)
5838 return 0;
5839
5840 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005841 smp->flags |= SMP_F_MAY_CHANGE;
5842 return 0;
5843 }
5844
Emeric Brunba841a12014-04-30 17:05:08 +02005845 if (cert_peer)
5846 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5847 else
5848 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005849 if (!crt)
5850 return 0;
5851
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005852 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5853 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005854
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005855 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5856 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005857 /* SSL_get_peer_certificate increase X509 * ref count */
5858 if (cert_peer)
5859 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005860 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005861 }
Emeric Brun521a0112012-10-22 12:22:55 +02005862
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005863 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005864 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005865 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005866 if (cert_peer)
5867 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005868
5869 return 1;
5870}
5871
Emeric Brun645ae792014-04-30 14:21:06 +02005872/* boolean, returns true if front conn. transport layer is SSL.
5873 * This function is also usable on backend conn if the fetch keyword 5th
5874 * char is 'b'.
5875 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005876static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005877smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005878{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005879 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5880 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005881
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005882 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005883 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005884 return 1;
5885}
5886
Emeric Brun2525b6b2012-10-18 15:59:43 +02005887/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005888static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005889smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005890{
5891#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005892 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005893
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005894 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005895 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005896 conn->xprt_ctx &&
5897 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005898 return 1;
5899#else
5900 return 0;
5901#endif
5902}
5903
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005904/* boolean, returns true if client session has been resumed */
5905static int
5906smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5907{
5908 struct connection *conn = objt_conn(smp->sess->origin);
5909
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005910 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005911 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005912 conn->xprt_ctx &&
5913 SSL_session_reused(conn->xprt_ctx);
5914 return 1;
5915}
5916
Emeric Brun645ae792014-04-30 14:21:06 +02005917/* string, returns the used cipher if front conn. transport layer is SSL.
5918 * This function is also usable on backend conn if the fetch keyword 5th
5919 * char is 'b'.
5920 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005921static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005922smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005923{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005924 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5925 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005926
Willy Tarreaube508f12016-03-10 11:47:01 +01005927 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005928 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005929 return 0;
5930
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005931 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5932 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005933 return 0;
5934
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005935 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005936 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005937 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005938
5939 return 1;
5940}
5941
Emeric Brun645ae792014-04-30 14:21:06 +02005942/* integer, returns the algoritm's keysize if front conn. transport layer
5943 * is SSL.
5944 * This function is also usable on backend conn if the fetch keyword 5th
5945 * char is 'b'.
5946 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005947static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005948smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005949{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005950 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5951 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005952
Willy Tarreaue237fe12016-03-10 17:05:28 +01005953 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005954
Emeric Brun589fcad2012-10-16 14:13:26 +02005955 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005956 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005957 return 0;
5958
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005959 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005960 return 0;
5961
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005962 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005963 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005964
5965 return 1;
5966}
5967
Emeric Brun645ae792014-04-30 14:21:06 +02005968/* integer, returns the used keysize if front conn. transport layer is SSL.
5969 * This function is also usable on backend conn if the fetch keyword 5th
5970 * char is 'b'.
5971 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005972static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005973smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005974{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005975 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5976 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005977
Emeric Brun589fcad2012-10-16 14:13:26 +02005978 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005979 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5980 return 0;
5981
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005982 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5983 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005984 return 0;
5985
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005986 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005987
5988 return 1;
5989}
5990
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005991#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005992static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005993smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005994{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005995 struct connection *conn;
5996
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005997 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005998 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005999
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006000 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006001 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6002 return 0;
6003
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006004 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006005 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006006 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02006007
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006008 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02006009 return 0;
6010
6011 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02006012}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006013#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02006014
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006015#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006016static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006017smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02006018{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006019 struct connection *conn;
6020
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006021 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006022 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02006023
Willy Tarreaue26bf052015-05-12 10:30:12 +02006024 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006025 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02006026 return 0;
6027
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006028 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006029 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006030 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02006031
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006032 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02006033 return 0;
6034
6035 return 1;
6036}
6037#endif
6038
Emeric Brun645ae792014-04-30 14:21:06 +02006039/* string, returns the used protocol if front conn. transport layer is SSL.
6040 * This function is also usable on backend conn if the fetch keyword 5th
6041 * char is 'b'.
6042 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02006043static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006044smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02006045{
Willy Tarreaue237fe12016-03-10 17:05:28 +01006046 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6047 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01006048
Emeric Brun589fcad2012-10-16 14:13:26 +02006049 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006050 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6051 return 0;
6052
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006053 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
6054 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02006055 return 0;
6056
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006057 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006058 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006059 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02006060
6061 return 1;
6062}
6063
Willy Tarreau87b09662015-04-03 00:22:06 +02006064/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02006065 * This function is also usable on backend conn if the fetch keyword 5th
6066 * char is 'b'.
6067 */
Emeric Brun589fcad2012-10-16 14:13:26 +02006068static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006069smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02006070{
6071#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006072 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6073 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02006074
Willy Tarreaue237fe12016-03-10 17:05:28 +01006075 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01006076
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006077 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006078 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02006079
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006080 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6081 return 0;
6082
Willy Tarreau192252e2015-04-04 01:47:55 +02006083 ssl_sess = SSL_get_session(conn->xprt_ctx);
6084 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02006085 return 0;
6086
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006087 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
6088 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02006089 return 0;
6090
6091 return 1;
6092#else
6093 return 0;
6094#endif
6095}
6096
6097static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006098smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02006099{
6100#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006101 struct connection *conn;
6102
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006103 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006104 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02006105
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006106 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006107 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6108 return 0;
6109
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006110 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
6111 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02006112 return 0;
6113
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006114 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02006115 return 1;
6116#else
6117 return 0;
6118#endif
6119}
6120
David Sc1ad52e2014-04-08 18:48:47 -04006121static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006122smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
6123{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006124 struct connection *conn;
6125 struct ssl_capture *capture;
6126
6127 conn = objt_conn(smp->sess->origin);
6128 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6129 return 0;
6130
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006131 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006132 if (!capture)
6133 return 0;
6134
6135 smp->flags = SMP_F_CONST;
6136 smp->data.type = SMP_T_BIN;
6137 smp->data.u.str.str = capture->ciphersuite;
6138 smp->data.u.str.len = capture->ciphersuite_len;
6139 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006140}
6141
6142static int
6143smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
6144{
6145 struct chunk *data;
6146
6147 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6148 return 0;
6149
6150 data = get_trash_chunk();
6151 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
6152 smp->data.type = SMP_T_BIN;
6153 smp->data.u.str = *data;
6154 return 1;
6155}
6156
6157static int
6158smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
6159{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006160 struct connection *conn;
6161 struct ssl_capture *capture;
6162
6163 conn = objt_conn(smp->sess->origin);
6164 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6165 return 0;
6166
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01006167 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006168 if (!capture)
6169 return 0;
6170
6171 smp->data.type = SMP_T_SINT;
6172 smp->data.u.sint = capture->xxh64;
6173 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006174}
6175
6176static int
6177smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
6178{
6179#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
6180 struct chunk *data;
6181 SSL_CIPHER cipher;
6182 int i;
6183 const char *str;
6184 unsigned char *bin;
6185
6186 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
6187 return 0;
6188
6189 /* The cipher algorith must not be SSL_SSLV2, because this
6190 * SSL version seems to not have the same cipher encoding,
6191 * and it is not supported by OpenSSL. Unfortunately, the
6192 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
6193 * with standard defines. We just set the variable to 0,
6194 * ensure that the match with SSL_SSLV2 fails.
6195 */
6196 cipher.algorithm_ssl = 0;
6197
6198 data = get_trash_chunk();
6199 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
6200 bin = (unsigned char *)smp->data.u.str.str + i;
6201 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
6202 str = SSL_CIPHER_standard_name(&cipher);
6203 if (!str || strcmp(str, "UNKNOWN") == 0)
6204 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
6205 else
6206 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
6207 }
6208 smp->data.type = SMP_T_STR;
6209 smp->data.u.str = *data;
6210 return 1;
6211#else
6212 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
6213#endif
6214}
6215
6216static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006217smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04006218{
6219#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01006220 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
6221 smp->strm ? smp->strm->si[1].end : NULL);
6222
David Sc1ad52e2014-04-08 18:48:47 -04006223 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04006224 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04006225
6226 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04006227 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
6228 return 0;
6229
6230 if (!(conn->flags & CO_FL_CONNECTED)) {
6231 smp->flags |= SMP_F_MAY_CHANGE;
6232 return 0;
6233 }
6234
6235 finished_trash = get_trash_chunk();
6236 if (!SSL_session_reused(conn->xprt_ctx))
6237 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6238 else
6239 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
6240
6241 if (!finished_len)
6242 return 0;
6243
Emeric Brunb73a9b02014-04-30 18:49:19 +02006244 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006245 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006246 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04006247
6248 return 1;
6249#else
6250 return 0;
6251#endif
6252}
6253
Emeric Brun2525b6b2012-10-18 15:59:43 +02006254/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006255static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006256smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006257{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006258 struct connection *conn;
6259
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006260 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006261 if (!conn || conn->xprt != &ssl_sock)
6262 return 0;
6263
6264 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006265 smp->flags = SMP_F_MAY_CHANGE;
6266 return 0;
6267 }
6268
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006269 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006270 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006271 smp->flags = 0;
6272
6273 return 1;
6274}
6275
Emeric Brun2525b6b2012-10-18 15:59:43 +02006276/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02006277static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006278smp_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 +02006279{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006280 struct connection *conn;
6281
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006282 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006283 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02006284 return 0;
6285
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006286 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006287 smp->flags = SMP_F_MAY_CHANGE;
6288 return 0;
6289 }
6290
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006291 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006292 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006293 smp->flags = 0;
6294
6295 return 1;
6296}
6297
Emeric Brun2525b6b2012-10-18 15:59:43 +02006298/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02006299static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006300smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02006301{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006302 struct connection *conn;
6303
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006304 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006305 if (!conn || conn->xprt != &ssl_sock)
6306 return 0;
6307
6308 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02006309 smp->flags = SMP_F_MAY_CHANGE;
6310 return 0;
6311 }
6312
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006313 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006314 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006315 smp->flags = 0;
6316
6317 return 1;
6318}
6319
Emeric Brun2525b6b2012-10-18 15:59:43 +02006320/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006321static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006322smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006323{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006324 struct connection *conn;
6325
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006326 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006327 if (!conn || conn->xprt != &ssl_sock)
6328 return 0;
6329
6330 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006331 smp->flags = SMP_F_MAY_CHANGE;
6332 return 0;
6333 }
6334
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006335 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006336 return 0;
6337
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006338 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006339 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006340 smp->flags = 0;
6341
6342 return 1;
6343}
6344
Emeric Brunfb510ea2012-10-05 12:00:26 +02006345/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006346static 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 +02006347{
6348 if (!*args[cur_arg + 1]) {
6349 if (err)
6350 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6351 return ERR_ALERT | ERR_FATAL;
6352 }
6353
Willy Tarreauef934602016-12-22 23:12:01 +01006354 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6355 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006356 else
6357 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006358
Emeric Brund94b3fe2012-09-20 18:23:56 +02006359 return 0;
6360}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006361static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6362{
6363 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
6364}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006365
Christopher Faulet31af49d2015-06-09 17:29:50 +02006366/* parse the "ca-sign-file" bind keyword */
6367static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6368{
6369 if (!*args[cur_arg + 1]) {
6370 if (err)
6371 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6372 return ERR_ALERT | ERR_FATAL;
6373 }
6374
Willy Tarreauef934602016-12-22 23:12:01 +01006375 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6376 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02006377 else
6378 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
6379
6380 return 0;
6381}
6382
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006383/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006384static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6385{
6386 if (!*args[cur_arg + 1]) {
6387 if (err)
6388 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
6389 return ERR_ALERT | ERR_FATAL;
6390 }
6391 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
6392 return 0;
6393}
6394
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006395/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006396static 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 +02006397{
6398 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006399 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006400 return ERR_ALERT | ERR_FATAL;
6401 }
6402
Emeric Brun76d88952012-10-05 15:47:31 +02006403 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02006404 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006405 return 0;
6406}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006407static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6408{
6409 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
6410}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006411/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006412static 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 +02006413{
Willy Tarreau38011032013-08-13 16:59:39 +02006414 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02006415
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006416 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006417 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006418 return ERR_ALERT | ERR_FATAL;
6419 }
6420
Willy Tarreauef934602016-12-22 23:12:01 +01006421 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
6422 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02006423 memprintf(err, "'%s' : path too long", args[cur_arg]);
6424 return ERR_ALERT | ERR_FATAL;
6425 }
Willy Tarreauef934602016-12-22 23:12:01 +01006426 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01006427 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02006428 return ERR_ALERT | ERR_FATAL;
6429
6430 return 0;
6431 }
6432
Willy Tarreau03209342016-12-22 17:08:28 +01006433 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006434 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006435
6436 return 0;
6437}
6438
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006439/* parse the "crt-list" bind keyword */
6440static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6441{
6442 if (!*args[cur_arg + 1]) {
6443 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
6444 return ERR_ALERT | ERR_FATAL;
6445 }
6446
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006447 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006448 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006449 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006450 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006451
6452 return 0;
6453}
6454
Emeric Brunfb510ea2012-10-05 12:00:26 +02006455/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006456static 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 +02006457{
Emeric Brun051cdab2012-10-02 19:25:50 +02006458#ifndef X509_V_FLAG_CRL_CHECK
6459 if (err)
6460 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6461 return ERR_ALERT | ERR_FATAL;
6462#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006463 if (!*args[cur_arg + 1]) {
6464 if (err)
6465 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6466 return ERR_ALERT | ERR_FATAL;
6467 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006468
Willy Tarreauef934602016-12-22 23:12:01 +01006469 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6470 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006471 else
6472 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006473
Emeric Brun2b58d042012-09-20 17:10:03 +02006474 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006475#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006476}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006477static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6478{
6479 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6480}
Emeric Brun2b58d042012-09-20 17:10:03 +02006481
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006482/* parse the "curves" bind keyword keyword */
6483static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6484{
6485#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6486 if (!*args[cur_arg + 1]) {
6487 if (err)
6488 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6489 return ERR_ALERT | ERR_FATAL;
6490 }
6491 conf->curves = strdup(args[cur_arg + 1]);
6492 return 0;
6493#else
6494 if (err)
6495 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6496 return ERR_ALERT | ERR_FATAL;
6497#endif
6498}
6499static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6500{
6501 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6502}
6503
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006504/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006505static 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 +02006506{
6507#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6508 if (err)
6509 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6510 return ERR_ALERT | ERR_FATAL;
6511#elif defined(OPENSSL_NO_ECDH)
6512 if (err)
6513 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6514 return ERR_ALERT | ERR_FATAL;
6515#else
6516 if (!*args[cur_arg + 1]) {
6517 if (err)
6518 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6519 return ERR_ALERT | ERR_FATAL;
6520 }
6521
6522 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006523
6524 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006525#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006526}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006527static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6528{
6529 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6530}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006531
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006532/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006533static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6534{
6535 int code;
6536 char *p = args[cur_arg + 1];
6537 unsigned long long *ignerr = &conf->crt_ignerr;
6538
6539 if (!*p) {
6540 if (err)
6541 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6542 return ERR_ALERT | ERR_FATAL;
6543 }
6544
6545 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6546 ignerr = &conf->ca_ignerr;
6547
6548 if (strcmp(p, "all") == 0) {
6549 *ignerr = ~0ULL;
6550 return 0;
6551 }
6552
6553 while (p) {
6554 code = atoi(p);
6555 if ((code <= 0) || (code > 63)) {
6556 if (err)
6557 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6558 args[cur_arg], code, args[cur_arg + 1]);
6559 return ERR_ALERT | ERR_FATAL;
6560 }
6561 *ignerr |= 1ULL << code;
6562 p = strchr(p, ',');
6563 if (p)
6564 p++;
6565 }
6566
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006567 return 0;
6568}
6569
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006570/* parse tls_method_options "no-xxx" and "force-xxx" */
6571static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006572{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006573 uint16_t v;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006574 char *p;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006575 p = strchr(arg, '-');
6576 if (!p)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006577 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006578 p++;
6579 if (!strcmp(p, "sslv3"))
6580 v = CONF_SSLV3;
6581 else if (!strcmp(p, "tlsv10"))
6582 v = CONF_TLSV10;
6583 else if (!strcmp(p, "tlsv11"))
6584 v = CONF_TLSV11;
6585 else if (!strcmp(p, "tlsv12"))
6586 v = CONF_TLSV12;
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02006587 else if (!strcmp(p, "tlsv13"))
6588 v = CONF_TLSV13;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006589 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006590 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006591 if (!strncmp(arg, "no-", 3))
6592 methods->flags |= methodVersions[v].flag;
6593 else if (!strncmp(arg, "force-", 6))
6594 methods->min = methods->max = v;
6595 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006596 goto fail;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006597 return 0;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006598 fail:
6599 if (err)
6600 memprintf(err, "'%s' : option not implemented", arg);
6601 return ERR_ALERT | ERR_FATAL;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006602}
6603
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006604static 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 +02006605{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006606 return parse_tls_method_options(args[cur_arg], &conf->ssl_methods, err);
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006607}
6608
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006609static 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 +02006610{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006611 return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
6612}
6613
6614/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
6615static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
6616{
6617 uint16_t i, v = 0;
6618 char *argv = args[cur_arg + 1];
6619 if (!*argv) {
6620 if (err)
6621 memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
6622 return ERR_ALERT | ERR_FATAL;
6623 }
6624 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
6625 if (!strcmp(argv, methodVersions[i].name))
6626 v = i;
6627 if (!v) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006628 if (err)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006629 memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006630 return ERR_ALERT | ERR_FATAL;
6631 }
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006632 if (!strcmp("ssl-min-ver", args[cur_arg]))
6633 methods->min = v;
6634 else if (!strcmp("ssl-max-ver", args[cur_arg]))
6635 methods->max = v;
6636 else {
6637 if (err)
6638 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
6639 return ERR_ALERT | ERR_FATAL;
6640 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006641 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006642}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006643
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006644static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6645{
6646 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6647}
6648
6649static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6650{
6651 return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
6652}
6653
Emeric Brun2d0c4822012-10-02 13:45:20 +02006654/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006655static 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 +02006656{
Emeric Brun89675492012-10-05 13:48:26 +02006657 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006658 return 0;
6659}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006660
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006661/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006662static 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 +02006663{
6664#ifdef OPENSSL_NPN_NEGOTIATED
6665 char *p1, *p2;
6666
6667 if (!*args[cur_arg + 1]) {
6668 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6669 return ERR_ALERT | ERR_FATAL;
6670 }
6671
6672 free(conf->npn_str);
6673
Willy Tarreau3724da12016-02-12 17:11:12 +01006674 /* the NPN string is built as a suite of (<len> <name>)*,
6675 * so we reuse each comma to store the next <len> and need
6676 * one more for the end of the string.
6677 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006678 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006679 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006680 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6681
6682 /* replace commas with the name length */
6683 p1 = conf->npn_str;
6684 p2 = p1 + 1;
6685 while (1) {
6686 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6687 if (!p2)
6688 p2 = p1 + 1 + strlen(p1 + 1);
6689
6690 if (p2 - (p1 + 1) > 255) {
6691 *p2 = '\0';
6692 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6693 return ERR_ALERT | ERR_FATAL;
6694 }
6695
6696 *p1 = p2 - (p1 + 1);
6697 p1 = p2;
6698
6699 if (!*p2)
6700 break;
6701
6702 *(p2++) = '\0';
6703 }
6704 return 0;
6705#else
6706 if (err)
6707 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6708 return ERR_ALERT | ERR_FATAL;
6709#endif
6710}
6711
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006712static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6713{
6714 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6715}
6716
Willy Tarreauab861d32013-04-02 02:30:41 +02006717/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006718static 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 +02006719{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006720#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006721 char *p1, *p2;
6722
6723 if (!*args[cur_arg + 1]) {
6724 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6725 return ERR_ALERT | ERR_FATAL;
6726 }
6727
6728 free(conf->alpn_str);
6729
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006730 /* the ALPN string is built as a suite of (<len> <name>)*,
6731 * so we reuse each comma to store the next <len> and need
6732 * one more for the end of the string.
6733 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006734 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006735 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006736 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6737
6738 /* replace commas with the name length */
6739 p1 = conf->alpn_str;
6740 p2 = p1 + 1;
6741 while (1) {
6742 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6743 if (!p2)
6744 p2 = p1 + 1 + strlen(p1 + 1);
6745
6746 if (p2 - (p1 + 1) > 255) {
6747 *p2 = '\0';
6748 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6749 return ERR_ALERT | ERR_FATAL;
6750 }
6751
6752 *p1 = p2 - (p1 + 1);
6753 p1 = p2;
6754
6755 if (!*p2)
6756 break;
6757
6758 *(p2++) = '\0';
6759 }
6760 return 0;
6761#else
6762 if (err)
6763 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6764 return ERR_ALERT | ERR_FATAL;
6765#endif
6766}
6767
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006768static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6769{
6770 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6771}
6772
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006773/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006774static 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 +02006775{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006776 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006777 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006778
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006779 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6780 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006781 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006782 conf->ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
6783 if (!conf->ssl_methods.min)
6784 conf->ssl_methods.min = global_ssl.listen_default_sslmethods.min;
6785 if (!conf->ssl_methods.max)
6786 conf->ssl_methods.max = global_ssl.listen_default_sslmethods.max;
Emeric Brun76d88952012-10-05 15:47:31 +02006787
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006788 return 0;
6789}
6790
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006791/* parse the "prefer-client-ciphers" bind keyword */
6792static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6793{
6794 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
6795 return 0;
6796}
6797
Christopher Faulet31af49d2015-06-09 17:29:50 +02006798/* parse the "generate-certificates" bind keyword */
6799static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6800{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006801#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006802 conf->generate_certs = 1;
6803#else
6804 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6805 err && *err ? *err : "");
6806#endif
6807 return 0;
6808}
6809
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006810/* parse the "strict-sni" bind keyword */
6811static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6812{
6813 conf->strict_sni = 1;
6814 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006815}
6816
6817/* parse the "tls-ticket-keys" bind keyword */
6818static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6819{
6820#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6821 FILE *f;
6822 int i = 0;
6823 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006824 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006825
6826 if (!*args[cur_arg + 1]) {
6827 if (err)
6828 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6829 return ERR_ALERT | ERR_FATAL;
6830 }
6831
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006832 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6833 if(keys_ref) {
6834 conf->keys_ref = keys_ref;
6835 return 0;
6836 }
6837
Vincent Bernat02779b62016-04-03 13:48:43 +02006838 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006839 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006840
6841 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6842 if (err)
6843 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6844 return ERR_ALERT | ERR_FATAL;
6845 }
6846
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006847 keys_ref->filename = strdup(args[cur_arg + 1]);
6848
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006849 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6850 int len = strlen(thisline);
6851 /* Strip newline characters from the end */
6852 if(thisline[len - 1] == '\n')
6853 thisline[--len] = 0;
6854
6855 if(thisline[len - 1] == '\r')
6856 thisline[--len] = 0;
6857
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006858 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 +01006859 if (err)
6860 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006861 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006862 return ERR_ALERT | ERR_FATAL;
6863 }
6864 i++;
6865 }
6866
6867 if (i < TLS_TICKETS_NO) {
6868 if (err)
6869 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 +02006870 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006871 return ERR_ALERT | ERR_FATAL;
6872 }
6873
6874 fclose(f);
6875
6876 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006877 i -= 2;
6878 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006879 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006880 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006881
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006882 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6883
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006884 return 0;
6885#else
6886 if (err)
6887 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6888 return ERR_ALERT | ERR_FATAL;
6889#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006890}
6891
Emeric Brund94b3fe2012-09-20 18:23:56 +02006892/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006893static 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 +02006894{
6895 if (!*args[cur_arg + 1]) {
6896 if (err)
6897 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6898 return ERR_ALERT | ERR_FATAL;
6899 }
6900
6901 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006902 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006903 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006904 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006905 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006906 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006907 else {
6908 if (err)
6909 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6910 args[cur_arg], args[cur_arg + 1]);
6911 return ERR_ALERT | ERR_FATAL;
6912 }
6913
6914 return 0;
6915}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006916static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6917{
6918 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6919}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006920
Willy Tarreau92faadf2012-10-10 23:04:25 +02006921/************** "server" keywords ****************/
6922
Emeric Brunef42d922012-10-11 16:11:36 +02006923/* parse the "ca-file" server keyword */
6924static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6925{
6926 if (!*args[*cur_arg + 1]) {
6927 if (err)
6928 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6929 return ERR_ALERT | ERR_FATAL;
6930 }
6931
Willy Tarreauef934602016-12-22 23:12:01 +01006932 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6933 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006934 else
6935 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6936
6937 return 0;
6938}
6939
Willy Tarreau92faadf2012-10-10 23:04:25 +02006940/* parse the "check-ssl" server keyword */
6941static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6942{
6943 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006944 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6945 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6946 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006947 newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
6948 if (!newsrv->ssl_ctx.methods.min)
6949 newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
6950 if (!newsrv->ssl_ctx.methods.max)
6951 newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
6952
Willy Tarreau92faadf2012-10-10 23:04:25 +02006953 return 0;
6954}
6955
6956/* parse the "ciphers" server keyword */
6957static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6958{
6959 if (!*args[*cur_arg + 1]) {
6960 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6961 return ERR_ALERT | ERR_FATAL;
6962 }
6963
6964 free(newsrv->ssl_ctx.ciphers);
6965 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6966 return 0;
6967}
6968
Emeric Brunef42d922012-10-11 16:11:36 +02006969/* parse the "crl-file" server keyword */
6970static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6971{
6972#ifndef X509_V_FLAG_CRL_CHECK
6973 if (err)
6974 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6975 return ERR_ALERT | ERR_FATAL;
6976#else
6977 if (!*args[*cur_arg + 1]) {
6978 if (err)
6979 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6980 return ERR_ALERT | ERR_FATAL;
6981 }
6982
Willy Tarreauef934602016-12-22 23:12:01 +01006983 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6984 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006985 else
6986 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6987
6988 return 0;
6989#endif
6990}
6991
Emeric Bruna7aa3092012-10-26 12:58:00 +02006992/* parse the "crt" server keyword */
6993static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6994{
6995 if (!*args[*cur_arg + 1]) {
6996 if (err)
6997 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6998 return ERR_ALERT | ERR_FATAL;
6999 }
7000
Willy Tarreauef934602016-12-22 23:12:01 +01007001 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
7002 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02007003 else
7004 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
7005
7006 return 0;
7007}
Emeric Brunef42d922012-10-11 16:11:36 +02007008
Frédéric Lécaille340ae602017-03-13 10:38:04 +01007009/* parse the "no-check-ssl" server keyword */
7010static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7011{
7012 newsrv->check.use_ssl = 0;
7013 free(newsrv->ssl_ctx.ciphers);
7014 newsrv->ssl_ctx.ciphers = NULL;
7015 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
7016 return 0;
7017}
7018
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01007019/* parse the "no-send-proxy-v2-ssl" server keyword */
7020static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7021{
7022 newsrv->pp_opts &= ~SRV_PP_V2;
7023 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7024 return 0;
7025}
7026
7027/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
7028static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7029{
7030 newsrv->pp_opts &= ~SRV_PP_V2;
7031 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
7032 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
7033 return 0;
7034}
7035
Frédéric Lécaillee381d762017-03-13 11:54:17 +01007036/* parse the "no-ssl" server keyword */
7037static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7038{
7039 newsrv->use_ssl = 0;
7040 free(newsrv->ssl_ctx.ciphers);
7041 newsrv->ssl_ctx.ciphers = NULL;
7042 return 0;
7043}
7044
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007045/* parse the "no-ssl-reuse" server keyword */
7046static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7047{
7048 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
7049 return 0;
7050}
7051
Emeric Brunf9c5c472012-10-11 15:28:34 +02007052/* parse the "no-tls-tickets" server keyword */
7053static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7054{
7055 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
7056 return 0;
7057}
David Safb76832014-05-08 23:42:08 -04007058/* parse the "send-proxy-v2-ssl" server keyword */
7059static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7060{
7061 newsrv->pp_opts |= SRV_PP_V2;
7062 newsrv->pp_opts |= SRV_PP_V2_SSL;
7063 return 0;
7064}
7065
7066/* parse the "send-proxy-v2-ssl-cn" server keyword */
7067static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7068{
7069 newsrv->pp_opts |= SRV_PP_V2;
7070 newsrv->pp_opts |= SRV_PP_V2_SSL;
7071 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
7072 return 0;
7073}
Emeric Brunf9c5c472012-10-11 15:28:34 +02007074
Willy Tarreau732eac42015-07-09 11:40:25 +02007075/* parse the "sni" server keyword */
7076static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7077{
7078#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
7079 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
7080 return ERR_ALERT | ERR_FATAL;
7081#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007082 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02007083
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007084 arg = args[*cur_arg + 1];
7085 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02007086 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
7087 return ERR_ALERT | ERR_FATAL;
7088 }
7089
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007090 free(newsrv->sni_expr);
7091 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02007092
Willy Tarreau732eac42015-07-09 11:40:25 +02007093 return 0;
7094#endif
7095}
7096
Willy Tarreau92faadf2012-10-10 23:04:25 +02007097/* parse the "ssl" server keyword */
7098static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7099{
7100 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01007101 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
7102 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007103 return 0;
7104}
7105
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007106/* parse the "ssl-reuse" server keyword */
7107static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7108{
7109 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
7110 return 0;
7111}
7112
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01007113/* parse the "tls-tickets" server keyword */
7114static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7115{
7116 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
7117 return 0;
7118}
7119
Emeric Brunef42d922012-10-11 16:11:36 +02007120/* parse the "verify" server keyword */
7121static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7122{
7123 if (!*args[*cur_arg + 1]) {
7124 if (err)
7125 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
7126 return ERR_ALERT | ERR_FATAL;
7127 }
7128
7129 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007130 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02007131 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01007132 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02007133 else {
7134 if (err)
7135 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
7136 args[*cur_arg], args[*cur_arg + 1]);
7137 return ERR_ALERT | ERR_FATAL;
7138 }
7139
Evan Broderbe554312013-06-27 00:05:25 -07007140 return 0;
7141}
7142
7143/* parse the "verifyhost" server keyword */
7144static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
7145{
7146 if (!*args[*cur_arg + 1]) {
7147 if (err)
7148 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
7149 return ERR_ALERT | ERR_FATAL;
7150 }
7151
Frédéric Lécaille273f3212017-03-13 15:52:01 +01007152 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07007153 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
7154
Emeric Brunef42d922012-10-11 16:11:36 +02007155 return 0;
7156}
7157
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007158/* parse the "ssl-default-bind-options" keyword in global section */
7159static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
7160 struct proxy *defpx, const char *file, int line,
7161 char **err) {
7162 int i = 1;
7163
7164 if (*(args[i]) == 0) {
7165 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7166 return -1;
7167 }
7168 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007169 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007170 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Lukas Tribus53ae85c2017-05-04 15:45:40 +00007171 else if (!strcmp(args[i], "prefer-client-ciphers"))
7172 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007173 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7174 if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
7175 i++;
7176 else {
7177 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7178 return -1;
7179 }
7180 }
7181 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007182 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7183 return -1;
7184 }
7185 i++;
7186 }
7187 return 0;
7188}
7189
7190/* parse the "ssl-default-server-options" keyword in global section */
7191static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
7192 struct proxy *defpx, const char *file, int line,
7193 char **err) {
7194 int i = 1;
7195
7196 if (*(args[i]) == 0) {
7197 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
7198 return -1;
7199 }
7200 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007201 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01007202 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007203 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
7204 if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
7205 i++;
7206 else {
7207 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
7208 return -1;
7209 }
7210 }
7211 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007212 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
7213 return -1;
7214 }
7215 i++;
7216 }
7217 return 0;
7218}
7219
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007220/* parse the "ca-base" / "crt-base" keywords in global section.
7221 * Returns <0 on alert, >0 on warning, 0 on success.
7222 */
7223static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
7224 struct proxy *defpx, const char *file, int line,
7225 char **err)
7226{
7227 char **target;
7228
Willy Tarreauef934602016-12-22 23:12:01 +01007229 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007230
7231 if (too_many_args(1, args, err, NULL))
7232 return -1;
7233
7234 if (*target) {
7235 memprintf(err, "'%s' already specified.", args[0]);
7236 return -1;
7237 }
7238
7239 if (*(args[1]) == 0) {
7240 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
7241 return -1;
7242 }
7243 *target = strdup(args[1]);
7244 return 0;
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007245}
7246
7247/* parse the "ssl-mode-async" keyword in global section.
7248 * Returns <0 on alert, >0 on warning, 0 on success.
7249 */
7250static int ssl_parse_global_ssl_async(char **args, int section_type, struct proxy *curpx,
7251 struct proxy *defpx, const char *file, int line,
7252 char **err)
7253{
7254#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
7255 global_ssl.async = 1;
7256 return 0;
7257#else
7258 memprintf(err, "'%s': openssl library does not support async mode", args[0]);
7259 return -1;
7260#endif
7261}
7262
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007263#ifndef OPENSSL_NO_ENGINE
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007264static int ssl_check_async_engine_count(void) {
7265 int err_code = 0;
7266
Emeric Brun3854e012017-05-17 20:42:48 +02007267 if (global_ssl.async && (openssl_engines_initialized > 32)) {
7268 Alert("ssl-mode-async only supports a maximum of 32 engines.\n");
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007269 err_code = ERR_ABORT;
7270 }
7271 return err_code;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007272}
7273
Grant Zhang872f9c22017-01-21 01:10:18 +00007274/* parse the "ssl-engine" keyword in global section.
7275 * Returns <0 on alert, >0 on warning, 0 on success.
7276 */
7277static int ssl_parse_global_ssl_engine(char **args, int section_type, struct proxy *curpx,
7278 struct proxy *defpx, const char *file, int line,
7279 char **err)
7280{
7281 char *algo;
7282 int ret = -1;
7283
7284 if (*(args[1]) == 0) {
7285 memprintf(err, "global statement '%s' expects a valid engine name as an argument.", args[0]);
7286 return ret;
7287 }
7288
7289 if (*(args[2]) == 0) {
7290 /* if no list of algorithms is given, it defaults to ALL */
7291 algo = strdup("ALL");
7292 goto add_engine;
7293 }
7294
7295 /* otherwise the expected format is ssl-engine <engine_name> algo <list of algo> */
7296 if (strcmp(args[2], "algo") != 0) {
7297 memprintf(err, "global statement '%s' expects to have algo keyword.", args[0]);
7298 return ret;
7299 }
7300
7301 if (*(args[3]) == 0) {
7302 memprintf(err, "global statement '%s' expects algorithm names as an argument.", args[0]);
7303 return ret;
7304 }
7305 algo = strdup(args[3]);
7306
7307add_engine:
7308 if (ssl_init_single_engine(args[1], algo)==0) {
7309 openssl_engines_initialized++;
7310 ret = 0;
7311 }
7312 free(algo);
7313 return ret;
7314}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007315#endif
Grant Zhang872f9c22017-01-21 01:10:18 +00007316
Willy Tarreauf22e9682016-12-21 23:23:19 +01007317/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
7318 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
7319 */
7320static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
7321 struct proxy *defpx, const char *file, int line,
7322 char **err)
7323{
7324 char **target;
7325
Willy Tarreauef934602016-12-22 23:12:01 +01007326 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01007327
7328 if (too_many_args(1, args, err, NULL))
7329 return -1;
7330
7331 if (*(args[1]) == 0) {
7332 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
7333 return -1;
7334 }
7335
7336 free(*target);
7337 *target = strdup(args[1]);
7338 return 0;
7339}
7340
Willy Tarreau9ceda382016-12-21 23:13:03 +01007341/* parse various global tune.ssl settings consisting in positive integers.
7342 * Returns <0 on alert, >0 on warning, 0 on success.
7343 */
7344static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
7345 struct proxy *defpx, const char *file, int line,
7346 char **err)
7347{
7348 int *target;
7349
7350 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
7351 target = &global.tune.sslcachesize;
7352 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007353 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007354 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01007355 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007356 else if (strcmp(args[0], "maxsslconn") == 0)
7357 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007358 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
7359 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007360 else {
7361 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
7362 return -1;
7363 }
7364
7365 if (too_many_args(1, args, err, NULL))
7366 return -1;
7367
7368 if (*(args[1]) == 0) {
7369 memprintf(err, "'%s' expects an integer argument.", args[0]);
7370 return -1;
7371 }
7372
7373 *target = atoi(args[1]);
7374 if (*target < 0) {
7375 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
7376 return -1;
7377 }
7378 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007379}
7380
7381static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
7382 struct proxy *defpx, const char *file, int line,
7383 char **err)
7384{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007385 int ret;
7386
7387 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
7388 if (ret != 0)
7389 return ret;
7390
7391 if (pool2_ssl_capture) {
7392 memprintf(err, "'%s' is already configured.", args[0]);
7393 return -1;
7394 }
7395
7396 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
7397 if (!pool2_ssl_capture) {
7398 memprintf(err, "Out of memory error.");
7399 return -1;
7400 }
7401 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007402}
7403
7404/* parse "ssl.force-private-cache".
7405 * Returns <0 on alert, >0 on warning, 0 on success.
7406 */
7407static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
7408 struct proxy *defpx, const char *file, int line,
7409 char **err)
7410{
7411 if (too_many_args(0, args, err, NULL))
7412 return -1;
7413
Willy Tarreauef934602016-12-22 23:12:01 +01007414 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007415 return 0;
7416}
7417
7418/* parse "ssl.lifetime".
7419 * Returns <0 on alert, >0 on warning, 0 on success.
7420 */
7421static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
7422 struct proxy *defpx, const char *file, int line,
7423 char **err)
7424{
7425 const char *res;
7426
7427 if (too_many_args(1, args, err, NULL))
7428 return -1;
7429
7430 if (*(args[1]) == 0) {
7431 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
7432 return -1;
7433 }
7434
Willy Tarreauef934602016-12-22 23:12:01 +01007435 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01007436 if (res) {
7437 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
7438 return -1;
7439 }
7440 return 0;
7441}
7442
7443#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01007444/* parse "ssl-dh-param-file".
7445 * Returns <0 on alert, >0 on warning, 0 on success.
7446 */
7447static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
7448 struct proxy *defpx, const char *file, int line,
7449 char **err)
7450{
7451 if (too_many_args(1, args, err, NULL))
7452 return -1;
7453
7454 if (*(args[1]) == 0) {
7455 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
7456 return -1;
7457 }
7458
7459 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
7460 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
7461 return -1;
7462 }
7463 return 0;
7464}
7465
Willy Tarreau9ceda382016-12-21 23:13:03 +01007466/* parse "ssl.default-dh-param".
7467 * Returns <0 on alert, >0 on warning, 0 on success.
7468 */
7469static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
7470 struct proxy *defpx, const char *file, int line,
7471 char **err)
7472{
7473 if (too_many_args(1, args, err, NULL))
7474 return -1;
7475
7476 if (*(args[1]) == 0) {
7477 memprintf(err, "'%s' expects an integer argument.", args[0]);
7478 return -1;
7479 }
7480
Willy Tarreauef934602016-12-22 23:12:01 +01007481 global_ssl.default_dh_param = atoi(args[1]);
7482 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01007483 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
7484 return -1;
7485 }
7486 return 0;
7487}
7488#endif
7489
7490
William Lallemand32af2032016-10-29 18:09:35 +02007491/* This function is used with TLS ticket keys management. It permits to browse
7492 * each reference. The variable <getnext> must contain the current node,
7493 * <end> point to the root node.
7494 */
7495#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7496static inline
7497struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
7498{
7499 struct tls_keys_ref *ref = getnext;
7500
7501 while (1) {
7502
7503 /* Get next list entry. */
7504 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
7505
7506 /* If the entry is the last of the list, return NULL. */
7507 if (&ref->list == end)
7508 return NULL;
7509
7510 return ref;
7511 }
7512}
7513
7514static inline
7515struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7516{
7517 int id;
7518 char *error;
7519
7520 /* If the reference starts by a '#', this is numeric id. */
7521 if (reference[0] == '#') {
7522 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7523 id = strtol(reference + 1, &error, 10);
7524 if (*error != '\0')
7525 return NULL;
7526
7527 /* Perform the unique id lookup. */
7528 return tlskeys_ref_lookupid(id);
7529 }
7530
7531 /* Perform the string lookup. */
7532 return tlskeys_ref_lookup(reference);
7533}
7534#endif
7535
7536
7537#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7538
7539static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7540
7541static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7542 return cli_io_handler_tlskeys_files(appctx);
7543}
7544
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007545/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7546 * (next index to be dumped), and cli.p0 (next key reference).
7547 */
William Lallemand32af2032016-10-29 18:09:35 +02007548static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7549
7550 struct stream_interface *si = appctx->owner;
7551
7552 switch (appctx->st2) {
7553 case STAT_ST_INIT:
7554 /* Display the column headers. If the message cannot be sent,
7555 * quit the fucntion with returning 0. The function is called
7556 * later and restart at the state "STAT_ST_INIT".
7557 */
7558 chunk_reset(&trash);
7559
7560 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7561 chunk_appendf(&trash, "# id secret\n");
7562 else
7563 chunk_appendf(&trash, "# id (file)\n");
7564
7565 if (bi_putchk(si_ic(si), &trash) == -1) {
7566 si_applet_cant_put(si);
7567 return 0;
7568 }
7569
William Lallemand32af2032016-10-29 18:09:35 +02007570 /* Now, we start the browsing of the references lists.
7571 * Note that the following call to LIST_ELEM return bad pointer. The only
7572 * available field of this pointer is <list>. It is used with the function
7573 * tlskeys_list_get_next() for retruning the first available entry
7574 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007575 if (appctx->ctx.cli.p0 == NULL) {
7576 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7577 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007578 }
7579
7580 appctx->st2 = STAT_ST_LIST;
7581 /* fall through */
7582
7583 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007584 while (appctx->ctx.cli.p0) {
7585 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7586 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007587
7588 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007589 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007590 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007591
7592 if (appctx->ctx.cli.i1 == 0)
7593 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7594
William Lallemand32af2032016-10-29 18:09:35 +02007595 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007596 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007597 struct chunk *t2 = get_trash_chunk();
7598
7599 chunk_reset(t2);
7600 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007601 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007602 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007603 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007604
7605 if (bi_putchk(si_ic(si), &trash) == -1) {
7606 /* let's try again later from this stream. We add ourselves into
7607 * this stream's users so that it can remove us upon termination.
7608 */
7609 si_applet_cant_put(si);
7610 return 0;
7611 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007612 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007613 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007614 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007615 }
7616 if (bi_putchk(si_ic(si), &trash) == -1) {
7617 /* let's try again later from this stream. We add ourselves into
7618 * this stream's users so that it can remove us upon termination.
7619 */
7620 si_applet_cant_put(si);
7621 return 0;
7622 }
7623
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007624 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007625 break;
7626
7627 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007628 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007629 }
7630
7631 appctx->st2 = STAT_ST_FIN;
7632 /* fall through */
7633
7634 default:
7635 appctx->st2 = STAT_ST_FIN;
7636 return 1;
7637 }
7638 return 0;
7639}
7640
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007641/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007642static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7643{
William Lallemand32af2032016-10-29 18:09:35 +02007644 /* no parameter, shows only file list */
7645 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007646 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007647 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007648 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007649 }
7650
7651 if (args[2][0] == '*') {
7652 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007653 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007654 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007655 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7656 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007657 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007658 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007659 return 1;
7660 }
7661 }
William Lallemand32af2032016-10-29 18:09:35 +02007662 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007663 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007664}
7665
William Lallemand32af2032016-10-29 18:09:35 +02007666static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7667{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007668 struct tls_keys_ref *ref;
7669
William Lallemand32af2032016-10-29 18:09:35 +02007670 /* Expect two parameters: the filename and the new new TLS key in encoding */
7671 if (!*args[3] || !*args[4]) {
7672 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 +01007673 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007674 return 1;
7675 }
7676
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007677 ref = tlskeys_ref_lookup_ref(args[3]);
7678 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007679 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007680 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007681 return 1;
7682 }
7683
7684 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7685 if (trash.len != sizeof(struct tls_sess_key)) {
7686 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007687 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007688 return 1;
7689 }
7690
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007691 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7692 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007693
7694 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007695 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007696 return 1;
7697
7698}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007699#endif
William Lallemand32af2032016-10-29 18:09:35 +02007700
7701static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7702{
7703#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7704 char *err = NULL;
7705
7706 /* Expect one parameter: the new response in base64 encoding */
7707 if (!*args[3]) {
7708 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007709 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007710 return 1;
7711 }
7712
7713 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7714 if (trash.len < 0) {
7715 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007716 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007717 return 1;
7718 }
7719
7720 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7721 if (err) {
7722 memprintf(&err, "%s.\n", err);
7723 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007724 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007725 }
7726 return 1;
7727 }
7728 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007729 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007730 return 1;
7731#else
7732 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 +01007733 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007734 return 1;
7735#endif
7736
7737}
7738
7739/* register cli keywords */
7740static struct cli_kw_list cli_kws = {{ },{
7741#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7742 { { "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 },
7743 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007744#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007745 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007746 { { NULL }, NULL, NULL, NULL }
7747}};
7748
7749
Willy Tarreau7875d092012-09-10 08:20:03 +02007750/* Note: must not be declared <const> as its list will be overwritten.
7751 * Please take care of keeping this list alphabetically sorted.
7752 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007753static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007754 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007755 { "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 +02007756 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7757 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007758 { "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 +02007759 { "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 +02007760 { "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 +02007761 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7762 { "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 +01007763 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007764 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007765 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7766 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7767 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7768 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7769 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7770 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7771 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7772 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007773 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007774 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7775 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007776 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007777 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7778 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7779 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7780 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7781 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7782 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7783 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007784 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007785 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007786 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007787 { "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 +01007788 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007789 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7790 { "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 +02007791 { "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 +02007792#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007793 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007794#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007795#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007796 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007797#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007798 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007799 { "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 +02007800 { "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 +01007801 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7802 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007803 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7804 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7805 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7806 { "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 +02007807 { NULL, NULL, 0, 0, 0 },
7808}};
7809
7810/* Note: must not be declared <const> as its list will be overwritten.
7811 * Please take care of keeping this list alphabetically sorted.
7812 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007813static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007814 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7815 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007816 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007817}};
7818
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007819/* Note: must not be declared <const> as its list will be overwritten.
7820 * Please take care of keeping this list alphabetically sorted, doing so helps
7821 * all code contributors.
7822 * Optional keywords are also declared with a NULL ->parse() function so that
7823 * the config parser can report an appropriate error when a known keyword was
7824 * not enabled.
7825 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007826static struct ssl_bind_kw ssl_bind_kws[] = {
7827 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7828 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7829 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7830 { "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 +01007831 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007832 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007833 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7834 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7835 { NULL, NULL, 0 },
7836};
7837
Willy Tarreau51fb7652012-09-18 18:24:39 +02007838static struct bind_kw_list bind_kws = { "SSL", { }, {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007839 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7840 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7841 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
7842 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7843 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
7844 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7845 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7846 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7847 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7848 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
7849 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
7850 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7851 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
7852 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
7853 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
7854 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02007855 { "force-tlsv13", bind_parse_tls_method_options, 0 }, /* force TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007856 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
7857 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
7858 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
7859 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
7860 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02007861 { "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007862 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7863 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007864 { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
7865 { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007866 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7867 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7868 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7869 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
7870 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007871 { NULL, NULL, 0 },
7872}};
Emeric Brun46591952012-05-18 15:47:34 +02007873
Willy Tarreau92faadf2012-10-10 23:04:25 +02007874/* Note: must not be declared <const> as its list will be overwritten.
7875 * Please take care of keeping this list alphabetically sorted, doing so helps
7876 * all code contributors.
7877 * Optional keywords are also declared with a NULL ->parse() function so that
7878 * the config parser can report an appropriate error when a known keyword was
7879 * not enabled.
7880 */
7881static struct srv_kw_list srv_kws = { "SSL", { }, {
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007882 { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
7883 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
7884 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
7885 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
7886 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
7887 { "force-sslv3", srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
7888 { "force-tlsv10", srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
7889 { "force-tlsv11", srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
7890 { "force-tlsv12", srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
7891 { "force-tlsv13", srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
7892 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
7893 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
7894 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
7895 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
7896 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
7897 { "no-sslv3", srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
7898 { "no-tlsv10", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
7899 { "no-tlsv11", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
7900 { "no-tlsv12", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
7901 { "no-tlsv13", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
7902 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
7903 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
7904 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
7905 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
7906 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
7907 { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1 }, /* minimum version */
7908 { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1 }, /* maximum version */
7909 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
7910 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
7911 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
7912 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007913 { NULL, NULL, 0, 0 },
7914}};
7915
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007916static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007917 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7918 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007919 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007920 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7921 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007922#ifndef OPENSSL_NO_DH
7923 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7924#endif
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00007925 { CFG_GLOBAL, "ssl-mode-async", ssl_parse_global_ssl_async },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007926#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00007927 { CFG_GLOBAL, "ssl-engine", ssl_parse_global_ssl_engine },
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02007928#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007929 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7930#ifndef OPENSSL_NO_DH
7931 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7932#endif
7933 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7934 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7935 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7936 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007937 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007938 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7939 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007940 { 0, NULL, NULL },
7941}};
7942
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007943/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007944static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007945 .snd_buf = ssl_sock_from_buf,
7946 .rcv_buf = ssl_sock_to_buf,
7947 .rcv_pipe = NULL,
7948 .snd_pipe = NULL,
7949 .shutr = NULL,
7950 .shutw = ssl_sock_shutw,
7951 .close = ssl_sock_close,
7952 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007953 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007954 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007955 .prepare_srv = ssl_sock_prepare_srv_ctx,
7956 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007957 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007958};
7959
Daniel Jakots54ffb912015-11-06 20:02:41 +01007960#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007961
7962static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7963{
7964 if (ptr) {
7965 chunk_destroy(ptr);
7966 free(ptr);
7967 }
7968}
7969
7970#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007971static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7972{
7973 pool_free2(pool2_ssl_capture, ptr);
7974}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007975
Emeric Brun46591952012-05-18 15:47:34 +02007976__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007977static void __ssl_sock_init(void)
7978{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007979 char *ptr;
7980
Emeric Brun46591952012-05-18 15:47:34 +02007981 STACK_OF(SSL_COMP)* cm;
7982
Willy Tarreauef934602016-12-22 23:12:01 +01007983 if (global_ssl.listen_default_ciphers)
7984 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7985 if (global_ssl.connect_default_ciphers)
7986 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007987
Willy Tarreau13e14102016-12-22 20:25:26 +01007988 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007989 SSL_library_init();
7990 cm = SSL_COMP_get_compression_methods();
7991 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007992#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007993 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7994#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007995 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 +02007996 sample_register_fetches(&sample_fetch_keywords);
7997 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007998 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007999 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01008000 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02008001 cli_register_kw(&cli_kws);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008002#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008003 ENGINE_load_builtin_engines();
Grant Zhangfa6c7ee2017-01-14 01:42:15 +00008004 hap_register_post_check(ssl_check_async_engine_count);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008005#endif
Willy Tarreaud1c57502016-12-22 22:46:15 +01008006#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
8007 hap_register_post_check(tlskeys_finalize_config);
8008#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008009
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008010 ptr = NULL;
8011 memprintf(&ptr, "Built with OpenSSL version : "
8012#ifdef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008013 "BoringSSL");
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008014#else /* OPENSSL_IS_BORINGSSL */
8015 OPENSSL_VERSION_TEXT
8016 "\nRunning on OpenSSL version : %s%s",
8017 SSLeay_version(SSLEAY_VERSION),
8018 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
8019#endif
8020 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
8021#if OPENSSL_VERSION_NUMBER < 0x00907000L
8022 "no (library version too old)"
8023#elif defined(OPENSSL_NO_TLSEXT)
8024 "no (disabled via OPENSSL_NO_TLSEXT)"
8025#else
8026 "yes"
8027#endif
8028 "", ptr);
8029
8030 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
8031#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
8032 "yes"
8033#else
8034#ifdef OPENSSL_NO_TLSEXT
8035 "no (because of OPENSSL_NO_TLSEXT)"
8036#else
8037 "no (version might be too old, 0.9.8f min needed)"
8038#endif
8039#endif
8040 "", ptr);
8041
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01008042 memprintf(&ptr, "%s\nOpenSSL library supports : "
8043#if SSL_OP_NO_SSLv3
8044 "SSLv3 "
8045#endif
8046#if SSL_OP_NO_TLSv1
8047 "TLSv1.0 "
8048#endif
8049#if SSL_OP_NO_TLSv1_1
8050 "TLSv1.1 "
8051#endif
8052#if SSL_OP_NO_TLSv1_2
8053 "TLSv1.2 "
8054#endif
8055#if SSL_OP_NO_TLSv1_3
8056 "TLSv1.3"
8057#endif
8058 "", ptr);
8059
Willy Tarreauc2c0b612016-12-21 19:23:20 +01008060 hap_register_build_opts(ptr, 1);
8061
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01008062 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
8063 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02008064
8065#ifndef OPENSSL_NO_DH
8066 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
Grant Zhang872f9c22017-01-21 01:10:18 +00008067 hap_register_post_deinit(ssl_free_dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02008068#endif
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008069#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008070 hap_register_post_deinit(ssl_free_engines);
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008071#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02008072 /* Load SSL string for the verbose & debug mode. */
8073 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02008074}
8075
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008076#ifndef OPENSSL_NO_ENGINE
Grant Zhang872f9c22017-01-21 01:10:18 +00008077void ssl_free_engines(void) {
8078 struct ssl_engine_list *wl, *wlb;
8079 /* free up engine list */
8080 list_for_each_entry_safe(wl, wlb, &openssl_engines, list) {
8081 ENGINE_finish(wl->e);
8082 ENGINE_free(wl->e);
8083 LIST_DEL(&wl->list);
8084 free(wl);
8085 }
8086}
Emmanuel Hocdet9ac143b2017-05-29 14:36:20 +02008087#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02008088
Remi Gacogned3a23c32015-05-28 16:39:47 +02008089#ifndef OPENSSL_NO_DH
Grant Zhang872f9c22017-01-21 01:10:18 +00008090void ssl_free_dh(void) {
8091 if (local_dh_1024) {
8092 DH_free(local_dh_1024);
8093 local_dh_1024 = NULL;
8094 }
8095 if (local_dh_2048) {
8096 DH_free(local_dh_2048);
8097 local_dh_2048 = NULL;
8098 }
8099 if (local_dh_4096) {
8100 DH_free(local_dh_4096);
8101 local_dh_4096 = NULL;
8102 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02008103 if (global_dh) {
8104 DH_free(global_dh);
8105 global_dh = NULL;
8106 }
Grant Zhang872f9c22017-01-21 01:10:18 +00008107}
8108#endif
8109
8110__attribute__((destructor))
8111static void __ssl_sock_deinit(void)
8112{
8113#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
8114 lru64_destroy(ssl_ctx_lru_tree);
Remi Gacogned3a23c32015-05-28 16:39:47 +02008115#endif
8116
8117 ERR_remove_state(0);
8118 ERR_free_strings();
8119
8120 EVP_cleanup();
8121
8122#if OPENSSL_VERSION_NUMBER >= 0x00907000L
8123 CRYPTO_cleanup_all_ex_data();
8124#endif
8125}
8126
8127
Emeric Brun46591952012-05-18 15:47:34 +02008128/*
8129 * Local variables:
8130 * c-indent-level: 8
8131 * c-basic-offset: 8
8132 * End:
8133 */