blob: 21d50c753df61b4793bbf06db2fc7031bdcbabc4 [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
Emeric Brun46591952012-05-18 15:47:34 +020055
Christopher Faulet31af49d2015-06-09 17:29:50 +020056#include <import/lru.h>
57#include <import/xxhash.h>
58
Emeric Brun46591952012-05-18 15:47:34 +020059#include <common/buffer.h>
60#include <common/compat.h>
61#include <common/config.h>
62#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020063#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020064#include <common/standard.h>
65#include <common/ticks.h>
66#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010067#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010068#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020069
Emeric Brunfc0421f2012-09-07 17:30:07 +020070#include <ebsttree.h>
71
William Lallemand32af2032016-10-29 18:09:35 +020072#include <types/applet.h>
73#include <types/cli.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020074#include <types/global.h>
75#include <types/ssl_sock.h>
William Lallemand32af2032016-10-29 18:09:35 +020076#include <types/stats.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020077
Willy Tarreau7875d092012-09-10 08:20:03 +020078#include <proto/acl.h>
79#include <proto/arg.h>
William Lallemand32af2032016-10-29 18:09:35 +020080#include <proto/channel.h>
Emeric Brun46591952012-05-18 15:47:34 +020081#include <proto/connection.h>
William Lallemand32af2032016-10-29 18:09:35 +020082#include <proto/cli.h>
Emeric Brun46591952012-05-18 15:47:34 +020083#include <proto/fd.h>
84#include <proto/freq_ctr.h>
85#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020086#include <proto/listener.h>
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020087#include <proto/openssl-compat.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010088#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020089#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020090#include <proto/server.h>
William Lallemand32af2032016-10-29 18:09:35 +020091#include <proto/stream_interface.h>
Emeric Brun46591952012-05-18 15:47:34 +020092#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020093#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020094#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020095#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020096#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020097#include <proto/task.h>
98
Willy Tarreau518cedd2014-02-17 15:43:01 +010099/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +0200100#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +0100101#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +0100102#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +0200103#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
104
Emeric Brunf282a812012-09-21 15:27:54 +0200105/* bits 0xFFFF0000 are reserved to store verify errors */
106
107/* Verify errors macros */
108#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
109#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
110#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
111
112#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
113#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
114#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200115
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100116/* Supported hash function for TLS tickets */
117#ifdef OPENSSL_NO_SHA256
118#define HASH_FUNCT EVP_sha1
119#else
120#define HASH_FUNCT EVP_sha256
121#endif /* OPENSSL_NO_SHA256 */
122
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200123/* ssl_methods flags for ssl options */
124#define MC_SSL_O_ALL 0x0000
125#define MC_SSL_O_NO_SSLV3 0x0001 /* disable SSLv3 */
126#define MC_SSL_O_NO_TLSV10 0x0002 /* disable TLSv10 */
127#define MC_SSL_O_NO_TLSV11 0x0004 /* disable TLSv11 */
128#define MC_SSL_O_NO_TLSV12 0x0008 /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +0200129#define MC_SSL_O_NO_TLSV13 0x0010 /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200130
131/* ssl_methods versions */
132enum {
133 CONF_TLSV_NONE = 0,
134 CONF_TLSV_MIN = 1,
135 CONF_SSLV3 = 1,
136 CONF_TLSV10 = 2,
137 CONF_TLSV11 = 3,
138 CONF_TLSV12 = 4,
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +0200139 CONF_TLSV13 = 5,
140 CONF_TLSV_MAX = 5,
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200141};
142
Emeric Brun850efd52014-01-29 12:24:34 +0100143/* server and bind verify method, it uses a global value as default */
144enum {
145 SSL_SOCK_VERIFY_DEFAULT = 0,
146 SSL_SOCK_VERIFY_REQUIRED = 1,
147 SSL_SOCK_VERIFY_OPTIONAL = 2,
148 SSL_SOCK_VERIFY_NONE = 3,
149};
150
Willy Tarreau71b734c2014-01-28 15:19:44 +0100151int sslconns = 0;
152int totalsslconns = 0;
Willy Tarreaud9f5cca2016-12-22 21:08:52 +0100153static struct xprt_ops ssl_sock;
Emeric Brune1f38db2012-09-03 20:36:47 +0200154
Willy Tarreauef934602016-12-22 23:12:01 +0100155static struct {
156 char *crt_base; /* base directory path for certificates */
157 char *ca_base; /* base directory path for CAs and CRLs */
158
159 char *listen_default_ciphers;
160 char *connect_default_ciphers;
161 int listen_default_ssloptions;
162 int connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200163 struct tls_version_filter listen_default_sslmethods;
164 struct tls_version_filter connect_default_sslmethods;
Willy Tarreauef934602016-12-22 23:12:01 +0100165
166 int private_cache; /* Force to use a private session cache even if nbproc > 1 */
167 unsigned int life_time; /* SSL session lifetime in seconds */
168 unsigned int max_record; /* SSL max record size */
169 unsigned int default_dh_param; /* SSL maximum DH parameter size */
170 int ctx_cache; /* max number of entries in the ssl_ctx cache. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100171 int capture_cipherlist; /* Size of the cipherlist buffer. */
Willy Tarreauef934602016-12-22 23:12:01 +0100172} global_ssl = {
173#ifdef LISTEN_DEFAULT_CIPHERS
174 .listen_default_ciphers = LISTEN_DEFAULT_CIPHERS,
175#endif
176#ifdef CONNECT_DEFAULT_CIPHERS
177 .connect_default_ciphers = CONNECT_DEFAULT_CIPHERS,
178#endif
179 .listen_default_ssloptions = BC_SSL_O_NONE,
180 .connect_default_ssloptions = SRV_SSL_O_NONE,
181
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200182 .listen_default_sslmethods.flags = MC_SSL_O_ALL,
183 .listen_default_sslmethods.min = CONF_TLSV_NONE,
184 .listen_default_sslmethods.max = CONF_TLSV_NONE,
185 .connect_default_sslmethods.flags = MC_SSL_O_ALL,
186 .connect_default_sslmethods.min = CONF_TLSV_NONE,
187 .connect_default_sslmethods.max = CONF_TLSV_NONE,
188
Willy Tarreauef934602016-12-22 23:12:01 +0100189#ifdef DEFAULT_SSL_MAX_RECORD
190 .max_record = DEFAULT_SSL_MAX_RECORD,
191#endif
192 .default_dh_param = SSL_DEFAULT_DH_PARAM,
193 .ctx_cache = DEFAULT_SSL_CTX_CACHE,
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100194 .capture_cipherlist = 0,
Willy Tarreauef934602016-12-22 23:12:01 +0100195};
196
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100197/* This memory pool is used for capturing clienthello parameters. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100198struct ssl_capture {
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100199 unsigned long long int xxh64;
200 unsigned char ciphersuite_len;
201 char ciphersuite[0];
202};
203struct pool_head *pool2_ssl_capture = NULL;
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100204static int ssl_capture_ptr_index = -1;
Willy Tarreauef934602016-12-22 23:12:01 +0100205
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200206#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
207struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
208#endif
209
Remi Gacogne8de54152014-07-15 11:36:40 +0200210#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200211static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200212static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200213static DH *local_dh_1024 = NULL;
214static DH *local_dh_2048 = NULL;
215static DH *local_dh_4096 = NULL;
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +0100216static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
Remi Gacogne8de54152014-07-15 11:36:40 +0200217#endif /* OPENSSL_NO_DH */
218
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100219#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +0200220/* X509V3 Extensions that will be added on generated certificates */
221#define X509V3_EXT_SIZE 5
222static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
223 "basicConstraints",
224 "nsComment",
225 "subjectKeyIdentifier",
226 "authorityKeyIdentifier",
227 "keyUsage",
228};
229static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
230 "CA:FALSE",
231 "\"OpenSSL Generated Certificate\"",
232 "hash",
233 "keyid,issuer:always",
234 "nonRepudiation,digitalSignature,keyEncipherment"
235};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200236/* LRU cache to store generated certificate */
237static struct lru64_head *ssl_ctx_lru_tree = NULL;
238static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200239#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
240
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100241static struct ssl_bind_kw ssl_bind_kws[];
242
yanbzhube2774d2015-12-10 15:07:30 -0500243#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
244/* The order here matters for picking a default context,
245 * keep the most common keytype at the bottom of the list
246 */
247const char *SSL_SOCK_KEYTYPE_NAMES[] = {
248 "dsa",
249 "ecdsa",
250 "rsa"
251};
252#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100253#else
254#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500255#endif
256
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100257/*
258 * This function gives the detail of the SSL error. It is used only
259 * if the debug mode and the verbose mode are activated. It dump all
260 * the SSL error until the stack was empty.
261 */
262static forceinline void ssl_sock_dump_errors(struct connection *conn)
263{
264 unsigned long ret;
265
266 if (unlikely(global.mode & MODE_DEBUG)) {
267 while(1) {
268 ret = ERR_get_error();
269 if (ret == 0)
270 return;
271 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
272 (unsigned short)conn->t.sock.fd, ret,
273 ERR_func_error_string(ret), ERR_reason_error_string(ret));
274 }
275 }
276}
277
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200278#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500279/*
280 * struct alignment works here such that the key.key is the same as key_data
281 * Do not change the placement of key_data
282 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200283struct certificate_ocsp {
284 struct ebmb_node key;
285 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
286 struct chunk response;
287 long expire;
288};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200289
yanbzhube2774d2015-12-10 15:07:30 -0500290struct ocsp_cbk_arg {
291 int is_single;
292 int single_kt;
293 union {
294 struct certificate_ocsp *s_ocsp;
295 /*
296 * m_ocsp will have multiple entries dependent on key type
297 * Entry 0 - DSA
298 * Entry 1 - ECDSA
299 * Entry 2 - RSA
300 */
301 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
302 };
303};
304
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200305/*
306 * This function returns the number of seconds elapsed
307 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
308 * date presented un ASN1_GENERALIZEDTIME.
309 *
310 * In parsing error case, it returns -1.
311 */
312static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
313{
314 long epoch;
315 char *p, *end;
316 const unsigned short month_offset[12] = {
317 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
318 };
319 int year, month;
320
321 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
322
323 p = (char *)d->data;
324 end = p + d->length;
325
326 if (end - p < 4) return -1;
327 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
328 p += 4;
329 if (end - p < 2) return -1;
330 month = 10 * (p[0] - '0') + p[1] - '0';
331 if (month < 1 || month > 12) return -1;
332 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
333 We consider leap years and the current month (<marsh or not) */
334 epoch = ( ((year - 1970) * 365)
335 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
336 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
337 + month_offset[month-1]
338 ) * 24 * 60 * 60;
339 p += 2;
340 if (end - p < 2) return -1;
341 /* Add the number of seconds of completed days of current month */
342 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
343 p += 2;
344 if (end - p < 2) return -1;
345 /* Add the completed hours of the current day */
346 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
347 p += 2;
348 if (end - p < 2) return -1;
349 /* Add the completed minutes of the current hour */
350 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
351 p += 2;
352 if (p == end) return -1;
353 /* Test if there is available seconds */
354 if (p[0] < '0' || p[0] > '9')
355 goto nosec;
356 if (end - p < 2) return -1;
357 /* Add the seconds of the current minute */
358 epoch += 10 * (p[0] - '0') + p[1] - '0';
359 p += 2;
360 if (p == end) return -1;
361 /* Ignore seconds float part if present */
362 if (p[0] == '.') {
363 do {
364 if (++p == end) return -1;
365 } while (p[0] >= '0' && p[0] <= '9');
366 }
367
368nosec:
369 if (p[0] == 'Z') {
370 if (end - p != 1) return -1;
371 return epoch;
372 }
373 else if (p[0] == '+') {
374 if (end - p != 5) return -1;
375 /* Apply timezone offset */
376 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
377 }
378 else if (p[0] == '-') {
379 if (end - p != 5) return -1;
380 /* Apply timezone offset */
381 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
382 }
383
384 return -1;
385}
386
Emeric Brun1d3865b2014-06-20 15:37:32 +0200387static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200388
389/* This function starts to check if the OCSP response (in DER format) contained
390 * in chunk 'ocsp_response' is valid (else exits on error).
391 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
392 * contained in the OCSP Response and exits on error if no match.
393 * If it's a valid OCSP Response:
394 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
395 * pointed by 'ocsp'.
396 * If 'ocsp' is NULL, the function looks up into the OCSP response's
397 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
398 * from the response) and exits on error if not found. Finally, If an OCSP response is
399 * already present in the container, it will be overwritten.
400 *
401 * Note: OCSP response containing more than one OCSP Single response is not
402 * considered valid.
403 *
404 * Returns 0 on success, 1 in error case.
405 */
406static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
407{
408 OCSP_RESPONSE *resp;
409 OCSP_BASICRESP *bs = NULL;
410 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200411 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200412 unsigned char *p = (unsigned char *)ocsp_response->str;
413 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200414 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200415 int reason;
416 int ret = 1;
417
418 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
419 if (!resp) {
420 memprintf(err, "Unable to parse OCSP response");
421 goto out;
422 }
423
424 rc = OCSP_response_status(resp);
425 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
426 memprintf(err, "OCSP response status not successful");
427 goto out;
428 }
429
430 bs = OCSP_response_get1_basic(resp);
431 if (!bs) {
432 memprintf(err, "Failed to get basic response from OCSP Response");
433 goto out;
434 }
435
436 count_sr = OCSP_resp_count(bs);
437 if (count_sr > 1) {
438 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
439 goto out;
440 }
441
442 sr = OCSP_resp_get0(bs, 0);
443 if (!sr) {
444 memprintf(err, "Failed to get OCSP single response");
445 goto out;
446 }
447
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200448 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
449
Emeric Brun4147b2e2014-06-16 18:36:30 +0200450 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
451 if (rc != V_OCSP_CERTSTATUS_GOOD) {
452 memprintf(err, "OCSP single response: certificate status not good");
453 goto out;
454 }
455
Emeric Brun13a6b482014-06-20 15:44:34 +0200456 if (!nextupd) {
457 memprintf(err, "OCSP single response: missing nextupdate");
458 goto out;
459 }
460
Emeric Brunc8b27b62014-06-19 14:16:17 +0200461 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200462 if (!rc) {
463 memprintf(err, "OCSP single response: no longer valid.");
464 goto out;
465 }
466
467 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200468 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200469 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
470 goto out;
471 }
472 }
473
474 if (!ocsp) {
475 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
476 unsigned char *p;
477
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200478 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200479 if (!rc) {
480 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
481 goto out;
482 }
483
484 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
485 memprintf(err, "OCSP single response: Certificate ID too long");
486 goto out;
487 }
488
489 p = key;
490 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200491 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200492 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
493 if (!ocsp) {
494 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
495 goto out;
496 }
497 }
498
499 /* According to comments on "chunk_dup", the
500 previous chunk buffer will be freed */
501 if (!chunk_dup(&ocsp->response, ocsp_response)) {
502 memprintf(err, "OCSP response: Memory allocation error");
503 goto out;
504 }
505
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200506 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
507
Emeric Brun4147b2e2014-06-16 18:36:30 +0200508 ret = 0;
509out:
Janusz Dziemidowicz8d710492017-03-08 16:59:41 +0100510 ERR_clear_error();
511
Emeric Brun4147b2e2014-06-16 18:36:30 +0200512 if (bs)
513 OCSP_BASICRESP_free(bs);
514
515 if (resp)
516 OCSP_RESPONSE_free(resp);
517
518 return ret;
519}
520/*
521 * External function use to update the OCSP response in the OCSP response's
522 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
523 * to update in DER format.
524 *
525 * Returns 0 on success, 1 in error case.
526 */
527int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
528{
529 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
530}
531
532/*
533 * This function load the OCSP Resonse in DER format contained in file at
534 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
535 *
536 * Returns 0 on success, 1 in error case.
537 */
538static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
539{
540 int fd = -1;
541 int r = 0;
542 int ret = 1;
543
544 fd = open(ocsp_path, O_RDONLY);
545 if (fd == -1) {
546 memprintf(err, "Error opening OCSP response file");
547 goto end;
548 }
549
550 trash.len = 0;
551 while (trash.len < trash.size) {
552 r = read(fd, trash.str + trash.len, trash.size - trash.len);
553 if (r < 0) {
554 if (errno == EINTR)
555 continue;
556
557 memprintf(err, "Error reading OCSP response from file");
558 goto end;
559 }
560 else if (r == 0) {
561 break;
562 }
563 trash.len += r;
564 }
565
566 close(fd);
567 fd = -1;
568
569 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
570end:
571 if (fd != -1)
572 close(fd);
573
574 return ret;
575}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100576#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200577
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100578#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
579static 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)
580{
581 struct tls_sess_key *keys;
582 struct connection *conn;
583 int head;
584 int i;
585
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200586 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200587 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
588 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100589
590 if (enc) {
591 memcpy(key_name, keys[head].name, 16);
592
593 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
594 return -1;
595
596 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
597 return -1;
598
599 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
600
601 return 1;
602 } else {
603 for (i = 0; i < TLS_TICKETS_NO; i++) {
604 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
605 goto found;
606 }
607 return 0;
608
609 found:
610 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
611 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
612 return -1;
613 /* 2 for key renewal, 1 if current key is still valid */
614 return i ? 2 : 1;
615 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200616}
617
618struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
619{
620 struct tls_keys_ref *ref;
621
622 list_for_each_entry(ref, &tlskeys_reference, list)
623 if (ref->filename && strcmp(filename, ref->filename) == 0)
624 return ref;
625 return NULL;
626}
627
628struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
629{
630 struct tls_keys_ref *ref;
631
632 list_for_each_entry(ref, &tlskeys_reference, list)
633 if (ref->unique_id == unique_id)
634 return ref;
635 return NULL;
636}
637
638int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
639 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
640
641 if(!ref) {
642 memprintf(err, "Unable to locate the referenced filename: %s", filename);
643 return 1;
644 }
645
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530646 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
647 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200648
649 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100650}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200651
652/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100653 * automatic ids. It's called just after the basic checks. It returns
654 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200655 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100656static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200657{
658 int i = 0;
659 struct tls_keys_ref *ref, *ref2, *ref3;
660 struct list tkr = LIST_HEAD_INIT(tkr);
661
662 list_for_each_entry(ref, &tlskeys_reference, list) {
663 if (ref->unique_id == -1) {
664 /* Look for the first free id. */
665 while (1) {
666 list_for_each_entry(ref2, &tlskeys_reference, list) {
667 if (ref2->unique_id == i) {
668 i++;
669 break;
670 }
671 }
672 if (&ref2->list == &tlskeys_reference)
673 break;
674 }
675
676 /* Uses the unique id and increment it for the next entry. */
677 ref->unique_id = i;
678 i++;
679 }
680 }
681
682 /* This sort the reference list by id. */
683 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
684 LIST_DEL(&ref->list);
685 list_for_each_entry(ref3, &tkr, list) {
686 if (ref->unique_id < ref3->unique_id) {
687 LIST_ADDQ(&ref3->list, &ref->list);
688 break;
689 }
690 }
691 if (&ref3->list == &tkr)
692 LIST_ADDQ(&tkr, &ref->list);
693 }
694
695 /* swap root */
696 LIST_ADD(&tkr, &tlskeys_reference);
697 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100698 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200699}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100700#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
701
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100702#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500703int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
704{
705 switch (evp_keytype) {
706 case EVP_PKEY_RSA:
707 return 2;
708 case EVP_PKEY_DSA:
709 return 0;
710 case EVP_PKEY_EC:
711 return 1;
712 }
713
714 return -1;
715}
716
Emeric Brun4147b2e2014-06-16 18:36:30 +0200717/*
718 * Callback used to set OCSP status extension content in server hello.
719 */
720int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
721{
yanbzhube2774d2015-12-10 15:07:30 -0500722 struct certificate_ocsp *ocsp;
723 struct ocsp_cbk_arg *ocsp_arg;
724 char *ssl_buf;
725 EVP_PKEY *ssl_pkey;
726 int key_type;
727 int index;
728
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200729 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500730
731 ssl_pkey = SSL_get_privatekey(ssl);
732 if (!ssl_pkey)
733 return SSL_TLSEXT_ERR_NOACK;
734
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200735 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500736
737 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
738 ocsp = ocsp_arg->s_ocsp;
739 else {
740 /* For multiple certs per context, we have to find the correct OCSP response based on
741 * the certificate type
742 */
743 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
744
745 if (index < 0)
746 return SSL_TLSEXT_ERR_NOACK;
747
748 ocsp = ocsp_arg->m_ocsp[index];
749
750 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200751
752 if (!ocsp ||
753 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200754 !ocsp->response.len ||
755 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200756 return SSL_TLSEXT_ERR_NOACK;
757
758 ssl_buf = OPENSSL_malloc(ocsp->response.len);
759 if (!ssl_buf)
760 return SSL_TLSEXT_ERR_NOACK;
761
762 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
763 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
764
765 return SSL_TLSEXT_ERR_OK;
766}
767
768/*
769 * This function enables the handling of OCSP status extension on 'ctx' if a
770 * file name 'cert_path' suffixed using ".ocsp" is present.
771 * To enable OCSP status extension, the issuer's certificate is mandatory.
772 * It should be present in the certificate's extra chain builded from file
773 * 'cert_path'. If not found, the issuer certificate is loaded from a file
774 * named 'cert_path' suffixed using '.issuer'.
775 *
776 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
777 * response. If file is empty or content is not a valid OCSP response,
778 * OCSP status extension is enabled but OCSP response is ignored (a warning
779 * is displayed).
780 *
781 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
782 * succesfully enabled, or -1 in other error case.
783 */
784static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
785{
786
787 BIO *in = NULL;
788 X509 *x, *xi = NULL, *issuer = NULL;
789 STACK_OF(X509) *chain = NULL;
790 OCSP_CERTID *cid = NULL;
791 SSL *ssl;
792 char ocsp_path[MAXPATHLEN+1];
793 int i, ret = -1;
794 struct stat st;
795 struct certificate_ocsp *ocsp = NULL, *iocsp;
796 char *warn = NULL;
797 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200798 pem_password_cb *passwd_cb;
799 void *passwd_cb_userdata;
800 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200801
802 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
803
804 if (stat(ocsp_path, &st))
805 return 1;
806
807 ssl = SSL_new(ctx);
808 if (!ssl)
809 goto out;
810
811 x = SSL_get_certificate(ssl);
812 if (!x)
813 goto out;
814
815 /* Try to lookup for issuer in certificate extra chain */
816#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
817 SSL_CTX_get_extra_chain_certs(ctx, &chain);
818#else
819 chain = ctx->extra_certs;
820#endif
821 for (i = 0; i < sk_X509_num(chain); i++) {
822 issuer = sk_X509_value(chain, i);
823 if (X509_check_issued(issuer, x) == X509_V_OK)
824 break;
825 else
826 issuer = NULL;
827 }
828
829 /* If not found try to load issuer from a suffixed file */
830 if (!issuer) {
831 char issuer_path[MAXPATHLEN+1];
832
833 in = BIO_new(BIO_s_file());
834 if (!in)
835 goto out;
836
837 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
838 if (BIO_read_filename(in, issuer_path) <= 0)
839 goto out;
840
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200841 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
842 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
843
844 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200845 if (!xi)
846 goto out;
847
848 if (X509_check_issued(xi, x) != X509_V_OK)
849 goto out;
850
851 issuer = xi;
852 }
853
854 cid = OCSP_cert_to_id(0, x, issuer);
855 if (!cid)
856 goto out;
857
858 i = i2d_OCSP_CERTID(cid, NULL);
859 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
860 goto out;
861
Vincent Bernat02779b62016-04-03 13:48:43 +0200862 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200863 if (!ocsp)
864 goto out;
865
866 p = ocsp->key_data;
867 i2d_OCSP_CERTID(cid, &p);
868
869 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
870 if (iocsp == ocsp)
871 ocsp = NULL;
872
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200873#ifndef SSL_CTX_get_tlsext_status_cb
874# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
875 *cb = (void (*) (void))ctx->tlsext_status_cb;
876#endif
877 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
878
879 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200880 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100881 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500882
883 cb_arg->is_single = 1;
884 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200885
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100886 pkey = X509_get_pubkey(x);
887 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
888 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500889
890 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
891 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
892 } else {
893 /*
894 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
895 * Update that cb_arg with the new cert's staple
896 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200897 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500898 struct certificate_ocsp *tmp_ocsp;
899 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200900 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100901 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200902
903#ifdef SSL_CTX_get_tlsext_status_arg
904 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
905#else
906 cb_arg = ctx->tlsext_status_arg;
907#endif
yanbzhube2774d2015-12-10 15:07:30 -0500908
909 /*
910 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
911 * the order of operations below matter, take care when changing it
912 */
913 tmp_ocsp = cb_arg->s_ocsp;
914 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
915 cb_arg->s_ocsp = NULL;
916 cb_arg->m_ocsp[index] = tmp_ocsp;
917 cb_arg->is_single = 0;
918 cb_arg->single_kt = 0;
919
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100920 pkey = X509_get_pubkey(x);
921 key_type = EVP_PKEY_base_id(pkey);
922 EVP_PKEY_free(pkey);
923
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200924 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500925 if (index >= 0 && !cb_arg->m_ocsp[index])
926 cb_arg->m_ocsp[index] = iocsp;
927
928 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200929
930 ret = 0;
931
932 warn = NULL;
933 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
934 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
935 Warning("%s.\n", warn);
936 }
937
938out:
939 if (ssl)
940 SSL_free(ssl);
941
942 if (in)
943 BIO_free(in);
944
945 if (xi)
946 X509_free(xi);
947
948 if (cid)
949 OCSP_CERTID_free(cid);
950
951 if (ocsp)
952 free(ocsp);
953
954 if (warn)
955 free(warn);
956
957
958 return ret;
959}
960
961#endif
962
Daniel Jakots54ffb912015-11-06 20:02:41 +0100963#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100964
965#define CT_EXTENSION_TYPE 18
966
967static int sctl_ex_index = -1;
968
969/*
970 * Try to parse Signed Certificate Timestamp List structure. This function
971 * makes only basic test if the data seems like SCTL. No signature validation
972 * is performed.
973 */
974static int ssl_sock_parse_sctl(struct chunk *sctl)
975{
976 int ret = 1;
977 int len, pos, sct_len;
978 unsigned char *data;
979
980 if (sctl->len < 2)
981 goto out;
982
983 data = (unsigned char *)sctl->str;
984 len = (data[0] << 8) | data[1];
985
986 if (len + 2 != sctl->len)
987 goto out;
988
989 data = data + 2;
990 pos = 0;
991 while (pos < len) {
992 if (len - pos < 2)
993 goto out;
994
995 sct_len = (data[pos] << 8) | data[pos + 1];
996 if (pos + sct_len + 2 > len)
997 goto out;
998
999 pos += sct_len + 2;
1000 }
1001
1002 ret = 0;
1003
1004out:
1005 return ret;
1006}
1007
1008static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
1009{
1010 int fd = -1;
1011 int r = 0;
1012 int ret = 1;
1013
1014 *sctl = NULL;
1015
1016 fd = open(sctl_path, O_RDONLY);
1017 if (fd == -1)
1018 goto end;
1019
1020 trash.len = 0;
1021 while (trash.len < trash.size) {
1022 r = read(fd, trash.str + trash.len, trash.size - trash.len);
1023 if (r < 0) {
1024 if (errno == EINTR)
1025 continue;
1026
1027 goto end;
1028 }
1029 else if (r == 0) {
1030 break;
1031 }
1032 trash.len += r;
1033 }
1034
1035 ret = ssl_sock_parse_sctl(&trash);
1036 if (ret)
1037 goto end;
1038
Vincent Bernat02779b62016-04-03 13:48:43 +02001039 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001040 if (!chunk_dup(*sctl, &trash)) {
1041 free(*sctl);
1042 *sctl = NULL;
1043 goto end;
1044 }
1045
1046end:
1047 if (fd != -1)
1048 close(fd);
1049
1050 return ret;
1051}
1052
1053int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1054{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001055 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001056
1057 *out = (unsigned char *)sctl->str;
1058 *outlen = sctl->len;
1059
1060 return 1;
1061}
1062
1063int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1064{
1065 return 1;
1066}
1067
1068static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1069{
1070 char sctl_path[MAXPATHLEN+1];
1071 int ret = -1;
1072 struct stat st;
1073 struct chunk *sctl = NULL;
1074
1075 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1076
1077 if (stat(sctl_path, &st))
1078 return 1;
1079
1080 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1081 goto out;
1082
1083 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1084 free(sctl);
1085 goto out;
1086 }
1087
1088 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1089
1090 ret = 0;
1091
1092out:
1093 return ret;
1094}
1095
1096#endif
1097
Emeric Brune1f38db2012-09-03 20:36:47 +02001098void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1099{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001100 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001101 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001102 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001103
1104 if (where & SSL_CB_HANDSHAKE_START) {
1105 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001106 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001107 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001108 conn->err_code = CO_ER_SSL_RENEG;
1109 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001110 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001111
1112 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1113 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1114 /* Long certificate chains optimz
1115 If write and read bios are differents, we
1116 consider that the buffering was activated,
1117 so we rise the output buffer size from 4k
1118 to 16k */
1119 write_bio = SSL_get_wbio(ssl);
1120 if (write_bio != SSL_get_rbio(ssl)) {
1121 BIO_set_write_buffer_size(write_bio, 16384);
1122 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1123 }
1124 }
1125 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001126}
1127
Emeric Brune64aef12012-09-21 13:15:06 +02001128/* Callback is called for each certificate of the chain during a verify
1129 ok is set to 1 if preverify detect no error on current certificate.
1130 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001131int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001132{
1133 SSL *ssl;
1134 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001135 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001136
1137 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001138 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001139
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001140 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001141
Emeric Brun81c00f02012-09-21 14:31:21 +02001142 if (ok) /* no errors */
1143 return ok;
1144
1145 depth = X509_STORE_CTX_get_error_depth(x_store);
1146 err = X509_STORE_CTX_get_error(x_store);
1147
1148 /* check if CA error needs to be ignored */
1149 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001150 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1151 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1152 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001153 }
1154
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001155 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001156 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001157 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001158 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001159 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001160
Willy Tarreau20879a02012-12-03 16:32:10 +01001161 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001162 return 0;
1163 }
1164
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001165 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1166 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001167
Emeric Brun81c00f02012-09-21 14:31:21 +02001168 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001169 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001170 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001171 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001172 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001173 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001174
Willy Tarreau20879a02012-12-03 16:32:10 +01001175 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001176 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001177}
1178
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001179static inline
1180void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001181 const void *buf, size_t len, SSL *ssl)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001182{
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001183 struct ssl_capture *capture;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001184 unsigned char *msg;
1185 unsigned char *end;
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001186 size_t rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001187
1188 /* This function is called for "from client" and "to server"
1189 * connections. The combination of write_p == 0 and content_type == 22
1190 * is only avalaible during "from client" connection.
1191 */
1192
1193 /* "write_p" is set to 0 is the bytes are received messages,
1194 * otherwise it is set to 1.
1195 */
1196 if (write_p != 0)
1197 return;
1198
1199 /* content_type contains the type of message received or sent
1200 * according with the SSL/TLS protocol spec. This message is
1201 * encoded with one byte. The value 256 (two bytes) is used
1202 * for designing the SSL/TLS record layer. According with the
1203 * rfc6101, the expected message (other than 256) are:
1204 * - change_cipher_spec(20)
1205 * - alert(21)
1206 * - handshake(22)
1207 * - application_data(23)
1208 * - (255)
1209 * We are interessed by the handshake and specially the client
1210 * hello.
1211 */
1212 if (content_type != 22)
1213 return;
1214
1215 /* The message length is at least 4 bytes, containing the
1216 * message type and the message length.
1217 */
1218 if (len < 4)
1219 return;
1220
1221 /* First byte of the handshake message id the type of
1222 * message. The konwn types are:
1223 * - hello_request(0)
1224 * - client_hello(1)
1225 * - server_hello(2)
1226 * - certificate(11)
1227 * - server_key_exchange (12)
1228 * - certificate_request(13)
1229 * - server_hello_done(14)
1230 * We are interested by the client hello.
1231 */
1232 msg = (unsigned char *)buf;
1233 if (msg[0] != 1)
1234 return;
1235
1236 /* Next three bytes are the length of the message. The total length
1237 * must be this decoded length + 4. If the length given as argument
1238 * is not the same, we abort the protocol dissector.
1239 */
1240 rec_len = (msg[1] << 16) + (msg[2] << 8) + msg[3];
1241 if (len < rec_len + 4)
1242 return;
1243 msg += 4;
1244 end = msg + rec_len;
1245 if (end < msg)
1246 return;
1247
1248 /* Expect 2 bytes for protocol version (1 byte for major and 1 byte
1249 * for minor, the random, composed by 4 bytes for the unix time and
1250 * 28 bytes for unix payload, and them 1 byte for the session id. So
1251 * we jump 1 + 1 + 4 + 28 + 1 bytes.
1252 */
1253 msg += 1 + 1 + 4 + 28 + 1;
1254 if (msg > end)
1255 return;
1256
1257 /* Next two bytes are the ciphersuite length. */
1258 if (msg + 2 > end)
1259 return;
1260 rec_len = (msg[0] << 8) + msg[1];
1261 msg += 2;
1262 if (msg + rec_len > end || msg + rec_len < msg)
1263 return;
1264
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001265 capture = pool_alloc_dirty(pool2_ssl_capture);
1266 if (!capture)
1267 return;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001268 /* Compute the xxh64 of the ciphersuite. */
1269 capture->xxh64 = XXH64(msg, rec_len, 0);
1270
1271 /* Capture the ciphersuite. */
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001272 capture->ciphersuite_len = (global_ssl.capture_cipherlist < rec_len) ?
1273 global_ssl.capture_cipherlist : rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001274 memcpy(capture->ciphersuite, msg, capture->ciphersuite_len);
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001275
1276 SSL_set_ex_data(ssl, ssl_capture_ptr_index, capture);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001277}
1278
Emeric Brun29f037d2014-04-25 19:05:36 +02001279/* Callback is called for ssl protocol analyse */
1280void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1281{
Emeric Brun29f037d2014-04-25 19:05:36 +02001282#ifdef TLS1_RT_HEARTBEAT
1283 /* test heartbeat received (write_p is set to 0
1284 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001285 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001286 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001287 const unsigned char *p = buf;
1288 unsigned int payload;
1289
Emeric Brun29f037d2014-04-25 19:05:36 +02001290 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001291
1292 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1293 if (*p != TLS1_HB_REQUEST)
1294 return;
1295
Willy Tarreauaeed6722014-04-25 23:59:58 +02001296 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001297 goto kill_it;
1298
1299 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001300 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001301 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001302 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001303 /* We have a clear heartbleed attack (CVE-2014-0160), the
1304 * advertised payload is larger than the advertised packet
1305 * length, so we have garbage in the buffer between the
1306 * payload and the end of the buffer (p+len). We can't know
1307 * if the SSL stack is patched, and we don't know if we can
1308 * safely wipe out the area between p+3+len and payload.
1309 * So instead, we prevent the response from being sent by
1310 * setting the max_send_fragment to 0 and we report an SSL
1311 * error, which will kill this connection. It will be reported
1312 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001313 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1314 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001315 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001316 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1317 return;
1318 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001319#endif
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001320 if (global_ssl.capture_cipherlist > 0)
1321 ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
Emeric Brun29f037d2014-04-25 19:05:36 +02001322}
1323
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001324#ifdef OPENSSL_NPN_NEGOTIATED
1325/* This callback is used so that the server advertises the list of
1326 * negociable protocols for NPN.
1327 */
1328static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1329 unsigned int *len, void *arg)
1330{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001331 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001332
1333 *data = (const unsigned char *)conf->npn_str;
1334 *len = conf->npn_len;
1335 return SSL_TLSEXT_ERR_OK;
1336}
1337#endif
1338
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001339#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001340/* This callback is used so that the server advertises the list of
1341 * negociable protocols for ALPN.
1342 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001343static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1344 unsigned char *outlen,
1345 const unsigned char *server,
1346 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001347{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001348 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001349
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001350 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1351 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1352 return SSL_TLSEXT_ERR_NOACK;
1353 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001354 return SSL_TLSEXT_ERR_OK;
1355}
1356#endif
1357
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001358#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001359#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001360
Christopher Faulet30548802015-06-11 13:39:32 +02001361/* Create a X509 certificate with the specified servername and serial. This
1362 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001363static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001364ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001365{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001366 static unsigned int serial = 0;
1367
Christopher Faulet7969a332015-10-09 11:15:03 +02001368 X509 *cacert = bind_conf->ca_sign_cert;
1369 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001370 SSL_CTX *ssl_ctx = NULL;
1371 X509 *newcrt = NULL;
1372 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001373 X509_NAME *name;
1374 const EVP_MD *digest;
1375 X509V3_CTX ctx;
1376 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001377 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001378
Christopher Faulet7969a332015-10-09 11:15:03 +02001379 /* Get the private key of the defautl certificate and use it */
1380 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001381 goto mkcert_error;
1382
1383 /* Create the certificate */
1384 if (!(newcrt = X509_new()))
1385 goto mkcert_error;
1386
1387 /* Set version number for the certificate (X509v3) and the serial
1388 * number */
1389 if (X509_set_version(newcrt, 2L) != 1)
1390 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001391 if (!serial)
1392 serial = now_ms;
1393 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001394
1395 /* Set duration for the certificate */
1396 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1397 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1398 goto mkcert_error;
1399
1400 /* set public key in the certificate */
1401 if (X509_set_pubkey(newcrt, pkey) != 1)
1402 goto mkcert_error;
1403
1404 /* Set issuer name from the CA */
1405 if (!(name = X509_get_subject_name(cacert)))
1406 goto mkcert_error;
1407 if (X509_set_issuer_name(newcrt, name) != 1)
1408 goto mkcert_error;
1409
1410 /* Set the subject name using the same, but the CN */
1411 name = X509_NAME_dup(name);
1412 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1413 (const unsigned char *)servername,
1414 -1, -1, 0) != 1) {
1415 X509_NAME_free(name);
1416 goto mkcert_error;
1417 }
1418 if (X509_set_subject_name(newcrt, name) != 1) {
1419 X509_NAME_free(name);
1420 goto mkcert_error;
1421 }
1422 X509_NAME_free(name);
1423
1424 /* Add x509v3 extensions as specified */
1425 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1426 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1427 X509_EXTENSION *ext;
1428
1429 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1430 goto mkcert_error;
1431 if (!X509_add_ext(newcrt, ext, -1)) {
1432 X509_EXTENSION_free(ext);
1433 goto mkcert_error;
1434 }
1435 X509_EXTENSION_free(ext);
1436 }
1437
1438 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001439
1440 key_type = EVP_PKEY_base_id(capkey);
1441
1442 if (key_type == EVP_PKEY_DSA)
1443 digest = EVP_sha1();
1444 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001445 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001446 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001447 digest = EVP_sha256();
1448 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001449#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001450 int nid;
1451
1452 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1453 goto mkcert_error;
1454 if (!(digest = EVP_get_digestbynid(nid)))
1455 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001456#else
1457 goto mkcert_error;
1458#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001459 }
1460
Christopher Faulet31af49d2015-06-09 17:29:50 +02001461 if (!(X509_sign(newcrt, capkey, digest)))
1462 goto mkcert_error;
1463
1464 /* Create and set the new SSL_CTX */
1465 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1466 goto mkcert_error;
1467 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1468 goto mkcert_error;
1469 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1470 goto mkcert_error;
1471 if (!SSL_CTX_check_private_key(ssl_ctx))
1472 goto mkcert_error;
1473
1474 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001475
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001476#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001477 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001478#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001479#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1480 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001481 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001482 EC_KEY *ecc;
1483 int nid;
1484
1485 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1486 goto end;
1487 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1488 goto end;
1489 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1490 EC_KEY_free(ecc);
1491 }
1492#endif
1493 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001494 return ssl_ctx;
1495
1496 mkcert_error:
1497 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1498 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001499 return NULL;
1500}
1501
Christopher Faulet7969a332015-10-09 11:15:03 +02001502SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001503ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001504{
1505 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001506
1507 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001508}
1509
Christopher Faulet30548802015-06-11 13:39:32 +02001510/* Do a lookup for a certificate in the LRU cache used to store generated
1511 * certificates. */
1512SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001513ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001514{
1515 struct lru64 *lru = NULL;
1516
1517 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001518 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001519 if (lru && lru->domain)
1520 return (SSL_CTX *)lru->data;
1521 }
1522 return NULL;
1523}
1524
Christopher Fauletd2cab922015-07-28 16:03:47 +02001525/* Set a certificate int the LRU cache used to store generated
1526 * certificate. Return 0 on success, otherwise -1 */
1527int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001528ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001529{
1530 struct lru64 *lru = NULL;
1531
1532 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001533 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001534 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001535 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001536 if (lru->domain && lru->data)
1537 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001538 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001539 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001540 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001541 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001542}
1543
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001544/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001545unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001546ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001547{
1548 return XXH32(data, len, ssl_ctx_lru_seed);
1549}
1550
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001551/* Generate a cert and immediately assign it to the SSL session so that the cert's
1552 * refcount is maintained regardless of the cert's presence in the LRU cache.
1553 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001554static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001555ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001556{
1557 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001558 SSL_CTX *ssl_ctx = NULL;
1559 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001560 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001561
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001562 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001563 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001564 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001565 if (lru && lru->domain)
1566 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001567 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001568 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001569 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001570 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001571 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001572 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001573 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001574 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001575 SSL_set_SSL_CTX(ssl, ssl_ctx);
1576 /* No LRU cache, this CTX will be released as soon as the session dies */
1577 SSL_CTX_free(ssl_ctx);
1578 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001579 return ssl_ctx;
1580}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001581#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001582
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001583static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1584{
1585 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1586 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1587 SSL_set_SSL_CTX(ssl, ctx);
1588}
1589
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001590#ifdef OPENSSL_IS_BORINGSSL
1591
1592static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1593{
1594 (void)al; /* shut gcc stupid warning */
1595 (void)priv;
1596
1597 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1598 return SSL_TLSEXT_ERR_NOACK;
1599 return SSL_TLSEXT_ERR_OK;
1600}
1601
1602static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1603{
1604 struct connection *conn;
1605 struct bind_conf *s;
1606 const uint8_t *extension_data;
1607 size_t extension_len;
1608 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1609 const SSL_CIPHER *cipher;
1610 uint16_t cipher_suite;
1611 uint8_t name_type, hash, sign;
1612 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1613
1614 char *wildp = NULL;
1615 const uint8_t *servername;
1616 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1617 int i;
1618
1619 conn = SSL_get_app_data(ctx->ssl);
1620 s = objt_listener(conn->target)->bind_conf;
1621
1622 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1623 &extension_data, &extension_len)) {
1624 CBS_init(&extension, extension_data, extension_len);
1625
1626 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1627 || !CBS_get_u8(&server_name_list, &name_type)
1628 /* Although the server_name extension was intended to be extensible to
1629 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1630 * different name types will cause an error. Further, RFC 4366 originally
1631 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1632 * adding new name types is no longer feasible.
1633 *
1634 * Act as if the extensibility does not exist to simplify parsing. */
1635 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1636 || CBS_len(&server_name_list) != 0
1637 || CBS_len(&extension) != 0
1638 || name_type != TLSEXT_NAMETYPE_host_name
1639 || CBS_len(&host_name) == 0
1640 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1641 || CBS_contains_zero_byte(&host_name)) {
1642 goto abort;
1643 }
1644 } else {
1645 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001646 if (!s->strict_sni) {
1647 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001648 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001649 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001650 goto abort;
1651 }
1652
1653 /* extract/check clientHello informations */
1654 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
1655 CBS_init(&extension, extension_data, extension_len);
1656
1657 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
1658 || CBS_len(&sig_algs) == 0
1659 || CBS_len(&extension) != 0) {
1660 goto abort;
1661 }
1662 if (CBS_len(&sig_algs) % 2 != 0) {
1663 goto abort;
1664 }
1665 while (CBS_len(&sig_algs) != 0) {
1666 if (!CBS_get_u8(&sig_algs, &hash)
1667 || !CBS_get_u8(&sig_algs, &sign)) {
1668 goto abort;
1669 }
1670 switch (sign) {
1671 case TLSEXT_signature_rsa:
1672 has_rsa = 1;
1673 break;
1674 case TLSEXT_signature_ecdsa:
1675 has_ecdsa_sig = 1;
1676 break;
1677 default:
1678 continue;
1679 }
1680 if (has_ecdsa_sig && has_rsa)
1681 break;
1682 }
1683 } else {
1684 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
1685 has_rsa = 1;
1686 }
1687 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
1688 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
1689
1690 while (CBS_len(&cipher_suites) != 0) {
1691 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1692 goto abort;
1693 }
1694 cipher = SSL_get_cipher_by_value(cipher_suite);
1695 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
1696 has_ecdsa = 1;
1697 break;
1698 }
1699 }
1700 }
1701
1702 servername = CBS_data(&host_name);
1703 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
1704 trash.str[i] = tolower(servername[i]);
1705 if (!wildp && (trash.str[i] == '.'))
1706 wildp = &trash.str[i];
1707 }
1708 trash.str[i] = 0;
1709
1710 /* lookup in full qualified names */
1711 node = ebst_lookup(&s->sni_ctx, trash.str);
1712
1713 /* lookup a not neg filter */
1714 for (n = node; n; n = ebmb_next_dup(n)) {
1715 if (!container_of(n, struct sni_ctx, name)->neg) {
1716 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1717 case TLSEXT_signature_ecdsa:
1718 if (has_ecdsa) {
1719 node_ecdsa = n;
1720 goto find_one;
1721 }
1722 break;
1723 case TLSEXT_signature_rsa:
1724 if (has_rsa && !node_rsa) {
1725 node_rsa = n;
1726 if (!has_ecdsa)
1727 goto find_one;
1728 }
1729 break;
1730 default: /* TLSEXT_signature_anonymous */
1731 if (!node_anonymous)
1732 node_anonymous = n;
1733 break;
1734 }
1735 }
1736 }
1737 if (wildp) {
1738 /* lookup in wildcards names */
1739 node = ebst_lookup(&s->sni_w_ctx, wildp);
1740 for (n = node; n; n = ebmb_next_dup(n)) {
1741 if (!container_of(n, struct sni_ctx, name)->neg) {
1742 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1743 case TLSEXT_signature_ecdsa:
1744 if (has_ecdsa) {
1745 node_ecdsa = n;
1746 goto find_one;
1747 }
1748 break;
1749 case TLSEXT_signature_rsa:
1750 if (has_rsa && !node_rsa) {
1751 node_rsa = n;
1752 if (!has_ecdsa)
1753 goto find_one;
1754 }
1755 break;
1756 default: /* TLSEXT_signature_anonymous */
1757 if (!node_anonymous)
1758 node_anonymous = n;
1759 break;
1760 }
1761 }
1762 }
1763 }
1764 find_one:
1765 /* select by key_signature priority order */
1766 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
1767
1768 if (node) {
1769 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001770 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001771 return 1;
1772 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001773 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001774 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001775 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001776 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001777 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001778 abort:
1779 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
1780 conn->err_code = CO_ER_SSL_HANDSHAKE;
1781 return -1;
1782}
1783
1784#else /* OPENSSL_IS_BORINGSSL */
1785
Emeric Brunfc0421f2012-09-07 17:30:07 +02001786/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1787 * warning when no match is found, which implies the default (first) cert
1788 * will keep being used.
1789 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001790static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001791{
1792 const char *servername;
1793 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001794 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001795 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001796 int i;
1797 (void)al; /* shut gcc stupid warning */
1798
1799 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001800 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001801#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02001802 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001803 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001804 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001805 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001806
Willy Tarreauf6721452015-07-07 18:04:38 +02001807 conn_get_to_addr(conn);
1808 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001809 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1810 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001811 if (ctx) {
1812 /* switch ctx */
1813 SSL_set_SSL_CTX(ssl, ctx);
1814 return SSL_TLSEXT_ERR_OK;
1815 }
Christopher Faulet30548802015-06-11 13:39:32 +02001816 }
1817 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001818#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001819 if (s->strict_sni)
1820 return SSL_TLSEXT_ERR_ALERT_FATAL;
1821 ssl_sock_switchctx_set(ssl, s->default_ctx);
1822 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001823 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001824
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001825 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001826 if (!servername[i])
1827 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001828 trash.str[i] = tolower(servername[i]);
1829 if (!wildp && (trash.str[i] == '.'))
1830 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001831 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001832 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001833
1834 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001835 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001836
1837 /* lookup a not neg filter */
1838 for (n = node; n; n = ebmb_next_dup(n)) {
1839 if (!container_of(n, struct sni_ctx, name)->neg) {
1840 node = n;
1841 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001842 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001843 }
1844 if (!node && wildp) {
1845 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001846 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001847 }
1848 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001849#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001850 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001851 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001852 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001853 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001854 return SSL_TLSEXT_ERR_OK;
1855 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001856#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001857 if (s->strict_sni)
1858 return SSL_TLSEXT_ERR_ALERT_FATAL;
1859 ssl_sock_switchctx_set(ssl, s->default_ctx);
1860 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001861 }
1862
1863 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001864 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001865 return SSL_TLSEXT_ERR_OK;
1866}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001867#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001868#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1869
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001870#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001871
1872static DH * ssl_get_dh_1024(void)
1873{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001874 static unsigned char dh1024_p[]={
1875 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1876 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1877 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1878 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1879 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1880 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1881 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1882 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1883 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1884 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1885 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1886 };
1887 static unsigned char dh1024_g[]={
1888 0x02,
1889 };
1890
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001891 BIGNUM *p;
1892 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001893 DH *dh = DH_new();
1894 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001895 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1896 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001897
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001898 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001899 DH_free(dh);
1900 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001901 } else {
1902 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001903 }
1904 }
1905 return dh;
1906}
1907
1908static DH *ssl_get_dh_2048(void)
1909{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001910 static unsigned char dh2048_p[]={
1911 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1912 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1913 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1914 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1915 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1916 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1917 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1918 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1919 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1920 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1921 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1922 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1923 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1924 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1925 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1926 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1927 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1928 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1929 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1930 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1931 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1932 0xB7,0x1F,0x77,0xF3,
1933 };
1934 static unsigned char dh2048_g[]={
1935 0x02,
1936 };
1937
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001938 BIGNUM *p;
1939 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001940 DH *dh = DH_new();
1941 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001942 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1943 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001944
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001945 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001946 DH_free(dh);
1947 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001948 } else {
1949 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001950 }
1951 }
1952 return dh;
1953}
1954
1955static DH *ssl_get_dh_4096(void)
1956{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001957 static unsigned char dh4096_p[]={
1958 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1959 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1960 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1961 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1962 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1963 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1964 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1965 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1966 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1967 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1968 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1969 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1970 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1971 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1972 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1973 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1974 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1975 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1976 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1977 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1978 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1979 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1980 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1981 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1982 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1983 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1984 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1985 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1986 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1987 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1988 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1989 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1990 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1991 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1992 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1993 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1994 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1995 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1996 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1997 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1998 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1999 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
2000 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002001 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02002002 static unsigned char dh4096_g[]={
2003 0x02,
2004 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002005
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002006 BIGNUM *p;
2007 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002008 DH *dh = DH_new();
2009 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002010 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
2011 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002012
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002013 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002014 DH_free(dh);
2015 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002016 } else {
2017 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002018 }
2019 }
2020 return dh;
2021}
2022
2023/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01002024 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002025static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
2026{
2027 DH *dh = NULL;
2028 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002029 int type;
2030
2031 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002032
2033 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2034 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2035 */
2036 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2037 keylen = EVP_PKEY_bits(pkey);
2038 }
2039
Willy Tarreauef934602016-12-22 23:12:01 +01002040 if (keylen > global_ssl.default_dh_param) {
2041 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002042 }
2043
Remi Gacogned3a341a2015-05-29 16:26:17 +02002044 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002045 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002046 }
2047 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002048 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002049 }
2050 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002051 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002052 }
2053
2054 return dh;
2055}
2056
Remi Gacogne47783ef2015-05-29 15:53:22 +02002057static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002058{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002059 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002060 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002061
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002062 if (in == NULL)
2063 goto end;
2064
Remi Gacogne47783ef2015-05-29 15:53:22 +02002065 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002066 goto end;
2067
Remi Gacogne47783ef2015-05-29 15:53:22 +02002068 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2069
2070end:
2071 if (in)
2072 BIO_free(in);
2073
2074 return dh;
2075}
2076
2077int ssl_sock_load_global_dh_param_from_file(const char *filename)
2078{
2079 global_dh = ssl_sock_get_dh_from_file(filename);
2080
2081 if (global_dh) {
2082 return 0;
2083 }
2084
2085 return -1;
2086}
2087
2088/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2089 if an error occured, and 0 if parameter not found. */
2090int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2091{
2092 int ret = -1;
2093 DH *dh = ssl_sock_get_dh_from_file(file);
2094
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002095 if (dh) {
2096 ret = 1;
2097 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002098
2099 if (ssl_dh_ptr_index >= 0) {
2100 /* store a pointer to the DH params to avoid complaining about
2101 ssl-default-dh-param not being set for this SSL_CTX */
2102 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2103 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002104 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002105 else if (global_dh) {
2106 SSL_CTX_set_tmp_dh(ctx, global_dh);
2107 ret = 0; /* DH params not found */
2108 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002109 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002110 /* Clear openssl global errors stack */
2111 ERR_clear_error();
2112
Willy Tarreauef934602016-12-22 23:12:01 +01002113 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002114 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002115 if (local_dh_1024 == NULL)
2116 local_dh_1024 = ssl_get_dh_1024();
2117
Remi Gacogne8de54152014-07-15 11:36:40 +02002118 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002119 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002120
Remi Gacogne8de54152014-07-15 11:36:40 +02002121 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002122 }
2123 else {
2124 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2125 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002126
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002127 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002128 }
Emeric Brun644cde02012-12-14 11:21:13 +01002129
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002130end:
2131 if (dh)
2132 DH_free(dh);
2133
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002134 return ret;
2135}
2136#endif
2137
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002138static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2139 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002140{
2141 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002142 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002143 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002144
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002145 if (*name == '!') {
2146 neg = 1;
2147 name++;
2148 }
2149 if (*name == '*') {
2150 wild = 1;
2151 name++;
2152 }
2153 /* !* filter is a nop */
2154 if (neg && wild)
2155 return order;
2156 if (*name) {
2157 int j, len;
2158 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002159 for (j = 0; j < len && j < trash.size; j++)
2160 trash.str[j] = tolower(name[j]);
2161 if (j >= trash.size)
2162 return order;
2163 trash.str[j] = 0;
2164
2165 /* Check for duplicates. */
2166 if (wild)
2167 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2168 else
2169 node = ebst_lookup(&s->sni_ctx, trash.str);
2170 for (; node; node = ebmb_next_dup(node)) {
2171 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002172 if (sc->ctx == ctx && sc->conf == conf &&
2173 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002174 return order;
2175 }
2176
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002177 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002178 if (!sc)
2179 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002180 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002181 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002182 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002183 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002184 sc->order = order++;
2185 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002186 if (wild)
2187 ebst_insert(&s->sni_w_ctx, &sc->name);
2188 else
2189 ebst_insert(&s->sni_ctx, &sc->name);
2190 }
2191 return order;
2192}
2193
yanbzhu488a4d22015-12-01 15:16:07 -05002194
2195/* The following code is used for loading multiple crt files into
2196 * SSL_CTX's based on CN/SAN
2197 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002198#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002199/* This is used to preload the certifcate, private key
2200 * and Cert Chain of a file passed in via the crt
2201 * argument
2202 *
2203 * This way, we do not have to read the file multiple times
2204 */
2205struct cert_key_and_chain {
2206 X509 *cert;
2207 EVP_PKEY *key;
2208 unsigned int num_chain_certs;
2209 /* This is an array of X509 pointers */
2210 X509 **chain_certs;
2211};
2212
yanbzhu08ce6ab2015-12-02 13:01:29 -05002213#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2214
2215struct key_combo_ctx {
2216 SSL_CTX *ctx;
2217 int order;
2218};
2219
2220/* Map used for processing multiple keypairs for a single purpose
2221 *
2222 * This maps CN/SNI name to certificate type
2223 */
2224struct sni_keytype {
2225 int keytypes; /* BITMASK for keytypes */
2226 struct ebmb_node name; /* node holding the servername value */
2227};
2228
2229
yanbzhu488a4d22015-12-01 15:16:07 -05002230/* Frees the contents of a cert_key_and_chain
2231 */
2232static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2233{
2234 int i;
2235
2236 if (!ckch)
2237 return;
2238
2239 /* Free the certificate and set pointer to NULL */
2240 if (ckch->cert)
2241 X509_free(ckch->cert);
2242 ckch->cert = NULL;
2243
2244 /* Free the key and set pointer to NULL */
2245 if (ckch->key)
2246 EVP_PKEY_free(ckch->key);
2247 ckch->key = NULL;
2248
2249 /* Free each certificate in the chain */
2250 for (i = 0; i < ckch->num_chain_certs; i++) {
2251 if (ckch->chain_certs[i])
2252 X509_free(ckch->chain_certs[i]);
2253 }
2254
2255 /* Free the chain obj itself and set to NULL */
2256 if (ckch->num_chain_certs > 0) {
2257 free(ckch->chain_certs);
2258 ckch->num_chain_certs = 0;
2259 ckch->chain_certs = NULL;
2260 }
2261
2262}
2263
2264/* checks if a key and cert exists in the ckch
2265 */
2266static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2267{
2268 return (ckch->cert != NULL && ckch->key != NULL);
2269}
2270
2271
2272/* Loads the contents of a crt file (path) into a cert_key_and_chain
2273 * This allows us to carry the contents of the file without having to
2274 * read the file multiple times.
2275 *
2276 * returns:
2277 * 0 on Success
2278 * 1 on SSL Failure
2279 * 2 on file not found
2280 */
2281static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2282{
2283
2284 BIO *in;
2285 X509 *ca = NULL;
2286 int ret = 1;
2287
2288 ssl_sock_free_cert_key_and_chain_contents(ckch);
2289
2290 in = BIO_new(BIO_s_file());
2291 if (in == NULL)
2292 goto end;
2293
2294 if (BIO_read_filename(in, path) <= 0)
2295 goto end;
2296
yanbzhu488a4d22015-12-01 15:16:07 -05002297 /* Read Private Key */
2298 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2299 if (ckch->key == NULL) {
2300 memprintf(err, "%sunable to load private key from file '%s'.\n",
2301 err && *err ? *err : "", path);
2302 goto end;
2303 }
2304
Willy Tarreaubb137a82016-04-06 19:02:38 +02002305 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002306 if (BIO_reset(in) == -1) {
2307 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2308 err && *err ? *err : "", path);
2309 goto end;
2310 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002311
2312 /* Read Certificate */
2313 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2314 if (ckch->cert == NULL) {
2315 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2316 err && *err ? *err : "", path);
2317 goto end;
2318 }
2319
yanbzhu488a4d22015-12-01 15:16:07 -05002320 /* Read Certificate Chain */
2321 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2322 /* Grow the chain certs */
2323 ckch->num_chain_certs++;
2324 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2325
2326 /* use - 1 here since we just incremented it above */
2327 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2328 }
2329 ret = ERR_get_error();
2330 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2331 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2332 err && *err ? *err : "", path);
2333 ret = 1;
2334 goto end;
2335 }
2336
2337 ret = 0;
2338
2339end:
2340
2341 ERR_clear_error();
2342 if (in)
2343 BIO_free(in);
2344
2345 /* Something went wrong in one of the reads */
2346 if (ret != 0)
2347 ssl_sock_free_cert_key_and_chain_contents(ckch);
2348
2349 return ret;
2350}
2351
2352/* Loads the info in ckch into ctx
2353 * Currently, this does not process any information about ocsp, dhparams or
2354 * sctl
2355 * Returns
2356 * 0 on success
2357 * 1 on failure
2358 */
2359static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2360{
2361 int i = 0;
2362
2363 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2364 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2365 err && *err ? *err : "", path);
2366 return 1;
2367 }
2368
2369 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2370 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2371 err && *err ? *err : "", path);
2372 return 1;
2373 }
2374
yanbzhu488a4d22015-12-01 15:16:07 -05002375 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2376 for (i = 0; i < ckch->num_chain_certs; i++) {
2377 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002378 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2379 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002380 return 1;
2381 }
2382 }
2383
2384 if (SSL_CTX_check_private_key(ctx) <= 0) {
2385 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2386 err && *err ? *err : "", path);
2387 return 1;
2388 }
2389
2390 return 0;
2391}
2392
yanbzhu08ce6ab2015-12-02 13:01:29 -05002393
2394static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2395{
2396 struct sni_keytype *s_kt = NULL;
2397 struct ebmb_node *node;
2398 int i;
2399
2400 for (i = 0; i < trash.size; i++) {
2401 if (!str[i])
2402 break;
2403 trash.str[i] = tolower(str[i]);
2404 }
2405 trash.str[i] = 0;
2406 node = ebst_lookup(sni_keytypes, trash.str);
2407 if (!node) {
2408 /* CN not found in tree */
2409 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2410 /* Using memcpy here instead of strncpy.
2411 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2412 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2413 */
2414 memcpy(s_kt->name.key, trash.str, i+1);
2415 s_kt->keytypes = 0;
2416 ebst_insert(sni_keytypes, &s_kt->name);
2417 } else {
2418 /* CN found in tree */
2419 s_kt = container_of(node, struct sni_keytype, name);
2420 }
2421
2422 /* Mark that this CN has the keytype of key_index via keytypes mask */
2423 s_kt->keytypes |= 1<<key_index;
2424
2425}
2426
2427
2428/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2429 * If any are found, group these files into a set of SSL_CTX*
2430 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2431 *
2432 * This will allow the user to explictly group multiple cert/keys for a single purpose
2433 *
2434 * Returns
2435 * 0 on success
2436 * 1 on failure
2437 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002438static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2439 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002440{
2441 char fp[MAXPATHLEN+1] = {0};
2442 int n = 0;
2443 int i = 0;
2444 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2445 struct eb_root sni_keytypes_map = { {0} };
2446 struct ebmb_node *node;
2447 struct ebmb_node *next;
2448 /* Array of SSL_CTX pointers corresponding to each possible combo
2449 * of keytypes
2450 */
2451 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2452 int rv = 0;
2453 X509_NAME *xname = NULL;
2454 char *str = NULL;
2455#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2456 STACK_OF(GENERAL_NAME) *names = NULL;
2457#endif
2458
2459 /* Load all possible certs and keys */
2460 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2461 struct stat buf;
2462
2463 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2464 if (stat(fp, &buf) == 0) {
2465 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2466 rv = 1;
2467 goto end;
2468 }
2469 }
2470 }
2471
2472 /* Process each ckch and update keytypes for each CN/SAN
2473 * for example, if CN/SAN www.a.com is associated with
2474 * certs with keytype 0 and 2, then at the end of the loop,
2475 * www.a.com will have:
2476 * keyindex = 0 | 1 | 4 = 5
2477 */
2478 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2479
2480 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2481 continue;
2482
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002483 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002484 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002485 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2486 } else {
2487 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2488 * so the line that contains logic is marked via comments
2489 */
2490 xname = X509_get_subject_name(certs_and_keys[n].cert);
2491 i = -1;
2492 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2493 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002494 ASN1_STRING *value;
2495 value = X509_NAME_ENTRY_get_data(entry);
2496 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002497 /* Important line is here */
2498 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002499
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002500 OPENSSL_free(str);
2501 str = NULL;
2502 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002503 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002504
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002505 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002506#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002507 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2508 if (names) {
2509 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2510 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002511
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002512 if (name->type == GEN_DNS) {
2513 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2514 /* Important line is here */
2515 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002516
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002517 OPENSSL_free(str);
2518 str = NULL;
2519 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002520 }
2521 }
2522 }
2523 }
2524#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2525 }
2526
2527 /* If no files found, return error */
2528 if (eb_is_empty(&sni_keytypes_map)) {
2529 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2530 err && *err ? *err : "", path);
2531 rv = 1;
2532 goto end;
2533 }
2534
2535 /* We now have a map of CN/SAN to keytypes that are loaded in
2536 * Iterate through the map to create the SSL_CTX's (if needed)
2537 * and add each CTX to the SNI tree
2538 *
2539 * Some math here:
2540 * There are 2^n - 1 possibile combinations, each unique
2541 * combination is denoted by the key in the map. Each key
2542 * has a value between 1 and 2^n - 1. Conveniently, the array
2543 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2544 * entry in the array to correspond to the unique combo (key)
2545 * associated with i. This unique key combo (i) will be associated
2546 * with combos[i-1]
2547 */
2548
2549 node = ebmb_first(&sni_keytypes_map);
2550 while (node) {
2551 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002552 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002553
2554 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2555 i = container_of(node, struct sni_keytype, name)->keytypes;
2556 cur_ctx = key_combos[i-1].ctx;
2557
2558 if (cur_ctx == NULL) {
2559 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002560 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002561 if (cur_ctx == NULL) {
2562 memprintf(err, "%sunable to allocate SSL context.\n",
2563 err && *err ? *err : "");
2564 rv = 1;
2565 goto end;
2566 }
2567
yanbzhube2774d2015-12-10 15:07:30 -05002568 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002569 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2570 if (i & (1<<n)) {
2571 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002572 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2573 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002574 SSL_CTX_free(cur_ctx);
2575 rv = 1;
2576 goto end;
2577 }
yanbzhube2774d2015-12-10 15:07:30 -05002578
2579#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2580 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002581 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002582 if (err)
2583 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 +00002584 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002585 SSL_CTX_free(cur_ctx);
2586 rv = 1;
2587 goto end;
2588 }
2589#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002590 }
2591 }
2592
2593 /* Load DH params into the ctx to support DHE keys */
2594#ifndef OPENSSL_NO_DH
2595 if (ssl_dh_ptr_index >= 0)
2596 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2597
2598 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2599 if (rv < 0) {
2600 if (err)
2601 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2602 *err ? *err : "", path);
2603 rv = 1;
2604 goto end;
2605 }
2606#endif
2607
2608 /* Update key_combos */
2609 key_combos[i-1].ctx = cur_ctx;
2610 }
2611
2612 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002613 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2614 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002615 node = ebmb_next(node);
2616 }
2617
2618
2619 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2620 if (!bind_conf->default_ctx) {
2621 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2622 if (key_combos[i].ctx) {
2623 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002624 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002625 break;
2626 }
2627 }
2628 }
2629
2630end:
2631
2632 if (names)
2633 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2634
2635 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2636 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2637
2638 node = ebmb_first(&sni_keytypes_map);
2639 while (node) {
2640 next = ebmb_next(node);
2641 ebmb_delete(node);
2642 node = next;
2643 }
2644
2645 return rv;
2646}
2647#else
2648/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002649static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2650 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002651{
2652 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2653 err && *err ? *err : "", path, strerror(errno));
2654 return 1;
2655}
2656
yanbzhu488a4d22015-12-01 15:16:07 -05002657#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2658
Emeric Brunfc0421f2012-09-07 17:30:07 +02002659/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2660 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2661 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002662static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2663 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002664{
2665 BIO *in;
2666 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002667 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002668 int ret = -1;
2669 int order = 0;
2670 X509_NAME *xname;
2671 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002672 pem_password_cb *passwd_cb;
2673 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002674 EVP_PKEY *pkey;
2675 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002676
Emeric Brunfc0421f2012-09-07 17:30:07 +02002677#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2678 STACK_OF(GENERAL_NAME) *names;
2679#endif
2680
2681 in = BIO_new(BIO_s_file());
2682 if (in == NULL)
2683 goto end;
2684
2685 if (BIO_read_filename(in, file) <= 0)
2686 goto end;
2687
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002688
2689 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2690 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2691
2692 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002693 if (x == NULL)
2694 goto end;
2695
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002696 pkey = X509_get_pubkey(x);
2697 if (pkey) {
2698 switch(EVP_PKEY_base_id(pkey)) {
2699 case EVP_PKEY_RSA:
2700 key_sig = TLSEXT_signature_rsa;
2701 break;
2702 case EVP_PKEY_EC:
2703 key_sig = TLSEXT_signature_ecdsa;
2704 break;
2705 }
2706 EVP_PKEY_free(pkey);
2707 }
2708
Emeric Brun50bcecc2013-04-22 13:05:23 +02002709 if (fcount) {
2710 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002711 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002712 }
2713 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002714#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002715 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2716 if (names) {
2717 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2718 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2719 if (name->type == GEN_DNS) {
2720 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002721 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002722 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002723 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002724 }
2725 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002726 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002727 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002728#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002729 xname = X509_get_subject_name(x);
2730 i = -1;
2731 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2732 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002733 ASN1_STRING *value;
2734
2735 value = X509_NAME_ENTRY_get_data(entry);
2736 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002737 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002738 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002739 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002740 }
2741 }
2742
2743 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2744 if (!SSL_CTX_use_certificate(ctx, x))
2745 goto end;
2746
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002747#ifdef SSL_CTX_clear_extra_chain_certs
2748 SSL_CTX_clear_extra_chain_certs(ctx);
2749#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002750 if (ctx->extra_certs != NULL) {
2751 sk_X509_pop_free(ctx->extra_certs, X509_free);
2752 ctx->extra_certs = NULL;
2753 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002754#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002755
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002756 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002757 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2758 X509_free(ca);
2759 goto end;
2760 }
2761 }
2762
2763 err = ERR_get_error();
2764 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2765 /* we successfully reached the last cert in the file */
2766 ret = 1;
2767 }
2768 ERR_clear_error();
2769
2770end:
2771 if (x)
2772 X509_free(x);
2773
2774 if (in)
2775 BIO_free(in);
2776
2777 return ret;
2778}
2779
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002780static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2781 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002782{
2783 int ret;
2784 SSL_CTX *ctx;
2785
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002786 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02002787 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002788 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2789 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002790 return 1;
2791 }
2792
2793 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002794 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2795 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002796 SSL_CTX_free(ctx);
2797 return 1;
2798 }
2799
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002800 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002801 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002802 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2803 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002804 if (ret < 0) /* serious error, must do that ourselves */
2805 SSL_CTX_free(ctx);
2806 return 1;
2807 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002808
2809 if (SSL_CTX_check_private_key(ctx) <= 0) {
2810 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2811 err && *err ? *err : "", path);
2812 return 1;
2813 }
2814
Emeric Brunfc0421f2012-09-07 17:30:07 +02002815 /* we must not free the SSL_CTX anymore below, since it's already in
2816 * the tree, so it will be discovered and cleaned in time.
2817 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002818#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002819 /* store a NULL pointer to indicate we have not yet loaded
2820 a custom DH param file */
2821 if (ssl_dh_ptr_index >= 0) {
2822 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2823 }
2824
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002825 ret = ssl_sock_load_dh_params(ctx, path);
2826 if (ret < 0) {
2827 if (err)
2828 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2829 *err ? *err : "", path);
2830 return 1;
2831 }
2832#endif
2833
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002834#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002835 ret = ssl_sock_load_ocsp(ctx, path);
2836 if (ret < 0) {
2837 if (err)
2838 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",
2839 *err ? *err : "", path);
2840 return 1;
2841 }
2842#endif
2843
Daniel Jakots54ffb912015-11-06 20:02:41 +01002844#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002845 if (sctl_ex_index >= 0) {
2846 ret = ssl_sock_load_sctl(ctx, path);
2847 if (ret < 0) {
2848 if (err)
2849 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2850 *err ? *err : "", path);
2851 return 1;
2852 }
2853 }
2854#endif
2855
Emeric Brunfc0421f2012-09-07 17:30:07 +02002856#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002857 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002858 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2859 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002860 return 1;
2861 }
2862#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002863 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002864 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002865 bind_conf->default_ssl_conf = ssl_conf;
2866 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002867
2868 return 0;
2869}
2870
Willy Tarreau03209342016-12-22 17:08:28 +01002871int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002872{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002873 struct dirent **de_list;
2874 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002875 DIR *dir;
2876 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002877 char *end;
2878 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002879 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002880#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2881 int is_bundle;
2882 int j;
2883#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002884
yanbzhu08ce6ab2015-12-02 13:01:29 -05002885 if (stat(path, &buf) == 0) {
2886 dir = opendir(path);
2887 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002888 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002889
yanbzhu08ce6ab2015-12-02 13:01:29 -05002890 /* strip trailing slashes, including first one */
2891 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2892 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002893
yanbzhu08ce6ab2015-12-02 13:01:29 -05002894 n = scandir(path, &de_list, 0, alphasort);
2895 if (n < 0) {
2896 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2897 err && *err ? *err : "", path, strerror(errno));
2898 cfgerr++;
2899 }
2900 else {
2901 for (i = 0; i < n; i++) {
2902 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002903
yanbzhu08ce6ab2015-12-02 13:01:29 -05002904 end = strrchr(de->d_name, '.');
2905 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2906 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002907
yanbzhu08ce6ab2015-12-02 13:01:29 -05002908 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2909 if (stat(fp, &buf) != 0) {
2910 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2911 err && *err ? *err : "", fp, strerror(errno));
2912 cfgerr++;
2913 goto ignore_entry;
2914 }
2915 if (!S_ISREG(buf.st_mode))
2916 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002917
2918#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2919 is_bundle = 0;
2920 /* Check if current entry in directory is part of a multi-cert bundle */
2921
2922 if (end) {
2923 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2924 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2925 is_bundle = 1;
2926 break;
2927 }
2928 }
2929
2930 if (is_bundle) {
2931 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2932 int dp_len;
2933
2934 dp_len = end - de->d_name;
2935 snprintf(dp, dp_len + 1, "%s", de->d_name);
2936
2937 /* increment i and free de until we get to a non-bundle cert
2938 * Note here that we look at de_list[i + 1] before freeing de
2939 * this is important since ignore_entry will free de
2940 */
2941 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2942 free(de);
2943 i++;
2944 de = de_list[i];
2945 }
2946
2947 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002948 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002949
2950 /* Successfully processed the bundle */
2951 goto ignore_entry;
2952 }
2953 }
2954
2955#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002956 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002957ignore_entry:
2958 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002959 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002960 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002961 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002962 closedir(dir);
2963 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002964 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002965
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002966 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002967
Emeric Brunfc0421f2012-09-07 17:30:07 +02002968 return cfgerr;
2969}
2970
Thierry Fournier383085f2013-01-24 14:15:43 +01002971/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2972 * done once. Zero is returned if the operation fails. No error is returned
2973 * if the random is said as not implemented, because we expect that openssl
2974 * will use another method once needed.
2975 */
2976static int ssl_initialize_random()
2977{
2978 unsigned char random;
2979 static int random_initialized = 0;
2980
2981 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2982 random_initialized = 1;
2983
2984 return random_initialized;
2985}
2986
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002987/* release ssl bind conf */
2988void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002989{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002990 if (conf) {
2991#ifdef OPENSSL_NPN_NEGOTIATED
2992 free(conf->npn_str);
2993 conf->npn_str = NULL;
2994#endif
2995#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2996 free(conf->alpn_str);
2997 conf->alpn_str = NULL;
2998#endif
2999 free(conf->ca_file);
3000 conf->ca_file = NULL;
3001 free(conf->crl_file);
3002 conf->crl_file = NULL;
3003 free(conf->ciphers);
3004 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003005 free(conf->curves);
3006 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003007 free(conf->ecdhe);
3008 conf->ecdhe = NULL;
3009 }
3010}
3011
3012int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
3013{
3014 char thisline[CRT_LINESIZE];
3015 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003016 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05003017 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003018 int linenum = 0;
3019 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003020
Willy Tarreauad1731d2013-04-02 17:35:58 +02003021 if ((f = fopen(file, "r")) == NULL) {
3022 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003023 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003024 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003025
3026 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003027 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003028 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003029 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003030 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003031 char *crt_path;
3032 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003033
3034 linenum++;
3035 end = line + strlen(line);
3036 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3037 /* Check if we reached the limit and the last char is not \n.
3038 * Watch out for the last line without the terminating '\n'!
3039 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003040 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3041 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003042 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003043 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003044 }
3045
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003046 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003047 newarg = 1;
3048 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003049 if (*line == '#' || *line == '\n' || *line == '\r') {
3050 /* end of string, end of loop */
3051 *line = 0;
3052 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003053 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003054 newarg = 1;
3055 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003056 } else if (*line == '[') {
3057 if (ssl_b) {
3058 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3059 cfgerr = 1;
3060 break;
3061 }
3062 if (!arg) {
3063 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3064 cfgerr = 1;
3065 break;
3066 }
3067 ssl_b = arg;
3068 newarg = 1;
3069 *line = 0;
3070 } else if (*line == ']') {
3071 if (ssl_e) {
3072 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003073 cfgerr = 1;
3074 break;
3075 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003076 if (!ssl_b) {
3077 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3078 cfgerr = 1;
3079 break;
3080 }
3081 ssl_e = arg;
3082 newarg = 1;
3083 *line = 0;
3084 } else if (newarg) {
3085 if (arg == MAX_CRT_ARGS) {
3086 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3087 cfgerr = 1;
3088 break;
3089 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003090 newarg = 0;
3091 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003092 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003093 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003094 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003095 if (cfgerr)
3096 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003097 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003098
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003099 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003100 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003101 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003102
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003103 crt_path = args[0];
3104 if (*crt_path != '/' && global_ssl.crt_base) {
3105 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3106 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3107 crt_path, linenum, file);
3108 cfgerr = 1;
3109 break;
3110 }
3111 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3112 crt_path = path;
3113 }
3114
3115 ssl_conf = calloc(1, sizeof *ssl_conf);
3116 cur_arg = ssl_b ? ssl_b : 1;
3117 while (cur_arg < ssl_e) {
3118 newarg = 0;
3119 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3120 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3121 newarg = 1;
3122 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3123 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3124 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3125 args[cur_arg], linenum, file);
3126 cfgerr = 1;
3127 }
3128 cur_arg += 1 + ssl_bind_kws[i].skip;
3129 break;
3130 }
3131 }
3132 if (!cfgerr && !newarg) {
3133 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3134 args[cur_arg], linenum, file);
3135 cfgerr = 1;
3136 break;
3137 }
3138 }
3139 if (cfgerr) {
3140 ssl_sock_free_ssl_conf(ssl_conf);
3141 free(ssl_conf);
3142 ssl_conf = NULL;
3143 break;
3144 }
3145
3146 if (stat(crt_path, &buf) == 0) {
3147 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3148 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003149 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003150 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3151 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003152 }
3153
Willy Tarreauad1731d2013-04-02 17:35:58 +02003154 if (cfgerr) {
3155 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003156 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003157 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003158 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003159 fclose(f);
3160 return cfgerr;
3161}
3162
Emeric Brunfc0421f2012-09-07 17:30:07 +02003163#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
3164#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
3165#endif
3166
3167#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
3168#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01003169#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02003170#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003171#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
3172#define SSL_OP_SINGLE_ECDH_USE 0
3173#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02003174#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
3175#define SSL_OP_NO_TICKET 0
3176#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003177#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
3178#define SSL_OP_NO_COMPRESSION 0
3179#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02003180#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
3181#define SSL_OP_NO_TLSv1_1 0
3182#endif
3183#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
3184#define SSL_OP_NO_TLSv1_2 0
3185#endif
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02003186#ifndef SSL_OP_NO_TLSv1_3 /* dev */
3187#define SSL_OP_NO_TLSv1_3 0
3188#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003189#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
3190#define SSL_OP_SINGLE_DH_USE 0
3191#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003192#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
3193#define SSL_OP_SINGLE_ECDH_USE 0
3194#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003195#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
3196#define SSL_MODE_RELEASE_BUFFERS 0
3197#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01003198#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
3199#define SSL_MODE_SMALL_BUFFERS 0
3200#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003201
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003202#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3203static void ssl_set_SSLv3_func(SSL_CTX *ctx, int is_server)
3204{
3205#if SSL_OP_NO_SSLv3
3206 is_server ? SSL_CTX_set_ssl_version(ctx, SSLv3_server_method())
3207 : SSL_CTX_set_ssl_version(ctx, SSLv3_client_method());
3208#endif
3209}
3210static void ssl_set_TLSv10_func(SSL_CTX *ctx, int is_server) {
3211 is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_server_method())
3212 : SSL_CTX_set_ssl_version(ctx, TLSv1_client_method());
3213}
3214static void ssl_set_TLSv11_func(SSL_CTX *ctx, int is_server) {
3215#if SSL_OP_NO_TLSv1_1
3216 is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method())
3217 : SSL_CTX_set_ssl_version(ctx, TLSv1_1_client_method());
3218#endif
3219}
3220static void ssl_set_TLSv12_func(SSL_CTX *ctx, int is_server) {
3221#if SSL_OP_NO_TLSv1_2
3222 is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method())
3223 : SSL_CTX_set_ssl_version(ctx, TLSv1_2_client_method());
3224#endif
3225}
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02003226static void ssl_set_TLSv13_func(SSL_CTX *ctx, int is_server) {
3227 /* TLS 1.2 is the last supported version in this context. */
3228}
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003229#else /* openssl >= 1.1.0 */
3230static void ssl_set_SSLv3_func(SSL_CTX *ctx, int is_max) {
3231 is_max ? SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION)
3232 : SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
3233}
3234static void ssl_set_TLSv10_func(SSL_CTX *ctx, int is_max) {
3235 is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION)
3236 : SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
3237}
3238static void ssl_set_TLSv11_func(SSL_CTX *ctx, int is_max) {
3239 is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION)
3240 : SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
3241}
3242static void ssl_set_TLSv12_func(SSL_CTX *ctx, int is_max) {
3243 is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)
3244 : SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
3245}
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02003246static void ssl_set_TLSv13_func(SSL_CTX *ctx, int is_max) {
3247#if SSL_OP_NO_TLSv1_3
3248 is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION)
3249 : SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
3250#endif
3251}
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003252#endif
3253static void ssl_set_None_func(SSL_CTX *ctx, int i) {
3254}
3255
3256static struct {
3257 int option;
3258 uint16_t flag;
3259 void (*set_version)(SSL_CTX *, int);
3260 const char *name;
3261} methodVersions[] = {
3262 {0, 0, ssl_set_None_func, "NONE"}, /* CONF_TLSV_NONE */
3263 {SSL_OP_NO_SSLv3, MC_SSL_O_NO_SSLV3, ssl_set_SSLv3_func, "SSLv3"}, /* CONF_SSLV3 */
3264 {SSL_OP_NO_TLSv1, MC_SSL_O_NO_TLSV10, ssl_set_TLSv10_func, "TLSv1.0"}, /* CONF_TLSV10 */
3265 {SSL_OP_NO_TLSv1_1, MC_SSL_O_NO_TLSV11, ssl_set_TLSv11_func, "TLSv1.1"}, /* CONF_TLSV11 */
3266 {SSL_OP_NO_TLSv1_2, MC_SSL_O_NO_TLSV12, ssl_set_TLSv12_func, "TLSv1.2"}, /* CONF_TLSV12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02003267 {SSL_OP_NO_TLSv1_3, MC_SSL_O_NO_TLSV13, ssl_set_TLSv13_func, "TLSv1.3"}, /* CONF_TLSV13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003268};
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003269
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003270/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003271static int
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003272ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003273{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003274 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003275 long options =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003276 SSL_OP_ALL | /* all known workarounds for bugs */
3277 SSL_OP_NO_SSLv2 |
3278 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003279 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003280 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003281 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3282 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003283 long mode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003284 SSL_MODE_ENABLE_PARTIAL_WRITE |
3285 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003286 SSL_MODE_RELEASE_BUFFERS |
3287 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003288 struct tls_version_filter *conf_ssl_methods = &bind_conf->ssl_methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003289 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003290 int flags = MC_SSL_O_ALL;
3291 int cfgerr = 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003292
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003293 ctx = SSL_CTX_new(SSLv23_server_method());
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003294 bind_conf->initial_ctx = ctx;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003295
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003296 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
3297 Warning("Proxy '%s': no-sslv3/no-tlsv1x are ignored for bind '%s' at [%s:%d]. "
3298 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
3299 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3300 else
3301 flags = conf_ssl_methods->flags;
3302
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003303 if (conf_ssl_methods->min)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003304 flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003305 if (conf_ssl_methods->max)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003306 flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003307
3308 /* Find min, max and holds */
3309 min = max = CONF_TLSV_NONE;
3310 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003311 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003312 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003313 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003314 if (min) {
3315 if (hole) {
3316 Warning("Proxy '%s': SSL/TLS versions range not contiguous for bind '%s' at [%s:%d]. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003317 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003318 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line,
3319 methodVersions[hole].name);
3320 hole = 0;
3321 }
3322 max = i;
3323 }
3324 else {
3325 min = max = i;
3326 }
3327 }
3328 else {
3329 if (min)
3330 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003331 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003332 if (!min) {
3333 Alert("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003334 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003335 cfgerr += 1;
3336 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003337
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003338#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3339 /* Keep force-xxx implementation as it is in older haproxy. It's a
3340 precautionary measure to avoid any suprise with older openssl version. */
3341 if (min == max)
3342 methodVersions[min].set_version(ctx, 1 /* server */);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003343 else
3344 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3345 if (flags & methodVersions[i].flag)
3346 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003347#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003348 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003349 methodVersions[min].set_version(ctx, 0);
3350 methodVersions[max].set_version(ctx, 1);
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003351#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003352
3353 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3354 options |= SSL_OP_NO_TICKET;
3355 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
3356 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
3357 SSL_CTX_set_options(ctx, options);
3358 SSL_CTX_set_mode(ctx, mode);
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003359 if (global_ssl.life_time)
3360 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003361
3362#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3363#ifdef OPENSSL_IS_BORINGSSL
3364 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3365 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3366#else
3367 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3368 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3369#endif
3370#endif
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003371 return cfgerr;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003372}
3373
3374int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3375{
3376 struct proxy *curproxy = bind_conf->frontend;
3377 int cfgerr = 0;
3378 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003379 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003380 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003381 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003382
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003383 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003384 case SSL_SOCK_VERIFY_NONE:
3385 verify = SSL_VERIFY_NONE;
3386 break;
3387 case SSL_SOCK_VERIFY_OPTIONAL:
3388 verify = SSL_VERIFY_PEER;
3389 break;
3390 case SSL_SOCK_VERIFY_REQUIRED:
3391 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3392 break;
3393 }
3394 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3395 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003396 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3397 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3398 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003399 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003400 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003401 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003402 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003403 cfgerr++;
3404 }
3405 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003406 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003407 }
Emeric Brun850efd52014-01-29 12:24:34 +01003408 else {
3409 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3410 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3411 cfgerr++;
3412 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003413#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003414 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003415 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3416
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003417 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003418 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003419 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003420 cfgerr++;
3421 }
Emeric Brun561e5742012-10-02 15:20:55 +02003422 else {
3423 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3424 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003425 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003426#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003427 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003428 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003429#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003430 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003431 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3432 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3433 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3434 cfgerr++;
3435 }
3436 }
3437#endif
3438
Emeric Brunfc0421f2012-09-07 17:30:07 +02003439 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003440 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3441 if (conf_ciphers &&
3442 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003443 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 +01003444 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003445 cfgerr++;
3446 }
3447
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003448#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003449 /* If tune.ssl.default-dh-param has not been set,
3450 neither has ssl-default-dh-file and no static DH
3451 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003452 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003453 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003454 (ssl_dh_ptr_index == -1 ||
3455 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003456 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3457 const SSL_CIPHER * cipher = NULL;
3458 char cipher_description[128];
3459 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3460 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3461 which is not ephemeral DH. */
3462 const char dhe_description[] = " Kx=DH ";
3463 const char dhe_export_description[] = " Kx=DH(";
3464 int idx = 0;
3465 int dhe_found = 0;
3466 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003467
Remi Gacogne23d5d372014-10-10 17:04:26 +02003468 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003469
Remi Gacogne23d5d372014-10-10 17:04:26 +02003470 if (ssl) {
3471 ciphers = SSL_get_ciphers(ssl);
3472
3473 if (ciphers) {
3474 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3475 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3476 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3477 if (strstr(cipher_description, dhe_description) != NULL ||
3478 strstr(cipher_description, dhe_export_description) != NULL) {
3479 dhe_found = 1;
3480 break;
3481 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003482 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003483 }
3484 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003485 SSL_free(ssl);
3486 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003487 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003488
Lukas Tribus90132722014-08-18 00:56:33 +02003489 if (dhe_found) {
3490 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 +02003491 }
3492
Willy Tarreauef934602016-12-22 23:12:01 +01003493 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003494 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003495
Willy Tarreauef934602016-12-22 23:12:01 +01003496 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003497 if (local_dh_1024 == NULL) {
3498 local_dh_1024 = ssl_get_dh_1024();
3499 }
Willy Tarreauef934602016-12-22 23:12:01 +01003500 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003501 if (local_dh_2048 == NULL) {
3502 local_dh_2048 = ssl_get_dh_2048();
3503 }
Willy Tarreauef934602016-12-22 23:12:01 +01003504 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003505 if (local_dh_4096 == NULL) {
3506 local_dh_4096 = ssl_get_dh_4096();
3507 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003508 }
3509 }
3510 }
3511#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003512
Emeric Brunfc0421f2012-09-07 17:30:07 +02003513 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003514#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003515 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003516#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003517
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003518#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003519 ssl_conf_cur = NULL;
3520 if (ssl_conf && ssl_conf->npn_str)
3521 ssl_conf_cur = ssl_conf;
3522 else if (bind_conf->ssl_conf.npn_str)
3523 ssl_conf_cur = &bind_conf->ssl_conf;
3524 if (ssl_conf_cur)
3525 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003526#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003527#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003528 ssl_conf_cur = NULL;
3529 if (ssl_conf && ssl_conf->alpn_str)
3530 ssl_conf_cur = ssl_conf;
3531 else if (bind_conf->ssl_conf.alpn_str)
3532 ssl_conf_cur = &bind_conf->ssl_conf;
3533 if (ssl_conf_cur)
3534 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003535#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003536#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3537 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3538 if (conf_curves) {
3539 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3540 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3541 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3542 cfgerr++;
3543 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003544#if defined(SSL_CTX_set_ecdh_auto)
3545 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3546#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003547 }
3548#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003549#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003550 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003551 int i;
3552 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003553 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3554 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003555
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003556 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003557 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3558 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 +01003559 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003560 cfgerr++;
3561 }
3562 else {
3563 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3564 EC_KEY_free(ecdh);
3565 }
3566 }
3567#endif
3568
Emeric Brunfc0421f2012-09-07 17:30:07 +02003569 return cfgerr;
3570}
3571
Evan Broderbe554312013-06-27 00:05:25 -07003572static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3573{
3574 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3575 size_t prefixlen, suffixlen;
3576
3577 /* Trivial case */
3578 if (strcmp(pattern, hostname) == 0)
3579 return 1;
3580
Evan Broderbe554312013-06-27 00:05:25 -07003581 /* The rest of this logic is based on RFC 6125, section 6.4.3
3582 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3583
Emeric Bruna848dae2013-10-08 11:27:28 +02003584 pattern_wildcard = NULL;
3585 pattern_left_label_end = pattern;
3586 while (*pattern_left_label_end != '.') {
3587 switch (*pattern_left_label_end) {
3588 case 0:
3589 /* End of label not found */
3590 return 0;
3591 case '*':
3592 /* If there is more than one wildcards */
3593 if (pattern_wildcard)
3594 return 0;
3595 pattern_wildcard = pattern_left_label_end;
3596 break;
3597 }
3598 pattern_left_label_end++;
3599 }
3600
3601 /* If it's not trivial and there is no wildcard, it can't
3602 * match */
3603 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003604 return 0;
3605
3606 /* Make sure all labels match except the leftmost */
3607 hostname_left_label_end = strchr(hostname, '.');
3608 if (!hostname_left_label_end
3609 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3610 return 0;
3611
3612 /* Make sure the leftmost label of the hostname is long enough
3613 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003614 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003615 return 0;
3616
3617 /* Finally compare the string on either side of the
3618 * wildcard */
3619 prefixlen = pattern_wildcard - pattern;
3620 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003621 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3622 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003623 return 0;
3624
3625 return 1;
3626}
3627
3628static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3629{
3630 SSL *ssl;
3631 struct connection *conn;
3632 char *servername;
3633
3634 int depth;
3635 X509 *cert;
3636 STACK_OF(GENERAL_NAME) *alt_names;
3637 int i;
3638 X509_NAME *cert_subject;
3639 char *str;
3640
3641 if (ok == 0)
3642 return ok;
3643
3644 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003645 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003646
3647 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3648
3649 /* We only need to verify the CN on the actual server cert,
3650 * not the indirect CAs */
3651 depth = X509_STORE_CTX_get_error_depth(ctx);
3652 if (depth != 0)
3653 return ok;
3654
3655 /* At this point, the cert is *not* OK unless we can find a
3656 * hostname match */
3657 ok = 0;
3658
3659 cert = X509_STORE_CTX_get_current_cert(ctx);
3660 /* It seems like this might happen if verify peer isn't set */
3661 if (!cert)
3662 return ok;
3663
3664 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3665 if (alt_names) {
3666 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3667 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3668 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003669#if OPENSSL_VERSION_NUMBER < 0x00907000L
3670 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3671#else
Evan Broderbe554312013-06-27 00:05:25 -07003672 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003673#endif
Evan Broderbe554312013-06-27 00:05:25 -07003674 ok = ssl_sock_srv_hostcheck(str, servername);
3675 OPENSSL_free(str);
3676 }
3677 }
3678 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003679 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003680 }
3681
3682 cert_subject = X509_get_subject_name(cert);
3683 i = -1;
3684 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3685 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003686 ASN1_STRING *value;
3687 value = X509_NAME_ENTRY_get_data(entry);
3688 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003689 ok = ssl_sock_srv_hostcheck(str, servername);
3690 OPENSSL_free(str);
3691 }
3692 }
3693
3694 return ok;
3695}
3696
Emeric Brun94324a42012-10-11 14:00:19 +02003697/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003698int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003699{
Willy Tarreau03209342016-12-22 17:08:28 +01003700 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003701 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003702 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003703 SSL_OP_ALL | /* all known workarounds for bugs */
3704 SSL_OP_NO_SSLv2 |
3705 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003706 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003707 SSL_MODE_ENABLE_PARTIAL_WRITE |
3708 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003709 SSL_MODE_RELEASE_BUFFERS |
3710 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003711 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003712 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003713 struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003714 int i, min, max, hole;
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003715 int flags = MC_SSL_O_ALL;
Emeric Brun94324a42012-10-11 14:00:19 +02003716
Thierry Fournier383085f2013-01-24 14:15:43 +01003717 /* Make sure openssl opens /dev/urandom before the chroot */
3718 if (!ssl_initialize_random()) {
3719 Alert("OpenSSL random data generator initialization failed.\n");
3720 cfgerr++;
3721 }
3722
Willy Tarreaufce03112015-01-15 21:32:40 +01003723 /* Automatic memory computations need to know we use SSL there */
3724 global.ssl_used_backend = 1;
3725
3726 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003727 srv->ssl_ctx.reused_sess = NULL;
3728 if (srv->use_ssl)
3729 srv->xprt = &ssl_sock;
3730 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003731 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003732
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003733 ctx = SSL_CTX_new(SSLv23_client_method());
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003734 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02003735 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3736 proxy_type_str(curproxy), curproxy->id,
3737 srv->id);
3738 cfgerr++;
3739 return cfgerr;
3740 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003741
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003742 if (conf_ssl_methods->flags && (conf_ssl_methods->min || conf_ssl_methods->max))
3743 Warning("config : %s '%s': no-sslv3/no-tlsv1x are ignored for server '%s'. "
3744 "Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
3745 proxy_type_str(curproxy), curproxy->id, srv->id);
3746 else
3747 flags = conf_ssl_methods->flags;
3748
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003749 /* Real min and max should be determinate with configuration and openssl's capabilities */
3750 if (conf_ssl_methods->min)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003751 flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003752 if (conf_ssl_methods->max)
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003753 flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003754
3755 /* find min, max and holds */
3756 min = max = CONF_TLSV_NONE;
3757 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003758 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003759 /* version is in openssl && version not disable in configuration */
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003760 if (methodVersions[i].option && !(flags & methodVersions[i].flag)) {
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003761 if (min) {
3762 if (hole) {
3763 Warning("config : %s '%s': SSL/TLS versions range not contiguous for server '%s'. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003764 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003765 proxy_type_str(curproxy), curproxy->id, srv->id,
3766 methodVersions[hole].name);
3767 hole = 0;
3768 }
3769 max = i;
3770 }
3771 else {
3772 min = max = i;
3773 }
3774 }
3775 else {
3776 if (min)
3777 hole = i;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003778 }
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003779 if (!min) {
3780 Alert("config : %s '%s': all SSL/TLS versions are disabled for server '%s'.\n",
3781 proxy_type_str(curproxy), curproxy->id, srv->id);
3782 cfgerr += 1;
3783 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003784
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003785#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3786 /* Keep force-xxx implementation as it is in older haproxy. It's a
3787 precautionary measure to avoid any suprise with older openssl version. */
3788 if (min == max)
3789 methodVersions[min].set_version(ctx, 0 /* client */);
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003790 else
3791 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3792 if (flags & methodVersions[i].flag)
3793 options |= methodVersions[i].option;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003794#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003795 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003796 methodVersions[min].set_version(ctx, 0);
3797 methodVersions[max].set_version(ctx, 1);
3798#endif
3799
3800 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3801 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003802 SSL_CTX_set_options(ctx, options);
3803 SSL_CTX_set_mode(ctx, mode);
3804 srv->ssl_ctx.ctx = ctx;
3805
Emeric Bruna7aa3092012-10-26 12:58:00 +02003806 if (srv->ssl_ctx.client_crt) {
3807 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3808 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3809 proxy_type_str(curproxy), curproxy->id,
3810 srv->id, srv->ssl_ctx.client_crt);
3811 cfgerr++;
3812 }
3813 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3814 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3815 proxy_type_str(curproxy), curproxy->id,
3816 srv->id, srv->ssl_ctx.client_crt);
3817 cfgerr++;
3818 }
3819 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3820 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3821 proxy_type_str(curproxy), curproxy->id,
3822 srv->id, srv->ssl_ctx.client_crt);
3823 cfgerr++;
3824 }
3825 }
Emeric Brun94324a42012-10-11 14:00:19 +02003826
Emeric Brun850efd52014-01-29 12:24:34 +01003827 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3828 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01003829 switch (srv->ssl_ctx.verify) {
3830 case SSL_SOCK_VERIFY_NONE:
3831 verify = SSL_VERIFY_NONE;
3832 break;
3833 case SSL_SOCK_VERIFY_REQUIRED:
3834 verify = SSL_VERIFY_PEER;
3835 break;
3836 }
Evan Broderbe554312013-06-27 00:05:25 -07003837 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003838 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003839 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003840 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003841 if (srv->ssl_ctx.ca_file) {
3842 /* load CAfile to verify */
3843 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003844 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003845 curproxy->id, srv->id,
3846 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3847 cfgerr++;
3848 }
3849 }
Emeric Brun850efd52014-01-29 12:24:34 +01003850 else {
3851 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003852 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 +01003853 curproxy->id, srv->id,
3854 srv->conf.file, srv->conf.line);
3855 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003856 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003857 curproxy->id, srv->id,
3858 srv->conf.file, srv->conf.line);
3859 cfgerr++;
3860 }
Emeric Brunef42d922012-10-11 16:11:36 +02003861#ifdef X509_V_FLAG_CRL_CHECK
3862 if (srv->ssl_ctx.crl_file) {
3863 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3864
3865 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003866 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003867 curproxy->id, srv->id,
3868 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3869 cfgerr++;
3870 }
3871 else {
3872 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3873 }
3874 }
3875#endif
3876 }
3877
Emeric Brun94324a42012-10-11 14:00:19 +02003878 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3879 if (srv->ssl_ctx.ciphers &&
3880 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3881 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3882 curproxy->id, srv->id,
3883 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3884 cfgerr++;
3885 }
3886
3887 return cfgerr;
3888}
3889
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003890/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003891 * be NULL, in which case nothing is done. Returns the number of errors
3892 * encountered.
3893 */
Willy Tarreau03209342016-12-22 17:08:28 +01003894int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003895{
3896 struct ebmb_node *node;
3897 struct sni_ctx *sni;
3898 int err = 0;
3899
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003900 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003901 return 0;
3902
Willy Tarreaufce03112015-01-15 21:32:40 +01003903 /* Automatic memory computations need to know we use SSL there */
3904 global.ssl_used_frontend = 1;
3905
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003906 /* Make sure openssl opens /dev/urandom before the chroot */
3907 if (!ssl_initialize_random()) {
3908 Alert("OpenSSL random data generator initialization failed.\n");
3909 err++;
3910 }
3911 /* Create initial_ctx used to start the ssl connection before do switchctx */
3912 if (!bind_conf->initial_ctx) {
Emmanuel Hocdetabd32332017-05-05 18:06:12 +02003913 err += ssl_sock_initial_ctx(bind_conf);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003914 /* It should not be necessary to call this function, but it's
3915 necessary first to check and move all initialisation related
3916 to initial_ctx in ssl_sock_initial_ctx. */
3917 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
3918 }
Emeric Brun0bed9942014-10-30 19:25:24 +01003919 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003920 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003921
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003922 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003923 while (node) {
3924 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003925 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3926 /* only initialize the CTX on its first occurrence and
3927 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003928 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003929 node = ebmb_next(node);
3930 }
3931
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003932 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003933 while (node) {
3934 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003935 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3936 /* only initialize the CTX on its first occurrence and
3937 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003938 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003939 node = ebmb_next(node);
3940 }
3941 return err;
3942}
3943
Willy Tarreau55d37912016-12-21 23:38:39 +01003944/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3945 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3946 * alerts are directly emitted since the rest of the stack does it below.
3947 */
3948int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3949{
3950 struct proxy *px = bind_conf->frontend;
3951 int alloc_ctx;
3952 int err;
3953
3954 if (!bind_conf->is_ssl) {
3955 if (bind_conf->default_ctx) {
3956 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3957 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3958 }
3959 return 0;
3960 }
3961 if (!bind_conf->default_ctx) {
3962 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3963 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3964 return -1;
3965 }
3966
Willy Tarreauef934602016-12-22 23:12:01 +01003967 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003968 if (alloc_ctx < 0) {
3969 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3970 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");
3971 else
3972 Alert("Unable to allocate SSL session cache.\n");
3973 return -1;
3974 }
3975
3976 err = 0;
3977 /* initialize all certificate contexts */
3978 err += ssl_sock_prepare_all_ctx(bind_conf);
3979
3980 /* initialize CA variables if the certificates generation is enabled */
3981 err += ssl_sock_load_ca(bind_conf);
3982
3983 return -err;
3984}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003985
3986/* release ssl context allocated for servers. */
3987void ssl_sock_free_srv_ctx(struct server *srv)
3988{
3989 if (srv->ssl_ctx.ctx)
3990 SSL_CTX_free(srv->ssl_ctx.ctx);
3991}
3992
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003993/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003994 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3995 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003996void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003997{
3998 struct ebmb_node *node, *back;
3999 struct sni_ctx *sni;
4000
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004001 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02004002 return;
4003
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004004 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004005 while (node) {
4006 sni = ebmb_entry(node, struct sni_ctx, name);
4007 back = ebmb_next(node);
4008 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004009 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004010 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004011 ssl_sock_free_ssl_conf(sni->conf);
4012 free(sni->conf);
4013 sni->conf = NULL;
4014 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004015 free(sni);
4016 node = back;
4017 }
4018
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004019 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02004020 while (node) {
4021 sni = ebmb_entry(node, struct sni_ctx, name);
4022 back = ebmb_next(node);
4023 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004024 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004025 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004026 ssl_sock_free_ssl_conf(sni->conf);
4027 free(sni->conf);
4028 sni->conf = NULL;
4029 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004030 free(sni);
4031 node = back;
4032 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004033 SSL_CTX_free(bind_conf->initial_ctx);
4034 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004035 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004036 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02004037}
4038
Willy Tarreau795cdab2016-12-22 17:30:54 +01004039/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
4040void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
4041{
4042 ssl_sock_free_ca(bind_conf);
4043 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004044 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004045 free(bind_conf->ca_sign_file);
4046 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004047 if (bind_conf->keys_ref) {
4048 free(bind_conf->keys_ref->filename);
4049 free(bind_conf->keys_ref->tlskeys);
4050 LIST_DEL(&bind_conf->keys_ref->list);
4051 free(bind_conf->keys_ref);
4052 }
4053 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004054 bind_conf->ca_sign_pass = NULL;
4055 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004056}
4057
Christopher Faulet31af49d2015-06-09 17:29:50 +02004058/* Load CA cert file and private key used to generate certificates */
4059int
Willy Tarreau03209342016-12-22 17:08:28 +01004060ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02004061{
Willy Tarreau03209342016-12-22 17:08:28 +01004062 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004063 FILE *fp;
4064 X509 *cacert = NULL;
4065 EVP_PKEY *capkey = NULL;
4066 int err = 0;
4067
4068 if (!bind_conf || !bind_conf->generate_certs)
4069 return err;
4070
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004071#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01004072 if (global_ssl.ctx_cache)
4073 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02004074 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02004075#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02004076
Christopher Faulet31af49d2015-06-09 17:29:50 +02004077 if (!bind_conf->ca_sign_file) {
4078 Alert("Proxy '%s': cannot enable certificate generation, "
4079 "no CA certificate File configured at [%s:%d].\n",
4080 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004081 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004082 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004083
4084 /* read in the CA certificate */
4085 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
4086 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4087 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004088 goto load_error;
4089 }
4090 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
4091 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4092 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004093 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004094 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004095 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004096 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
4097 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
4098 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004099 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004100 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004101
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004102 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004103 bind_conf->ca_sign_cert = cacert;
4104 bind_conf->ca_sign_pkey = capkey;
4105 return err;
4106
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004107 read_error:
4108 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004109 if (capkey) EVP_PKEY_free(capkey);
4110 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004111 load_error:
4112 bind_conf->generate_certs = 0;
4113 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004114 return err;
4115}
4116
4117/* Release CA cert and private key used to generate certificated */
4118void
4119ssl_sock_free_ca(struct bind_conf *bind_conf)
4120{
4121 if (!bind_conf)
4122 return;
4123
4124 if (bind_conf->ca_sign_pkey)
4125 EVP_PKEY_free(bind_conf->ca_sign_pkey);
4126 if (bind_conf->ca_sign_cert)
4127 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01004128 bind_conf->ca_sign_pkey = NULL;
4129 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004130}
4131
Emeric Brun46591952012-05-18 15:47:34 +02004132/*
4133 * This function is called if SSL * context is not yet allocated. The function
4134 * is designed to be called before any other data-layer operation and sets the
4135 * handshake flag on the connection. It is safe to call it multiple times.
4136 * It returns 0 on success and -1 in error case.
4137 */
4138static int ssl_sock_init(struct connection *conn)
4139{
4140 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004141 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004142 return 0;
4143
Willy Tarreau3c728722014-01-23 13:50:42 +01004144 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004145 return 0;
4146
Willy Tarreau20879a02012-12-03 16:32:10 +01004147 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4148 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004149 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004150 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004151
Emeric Brun46591952012-05-18 15:47:34 +02004152 /* If it is in client mode initiate SSL session
4153 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004154 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004155 int may_retry = 1;
4156
4157 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004158 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004159 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004160 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004161 if (may_retry--) {
4162 pool_gc2();
4163 goto retry_connect;
4164 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004165 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004166 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004167 }
Emeric Brun46591952012-05-18 15:47:34 +02004168
Emeric Brun46591952012-05-18 15:47:34 +02004169 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004170 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4171 SSL_free(conn->xprt_ctx);
4172 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004173 if (may_retry--) {
4174 pool_gc2();
4175 goto retry_connect;
4176 }
Emeric Brun55476152014-11-12 17:35:37 +01004177 conn->err_code = CO_ER_SSL_NO_MEM;
4178 return -1;
4179 }
Emeric Brun46591952012-05-18 15:47:34 +02004180
Evan Broderbe554312013-06-27 00:05:25 -07004181 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004182 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4183 SSL_free(conn->xprt_ctx);
4184 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004185 if (may_retry--) {
4186 pool_gc2();
4187 goto retry_connect;
4188 }
Emeric Brun55476152014-11-12 17:35:37 +01004189 conn->err_code = CO_ER_SSL_NO_MEM;
4190 return -1;
4191 }
4192
4193 SSL_set_connect_state(conn->xprt_ctx);
4194 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4195 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4196 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4197 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4198 }
4199 }
Evan Broderbe554312013-06-27 00:05:25 -07004200
Emeric Brun46591952012-05-18 15:47:34 +02004201 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004202 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004203
4204 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004205 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004206 return 0;
4207 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004208 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004209 int may_retry = 1;
4210
4211 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004212 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004213 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004214 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004215 if (may_retry--) {
4216 pool_gc2();
4217 goto retry_accept;
4218 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004219 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004220 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004221 }
Emeric Brun46591952012-05-18 15:47:34 +02004222
Emeric Brun46591952012-05-18 15:47:34 +02004223 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004224 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4225 SSL_free(conn->xprt_ctx);
4226 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004227 if (may_retry--) {
4228 pool_gc2();
4229 goto retry_accept;
4230 }
Emeric Brun55476152014-11-12 17:35:37 +01004231 conn->err_code = CO_ER_SSL_NO_MEM;
4232 return -1;
4233 }
Emeric Brun46591952012-05-18 15:47:34 +02004234
Emeric Brune1f38db2012-09-03 20:36:47 +02004235 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004236 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4237 SSL_free(conn->xprt_ctx);
4238 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004239 if (may_retry--) {
4240 pool_gc2();
4241 goto retry_accept;
4242 }
Emeric Brun55476152014-11-12 17:35:37 +01004243 conn->err_code = CO_ER_SSL_NO_MEM;
4244 return -1;
4245 }
4246
4247 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004248
Emeric Brun46591952012-05-18 15:47:34 +02004249 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004250 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004251
4252 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004253 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004254 return 0;
4255 }
4256 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004257 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004258 return -1;
4259}
4260
4261
4262/* This is the callback which is used when an SSL handshake is pending. It
4263 * updates the FD status if it wants some polling before being called again.
4264 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4265 * otherwise it returns non-zero and removes itself from the connection's
4266 * flags (the bit is provided in <flag> by the caller).
4267 */
4268int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4269{
4270 int ret;
4271
Willy Tarreau3c728722014-01-23 13:50:42 +01004272 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004273 return 0;
4274
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004275 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004276 goto out_error;
4277
Emeric Brun674b7432012-11-08 19:21:55 +01004278 /* If we use SSL_do_handshake to process a reneg initiated by
4279 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4280 * Usually SSL_write and SSL_read are used and process implicitly
4281 * the reneg handshake.
4282 * Here we use SSL_peek as a workaround for reneg.
4283 */
4284 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4285 char c;
4286
4287 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4288 if (ret <= 0) {
4289 /* handshake may have not been completed, let's find why */
4290 ret = SSL_get_error(conn->xprt_ctx, ret);
4291 if (ret == SSL_ERROR_WANT_WRITE) {
4292 /* SSL handshake needs to write, L4 connection may not be ready */
4293 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004294 __conn_sock_want_send(conn);
4295 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004296 return 0;
4297 }
4298 else if (ret == SSL_ERROR_WANT_READ) {
4299 /* handshake may have been completed but we have
4300 * no more data to read.
4301 */
4302 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4303 ret = 1;
4304 goto reneg_ok;
4305 }
4306 /* SSL handshake needs to read, L4 connection is ready */
4307 if (conn->flags & CO_FL_WAIT_L4_CONN)
4308 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4309 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004310 __conn_sock_want_recv(conn);
4311 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004312 return 0;
4313 }
4314 else if (ret == SSL_ERROR_SYSCALL) {
4315 /* if errno is null, then connection was successfully established */
4316 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4317 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004318 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004319#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4320 conn->err_code = CO_ER_SSL_HANDSHAKE;
4321#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004322 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004323#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004324 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4325 empty_handshake = state == TLS_ST_BEFORE;
4326#else
4327 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4328#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004329 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004330 if (!errno) {
4331 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4332 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4333 else
4334 conn->err_code = CO_ER_SSL_EMPTY;
4335 }
4336 else {
4337 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4338 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4339 else
4340 conn->err_code = CO_ER_SSL_ABORT;
4341 }
4342 }
4343 else {
4344 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4345 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004346 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004347 conn->err_code = CO_ER_SSL_HANDSHAKE;
4348 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004349#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004350 }
Emeric Brun674b7432012-11-08 19:21:55 +01004351 goto out_error;
4352 }
4353 else {
4354 /* Fail on all other handshake errors */
4355 /* Note: OpenSSL may leave unread bytes in the socket's
4356 * buffer, causing an RST to be emitted upon close() on
4357 * TCP sockets. We first try to drain possibly pending
4358 * data to avoid this as much as possible.
4359 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004360 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004361 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004362 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4363 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004364 goto out_error;
4365 }
4366 }
4367 /* read some data: consider handshake completed */
4368 goto reneg_ok;
4369 }
4370
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004371 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004372 if (ret != 1) {
4373 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004374 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004375
4376 if (ret == SSL_ERROR_WANT_WRITE) {
4377 /* SSL handshake needs to write, L4 connection may not be ready */
4378 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004379 __conn_sock_want_send(conn);
4380 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004381 return 0;
4382 }
4383 else if (ret == SSL_ERROR_WANT_READ) {
4384 /* SSL handshake needs to read, L4 connection is ready */
4385 if (conn->flags & CO_FL_WAIT_L4_CONN)
4386 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4387 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004388 __conn_sock_want_recv(conn);
4389 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004390 return 0;
4391 }
Willy Tarreau89230192012-09-28 20:22:13 +02004392 else if (ret == SSL_ERROR_SYSCALL) {
4393 /* if errno is null, then connection was successfully established */
4394 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4395 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004396 if (!conn->err_code) {
4397#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4398 conn->err_code = CO_ER_SSL_HANDSHAKE;
4399#else
4400 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004401#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004402 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4403 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004404#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004405 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004406#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004407 if (empty_handshake) {
4408 if (!errno) {
4409 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4410 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4411 else
4412 conn->err_code = CO_ER_SSL_EMPTY;
4413 }
4414 else {
4415 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4416 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4417 else
4418 conn->err_code = CO_ER_SSL_ABORT;
4419 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004420 }
4421 else {
4422 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4423 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4424 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004425 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004426 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004427#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004428 }
Willy Tarreau89230192012-09-28 20:22:13 +02004429 goto out_error;
4430 }
Emeric Brun46591952012-05-18 15:47:34 +02004431 else {
4432 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004433 /* Note: OpenSSL may leave unread bytes in the socket's
4434 * buffer, causing an RST to be emitted upon close() on
4435 * TCP sockets. We first try to drain possibly pending
4436 * data to avoid this as much as possible.
4437 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004438 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004439 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004440 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4441 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004442 goto out_error;
4443 }
4444 }
4445
Emeric Brun674b7432012-11-08 19:21:55 +01004446reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004447 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004448 if (!SSL_session_reused(conn->xprt_ctx)) {
4449 if (objt_server(conn->target)) {
4450 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4451 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4452 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4453
Emeric Brun46591952012-05-18 15:47:34 +02004454 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004455 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004456 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004457 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4458 }
Emeric Brun46591952012-05-18 15:47:34 +02004459
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004460 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4461 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004462 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004463 else {
4464 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4465 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4466 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4467 }
Emeric Brun46591952012-05-18 15:47:34 +02004468 }
4469
4470 /* The connection is now established at both layers, it's time to leave */
4471 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4472 return 1;
4473
4474 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004475 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004476 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004477 ERR_clear_error();
4478
Emeric Brun9fa89732012-10-04 17:09:56 +02004479 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004480 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4481 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4482 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004483 }
4484
Emeric Brun46591952012-05-18 15:47:34 +02004485 /* Fail on all other handshake errors */
4486 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004487 if (!conn->err_code)
4488 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004489 return 0;
4490}
4491
4492/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004493 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004494 * buffer wraps, in which case a second call may be performed. The connection's
4495 * flags are updated with whatever special event is detected (error, read0,
4496 * empty). The caller is responsible for taking care of those events and
4497 * avoiding the call if inappropriate. The function does not call the
4498 * connection's polling update function, so the caller is responsible for this.
4499 */
4500static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4501{
4502 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004503 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004504
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004505 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004506 goto out_error;
4507
4508 if (conn->flags & CO_FL_HANDSHAKE)
4509 /* a handshake was requested */
4510 return 0;
4511
Willy Tarreauabf08d92014-01-14 11:31:27 +01004512 /* let's realign the buffer to optimize I/O */
4513 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004514 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004515
4516 /* read the largest possible block. For this, we perform only one call
4517 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4518 * in which case we accept to do it once again. A new attempt is made on
4519 * EINTR too.
4520 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004521 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004522 /* first check if we have some room after p+i */
4523 try = buf->data + buf->size - (buf->p + buf->i);
4524 /* otherwise continue between data and p-o */
4525 if (try <= 0) {
4526 try = buf->p - (buf->data + buf->o);
4527 if (try <= 0)
4528 break;
4529 }
4530 if (try > count)
4531 try = count;
4532
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004533 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004534 if (conn->flags & CO_FL_ERROR) {
4535 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004536 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004537 }
Emeric Brun46591952012-05-18 15:47:34 +02004538 if (ret > 0) {
4539 buf->i += ret;
4540 done += ret;
4541 if (ret < try)
4542 break;
4543 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004544 }
4545 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004546 ret = SSL_get_error(conn->xprt_ctx, ret);
4547 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004548 /* error on protocol or underlying transport */
4549 if ((ret != SSL_ERROR_SYSCALL)
4550 || (errno && (errno != EAGAIN)))
4551 conn->flags |= CO_FL_ERROR;
4552
Emeric Brun644cde02012-12-14 11:21:13 +01004553 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004554 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004555 ERR_clear_error();
4556 }
Emeric Brun46591952012-05-18 15:47:34 +02004557 goto read0;
4558 }
4559 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004560 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004561 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004562 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004563 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004564 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004565 break;
4566 }
4567 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004568 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4569 /* handshake is running, and it may need to re-enable read */
4570 conn->flags |= CO_FL_SSL_WAIT_HS;
4571 __conn_sock_want_recv(conn);
4572 break;
4573 }
Emeric Brun46591952012-05-18 15:47:34 +02004574 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004575 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004576 break;
4577 }
4578 /* otherwise it's a real error */
4579 goto out_error;
4580 }
4581 }
4582 return done;
4583
4584 read0:
4585 conn_sock_read0(conn);
4586 return done;
4587 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004588 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004589 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004590 ERR_clear_error();
4591
Emeric Brun46591952012-05-18 15:47:34 +02004592 conn->flags |= CO_FL_ERROR;
4593 return done;
4594}
4595
4596
4597/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004598 * <flags> may contain some CO_SFL_* flags to hint the system about other
4599 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004600 * Only one call to send() is performed, unless the buffer wraps, in which case
4601 * a second call may be performed. The connection's flags are updated with
4602 * whatever special event is detected (error, empty). The caller is responsible
4603 * for taking care of those events and avoiding the call if inappropriate. The
4604 * function does not call the connection's polling update function, so the caller
4605 * is responsible for this.
4606 */
4607static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4608{
4609 int ret, try, done;
4610
4611 done = 0;
4612
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004613 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004614 goto out_error;
4615
4616 if (conn->flags & CO_FL_HANDSHAKE)
4617 /* a handshake was requested */
4618 return 0;
4619
4620 /* send the largest possible block. For this we perform only one call
4621 * to send() unless the buffer wraps and we exactly fill the first hunk,
4622 * in which case we accept to do it once again.
4623 */
4624 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004625 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004626
Willy Tarreau7bed9452014-02-02 02:00:24 +01004627 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004628 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004629 global_ssl.max_record && try > global_ssl.max_record) {
4630 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004631 }
4632 else {
4633 /* we need to keep the information about the fact that
4634 * we're not limiting the upcoming send(), because if it
4635 * fails, we'll have to retry with at least as many data.
4636 */
4637 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4638 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004639
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004640 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004641
Emeric Brune1f38db2012-09-03 20:36:47 +02004642 if (conn->flags & CO_FL_ERROR) {
4643 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004644 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004645 }
Emeric Brun46591952012-05-18 15:47:34 +02004646 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004647 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4648
Emeric Brun46591952012-05-18 15:47:34 +02004649 buf->o -= ret;
4650 done += ret;
4651
Willy Tarreau5fb38032012-12-16 19:39:09 +01004652 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004653 /* optimize data alignment in the buffer */
4654 buf->p = buf->data;
4655
4656 /* if the system buffer is full, don't insist */
4657 if (ret < try)
4658 break;
4659 }
4660 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004661 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004662 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004663 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4664 /* handshake is running, and it may need to re-enable write */
4665 conn->flags |= CO_FL_SSL_WAIT_HS;
4666 __conn_sock_want_send(conn);
4667 break;
4668 }
Emeric Brun46591952012-05-18 15:47:34 +02004669 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004670 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004671 break;
4672 }
4673 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004674 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004675 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004676 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004677 break;
4678 }
4679 goto out_error;
4680 }
4681 }
4682 return done;
4683
4684 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004685 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004686 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004687 ERR_clear_error();
4688
Emeric Brun46591952012-05-18 15:47:34 +02004689 conn->flags |= CO_FL_ERROR;
4690 return done;
4691}
4692
Emeric Brun46591952012-05-18 15:47:34 +02004693static void ssl_sock_close(struct connection *conn) {
4694
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004695 if (conn->xprt_ctx) {
4696 SSL_free(conn->xprt_ctx);
4697 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004698 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004699 }
Emeric Brun46591952012-05-18 15:47:34 +02004700}
4701
4702/* This function tries to perform a clean shutdown on an SSL connection, and in
4703 * any case, flags the connection as reusable if no handshake was in progress.
4704 */
4705static void ssl_sock_shutw(struct connection *conn, int clean)
4706{
4707 if (conn->flags & CO_FL_HANDSHAKE)
4708 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004709 if (!clean)
4710 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004711 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004712 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004713 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004714 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004715 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004716 ERR_clear_error();
4717 }
Emeric Brun46591952012-05-18 15:47:34 +02004718}
4719
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004720/* used for logging, may be changed for a sample fetch later */
4721const char *ssl_sock_get_cipher_name(struct connection *conn)
4722{
4723 if (!conn->xprt && !conn->xprt_ctx)
4724 return NULL;
4725 return SSL_get_cipher_name(conn->xprt_ctx);
4726}
4727
4728/* used for logging, may be changed for a sample fetch later */
4729const char *ssl_sock_get_proto_version(struct connection *conn)
4730{
4731 if (!conn->xprt && !conn->xprt_ctx)
4732 return NULL;
4733 return SSL_get_version(conn->xprt_ctx);
4734}
4735
Willy Tarreau8d598402012-10-22 17:58:39 +02004736/* Extract a serial from a cert, and copy it to a chunk.
4737 * Returns 1 if serial is found and copied, 0 if no serial found and
4738 * -1 if output is not large enough.
4739 */
4740static int
4741ssl_sock_get_serial(X509 *crt, struct chunk *out)
4742{
4743 ASN1_INTEGER *serial;
4744
4745 serial = X509_get_serialNumber(crt);
4746 if (!serial)
4747 return 0;
4748
4749 if (out->size < serial->length)
4750 return -1;
4751
4752 memcpy(out->str, serial->data, serial->length);
4753 out->len = serial->length;
4754 return 1;
4755}
4756
Emeric Brun43e79582014-10-29 19:03:26 +01004757/* Extract a cert to der, and copy it to a chunk.
4758 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4759 * -1 if output is not large enough.
4760 */
4761static int
4762ssl_sock_crt2der(X509 *crt, struct chunk *out)
4763{
4764 int len;
4765 unsigned char *p = (unsigned char *)out->str;;
4766
4767 len =i2d_X509(crt, NULL);
4768 if (len <= 0)
4769 return 1;
4770
4771 if (out->size < len)
4772 return -1;
4773
4774 i2d_X509(crt,&p);
4775 out->len = len;
4776 return 1;
4777}
4778
Emeric Brunce5ad802012-10-22 14:11:22 +02004779
4780/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4781 * Returns 1 if serial is found and copied, 0 if no valid time found
4782 * and -1 if output is not large enough.
4783 */
4784static int
4785ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4786{
4787 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4788 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4789
4790 if (gentm->length < 12)
4791 return 0;
4792 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4793 return 0;
4794 if (out->size < gentm->length-2)
4795 return -1;
4796
4797 memcpy(out->str, gentm->data+2, gentm->length-2);
4798 out->len = gentm->length-2;
4799 return 1;
4800 }
4801 else if (tm->type == V_ASN1_UTCTIME) {
4802 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4803
4804 if (utctm->length < 10)
4805 return 0;
4806 if (utctm->data[0] >= 0x35)
4807 return 0;
4808 if (out->size < utctm->length)
4809 return -1;
4810
4811 memcpy(out->str, utctm->data, utctm->length);
4812 out->len = utctm->length;
4813 return 1;
4814 }
4815
4816 return 0;
4817}
4818
Emeric Brun87855892012-10-17 17:39:35 +02004819/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4820 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4821 */
4822static int
4823ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4824{
4825 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004826 ASN1_OBJECT *obj;
4827 ASN1_STRING *data;
4828 const unsigned char *data_ptr;
4829 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004830 int i, j, n;
4831 int cur = 0;
4832 const char *s;
4833 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004834 int name_count;
4835
4836 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004837
4838 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004839 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004840 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004841 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004842 else
4843 j = i;
4844
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004845 ne = X509_NAME_get_entry(a, j);
4846 obj = X509_NAME_ENTRY_get_object(ne);
4847 data = X509_NAME_ENTRY_get_data(ne);
4848 data_ptr = ASN1_STRING_get0_data(data);
4849 data_len = ASN1_STRING_length(data);
4850 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004851 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004852 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004853 s = tmp;
4854 }
4855
4856 if (chunk_strcasecmp(entry, s) != 0)
4857 continue;
4858
4859 if (pos < 0)
4860 cur--;
4861 else
4862 cur++;
4863
4864 if (cur != pos)
4865 continue;
4866
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004867 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004868 return -1;
4869
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004870 memcpy(out->str, data_ptr, data_len);
4871 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004872 return 1;
4873 }
4874
4875 return 0;
4876
4877}
4878
4879/* Extract and format full DN from a X509_NAME and copy result into a chunk
4880 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4881 */
4882static int
4883ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4884{
4885 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004886 ASN1_OBJECT *obj;
4887 ASN1_STRING *data;
4888 const unsigned char *data_ptr;
4889 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004890 int i, n, ln;
4891 int l = 0;
4892 const char *s;
4893 char *p;
4894 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004895 int name_count;
4896
4897
4898 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004899
4900 out->len = 0;
4901 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004902 for (i = 0; i < name_count; i++) {
4903 ne = X509_NAME_get_entry(a, i);
4904 obj = X509_NAME_ENTRY_get_object(ne);
4905 data = X509_NAME_ENTRY_get_data(ne);
4906 data_ptr = ASN1_STRING_get0_data(data);
4907 data_len = ASN1_STRING_length(data);
4908 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004909 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004910 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004911 s = tmp;
4912 }
4913 ln = strlen(s);
4914
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004915 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004916 if (l > out->size)
4917 return -1;
4918 out->len = l;
4919
4920 *(p++)='/';
4921 memcpy(p, s, ln);
4922 p += ln;
4923 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004924 memcpy(p, data_ptr, data_len);
4925 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004926 }
4927
4928 if (!out->len)
4929 return 0;
4930
4931 return 1;
4932}
4933
David Safb76832014-05-08 23:42:08 -04004934char *ssl_sock_get_version(struct connection *conn)
4935{
4936 if (!ssl_sock_is_ssl(conn))
4937 return NULL;
4938
4939 return (char *)SSL_get_version(conn->xprt_ctx);
4940}
4941
Willy Tarreau119a4082016-12-22 21:58:38 +01004942/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4943 * to disable SNI.
4944 */
Willy Tarreau63076412015-07-10 11:33:32 +02004945void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4946{
4947#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004948 char *prev_name;
4949
Willy Tarreau63076412015-07-10 11:33:32 +02004950 if (!ssl_sock_is_ssl(conn))
4951 return;
4952
Willy Tarreau119a4082016-12-22 21:58:38 +01004953 /* if the SNI changes, we must destroy the reusable context so that a
4954 * new connection will present a new SNI. As an optimization we could
4955 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4956 * server.
4957 */
4958 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4959 if ((!prev_name && hostname) ||
4960 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4961 SSL_set_session(conn->xprt_ctx, NULL);
4962
Willy Tarreau63076412015-07-10 11:33:32 +02004963 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4964#endif
4965}
4966
Emeric Brun0abf8362014-06-24 18:26:41 +02004967/* Extract peer certificate's common name into the chunk dest
4968 * Returns
4969 * the len of the extracted common name
4970 * or 0 if no CN found in DN
4971 * or -1 on error case (i.e. no peer certificate)
4972 */
4973int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004974{
4975 X509 *crt = NULL;
4976 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004977 const char find_cn[] = "CN";
4978 const struct chunk find_cn_chunk = {
4979 .str = (char *)&find_cn,
4980 .len = sizeof(find_cn)-1
4981 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004982 int result = -1;
David Safb76832014-05-08 23:42:08 -04004983
4984 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004985 goto out;
David Safb76832014-05-08 23:42:08 -04004986
4987 /* SSL_get_peer_certificate, it increase X509 * ref count */
4988 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4989 if (!crt)
4990 goto out;
4991
4992 name = X509_get_subject_name(crt);
4993 if (!name)
4994 goto out;
David Safb76832014-05-08 23:42:08 -04004995
Emeric Brun0abf8362014-06-24 18:26:41 +02004996 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4997out:
David Safb76832014-05-08 23:42:08 -04004998 if (crt)
4999 X509_free(crt);
5000
5001 return result;
5002}
5003
Dave McCowan328fb582014-07-30 10:39:13 -04005004/* returns 1 if client passed a certificate for this session, 0 if not */
5005int ssl_sock_get_cert_used_sess(struct connection *conn)
5006{
5007 X509 *crt = NULL;
5008
5009 if (!ssl_sock_is_ssl(conn))
5010 return 0;
5011
5012 /* SSL_get_peer_certificate, it increase X509 * ref count */
5013 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5014 if (!crt)
5015 return 0;
5016
5017 X509_free(crt);
5018 return 1;
5019}
5020
5021/* returns 1 if client passed a certificate for this connection, 0 if not */
5022int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04005023{
5024 if (!ssl_sock_is_ssl(conn))
5025 return 0;
5026
5027 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
5028}
5029
5030/* returns result from SSL verify */
5031unsigned int ssl_sock_get_verify_result(struct connection *conn)
5032{
5033 if (!ssl_sock_is_ssl(conn))
5034 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
5035
5036 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
5037}
5038
Willy Tarreau7875d092012-09-10 08:20:03 +02005039/***** Below are some sample fetching functions for ACL/patterns *****/
5040
Emeric Brune64aef12012-09-21 13:15:06 +02005041/* boolean, returns true if client cert was present */
5042static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005043smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02005044{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005045 struct connection *conn;
5046
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005047 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005048 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02005049 return 0;
5050
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005051 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02005052 smp->flags |= SMP_F_MAY_CHANGE;
5053 return 0;
5054 }
5055
5056 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005057 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005058 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02005059
5060 return 1;
5061}
5062
Emeric Brun43e79582014-10-29 19:03:26 +01005063/* binary, returns a certificate in a binary chunk (der/raw).
5064 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5065 * should be use.
5066 */
5067static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005068smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01005069{
5070 int cert_peer = (kw[4] == 'c') ? 1 : 0;
5071 X509 *crt = NULL;
5072 int ret = 0;
5073 struct chunk *smp_trash;
5074 struct connection *conn;
5075
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005076 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01005077 if (!conn || conn->xprt != &ssl_sock)
5078 return 0;
5079
5080 if (!(conn->flags & CO_FL_CONNECTED)) {
5081 smp->flags |= SMP_F_MAY_CHANGE;
5082 return 0;
5083 }
5084
5085 if (cert_peer)
5086 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5087 else
5088 crt = SSL_get_certificate(conn->xprt_ctx);
5089
5090 if (!crt)
5091 goto out;
5092
5093 smp_trash = get_trash_chunk();
5094 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
5095 goto out;
5096
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005097 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005098 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01005099 ret = 1;
5100out:
5101 /* SSL_get_peer_certificate, it increase X509 * ref count */
5102 if (cert_peer && crt)
5103 X509_free(crt);
5104 return ret;
5105}
5106
Emeric Brunba841a12014-04-30 17:05:08 +02005107/* binary, returns serial of certificate in a binary chunk.
5108 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5109 * should be use.
5110 */
Willy Tarreau8d598402012-10-22 17:58:39 +02005111static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005112smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02005113{
Emeric Brunba841a12014-04-30 17:05:08 +02005114 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02005115 X509 *crt = NULL;
5116 int ret = 0;
5117 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005118 struct connection *conn;
5119
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005120 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005121 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02005122 return 0;
5123
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005124 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02005125 smp->flags |= SMP_F_MAY_CHANGE;
5126 return 0;
5127 }
5128
Emeric Brunba841a12014-04-30 17:05:08 +02005129 if (cert_peer)
5130 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5131 else
5132 crt = SSL_get_certificate(conn->xprt_ctx);
5133
Willy Tarreau8d598402012-10-22 17:58:39 +02005134 if (!crt)
5135 goto out;
5136
Willy Tarreau47ca5452012-12-23 20:22:19 +01005137 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005138 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5139 goto out;
5140
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005141 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005142 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005143 ret = 1;
5144out:
Emeric Brunba841a12014-04-30 17:05:08 +02005145 /* SSL_get_peer_certificate, it increase X509 * ref count */
5146 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005147 X509_free(crt);
5148 return ret;
5149}
Emeric Brune64aef12012-09-21 13:15:06 +02005150
Emeric Brunba841a12014-04-30 17:05:08 +02005151/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5152 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5153 * should be use.
5154 */
James Votha051b4a2013-05-14 20:37:59 +02005155static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005156smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005157{
Emeric Brunba841a12014-04-30 17:05:08 +02005158 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005159 X509 *crt = NULL;
5160 const EVP_MD *digest;
5161 int ret = 0;
5162 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005163 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005164
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005165 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005166 if (!conn || conn->xprt != &ssl_sock)
5167 return 0;
5168
5169 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005170 smp->flags |= SMP_F_MAY_CHANGE;
5171 return 0;
5172 }
5173
Emeric Brunba841a12014-04-30 17:05:08 +02005174 if (cert_peer)
5175 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5176 else
5177 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005178 if (!crt)
5179 goto out;
5180
5181 smp_trash = get_trash_chunk();
5182 digest = EVP_sha1();
5183 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5184
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005185 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005186 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005187 ret = 1;
5188out:
Emeric Brunba841a12014-04-30 17:05:08 +02005189 /* SSL_get_peer_certificate, it increase X509 * ref count */
5190 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005191 X509_free(crt);
5192 return ret;
5193}
5194
Emeric Brunba841a12014-04-30 17:05:08 +02005195/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5196 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5197 * should be use.
5198 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005199static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005200smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005201{
Emeric Brunba841a12014-04-30 17:05:08 +02005202 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005203 X509 *crt = NULL;
5204 int ret = 0;
5205 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005206 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005207
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005208 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005209 if (!conn || conn->xprt != &ssl_sock)
5210 return 0;
5211
5212 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005213 smp->flags |= SMP_F_MAY_CHANGE;
5214 return 0;
5215 }
5216
Emeric Brunba841a12014-04-30 17:05:08 +02005217 if (cert_peer)
5218 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5219 else
5220 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005221 if (!crt)
5222 goto out;
5223
Willy Tarreau47ca5452012-12-23 20:22:19 +01005224 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005225 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5226 goto out;
5227
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005228 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005229 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005230 ret = 1;
5231out:
Emeric Brunba841a12014-04-30 17:05:08 +02005232 /* SSL_get_peer_certificate, it increase X509 * ref count */
5233 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005234 X509_free(crt);
5235 return ret;
5236}
5237
Emeric Brunba841a12014-04-30 17:05:08 +02005238/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5239 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5240 * should be use.
5241 */
Emeric Brun87855892012-10-17 17:39:35 +02005242static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005243smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005244{
Emeric Brunba841a12014-04-30 17:05:08 +02005245 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005246 X509 *crt = NULL;
5247 X509_NAME *name;
5248 int ret = 0;
5249 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005250 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005251
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005252 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005253 if (!conn || conn->xprt != &ssl_sock)
5254 return 0;
5255
5256 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005257 smp->flags |= SMP_F_MAY_CHANGE;
5258 return 0;
5259 }
5260
Emeric Brunba841a12014-04-30 17:05:08 +02005261 if (cert_peer)
5262 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5263 else
5264 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005265 if (!crt)
5266 goto out;
5267
5268 name = X509_get_issuer_name(crt);
5269 if (!name)
5270 goto out;
5271
Willy Tarreau47ca5452012-12-23 20:22:19 +01005272 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005273 if (args && args[0].type == ARGT_STR) {
5274 int pos = 1;
5275
5276 if (args[1].type == ARGT_SINT)
5277 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005278
5279 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5280 goto out;
5281 }
5282 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5283 goto out;
5284
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005285 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005286 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005287 ret = 1;
5288out:
Emeric Brunba841a12014-04-30 17:05:08 +02005289 /* SSL_get_peer_certificate, it increase X509 * ref count */
5290 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005291 X509_free(crt);
5292 return ret;
5293}
5294
Emeric Brunba841a12014-04-30 17:05:08 +02005295/* string, returns notbefore date in ASN1_UTCTIME format.
5296 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5297 * should be use.
5298 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005299static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005300smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005301{
Emeric Brunba841a12014-04-30 17:05:08 +02005302 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005303 X509 *crt = NULL;
5304 int ret = 0;
5305 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005306 struct connection *conn;
5307
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005308 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005309 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005310 return 0;
5311
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005312 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005313 smp->flags |= SMP_F_MAY_CHANGE;
5314 return 0;
5315 }
5316
Emeric Brunba841a12014-04-30 17:05:08 +02005317 if (cert_peer)
5318 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5319 else
5320 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005321 if (!crt)
5322 goto out;
5323
Willy Tarreau47ca5452012-12-23 20:22:19 +01005324 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005325 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5326 goto out;
5327
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005328 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005329 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005330 ret = 1;
5331out:
Emeric Brunba841a12014-04-30 17:05:08 +02005332 /* SSL_get_peer_certificate, it increase X509 * ref count */
5333 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005334 X509_free(crt);
5335 return ret;
5336}
5337
Emeric Brunba841a12014-04-30 17:05:08 +02005338/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5339 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5340 * should be use.
5341 */
Emeric Brun87855892012-10-17 17:39:35 +02005342static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005343smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005344{
Emeric Brunba841a12014-04-30 17:05:08 +02005345 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005346 X509 *crt = NULL;
5347 X509_NAME *name;
5348 int ret = 0;
5349 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005350 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005351
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005352 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005353 if (!conn || conn->xprt != &ssl_sock)
5354 return 0;
5355
5356 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005357 smp->flags |= SMP_F_MAY_CHANGE;
5358 return 0;
5359 }
5360
Emeric Brunba841a12014-04-30 17:05:08 +02005361 if (cert_peer)
5362 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5363 else
5364 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005365 if (!crt)
5366 goto out;
5367
5368 name = X509_get_subject_name(crt);
5369 if (!name)
5370 goto out;
5371
Willy Tarreau47ca5452012-12-23 20:22:19 +01005372 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005373 if (args && args[0].type == ARGT_STR) {
5374 int pos = 1;
5375
5376 if (args[1].type == ARGT_SINT)
5377 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005378
5379 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5380 goto out;
5381 }
5382 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5383 goto out;
5384
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005385 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005386 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005387 ret = 1;
5388out:
Emeric Brunba841a12014-04-30 17:05:08 +02005389 /* SSL_get_peer_certificate, it increase X509 * ref count */
5390 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005391 X509_free(crt);
5392 return ret;
5393}
Emeric Brun9143d372012-12-20 15:44:16 +01005394
5395/* integer, returns true if current session use a client certificate */
5396static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005397smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005398{
5399 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005400 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005401
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005402 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005403 if (!conn || conn->xprt != &ssl_sock)
5404 return 0;
5405
5406 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005407 smp->flags |= SMP_F_MAY_CHANGE;
5408 return 0;
5409 }
5410
5411 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005412 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005413 if (crt) {
5414 X509_free(crt);
5415 }
5416
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005417 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005418 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005419 return 1;
5420}
5421
Emeric Brunba841a12014-04-30 17:05:08 +02005422/* integer, returns the certificate version
5423 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5424 * should be use.
5425 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005426static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005427smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005428{
Emeric Brunba841a12014-04-30 17:05:08 +02005429 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005430 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005431 struct connection *conn;
5432
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005433 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005434 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005435 return 0;
5436
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005437 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005438 smp->flags |= SMP_F_MAY_CHANGE;
5439 return 0;
5440 }
5441
Emeric Brunba841a12014-04-30 17:05:08 +02005442 if (cert_peer)
5443 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5444 else
5445 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005446 if (!crt)
5447 return 0;
5448
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005449 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005450 /* SSL_get_peer_certificate increase X509 * ref count */
5451 if (cert_peer)
5452 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005453 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005454
5455 return 1;
5456}
5457
Emeric Brunba841a12014-04-30 17:05:08 +02005458/* string, returns the certificate's signature algorithm.
5459 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5460 * should be use.
5461 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005462static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005463smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005464{
Emeric Brunba841a12014-04-30 17:05:08 +02005465 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005466 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005467 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005468 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005469 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005470
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005471 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005472 if (!conn || conn->xprt != &ssl_sock)
5473 return 0;
5474
5475 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005476 smp->flags |= SMP_F_MAY_CHANGE;
5477 return 0;
5478 }
5479
Emeric Brunba841a12014-04-30 17:05:08 +02005480 if (cert_peer)
5481 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5482 else
5483 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005484 if (!crt)
5485 return 0;
5486
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005487 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5488 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005489
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005490 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5491 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005492 /* SSL_get_peer_certificate increase X509 * ref count */
5493 if (cert_peer)
5494 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005495 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005496 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005497
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005498 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005499 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005500 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005501 /* SSL_get_peer_certificate increase X509 * ref count */
5502 if (cert_peer)
5503 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005504
5505 return 1;
5506}
5507
Emeric Brunba841a12014-04-30 17:05:08 +02005508/* string, returns the certificate's key algorithm.
5509 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5510 * should be use.
5511 */
Emeric Brun521a0112012-10-22 12:22:55 +02005512static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005513smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005514{
Emeric Brunba841a12014-04-30 17:05:08 +02005515 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005516 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005517 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005518 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005519 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005520
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005521 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005522 if (!conn || conn->xprt != &ssl_sock)
5523 return 0;
5524
5525 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005526 smp->flags |= SMP_F_MAY_CHANGE;
5527 return 0;
5528 }
5529
Emeric Brunba841a12014-04-30 17:05:08 +02005530 if (cert_peer)
5531 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5532 else
5533 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005534 if (!crt)
5535 return 0;
5536
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005537 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5538 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005539
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005540 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5541 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005542 /* SSL_get_peer_certificate increase X509 * ref count */
5543 if (cert_peer)
5544 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005545 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005546 }
Emeric Brun521a0112012-10-22 12:22:55 +02005547
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005548 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005549 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005550 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005551 if (cert_peer)
5552 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005553
5554 return 1;
5555}
5556
Emeric Brun645ae792014-04-30 14:21:06 +02005557/* boolean, returns true if front conn. transport layer is SSL.
5558 * This function is also usable on backend conn if the fetch keyword 5th
5559 * char is 'b'.
5560 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005561static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005562smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005563{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005564 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5565 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005566
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005567 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005568 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005569 return 1;
5570}
5571
Emeric Brun2525b6b2012-10-18 15:59:43 +02005572/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005573static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005574smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005575{
5576#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005577 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005578
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005579 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005580 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005581 conn->xprt_ctx &&
5582 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005583 return 1;
5584#else
5585 return 0;
5586#endif
5587}
5588
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005589/* boolean, returns true if client session has been resumed */
5590static int
5591smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5592{
5593 struct connection *conn = objt_conn(smp->sess->origin);
5594
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005595 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005596 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005597 conn->xprt_ctx &&
5598 SSL_session_reused(conn->xprt_ctx);
5599 return 1;
5600}
5601
Emeric Brun645ae792014-04-30 14:21:06 +02005602/* string, returns the used cipher if front conn. transport layer is SSL.
5603 * This function is also usable on backend conn if the fetch keyword 5th
5604 * char is 'b'.
5605 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005606static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005607smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005608{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005609 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5610 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005611
Willy Tarreaube508f12016-03-10 11:47:01 +01005612 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005613 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005614 return 0;
5615
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005616 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5617 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005618 return 0;
5619
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005620 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005621 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005622 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005623
5624 return 1;
5625}
5626
Emeric Brun645ae792014-04-30 14:21:06 +02005627/* integer, returns the algoritm's keysize if front conn. transport layer
5628 * is SSL.
5629 * This function is also usable on backend conn if the fetch keyword 5th
5630 * char is 'b'.
5631 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005632static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005633smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005634{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005635 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5636 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005637
Willy Tarreaue237fe12016-03-10 17:05:28 +01005638 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005639
Emeric Brun589fcad2012-10-16 14:13:26 +02005640 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005641 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005642 return 0;
5643
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005644 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005645 return 0;
5646
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005647 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005648 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005649
5650 return 1;
5651}
5652
Emeric Brun645ae792014-04-30 14:21:06 +02005653/* integer, returns the used keysize if front conn. transport layer is SSL.
5654 * This function is also usable on backend conn if the fetch keyword 5th
5655 * char is 'b'.
5656 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005657static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005658smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005659{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005660 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5661 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005662
Emeric Brun589fcad2012-10-16 14:13:26 +02005663 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005664 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5665 return 0;
5666
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005667 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5668 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005669 return 0;
5670
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005671 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005672
5673 return 1;
5674}
5675
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005676#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005677static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005678smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005679{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005680 struct connection *conn;
5681
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005682 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005683 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005684
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005685 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005686 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5687 return 0;
5688
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005689 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005690 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005691 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005692
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005693 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005694 return 0;
5695
5696 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005697}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005698#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005699
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005700#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005701static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005702smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005703{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005704 struct connection *conn;
5705
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005706 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005707 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005708
Willy Tarreaue26bf052015-05-12 10:30:12 +02005709 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005710 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005711 return 0;
5712
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005713 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005714 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005715 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005716
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005717 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005718 return 0;
5719
5720 return 1;
5721}
5722#endif
5723
Emeric Brun645ae792014-04-30 14:21:06 +02005724/* string, returns the used protocol if front conn. transport layer is SSL.
5725 * This function is also usable on backend conn if the fetch keyword 5th
5726 * char is 'b'.
5727 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005728static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005729smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005730{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005731 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5732 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005733
Emeric Brun589fcad2012-10-16 14:13:26 +02005734 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005735 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5736 return 0;
5737
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005738 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5739 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005740 return 0;
5741
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005742 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005743 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005744 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005745
5746 return 1;
5747}
5748
Willy Tarreau87b09662015-04-03 00:22:06 +02005749/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005750 * This function is also usable on backend conn if the fetch keyword 5th
5751 * char is 'b'.
5752 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005753static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005754smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005755{
5756#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005757 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5758 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005759
Willy Tarreaue237fe12016-03-10 17:05:28 +01005760 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005761
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005762 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005763 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005764
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005765 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5766 return 0;
5767
Willy Tarreau192252e2015-04-04 01:47:55 +02005768 ssl_sess = SSL_get_session(conn->xprt_ctx);
5769 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005770 return 0;
5771
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005772 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5773 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005774 return 0;
5775
5776 return 1;
5777#else
5778 return 0;
5779#endif
5780}
5781
5782static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005783smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005784{
5785#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005786 struct connection *conn;
5787
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005788 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005789 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005790
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005791 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005792 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5793 return 0;
5794
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005795 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5796 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005797 return 0;
5798
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005799 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005800 return 1;
5801#else
5802 return 0;
5803#endif
5804}
5805
David Sc1ad52e2014-04-08 18:48:47 -04005806static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005807smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
5808{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005809 struct connection *conn;
5810 struct ssl_capture *capture;
5811
5812 conn = objt_conn(smp->sess->origin);
5813 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5814 return 0;
5815
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005816 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005817 if (!capture)
5818 return 0;
5819
5820 smp->flags = SMP_F_CONST;
5821 smp->data.type = SMP_T_BIN;
5822 smp->data.u.str.str = capture->ciphersuite;
5823 smp->data.u.str.len = capture->ciphersuite_len;
5824 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005825}
5826
5827static int
5828smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
5829{
5830 struct chunk *data;
5831
5832 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5833 return 0;
5834
5835 data = get_trash_chunk();
5836 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
5837 smp->data.type = SMP_T_BIN;
5838 smp->data.u.str = *data;
5839 return 1;
5840}
5841
5842static int
5843smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
5844{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005845 struct connection *conn;
5846 struct ssl_capture *capture;
5847
5848 conn = objt_conn(smp->sess->origin);
5849 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5850 return 0;
5851
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005852 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005853 if (!capture)
5854 return 0;
5855
5856 smp->data.type = SMP_T_SINT;
5857 smp->data.u.sint = capture->xxh64;
5858 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005859}
5860
5861static int
5862smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
5863{
5864#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
5865 struct chunk *data;
5866 SSL_CIPHER cipher;
5867 int i;
5868 const char *str;
5869 unsigned char *bin;
5870
5871 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5872 return 0;
5873
5874 /* The cipher algorith must not be SSL_SSLV2, because this
5875 * SSL version seems to not have the same cipher encoding,
5876 * and it is not supported by OpenSSL. Unfortunately, the
5877 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
5878 * with standard defines. We just set the variable to 0,
5879 * ensure that the match with SSL_SSLV2 fails.
5880 */
5881 cipher.algorithm_ssl = 0;
5882
5883 data = get_trash_chunk();
5884 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
5885 bin = (unsigned char *)smp->data.u.str.str + i;
5886 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
5887 str = SSL_CIPHER_standard_name(&cipher);
5888 if (!str || strcmp(str, "UNKNOWN") == 0)
5889 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
5890 else
5891 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
5892 }
5893 smp->data.type = SMP_T_STR;
5894 smp->data.u.str = *data;
5895 return 1;
5896#else
5897 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
5898#endif
5899}
5900
5901static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005902smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005903{
5904#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005905 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5906 smp->strm ? smp->strm->si[1].end : NULL);
5907
David Sc1ad52e2014-04-08 18:48:47 -04005908 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005909 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005910
5911 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005912 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5913 return 0;
5914
5915 if (!(conn->flags & CO_FL_CONNECTED)) {
5916 smp->flags |= SMP_F_MAY_CHANGE;
5917 return 0;
5918 }
5919
5920 finished_trash = get_trash_chunk();
5921 if (!SSL_session_reused(conn->xprt_ctx))
5922 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5923 else
5924 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5925
5926 if (!finished_len)
5927 return 0;
5928
Emeric Brunb73a9b02014-04-30 18:49:19 +02005929 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005930 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005931 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005932
5933 return 1;
5934#else
5935 return 0;
5936#endif
5937}
5938
Emeric Brun2525b6b2012-10-18 15:59:43 +02005939/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005940static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005941smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005942{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005943 struct connection *conn;
5944
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005945 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005946 if (!conn || conn->xprt != &ssl_sock)
5947 return 0;
5948
5949 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005950 smp->flags = SMP_F_MAY_CHANGE;
5951 return 0;
5952 }
5953
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005954 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005955 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005956 smp->flags = 0;
5957
5958 return 1;
5959}
5960
Emeric Brun2525b6b2012-10-18 15:59:43 +02005961/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005962static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005963smp_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 +02005964{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005965 struct connection *conn;
5966
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005967 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005968 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005969 return 0;
5970
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005971 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005972 smp->flags = SMP_F_MAY_CHANGE;
5973 return 0;
5974 }
5975
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005976 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005977 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005978 smp->flags = 0;
5979
5980 return 1;
5981}
5982
Emeric Brun2525b6b2012-10-18 15:59:43 +02005983/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005984static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005985smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005986{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005987 struct connection *conn;
5988
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005989 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005990 if (!conn || conn->xprt != &ssl_sock)
5991 return 0;
5992
5993 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005994 smp->flags = SMP_F_MAY_CHANGE;
5995 return 0;
5996 }
5997
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005998 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005999 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02006000 smp->flags = 0;
6001
6002 return 1;
6003}
6004
Emeric Brun2525b6b2012-10-18 15:59:43 +02006005/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006006static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02006007smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006008{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006009 struct connection *conn;
6010
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02006011 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006012 if (!conn || conn->xprt != &ssl_sock)
6013 return 0;
6014
6015 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006016 smp->flags = SMP_F_MAY_CHANGE;
6017 return 0;
6018 }
6019
Willy Tarreaub363a1f2013-10-01 10:45:07 +02006020 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006021 return 0;
6022
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02006023 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02006024 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006025 smp->flags = 0;
6026
6027 return 1;
6028}
6029
Emeric Brunfb510ea2012-10-05 12:00:26 +02006030/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006031static 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 +02006032{
6033 if (!*args[cur_arg + 1]) {
6034 if (err)
6035 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6036 return ERR_ALERT | ERR_FATAL;
6037 }
6038
Willy Tarreauef934602016-12-22 23:12:01 +01006039 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6040 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006041 else
6042 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006043
Emeric Brund94b3fe2012-09-20 18:23:56 +02006044 return 0;
6045}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006046static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6047{
6048 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
6049}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006050
Christopher Faulet31af49d2015-06-09 17:29:50 +02006051/* parse the "ca-sign-file" bind keyword */
6052static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6053{
6054 if (!*args[cur_arg + 1]) {
6055 if (err)
6056 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6057 return ERR_ALERT | ERR_FATAL;
6058 }
6059
Willy Tarreauef934602016-12-22 23:12:01 +01006060 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6061 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02006062 else
6063 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
6064
6065 return 0;
6066}
6067
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006068/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006069static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6070{
6071 if (!*args[cur_arg + 1]) {
6072 if (err)
6073 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
6074 return ERR_ALERT | ERR_FATAL;
6075 }
6076 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
6077 return 0;
6078}
6079
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006080/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006081static 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 +02006082{
6083 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006084 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006085 return ERR_ALERT | ERR_FATAL;
6086 }
6087
Emeric Brun76d88952012-10-05 15:47:31 +02006088 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02006089 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006090 return 0;
6091}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006092static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6093{
6094 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
6095}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006096/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006097static 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 +02006098{
Willy Tarreau38011032013-08-13 16:59:39 +02006099 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02006100
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006101 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006102 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006103 return ERR_ALERT | ERR_FATAL;
6104 }
6105
Willy Tarreauef934602016-12-22 23:12:01 +01006106 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
6107 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02006108 memprintf(err, "'%s' : path too long", args[cur_arg]);
6109 return ERR_ALERT | ERR_FATAL;
6110 }
Willy Tarreauef934602016-12-22 23:12:01 +01006111 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01006112 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02006113 return ERR_ALERT | ERR_FATAL;
6114
6115 return 0;
6116 }
6117
Willy Tarreau03209342016-12-22 17:08:28 +01006118 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006119 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006120
6121 return 0;
6122}
6123
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006124/* parse the "crt-list" bind keyword */
6125static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6126{
6127 if (!*args[cur_arg + 1]) {
6128 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
6129 return ERR_ALERT | ERR_FATAL;
6130 }
6131
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006132 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006133 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006134 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006135 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006136
6137 return 0;
6138}
6139
Emeric Brunfb510ea2012-10-05 12:00:26 +02006140/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006141static 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 +02006142{
Emeric Brun051cdab2012-10-02 19:25:50 +02006143#ifndef X509_V_FLAG_CRL_CHECK
6144 if (err)
6145 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6146 return ERR_ALERT | ERR_FATAL;
6147#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006148 if (!*args[cur_arg + 1]) {
6149 if (err)
6150 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6151 return ERR_ALERT | ERR_FATAL;
6152 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006153
Willy Tarreauef934602016-12-22 23:12:01 +01006154 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6155 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006156 else
6157 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006158
Emeric Brun2b58d042012-09-20 17:10:03 +02006159 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006160#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006161}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006162static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6163{
6164 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6165}
Emeric Brun2b58d042012-09-20 17:10:03 +02006166
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006167/* parse the "curves" bind keyword keyword */
6168static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6169{
6170#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6171 if (!*args[cur_arg + 1]) {
6172 if (err)
6173 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6174 return ERR_ALERT | ERR_FATAL;
6175 }
6176 conf->curves = strdup(args[cur_arg + 1]);
6177 return 0;
6178#else
6179 if (err)
6180 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6181 return ERR_ALERT | ERR_FATAL;
6182#endif
6183}
6184static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6185{
6186 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6187}
6188
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006189/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006190static 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 +02006191{
6192#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6193 if (err)
6194 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6195 return ERR_ALERT | ERR_FATAL;
6196#elif defined(OPENSSL_NO_ECDH)
6197 if (err)
6198 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6199 return ERR_ALERT | ERR_FATAL;
6200#else
6201 if (!*args[cur_arg + 1]) {
6202 if (err)
6203 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6204 return ERR_ALERT | ERR_FATAL;
6205 }
6206
6207 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006208
6209 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006210#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006211}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006212static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6213{
6214 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6215}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006216
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006217/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006218static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6219{
6220 int code;
6221 char *p = args[cur_arg + 1];
6222 unsigned long long *ignerr = &conf->crt_ignerr;
6223
6224 if (!*p) {
6225 if (err)
6226 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6227 return ERR_ALERT | ERR_FATAL;
6228 }
6229
6230 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6231 ignerr = &conf->ca_ignerr;
6232
6233 if (strcmp(p, "all") == 0) {
6234 *ignerr = ~0ULL;
6235 return 0;
6236 }
6237
6238 while (p) {
6239 code = atoi(p);
6240 if ((code <= 0) || (code > 63)) {
6241 if (err)
6242 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6243 args[cur_arg], code, args[cur_arg + 1]);
6244 return ERR_ALERT | ERR_FATAL;
6245 }
6246 *ignerr |= 1ULL << code;
6247 p = strchr(p, ',');
6248 if (p)
6249 p++;
6250 }
6251
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006252 return 0;
6253}
6254
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006255/* parse tls_method_options "no-xxx" and "force-xxx" */
6256static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006257{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006258 uint16_t v;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006259 char *p;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006260 p = strchr(arg, '-');
6261 if (!p)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006262 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006263 p++;
6264 if (!strcmp(p, "sslv3"))
6265 v = CONF_SSLV3;
6266 else if (!strcmp(p, "tlsv10"))
6267 v = CONF_TLSV10;
6268 else if (!strcmp(p, "tlsv11"))
6269 v = CONF_TLSV11;
6270 else if (!strcmp(p, "tlsv12"))
6271 v = CONF_TLSV12;
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02006272 else if (!strcmp(p, "tlsv13"))
6273 v = CONF_TLSV13;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006274 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006275 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006276 if (!strncmp(arg, "no-", 3))
6277 methods->flags |= methodVersions[v].flag;
6278 else if (!strncmp(arg, "force-", 6))
6279 methods->min = methods->max = v;
6280 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006281 goto fail;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006282 return 0;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006283 fail:
6284 if (err)
6285 memprintf(err, "'%s' : option not implemented", arg);
6286 return ERR_ALERT | ERR_FATAL;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006287}
6288
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006289static 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 +02006290{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006291 return parse_tls_method_options(args[cur_arg], &conf->ssl_methods, err);
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006292}
6293
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006294static 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 +02006295{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006296 return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
6297}
6298
6299/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
6300static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
6301{
6302 uint16_t i, v = 0;
6303 char *argv = args[cur_arg + 1];
6304 if (!*argv) {
6305 if (err)
6306 memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
6307 return ERR_ALERT | ERR_FATAL;
6308 }
6309 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
6310 if (!strcmp(argv, methodVersions[i].name))
6311 v = i;
6312 if (!v) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006313 if (err)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006314 memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006315 return ERR_ALERT | ERR_FATAL;
6316 }
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006317 if (!strcmp("ssl-min-ver", args[cur_arg]))
6318 methods->min = v;
6319 else if (!strcmp("ssl-max-ver", args[cur_arg]))
6320 methods->max = v;
6321 else {
6322 if (err)
6323 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
6324 return ERR_ALERT | ERR_FATAL;
6325 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006326 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006327}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006328
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006329static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6330{
6331 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6332}
6333
6334static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6335{
6336 return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
6337}
6338
Emeric Brun2d0c4822012-10-02 13:45:20 +02006339/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006340static 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 +02006341{
Emeric Brun89675492012-10-05 13:48:26 +02006342 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006343 return 0;
6344}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006345
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006346/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006347static 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 +02006348{
6349#ifdef OPENSSL_NPN_NEGOTIATED
6350 char *p1, *p2;
6351
6352 if (!*args[cur_arg + 1]) {
6353 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6354 return ERR_ALERT | ERR_FATAL;
6355 }
6356
6357 free(conf->npn_str);
6358
Willy Tarreau3724da12016-02-12 17:11:12 +01006359 /* the NPN string is built as a suite of (<len> <name>)*,
6360 * so we reuse each comma to store the next <len> and need
6361 * one more for the end of the string.
6362 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006363 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006364 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006365 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6366
6367 /* replace commas with the name length */
6368 p1 = conf->npn_str;
6369 p2 = p1 + 1;
6370 while (1) {
6371 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6372 if (!p2)
6373 p2 = p1 + 1 + strlen(p1 + 1);
6374
6375 if (p2 - (p1 + 1) > 255) {
6376 *p2 = '\0';
6377 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6378 return ERR_ALERT | ERR_FATAL;
6379 }
6380
6381 *p1 = p2 - (p1 + 1);
6382 p1 = p2;
6383
6384 if (!*p2)
6385 break;
6386
6387 *(p2++) = '\0';
6388 }
6389 return 0;
6390#else
6391 if (err)
6392 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6393 return ERR_ALERT | ERR_FATAL;
6394#endif
6395}
6396
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006397static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6398{
6399 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6400}
6401
Willy Tarreauab861d32013-04-02 02:30:41 +02006402/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006403static 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 +02006404{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006405#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006406 char *p1, *p2;
6407
6408 if (!*args[cur_arg + 1]) {
6409 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6410 return ERR_ALERT | ERR_FATAL;
6411 }
6412
6413 free(conf->alpn_str);
6414
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006415 /* the ALPN string is built as a suite of (<len> <name>)*,
6416 * so we reuse each comma to store the next <len> and need
6417 * one more for the end of the string.
6418 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006419 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006420 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006421 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6422
6423 /* replace commas with the name length */
6424 p1 = conf->alpn_str;
6425 p2 = p1 + 1;
6426 while (1) {
6427 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6428 if (!p2)
6429 p2 = p1 + 1 + strlen(p1 + 1);
6430
6431 if (p2 - (p1 + 1) > 255) {
6432 *p2 = '\0';
6433 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6434 return ERR_ALERT | ERR_FATAL;
6435 }
6436
6437 *p1 = p2 - (p1 + 1);
6438 p1 = p2;
6439
6440 if (!*p2)
6441 break;
6442
6443 *(p2++) = '\0';
6444 }
6445 return 0;
6446#else
6447 if (err)
6448 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6449 return ERR_ALERT | ERR_FATAL;
6450#endif
6451}
6452
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006453static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6454{
6455 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6456}
6457
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006458/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006459static 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 +02006460{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006461 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006462 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006463
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006464 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6465 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006466 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006467 conf->ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
6468 if (!conf->ssl_methods.min)
6469 conf->ssl_methods.min = global_ssl.listen_default_sslmethods.min;
6470 if (!conf->ssl_methods.max)
6471 conf->ssl_methods.max = global_ssl.listen_default_sslmethods.max;
Emeric Brun76d88952012-10-05 15:47:31 +02006472
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006473 return 0;
6474}
6475
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006476/* parse the "prefer-client-ciphers" bind keyword */
6477static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6478{
6479 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
6480 return 0;
6481}
6482
Christopher Faulet31af49d2015-06-09 17:29:50 +02006483/* parse the "generate-certificates" bind keyword */
6484static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6485{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006486#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006487 conf->generate_certs = 1;
6488#else
6489 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6490 err && *err ? *err : "");
6491#endif
6492 return 0;
6493}
6494
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006495/* parse the "strict-sni" bind keyword */
6496static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6497{
6498 conf->strict_sni = 1;
6499 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006500}
6501
6502/* parse the "tls-ticket-keys" bind keyword */
6503static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6504{
6505#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6506 FILE *f;
6507 int i = 0;
6508 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006509 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006510
6511 if (!*args[cur_arg + 1]) {
6512 if (err)
6513 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6514 return ERR_ALERT | ERR_FATAL;
6515 }
6516
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006517 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6518 if(keys_ref) {
6519 conf->keys_ref = keys_ref;
6520 return 0;
6521 }
6522
Vincent Bernat02779b62016-04-03 13:48:43 +02006523 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006524 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006525
6526 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6527 if (err)
6528 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6529 return ERR_ALERT | ERR_FATAL;
6530 }
6531
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006532 keys_ref->filename = strdup(args[cur_arg + 1]);
6533
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006534 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6535 int len = strlen(thisline);
6536 /* Strip newline characters from the end */
6537 if(thisline[len - 1] == '\n')
6538 thisline[--len] = 0;
6539
6540 if(thisline[len - 1] == '\r')
6541 thisline[--len] = 0;
6542
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006543 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 +01006544 if (err)
6545 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006546 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006547 return ERR_ALERT | ERR_FATAL;
6548 }
6549 i++;
6550 }
6551
6552 if (i < TLS_TICKETS_NO) {
6553 if (err)
6554 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 +02006555 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006556 return ERR_ALERT | ERR_FATAL;
6557 }
6558
6559 fclose(f);
6560
6561 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006562 i -= 2;
6563 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006564 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006565 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006566
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006567 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6568
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006569 return 0;
6570#else
6571 if (err)
6572 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6573 return ERR_ALERT | ERR_FATAL;
6574#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006575}
6576
Emeric Brund94b3fe2012-09-20 18:23:56 +02006577/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006578static 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 +02006579{
6580 if (!*args[cur_arg + 1]) {
6581 if (err)
6582 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6583 return ERR_ALERT | ERR_FATAL;
6584 }
6585
6586 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006587 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006588 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006589 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006590 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006591 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006592 else {
6593 if (err)
6594 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6595 args[cur_arg], args[cur_arg + 1]);
6596 return ERR_ALERT | ERR_FATAL;
6597 }
6598
6599 return 0;
6600}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006601static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6602{
6603 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6604}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006605
Willy Tarreau92faadf2012-10-10 23:04:25 +02006606/************** "server" keywords ****************/
6607
Emeric Brunef42d922012-10-11 16:11:36 +02006608/* parse the "ca-file" server keyword */
6609static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6610{
6611 if (!*args[*cur_arg + 1]) {
6612 if (err)
6613 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6614 return ERR_ALERT | ERR_FATAL;
6615 }
6616
Willy Tarreauef934602016-12-22 23:12:01 +01006617 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6618 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006619 else
6620 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6621
6622 return 0;
6623}
6624
Willy Tarreau92faadf2012-10-10 23:04:25 +02006625/* parse the "check-ssl" server keyword */
6626static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6627{
6628 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006629 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6630 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6631 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006632 newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
6633 if (!newsrv->ssl_ctx.methods.min)
6634 newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
6635 if (!newsrv->ssl_ctx.methods.max)
6636 newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
6637
Willy Tarreau92faadf2012-10-10 23:04:25 +02006638 return 0;
6639}
6640
6641/* parse the "ciphers" server keyword */
6642static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6643{
6644 if (!*args[*cur_arg + 1]) {
6645 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6646 return ERR_ALERT | ERR_FATAL;
6647 }
6648
6649 free(newsrv->ssl_ctx.ciphers);
6650 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6651 return 0;
6652}
6653
Emeric Brunef42d922012-10-11 16:11:36 +02006654/* parse the "crl-file" server keyword */
6655static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6656{
6657#ifndef X509_V_FLAG_CRL_CHECK
6658 if (err)
6659 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6660 return ERR_ALERT | ERR_FATAL;
6661#else
6662 if (!*args[*cur_arg + 1]) {
6663 if (err)
6664 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6665 return ERR_ALERT | ERR_FATAL;
6666 }
6667
Willy Tarreauef934602016-12-22 23:12:01 +01006668 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6669 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006670 else
6671 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6672
6673 return 0;
6674#endif
6675}
6676
Emeric Bruna7aa3092012-10-26 12:58:00 +02006677/* parse the "crt" server keyword */
6678static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6679{
6680 if (!*args[*cur_arg + 1]) {
6681 if (err)
6682 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6683 return ERR_ALERT | ERR_FATAL;
6684 }
6685
Willy Tarreauef934602016-12-22 23:12:01 +01006686 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6687 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006688 else
6689 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6690
6691 return 0;
6692}
Emeric Brunef42d922012-10-11 16:11:36 +02006693
Frédéric Lécaille340ae602017-03-13 10:38:04 +01006694/* parse the "no-check-ssl" server keyword */
6695static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6696{
6697 newsrv->check.use_ssl = 0;
6698 free(newsrv->ssl_ctx.ciphers);
6699 newsrv->ssl_ctx.ciphers = NULL;
6700 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
6701 return 0;
6702}
6703
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01006704/* parse the "no-send-proxy-v2-ssl" server keyword */
6705static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6706{
6707 newsrv->pp_opts &= ~SRV_PP_V2;
6708 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
6709 return 0;
6710}
6711
6712/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
6713static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6714{
6715 newsrv->pp_opts &= ~SRV_PP_V2;
6716 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
6717 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
6718 return 0;
6719}
6720
Frédéric Lécaillee381d762017-03-13 11:54:17 +01006721/* parse the "no-ssl" server keyword */
6722static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6723{
6724 newsrv->use_ssl = 0;
6725 free(newsrv->ssl_ctx.ciphers);
6726 newsrv->ssl_ctx.ciphers = NULL;
6727 return 0;
6728}
6729
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006730/* parse the "no-ssl-reuse" server keyword */
6731static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6732{
6733 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6734 return 0;
6735}
6736
Emeric Brunf9c5c472012-10-11 15:28:34 +02006737/* parse the "no-tls-tickets" server keyword */
6738static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6739{
6740 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6741 return 0;
6742}
David Safb76832014-05-08 23:42:08 -04006743/* parse the "send-proxy-v2-ssl" server keyword */
6744static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6745{
6746 newsrv->pp_opts |= SRV_PP_V2;
6747 newsrv->pp_opts |= SRV_PP_V2_SSL;
6748 return 0;
6749}
6750
6751/* parse the "send-proxy-v2-ssl-cn" server keyword */
6752static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6753{
6754 newsrv->pp_opts |= SRV_PP_V2;
6755 newsrv->pp_opts |= SRV_PP_V2_SSL;
6756 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6757 return 0;
6758}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006759
Willy Tarreau732eac42015-07-09 11:40:25 +02006760/* parse the "sni" server keyword */
6761static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6762{
6763#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6764 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6765 return ERR_ALERT | ERR_FATAL;
6766#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006767 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02006768
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006769 arg = args[*cur_arg + 1];
6770 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02006771 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6772 return ERR_ALERT | ERR_FATAL;
6773 }
6774
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006775 free(newsrv->sni_expr);
6776 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02006777
Willy Tarreau732eac42015-07-09 11:40:25 +02006778 return 0;
6779#endif
6780}
6781
Willy Tarreau92faadf2012-10-10 23:04:25 +02006782/* parse the "ssl" server keyword */
6783static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6784{
6785 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006786 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6787 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006788 return 0;
6789}
6790
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01006791/* parse the "ssl-reuse" server keyword */
6792static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6793{
6794 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
6795 return 0;
6796}
6797
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01006798/* parse the "tls-tickets" server keyword */
6799static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6800{
6801 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
6802 return 0;
6803}
6804
Emeric Brunef42d922012-10-11 16:11:36 +02006805/* parse the "verify" server keyword */
6806static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6807{
6808 if (!*args[*cur_arg + 1]) {
6809 if (err)
6810 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6811 return ERR_ALERT | ERR_FATAL;
6812 }
6813
6814 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006815 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006816 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006817 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006818 else {
6819 if (err)
6820 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6821 args[*cur_arg], args[*cur_arg + 1]);
6822 return ERR_ALERT | ERR_FATAL;
6823 }
6824
Evan Broderbe554312013-06-27 00:05:25 -07006825 return 0;
6826}
6827
6828/* parse the "verifyhost" server keyword */
6829static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6830{
6831 if (!*args[*cur_arg + 1]) {
6832 if (err)
6833 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6834 return ERR_ALERT | ERR_FATAL;
6835 }
6836
Frédéric Lécaille273f3212017-03-13 15:52:01 +01006837 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07006838 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6839
Emeric Brunef42d922012-10-11 16:11:36 +02006840 return 0;
6841}
6842
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006843/* parse the "ssl-default-bind-options" keyword in global section */
6844static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6845 struct proxy *defpx, const char *file, int line,
6846 char **err) {
6847 int i = 1;
6848
6849 if (*(args[i]) == 0) {
6850 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6851 return -1;
6852 }
6853 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006854 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006855 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006856 else if (!strcmp(args[i], "prefer-client-ciphers"))
6857 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006858 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
6859 if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
6860 i++;
6861 else {
6862 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
6863 return -1;
6864 }
6865 }
6866 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006867 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6868 return -1;
6869 }
6870 i++;
6871 }
6872 return 0;
6873}
6874
6875/* parse the "ssl-default-server-options" keyword in global section */
6876static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6877 struct proxy *defpx, const char *file, int line,
6878 char **err) {
6879 int i = 1;
6880
6881 if (*(args[i]) == 0) {
6882 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6883 return -1;
6884 }
6885 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006886 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006887 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006888 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
6889 if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
6890 i++;
6891 else {
6892 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
6893 return -1;
6894 }
6895 }
6896 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006897 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6898 return -1;
6899 }
6900 i++;
6901 }
6902 return 0;
6903}
6904
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006905/* parse the "ca-base" / "crt-base" keywords in global section.
6906 * Returns <0 on alert, >0 on warning, 0 on success.
6907 */
6908static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6909 struct proxy *defpx, const char *file, int line,
6910 char **err)
6911{
6912 char **target;
6913
Willy Tarreauef934602016-12-22 23:12:01 +01006914 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006915
6916 if (too_many_args(1, args, err, NULL))
6917 return -1;
6918
6919 if (*target) {
6920 memprintf(err, "'%s' already specified.", args[0]);
6921 return -1;
6922 }
6923
6924 if (*(args[1]) == 0) {
6925 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6926 return -1;
6927 }
6928 *target = strdup(args[1]);
6929 return 0;
6930}
6931
Willy Tarreauf22e9682016-12-21 23:23:19 +01006932/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6933 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6934 */
6935static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6936 struct proxy *defpx, const char *file, int line,
6937 char **err)
6938{
6939 char **target;
6940
Willy Tarreauef934602016-12-22 23:12:01 +01006941 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006942
6943 if (too_many_args(1, args, err, NULL))
6944 return -1;
6945
6946 if (*(args[1]) == 0) {
6947 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6948 return -1;
6949 }
6950
6951 free(*target);
6952 *target = strdup(args[1]);
6953 return 0;
6954}
6955
Willy Tarreau9ceda382016-12-21 23:13:03 +01006956/* parse various global tune.ssl settings consisting in positive integers.
6957 * Returns <0 on alert, >0 on warning, 0 on success.
6958 */
6959static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6960 struct proxy *defpx, const char *file, int line,
6961 char **err)
6962{
6963 int *target;
6964
6965 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6966 target = &global.tune.sslcachesize;
6967 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006968 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006969 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006970 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006971 else if (strcmp(args[0], "maxsslconn") == 0)
6972 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006973 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
6974 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006975 else {
6976 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6977 return -1;
6978 }
6979
6980 if (too_many_args(1, args, err, NULL))
6981 return -1;
6982
6983 if (*(args[1]) == 0) {
6984 memprintf(err, "'%s' expects an integer argument.", args[0]);
6985 return -1;
6986 }
6987
6988 *target = atoi(args[1]);
6989 if (*target < 0) {
6990 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6991 return -1;
6992 }
6993 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006994}
6995
6996static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
6997 struct proxy *defpx, const char *file, int line,
6998 char **err)
6999{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007000 int ret;
7001
7002 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
7003 if (ret != 0)
7004 return ret;
7005
7006 if (pool2_ssl_capture) {
7007 memprintf(err, "'%s' is already configured.", args[0]);
7008 return -1;
7009 }
7010
7011 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
7012 if (!pool2_ssl_capture) {
7013 memprintf(err, "Out of memory error.");
7014 return -1;
7015 }
7016 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007017}
7018
7019/* parse "ssl.force-private-cache".
7020 * Returns <0 on alert, >0 on warning, 0 on success.
7021 */
7022static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
7023 struct proxy *defpx, const char *file, int line,
7024 char **err)
7025{
7026 if (too_many_args(0, args, err, NULL))
7027 return -1;
7028
Willy Tarreauef934602016-12-22 23:12:01 +01007029 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007030 return 0;
7031}
7032
7033/* parse "ssl.lifetime".
7034 * Returns <0 on alert, >0 on warning, 0 on success.
7035 */
7036static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
7037 struct proxy *defpx, const char *file, int line,
7038 char **err)
7039{
7040 const char *res;
7041
7042 if (too_many_args(1, args, err, NULL))
7043 return -1;
7044
7045 if (*(args[1]) == 0) {
7046 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
7047 return -1;
7048 }
7049
Willy Tarreauef934602016-12-22 23:12:01 +01007050 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01007051 if (res) {
7052 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
7053 return -1;
7054 }
7055 return 0;
7056}
7057
7058#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01007059/* parse "ssl-dh-param-file".
7060 * Returns <0 on alert, >0 on warning, 0 on success.
7061 */
7062static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
7063 struct proxy *defpx, const char *file, int line,
7064 char **err)
7065{
7066 if (too_many_args(1, args, err, NULL))
7067 return -1;
7068
7069 if (*(args[1]) == 0) {
7070 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
7071 return -1;
7072 }
7073
7074 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
7075 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
7076 return -1;
7077 }
7078 return 0;
7079}
7080
Willy Tarreau9ceda382016-12-21 23:13:03 +01007081/* parse "ssl.default-dh-param".
7082 * Returns <0 on alert, >0 on warning, 0 on success.
7083 */
7084static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
7085 struct proxy *defpx, const char *file, int line,
7086 char **err)
7087{
7088 if (too_many_args(1, args, err, NULL))
7089 return -1;
7090
7091 if (*(args[1]) == 0) {
7092 memprintf(err, "'%s' expects an integer argument.", args[0]);
7093 return -1;
7094 }
7095
Willy Tarreauef934602016-12-22 23:12:01 +01007096 global_ssl.default_dh_param = atoi(args[1]);
7097 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01007098 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
7099 return -1;
7100 }
7101 return 0;
7102}
7103#endif
7104
7105
William Lallemand32af2032016-10-29 18:09:35 +02007106/* This function is used with TLS ticket keys management. It permits to browse
7107 * each reference. The variable <getnext> must contain the current node,
7108 * <end> point to the root node.
7109 */
7110#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7111static inline
7112struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
7113{
7114 struct tls_keys_ref *ref = getnext;
7115
7116 while (1) {
7117
7118 /* Get next list entry. */
7119 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
7120
7121 /* If the entry is the last of the list, return NULL. */
7122 if (&ref->list == end)
7123 return NULL;
7124
7125 return ref;
7126 }
7127}
7128
7129static inline
7130struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7131{
7132 int id;
7133 char *error;
7134
7135 /* If the reference starts by a '#', this is numeric id. */
7136 if (reference[0] == '#') {
7137 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7138 id = strtol(reference + 1, &error, 10);
7139 if (*error != '\0')
7140 return NULL;
7141
7142 /* Perform the unique id lookup. */
7143 return tlskeys_ref_lookupid(id);
7144 }
7145
7146 /* Perform the string lookup. */
7147 return tlskeys_ref_lookup(reference);
7148}
7149#endif
7150
7151
7152#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7153
7154static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7155
7156static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7157 return cli_io_handler_tlskeys_files(appctx);
7158}
7159
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007160/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7161 * (next index to be dumped), and cli.p0 (next key reference).
7162 */
William Lallemand32af2032016-10-29 18:09:35 +02007163static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7164
7165 struct stream_interface *si = appctx->owner;
7166
7167 switch (appctx->st2) {
7168 case STAT_ST_INIT:
7169 /* Display the column headers. If the message cannot be sent,
7170 * quit the fucntion with returning 0. The function is called
7171 * later and restart at the state "STAT_ST_INIT".
7172 */
7173 chunk_reset(&trash);
7174
7175 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7176 chunk_appendf(&trash, "# id secret\n");
7177 else
7178 chunk_appendf(&trash, "# id (file)\n");
7179
7180 if (bi_putchk(si_ic(si), &trash) == -1) {
7181 si_applet_cant_put(si);
7182 return 0;
7183 }
7184
William Lallemand32af2032016-10-29 18:09:35 +02007185 /* Now, we start the browsing of the references lists.
7186 * Note that the following call to LIST_ELEM return bad pointer. The only
7187 * available field of this pointer is <list>. It is used with the function
7188 * tlskeys_list_get_next() for retruning the first available entry
7189 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007190 if (appctx->ctx.cli.p0 == NULL) {
7191 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7192 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007193 }
7194
7195 appctx->st2 = STAT_ST_LIST;
7196 /* fall through */
7197
7198 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007199 while (appctx->ctx.cli.p0) {
7200 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7201 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007202
7203 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007204 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007205 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007206
7207 if (appctx->ctx.cli.i1 == 0)
7208 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7209
William Lallemand32af2032016-10-29 18:09:35 +02007210 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007211 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007212 struct chunk *t2 = get_trash_chunk();
7213
7214 chunk_reset(t2);
7215 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007216 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007217 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007218 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007219
7220 if (bi_putchk(si_ic(si), &trash) == -1) {
7221 /* let's try again later from this stream. We add ourselves into
7222 * this stream's users so that it can remove us upon termination.
7223 */
7224 si_applet_cant_put(si);
7225 return 0;
7226 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007227 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007228 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007229 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007230 }
7231 if (bi_putchk(si_ic(si), &trash) == -1) {
7232 /* let's try again later from this stream. We add ourselves into
7233 * this stream's users so that it can remove us upon termination.
7234 */
7235 si_applet_cant_put(si);
7236 return 0;
7237 }
7238
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007239 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007240 break;
7241
7242 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007243 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007244 }
7245
7246 appctx->st2 = STAT_ST_FIN;
7247 /* fall through */
7248
7249 default:
7250 appctx->st2 = STAT_ST_FIN;
7251 return 1;
7252 }
7253 return 0;
7254}
7255
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007256/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007257static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7258{
William Lallemand32af2032016-10-29 18:09:35 +02007259 /* no parameter, shows only file list */
7260 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007261 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007262 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007263 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007264 }
7265
7266 if (args[2][0] == '*') {
7267 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007268 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007269 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007270 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7271 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007272 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007273 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007274 return 1;
7275 }
7276 }
William Lallemand32af2032016-10-29 18:09:35 +02007277 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007278 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007279}
7280
William Lallemand32af2032016-10-29 18:09:35 +02007281static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7282{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007283 struct tls_keys_ref *ref;
7284
William Lallemand32af2032016-10-29 18:09:35 +02007285 /* Expect two parameters: the filename and the new new TLS key in encoding */
7286 if (!*args[3] || !*args[4]) {
7287 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 +01007288 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007289 return 1;
7290 }
7291
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007292 ref = tlskeys_ref_lookup_ref(args[3]);
7293 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007294 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007295 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007296 return 1;
7297 }
7298
7299 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7300 if (trash.len != sizeof(struct tls_sess_key)) {
7301 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007302 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007303 return 1;
7304 }
7305
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007306 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7307 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007308
7309 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007310 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007311 return 1;
7312
7313}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007314#endif
William Lallemand32af2032016-10-29 18:09:35 +02007315
7316static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7317{
7318#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7319 char *err = NULL;
7320
7321 /* Expect one parameter: the new response in base64 encoding */
7322 if (!*args[3]) {
7323 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007324 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007325 return 1;
7326 }
7327
7328 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7329 if (trash.len < 0) {
7330 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007331 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007332 return 1;
7333 }
7334
7335 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7336 if (err) {
7337 memprintf(&err, "%s.\n", err);
7338 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007339 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007340 }
7341 return 1;
7342 }
7343 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007344 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007345 return 1;
7346#else
7347 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 +01007348 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007349 return 1;
7350#endif
7351
7352}
7353
7354/* register cli keywords */
7355static struct cli_kw_list cli_kws = {{ },{
7356#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7357 { { "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 },
7358 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007359#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007360 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007361 { { NULL }, NULL, NULL, NULL }
7362}};
7363
7364
Willy Tarreau7875d092012-09-10 08:20:03 +02007365/* Note: must not be declared <const> as its list will be overwritten.
7366 * Please take care of keeping this list alphabetically sorted.
7367 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007368static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007369 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007370 { "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 +02007371 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7372 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007373 { "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 +02007374 { "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 +02007375 { "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 +02007376 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7377 { "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 +01007378 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007379 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007380 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7381 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7382 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7383 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7384 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7385 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7386 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7387 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007388 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007389 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7390 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007391 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007392 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7393 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7394 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7395 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7396 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7397 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7398 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007399 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007400 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007401 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007402 { "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 +01007403 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007404 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7405 { "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 +02007406 { "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 +02007407#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007408 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007409#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007410#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007411 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007412#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007413 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007414 { "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 +02007415 { "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 +01007416 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7417 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007418 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7419 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7420 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7421 { "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 +02007422 { NULL, NULL, 0, 0, 0 },
7423}};
7424
7425/* Note: must not be declared <const> as its list will be overwritten.
7426 * Please take care of keeping this list alphabetically sorted.
7427 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007428static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007429 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7430 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007431 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007432}};
7433
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007434/* Note: must not be declared <const> as its list will be overwritten.
7435 * Please take care of keeping this list alphabetically sorted, doing so helps
7436 * all code contributors.
7437 * Optional keywords are also declared with a NULL ->parse() function so that
7438 * the config parser can report an appropriate error when a known keyword was
7439 * not enabled.
7440 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007441static struct ssl_bind_kw ssl_bind_kws[] = {
7442 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7443 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7444 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7445 { "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 +01007446 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007447 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007448 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7449 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7450 { NULL, NULL, 0 },
7451};
7452
Willy Tarreau51fb7652012-09-18 18:24:39 +02007453static struct bind_kw_list bind_kws = { "SSL", { }, {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007454 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7455 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7456 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
7457 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7458 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
7459 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7460 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7461 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7462 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7463 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
7464 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
7465 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7466 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
7467 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
7468 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
7469 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02007470 { "force-tlsv13", bind_parse_tls_method_options, 0 }, /* force TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007471 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
7472 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
7473 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
7474 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
7475 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02007476 { "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007477 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7478 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007479 { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
7480 { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007481 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7482 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7483 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7484 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
7485 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007486 { NULL, NULL, 0 },
7487}};
Emeric Brun46591952012-05-18 15:47:34 +02007488
Willy Tarreau92faadf2012-10-10 23:04:25 +02007489/* Note: must not be declared <const> as its list will be overwritten.
7490 * Please take care of keeping this list alphabetically sorted, doing so helps
7491 * all code contributors.
7492 * Optional keywords are also declared with a NULL ->parse() function so that
7493 * the config parser can report an appropriate error when a known keyword was
7494 * not enabled.
7495 */
7496static struct srv_kw_list srv_kws = { "SSL", { }, {
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007497 { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
7498 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
7499 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
7500 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
7501 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
7502 { "force-sslv3", srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
7503 { "force-tlsv10", srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
7504 { "force-tlsv11", srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
7505 { "force-tlsv12", srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
7506 { "force-tlsv13", srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
7507 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
7508 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
7509 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
7510 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
7511 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
7512 { "no-sslv3", srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
7513 { "no-tlsv10", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
7514 { "no-tlsv11", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
7515 { "no-tlsv12", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
7516 { "no-tlsv13", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
7517 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
7518 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
7519 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
7520 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
7521 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
7522 { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1 }, /* minimum version */
7523 { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1 }, /* maximum version */
7524 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
7525 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
7526 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
7527 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007528 { NULL, NULL, 0, 0 },
7529}};
7530
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007531static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007532 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7533 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007534 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007535 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7536 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007537#ifndef OPENSSL_NO_DH
7538 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7539#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007540 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7541#ifndef OPENSSL_NO_DH
7542 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7543#endif
7544 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7545 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7546 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7547 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007548 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007549 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7550 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007551 { 0, NULL, NULL },
7552}};
7553
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007554/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007555static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007556 .snd_buf = ssl_sock_from_buf,
7557 .rcv_buf = ssl_sock_to_buf,
7558 .rcv_pipe = NULL,
7559 .snd_pipe = NULL,
7560 .shutr = NULL,
7561 .shutw = ssl_sock_shutw,
7562 .close = ssl_sock_close,
7563 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007564 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007565 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007566 .prepare_srv = ssl_sock_prepare_srv_ctx,
7567 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007568 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007569};
7570
Daniel Jakots54ffb912015-11-06 20:02:41 +01007571#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007572
7573static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7574{
7575 if (ptr) {
7576 chunk_destroy(ptr);
7577 free(ptr);
7578 }
7579}
7580
7581#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007582static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7583{
7584 pool_free2(pool2_ssl_capture, ptr);
7585}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007586
Emeric Brun46591952012-05-18 15:47:34 +02007587__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007588static void __ssl_sock_init(void)
7589{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007590 char *ptr;
7591
Emeric Brun46591952012-05-18 15:47:34 +02007592 STACK_OF(SSL_COMP)* cm;
7593
Willy Tarreauef934602016-12-22 23:12:01 +01007594 if (global_ssl.listen_default_ciphers)
7595 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7596 if (global_ssl.connect_default_ciphers)
7597 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007598
Willy Tarreau13e14102016-12-22 20:25:26 +01007599 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007600 SSL_library_init();
7601 cm = SSL_COMP_get_compression_methods();
7602 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007603#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007604 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7605#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007606 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 +02007607 sample_register_fetches(&sample_fetch_keywords);
7608 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007609 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007610 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007611 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007612 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007613#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7614 hap_register_post_check(tlskeys_finalize_config);
7615#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007616
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007617 ptr = NULL;
7618 memprintf(&ptr, "Built with OpenSSL version : "
7619#ifdef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01007620 "BoringSSL");
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007621#else /* OPENSSL_IS_BORINGSSL */
7622 OPENSSL_VERSION_TEXT
7623 "\nRunning on OpenSSL version : %s%s",
7624 SSLeay_version(SSLEAY_VERSION),
7625 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7626#endif
7627 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7628#if OPENSSL_VERSION_NUMBER < 0x00907000L
7629 "no (library version too old)"
7630#elif defined(OPENSSL_NO_TLSEXT)
7631 "no (disabled via OPENSSL_NO_TLSEXT)"
7632#else
7633 "yes"
7634#endif
7635 "", ptr);
7636
7637 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7638#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7639 "yes"
7640#else
7641#ifdef OPENSSL_NO_TLSEXT
7642 "no (because of OPENSSL_NO_TLSEXT)"
7643#else
7644 "no (version might be too old, 0.9.8f min needed)"
7645#endif
7646#endif
7647 "", ptr);
7648
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01007649 memprintf(&ptr, "%s\nOpenSSL library supports : "
7650#if SSL_OP_NO_SSLv3
7651 "SSLv3 "
7652#endif
7653#if SSL_OP_NO_TLSv1
7654 "TLSv1.0 "
7655#endif
7656#if SSL_OP_NO_TLSv1_1
7657 "TLSv1.1 "
7658#endif
7659#if SSL_OP_NO_TLSv1_2
7660 "TLSv1.2 "
7661#endif
7662#if SSL_OP_NO_TLSv1_3
7663 "TLSv1.3"
7664#endif
7665 "", ptr);
7666
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007667 hap_register_build_opts(ptr, 1);
7668
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007669 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7670 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007671
7672#ifndef OPENSSL_NO_DH
7673 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7674#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007675
7676 /* Load SSL string for the verbose & debug mode. */
7677 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007678}
7679
Remi Gacogned3a23c32015-05-28 16:39:47 +02007680__attribute__((destructor))
7681static void __ssl_sock_deinit(void)
7682{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007683#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007684 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007685#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007686
Remi Gacogned3a23c32015-05-28 16:39:47 +02007687#ifndef OPENSSL_NO_DH
7688 if (local_dh_1024) {
7689 DH_free(local_dh_1024);
7690 local_dh_1024 = NULL;
7691 }
7692
7693 if (local_dh_2048) {
7694 DH_free(local_dh_2048);
7695 local_dh_2048 = NULL;
7696 }
7697
7698 if (local_dh_4096) {
7699 DH_free(local_dh_4096);
7700 local_dh_4096 = NULL;
7701 }
7702
Remi Gacogne47783ef2015-05-29 15:53:22 +02007703 if (global_dh) {
7704 DH_free(global_dh);
7705 global_dh = NULL;
7706 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007707#endif
7708
7709 ERR_remove_state(0);
7710 ERR_free_strings();
7711
7712 EVP_cleanup();
7713
7714#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7715 CRYPTO_cleanup_all_ex_data();
7716#endif
7717}
7718
7719
Emeric Brun46591952012-05-18 15:47:34 +02007720/*
7721 * Local variables:
7722 * c-indent-level: 8
7723 * c-basic-offset: 8
7724 * End:
7725 */