blob: e30236a2219058f61a1bc6611506a9c9abbb1362 [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 Hocdet4de1ff12017-03-03 12:21:32 +01003271static SSL_CTX *
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 Hocdet4de1ff12017-03-03 12:21:32 +01003290
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003291 ctx = SSL_CTX_new(SSLv23_server_method());
3292
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003293 /* Real min and max should be determinate with configuration and openssl's capabilities */
3294 if (conf_ssl_methods->min)
3295 conf_ssl_methods->flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
3296 if (conf_ssl_methods->max)
3297 conf_ssl_methods->flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
3298
3299 /* Find min, max and holds */
3300 min = max = CONF_TLSV_NONE;
3301 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003302 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003303 /* version is in openssl && version not disable in configuration */
3304 if (methodVersions[i].option && !(conf_ssl_methods->flags & methodVersions[i].flag)) {
3305 if (min) {
3306 if (hole) {
3307 Warning("Proxy '%s': SSL/TLS versions range not contiguous for bind '%s' at [%s:%d]. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003308 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003309 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line,
3310 methodVersions[hole].name);
3311 hole = 0;
3312 }
3313 max = i;
3314 }
3315 else {
3316 min = max = i;
3317 }
3318 }
3319 else {
3320 if (min)
3321 hole = i;
3322 /* set SSL_NO_VERSION per default */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003323 options |= methodVersions[i].option;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003324 }
3325 if (!min)
3326 Warning("Proxy '%s': all SSL/TLS versions are disabled for bind '%s' at [%s:%d].\n",
3327 bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003328
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003329#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3330 /* Keep force-xxx implementation as it is in older haproxy. It's a
3331 precautionary measure to avoid any suprise with older openssl version. */
3332 if (min == max)
3333 methodVersions[min].set_version(ctx, 1 /* server */);
3334#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003335 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003336 methodVersions[min].set_version(ctx, 0);
3337 methodVersions[max].set_version(ctx, 1);
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003338#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003339
3340 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3341 options |= SSL_OP_NO_TICKET;
3342 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
3343 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
3344 SSL_CTX_set_options(ctx, options);
3345 SSL_CTX_set_mode(ctx, mode);
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003346 if (global_ssl.life_time)
3347 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003348
3349#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3350#ifdef OPENSSL_IS_BORINGSSL
3351 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3352 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3353#else
3354 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3355 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3356#endif
3357#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003358 return ctx;
3359}
3360
3361int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3362{
3363 struct proxy *curproxy = bind_conf->frontend;
3364 int cfgerr = 0;
3365 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003366 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003367 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003368 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003369
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003370 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003371 case SSL_SOCK_VERIFY_NONE:
3372 verify = SSL_VERIFY_NONE;
3373 break;
3374 case SSL_SOCK_VERIFY_OPTIONAL:
3375 verify = SSL_VERIFY_PEER;
3376 break;
3377 case SSL_SOCK_VERIFY_REQUIRED:
3378 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3379 break;
3380 }
3381 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3382 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003383 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3384 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3385 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003386 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003387 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003388 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003389 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003390 cfgerr++;
3391 }
3392 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003393 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003394 }
Emeric Brun850efd52014-01-29 12:24:34 +01003395 else {
3396 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3397 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3398 cfgerr++;
3399 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003400#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003401 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003402 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3403
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003404 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003405 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003406 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003407 cfgerr++;
3408 }
Emeric Brun561e5742012-10-02 15:20:55 +02003409 else {
3410 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3411 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003412 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003413#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003414 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003415 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003416#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003417 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003418 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3419 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3420 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3421 cfgerr++;
3422 }
3423 }
3424#endif
3425
Emeric Brunfc0421f2012-09-07 17:30:07 +02003426 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003427 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3428 if (conf_ciphers &&
3429 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003430 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 +01003431 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003432 cfgerr++;
3433 }
3434
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003435#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003436 /* If tune.ssl.default-dh-param has not been set,
3437 neither has ssl-default-dh-file and no static DH
3438 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003439 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003440 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003441 (ssl_dh_ptr_index == -1 ||
3442 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003443 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3444 const SSL_CIPHER * cipher = NULL;
3445 char cipher_description[128];
3446 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3447 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3448 which is not ephemeral DH. */
3449 const char dhe_description[] = " Kx=DH ";
3450 const char dhe_export_description[] = " Kx=DH(";
3451 int idx = 0;
3452 int dhe_found = 0;
3453 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003454
Remi Gacogne23d5d372014-10-10 17:04:26 +02003455 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003456
Remi Gacogne23d5d372014-10-10 17:04:26 +02003457 if (ssl) {
3458 ciphers = SSL_get_ciphers(ssl);
3459
3460 if (ciphers) {
3461 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3462 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3463 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3464 if (strstr(cipher_description, dhe_description) != NULL ||
3465 strstr(cipher_description, dhe_export_description) != NULL) {
3466 dhe_found = 1;
3467 break;
3468 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003469 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003470 }
3471 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003472 SSL_free(ssl);
3473 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003474 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003475
Lukas Tribus90132722014-08-18 00:56:33 +02003476 if (dhe_found) {
3477 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 +02003478 }
3479
Willy Tarreauef934602016-12-22 23:12:01 +01003480 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003481 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003482
Willy Tarreauef934602016-12-22 23:12:01 +01003483 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003484 if (local_dh_1024 == NULL) {
3485 local_dh_1024 = ssl_get_dh_1024();
3486 }
Willy Tarreauef934602016-12-22 23:12:01 +01003487 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003488 if (local_dh_2048 == NULL) {
3489 local_dh_2048 = ssl_get_dh_2048();
3490 }
Willy Tarreauef934602016-12-22 23:12:01 +01003491 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003492 if (local_dh_4096 == NULL) {
3493 local_dh_4096 = ssl_get_dh_4096();
3494 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003495 }
3496 }
3497 }
3498#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003499
Emeric Brunfc0421f2012-09-07 17:30:07 +02003500 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003501#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003502 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003503#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003504
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003505#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003506 ssl_conf_cur = NULL;
3507 if (ssl_conf && ssl_conf->npn_str)
3508 ssl_conf_cur = ssl_conf;
3509 else if (bind_conf->ssl_conf.npn_str)
3510 ssl_conf_cur = &bind_conf->ssl_conf;
3511 if (ssl_conf_cur)
3512 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003513#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003514#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003515 ssl_conf_cur = NULL;
3516 if (ssl_conf && ssl_conf->alpn_str)
3517 ssl_conf_cur = ssl_conf;
3518 else if (bind_conf->ssl_conf.alpn_str)
3519 ssl_conf_cur = &bind_conf->ssl_conf;
3520 if (ssl_conf_cur)
3521 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003522#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003523#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3524 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3525 if (conf_curves) {
3526 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3527 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3528 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3529 cfgerr++;
3530 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003531#if defined(SSL_CTX_set_ecdh_auto)
3532 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3533#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003534 }
3535#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003536#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003537 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003538 int i;
3539 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003540 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3541 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003542
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003543 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003544 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3545 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 +01003546 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003547 cfgerr++;
3548 }
3549 else {
3550 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3551 EC_KEY_free(ecdh);
3552 }
3553 }
3554#endif
3555
Emeric Brunfc0421f2012-09-07 17:30:07 +02003556 return cfgerr;
3557}
3558
Evan Broderbe554312013-06-27 00:05:25 -07003559static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3560{
3561 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3562 size_t prefixlen, suffixlen;
3563
3564 /* Trivial case */
3565 if (strcmp(pattern, hostname) == 0)
3566 return 1;
3567
Evan Broderbe554312013-06-27 00:05:25 -07003568 /* The rest of this logic is based on RFC 6125, section 6.4.3
3569 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3570
Emeric Bruna848dae2013-10-08 11:27:28 +02003571 pattern_wildcard = NULL;
3572 pattern_left_label_end = pattern;
3573 while (*pattern_left_label_end != '.') {
3574 switch (*pattern_left_label_end) {
3575 case 0:
3576 /* End of label not found */
3577 return 0;
3578 case '*':
3579 /* If there is more than one wildcards */
3580 if (pattern_wildcard)
3581 return 0;
3582 pattern_wildcard = pattern_left_label_end;
3583 break;
3584 }
3585 pattern_left_label_end++;
3586 }
3587
3588 /* If it's not trivial and there is no wildcard, it can't
3589 * match */
3590 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003591 return 0;
3592
3593 /* Make sure all labels match except the leftmost */
3594 hostname_left_label_end = strchr(hostname, '.');
3595 if (!hostname_left_label_end
3596 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3597 return 0;
3598
3599 /* Make sure the leftmost label of the hostname is long enough
3600 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003601 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003602 return 0;
3603
3604 /* Finally compare the string on either side of the
3605 * wildcard */
3606 prefixlen = pattern_wildcard - pattern;
3607 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003608 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3609 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003610 return 0;
3611
3612 return 1;
3613}
3614
3615static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3616{
3617 SSL *ssl;
3618 struct connection *conn;
3619 char *servername;
3620
3621 int depth;
3622 X509 *cert;
3623 STACK_OF(GENERAL_NAME) *alt_names;
3624 int i;
3625 X509_NAME *cert_subject;
3626 char *str;
3627
3628 if (ok == 0)
3629 return ok;
3630
3631 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003632 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003633
3634 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3635
3636 /* We only need to verify the CN on the actual server cert,
3637 * not the indirect CAs */
3638 depth = X509_STORE_CTX_get_error_depth(ctx);
3639 if (depth != 0)
3640 return ok;
3641
3642 /* At this point, the cert is *not* OK unless we can find a
3643 * hostname match */
3644 ok = 0;
3645
3646 cert = X509_STORE_CTX_get_current_cert(ctx);
3647 /* It seems like this might happen if verify peer isn't set */
3648 if (!cert)
3649 return ok;
3650
3651 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3652 if (alt_names) {
3653 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3654 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3655 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003656#if OPENSSL_VERSION_NUMBER < 0x00907000L
3657 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3658#else
Evan Broderbe554312013-06-27 00:05:25 -07003659 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003660#endif
Evan Broderbe554312013-06-27 00:05:25 -07003661 ok = ssl_sock_srv_hostcheck(str, servername);
3662 OPENSSL_free(str);
3663 }
3664 }
3665 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003666 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003667 }
3668
3669 cert_subject = X509_get_subject_name(cert);
3670 i = -1;
3671 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3672 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003673 ASN1_STRING *value;
3674 value = X509_NAME_ENTRY_get_data(entry);
3675 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003676 ok = ssl_sock_srv_hostcheck(str, servername);
3677 OPENSSL_free(str);
3678 }
3679 }
3680
3681 return ok;
3682}
3683
Emeric Brun94324a42012-10-11 14:00:19 +02003684/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003685int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003686{
Willy Tarreau03209342016-12-22 17:08:28 +01003687 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003688 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003689 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003690 SSL_OP_ALL | /* all known workarounds for bugs */
3691 SSL_OP_NO_SSLv2 |
3692 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003693 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003694 SSL_MODE_ENABLE_PARTIAL_WRITE |
3695 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003696 SSL_MODE_RELEASE_BUFFERS |
3697 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003698 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003699 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003700 struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003701 int i, min, max, hole;
Emeric Brun94324a42012-10-11 14:00:19 +02003702
Thierry Fournier383085f2013-01-24 14:15:43 +01003703 /* Make sure openssl opens /dev/urandom before the chroot */
3704 if (!ssl_initialize_random()) {
3705 Alert("OpenSSL random data generator initialization failed.\n");
3706 cfgerr++;
3707 }
3708
Willy Tarreaufce03112015-01-15 21:32:40 +01003709 /* Automatic memory computations need to know we use SSL there */
3710 global.ssl_used_backend = 1;
3711
3712 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003713 srv->ssl_ctx.reused_sess = NULL;
3714 if (srv->use_ssl)
3715 srv->xprt = &ssl_sock;
3716 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003717 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003718
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003719 ctx = SSL_CTX_new(SSLv23_client_method());
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003720 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02003721 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3722 proxy_type_str(curproxy), curproxy->id,
3723 srv->id);
3724 cfgerr++;
3725 return cfgerr;
3726 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003727
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003728 /* Real min and max should be determinate with configuration and openssl's capabilities */
3729 if (conf_ssl_methods->min)
3730 conf_ssl_methods->flags |= (methodVersions[conf_ssl_methods->min].flag - 1);
3731 if (conf_ssl_methods->max)
3732 conf_ssl_methods->flags |= ~((methodVersions[conf_ssl_methods->max].flag << 1) - 1);
3733
3734 /* find min, max and holds */
3735 min = max = CONF_TLSV_NONE;
3736 hole = 0;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003737 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003738 /* version is in openssl && version not disable in configuration */
3739 if (methodVersions[i].option && !(conf_ssl_methods->flags & methodVersions[i].flag)) {
3740 if (min) {
3741 if (hole) {
3742 Warning("config : %s '%s': SSL/TLS versions range not contiguous for server '%s'. "
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02003743 "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003744 proxy_type_str(curproxy), curproxy->id, srv->id,
3745 methodVersions[hole].name);
3746 hole = 0;
3747 }
3748 max = i;
3749 }
3750 else {
3751 min = max = i;
3752 }
3753 }
3754 else {
3755 if (min)
3756 hole = i;
3757 /* set SSL_NO_VERSION per default */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003758 options |= methodVersions[i].option;
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003759 }
3760 if (!min)
3761 Warning("config : %s '%s': all SSL/TLS versions are disabled for server '%s'.\n",
3762 proxy_type_str(curproxy), curproxy->id, srv->id);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003763
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003764#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3765 /* Keep force-xxx implementation as it is in older haproxy. It's a
3766 precautionary measure to avoid any suprise with older openssl version. */
3767 if (min == max)
3768 methodVersions[min].set_version(ctx, 0 /* client */);
3769#else /* openssl >= 1.1.0 */
Emmanuel Hocdetb4e9ba42017-03-30 19:25:07 +02003770 /* set the max_version is required to cap TLS version or activate new TLS (v1.3) */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003771 methodVersions[min].set_version(ctx, 0);
3772 methodVersions[max].set_version(ctx, 1);
3773#endif
3774
3775 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3776 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003777 SSL_CTX_set_options(ctx, options);
3778 SSL_CTX_set_mode(ctx, mode);
3779 srv->ssl_ctx.ctx = ctx;
3780
Emeric Bruna7aa3092012-10-26 12:58:00 +02003781 if (srv->ssl_ctx.client_crt) {
3782 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3783 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3784 proxy_type_str(curproxy), curproxy->id,
3785 srv->id, srv->ssl_ctx.client_crt);
3786 cfgerr++;
3787 }
3788 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3789 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3790 proxy_type_str(curproxy), curproxy->id,
3791 srv->id, srv->ssl_ctx.client_crt);
3792 cfgerr++;
3793 }
3794 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3795 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3796 proxy_type_str(curproxy), curproxy->id,
3797 srv->id, srv->ssl_ctx.client_crt);
3798 cfgerr++;
3799 }
3800 }
Emeric Brun94324a42012-10-11 14:00:19 +02003801
Emeric Brun850efd52014-01-29 12:24:34 +01003802 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3803 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01003804 switch (srv->ssl_ctx.verify) {
3805 case SSL_SOCK_VERIFY_NONE:
3806 verify = SSL_VERIFY_NONE;
3807 break;
3808 case SSL_SOCK_VERIFY_REQUIRED:
3809 verify = SSL_VERIFY_PEER;
3810 break;
3811 }
Evan Broderbe554312013-06-27 00:05:25 -07003812 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003813 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003814 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003815 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003816 if (srv->ssl_ctx.ca_file) {
3817 /* load CAfile to verify */
3818 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003819 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003820 curproxy->id, srv->id,
3821 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3822 cfgerr++;
3823 }
3824 }
Emeric Brun850efd52014-01-29 12:24:34 +01003825 else {
3826 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003827 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 +01003828 curproxy->id, srv->id,
3829 srv->conf.file, srv->conf.line);
3830 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003831 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003832 curproxy->id, srv->id,
3833 srv->conf.file, srv->conf.line);
3834 cfgerr++;
3835 }
Emeric Brunef42d922012-10-11 16:11:36 +02003836#ifdef X509_V_FLAG_CRL_CHECK
3837 if (srv->ssl_ctx.crl_file) {
3838 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3839
3840 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003841 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003842 curproxy->id, srv->id,
3843 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3844 cfgerr++;
3845 }
3846 else {
3847 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3848 }
3849 }
3850#endif
3851 }
3852
Emeric Brun94324a42012-10-11 14:00:19 +02003853 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3854 if (srv->ssl_ctx.ciphers &&
3855 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3856 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3857 curproxy->id, srv->id,
3858 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3859 cfgerr++;
3860 }
3861
3862 return cfgerr;
3863}
3864
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003865/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003866 * be NULL, in which case nothing is done. Returns the number of errors
3867 * encountered.
3868 */
Willy Tarreau03209342016-12-22 17:08:28 +01003869int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003870{
3871 struct ebmb_node *node;
3872 struct sni_ctx *sni;
3873 int err = 0;
3874
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003875 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003876 return 0;
3877
Willy Tarreaufce03112015-01-15 21:32:40 +01003878 /* Automatic memory computations need to know we use SSL there */
3879 global.ssl_used_frontend = 1;
3880
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003881 /* Make sure openssl opens /dev/urandom before the chroot */
3882 if (!ssl_initialize_random()) {
3883 Alert("OpenSSL random data generator initialization failed.\n");
3884 err++;
3885 }
3886 /* Create initial_ctx used to start the ssl connection before do switchctx */
3887 if (!bind_conf->initial_ctx) {
3888 bind_conf->initial_ctx = ssl_sock_initial_ctx(bind_conf);
3889 /* It should not be necessary to call this function, but it's
3890 necessary first to check and move all initialisation related
3891 to initial_ctx in ssl_sock_initial_ctx. */
3892 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
3893 }
Emeric Brun0bed9942014-10-30 19:25:24 +01003894 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003895 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003896
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003897 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003898 while (node) {
3899 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003900 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3901 /* only initialize the CTX on its first occurrence and
3902 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003903 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003904 node = ebmb_next(node);
3905 }
3906
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003907 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003908 while (node) {
3909 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003910 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3911 /* only initialize the CTX on its first occurrence and
3912 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003913 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003914 node = ebmb_next(node);
3915 }
3916 return err;
3917}
3918
Willy Tarreau55d37912016-12-21 23:38:39 +01003919/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3920 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3921 * alerts are directly emitted since the rest of the stack does it below.
3922 */
3923int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3924{
3925 struct proxy *px = bind_conf->frontend;
3926 int alloc_ctx;
3927 int err;
3928
3929 if (!bind_conf->is_ssl) {
3930 if (bind_conf->default_ctx) {
3931 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3932 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3933 }
3934 return 0;
3935 }
3936 if (!bind_conf->default_ctx) {
3937 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3938 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3939 return -1;
3940 }
3941
Willy Tarreauef934602016-12-22 23:12:01 +01003942 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003943 if (alloc_ctx < 0) {
3944 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3945 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");
3946 else
3947 Alert("Unable to allocate SSL session cache.\n");
3948 return -1;
3949 }
3950
3951 err = 0;
3952 /* initialize all certificate contexts */
3953 err += ssl_sock_prepare_all_ctx(bind_conf);
3954
3955 /* initialize CA variables if the certificates generation is enabled */
3956 err += ssl_sock_load_ca(bind_conf);
3957
3958 return -err;
3959}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003960
3961/* release ssl context allocated for servers. */
3962void ssl_sock_free_srv_ctx(struct server *srv)
3963{
3964 if (srv->ssl_ctx.ctx)
3965 SSL_CTX_free(srv->ssl_ctx.ctx);
3966}
3967
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003968/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003969 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3970 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003971void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003972{
3973 struct ebmb_node *node, *back;
3974 struct sni_ctx *sni;
3975
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003976 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003977 return;
3978
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003979 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003980 while (node) {
3981 sni = ebmb_entry(node, struct sni_ctx, name);
3982 back = ebmb_next(node);
3983 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003984 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003985 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003986 ssl_sock_free_ssl_conf(sni->conf);
3987 free(sni->conf);
3988 sni->conf = NULL;
3989 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003990 free(sni);
3991 node = back;
3992 }
3993
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003994 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003995 while (node) {
3996 sni = ebmb_entry(node, struct sni_ctx, name);
3997 back = ebmb_next(node);
3998 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003999 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02004000 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004001 ssl_sock_free_ssl_conf(sni->conf);
4002 free(sni->conf);
4003 sni->conf = NULL;
4004 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02004005 free(sni);
4006 node = back;
4007 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004008 SSL_CTX_free(bind_conf->initial_ctx);
4009 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02004010 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004011 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02004012}
4013
Willy Tarreau795cdab2016-12-22 17:30:54 +01004014/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
4015void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
4016{
4017 ssl_sock_free_ca(bind_conf);
4018 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01004019 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004020 free(bind_conf->ca_sign_file);
4021 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01004022 if (bind_conf->keys_ref) {
4023 free(bind_conf->keys_ref->filename);
4024 free(bind_conf->keys_ref->tlskeys);
4025 LIST_DEL(&bind_conf->keys_ref->list);
4026 free(bind_conf->keys_ref);
4027 }
4028 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004029 bind_conf->ca_sign_pass = NULL;
4030 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01004031}
4032
Christopher Faulet31af49d2015-06-09 17:29:50 +02004033/* Load CA cert file and private key used to generate certificates */
4034int
Willy Tarreau03209342016-12-22 17:08:28 +01004035ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02004036{
Willy Tarreau03209342016-12-22 17:08:28 +01004037 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004038 FILE *fp;
4039 X509 *cacert = NULL;
4040 EVP_PKEY *capkey = NULL;
4041 int err = 0;
4042
4043 if (!bind_conf || !bind_conf->generate_certs)
4044 return err;
4045
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004046#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01004047 if (global_ssl.ctx_cache)
4048 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02004049 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02004050#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02004051
Christopher Faulet31af49d2015-06-09 17:29:50 +02004052 if (!bind_conf->ca_sign_file) {
4053 Alert("Proxy '%s': cannot enable certificate generation, "
4054 "no CA certificate File configured at [%s:%d].\n",
4055 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004056 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004057 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004058
4059 /* read in the CA certificate */
4060 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
4061 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4062 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004063 goto load_error;
4064 }
4065 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
4066 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4067 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004068 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004069 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004070 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004071 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
4072 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
4073 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004074 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004075 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004076
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004077 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004078 bind_conf->ca_sign_cert = cacert;
4079 bind_conf->ca_sign_pkey = capkey;
4080 return err;
4081
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004082 read_error:
4083 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004084 if (capkey) EVP_PKEY_free(capkey);
4085 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004086 load_error:
4087 bind_conf->generate_certs = 0;
4088 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004089 return err;
4090}
4091
4092/* Release CA cert and private key used to generate certificated */
4093void
4094ssl_sock_free_ca(struct bind_conf *bind_conf)
4095{
4096 if (!bind_conf)
4097 return;
4098
4099 if (bind_conf->ca_sign_pkey)
4100 EVP_PKEY_free(bind_conf->ca_sign_pkey);
4101 if (bind_conf->ca_sign_cert)
4102 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01004103 bind_conf->ca_sign_pkey = NULL;
4104 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004105}
4106
Emeric Brun46591952012-05-18 15:47:34 +02004107/*
4108 * This function is called if SSL * context is not yet allocated. The function
4109 * is designed to be called before any other data-layer operation and sets the
4110 * handshake flag on the connection. It is safe to call it multiple times.
4111 * It returns 0 on success and -1 in error case.
4112 */
4113static int ssl_sock_init(struct connection *conn)
4114{
4115 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004116 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004117 return 0;
4118
Willy Tarreau3c728722014-01-23 13:50:42 +01004119 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004120 return 0;
4121
Willy Tarreau20879a02012-12-03 16:32:10 +01004122 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4123 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004124 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004125 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004126
Emeric Brun46591952012-05-18 15:47:34 +02004127 /* If it is in client mode initiate SSL session
4128 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004129 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004130 int may_retry = 1;
4131
4132 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004133 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004134 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004135 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004136 if (may_retry--) {
4137 pool_gc2();
4138 goto retry_connect;
4139 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004140 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004141 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004142 }
Emeric Brun46591952012-05-18 15:47:34 +02004143
Emeric Brun46591952012-05-18 15:47:34 +02004144 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004145 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4146 SSL_free(conn->xprt_ctx);
4147 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004148 if (may_retry--) {
4149 pool_gc2();
4150 goto retry_connect;
4151 }
Emeric Brun55476152014-11-12 17:35:37 +01004152 conn->err_code = CO_ER_SSL_NO_MEM;
4153 return -1;
4154 }
Emeric Brun46591952012-05-18 15:47:34 +02004155
Evan Broderbe554312013-06-27 00:05:25 -07004156 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004157 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4158 SSL_free(conn->xprt_ctx);
4159 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004160 if (may_retry--) {
4161 pool_gc2();
4162 goto retry_connect;
4163 }
Emeric Brun55476152014-11-12 17:35:37 +01004164 conn->err_code = CO_ER_SSL_NO_MEM;
4165 return -1;
4166 }
4167
4168 SSL_set_connect_state(conn->xprt_ctx);
4169 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4170 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4171 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4172 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4173 }
4174 }
Evan Broderbe554312013-06-27 00:05:25 -07004175
Emeric Brun46591952012-05-18 15:47:34 +02004176 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004177 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004178
4179 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004180 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004181 return 0;
4182 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004183 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004184 int may_retry = 1;
4185
4186 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004187 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004188 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004189 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004190 if (may_retry--) {
4191 pool_gc2();
4192 goto retry_accept;
4193 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004194 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004195 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004196 }
Emeric Brun46591952012-05-18 15:47:34 +02004197
Emeric Brun46591952012-05-18 15:47:34 +02004198 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004199 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4200 SSL_free(conn->xprt_ctx);
4201 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004202 if (may_retry--) {
4203 pool_gc2();
4204 goto retry_accept;
4205 }
Emeric Brun55476152014-11-12 17:35:37 +01004206 conn->err_code = CO_ER_SSL_NO_MEM;
4207 return -1;
4208 }
Emeric Brun46591952012-05-18 15:47:34 +02004209
Emeric Brune1f38db2012-09-03 20:36:47 +02004210 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004211 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4212 SSL_free(conn->xprt_ctx);
4213 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004214 if (may_retry--) {
4215 pool_gc2();
4216 goto retry_accept;
4217 }
Emeric Brun55476152014-11-12 17:35:37 +01004218 conn->err_code = CO_ER_SSL_NO_MEM;
4219 return -1;
4220 }
4221
4222 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004223
Emeric Brun46591952012-05-18 15:47:34 +02004224 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004225 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004226
4227 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004228 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004229 return 0;
4230 }
4231 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004232 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004233 return -1;
4234}
4235
4236
4237/* This is the callback which is used when an SSL handshake is pending. It
4238 * updates the FD status if it wants some polling before being called again.
4239 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4240 * otherwise it returns non-zero and removes itself from the connection's
4241 * flags (the bit is provided in <flag> by the caller).
4242 */
4243int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4244{
4245 int ret;
4246
Willy Tarreau3c728722014-01-23 13:50:42 +01004247 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004248 return 0;
4249
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004250 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004251 goto out_error;
4252
Emeric Brun674b7432012-11-08 19:21:55 +01004253 /* If we use SSL_do_handshake to process a reneg initiated by
4254 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4255 * Usually SSL_write and SSL_read are used and process implicitly
4256 * the reneg handshake.
4257 * Here we use SSL_peek as a workaround for reneg.
4258 */
4259 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4260 char c;
4261
4262 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4263 if (ret <= 0) {
4264 /* handshake may have not been completed, let's find why */
4265 ret = SSL_get_error(conn->xprt_ctx, ret);
4266 if (ret == SSL_ERROR_WANT_WRITE) {
4267 /* SSL handshake needs to write, L4 connection may not be ready */
4268 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004269 __conn_sock_want_send(conn);
4270 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004271 return 0;
4272 }
4273 else if (ret == SSL_ERROR_WANT_READ) {
4274 /* handshake may have been completed but we have
4275 * no more data to read.
4276 */
4277 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4278 ret = 1;
4279 goto reneg_ok;
4280 }
4281 /* SSL handshake needs to read, L4 connection is ready */
4282 if (conn->flags & CO_FL_WAIT_L4_CONN)
4283 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4284 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004285 __conn_sock_want_recv(conn);
4286 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004287 return 0;
4288 }
4289 else if (ret == SSL_ERROR_SYSCALL) {
4290 /* if errno is null, then connection was successfully established */
4291 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4292 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004293 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004294#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4295 conn->err_code = CO_ER_SSL_HANDSHAKE;
4296#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004297 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004298#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004299 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4300 empty_handshake = state == TLS_ST_BEFORE;
4301#else
4302 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4303#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004304 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004305 if (!errno) {
4306 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4307 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4308 else
4309 conn->err_code = CO_ER_SSL_EMPTY;
4310 }
4311 else {
4312 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4313 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4314 else
4315 conn->err_code = CO_ER_SSL_ABORT;
4316 }
4317 }
4318 else {
4319 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4320 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004321 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004322 conn->err_code = CO_ER_SSL_HANDSHAKE;
4323 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004324#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004325 }
Emeric Brun674b7432012-11-08 19:21:55 +01004326 goto out_error;
4327 }
4328 else {
4329 /* Fail on all other handshake errors */
4330 /* Note: OpenSSL may leave unread bytes in the socket's
4331 * buffer, causing an RST to be emitted upon close() on
4332 * TCP sockets. We first try to drain possibly pending
4333 * data to avoid this as much as possible.
4334 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004335 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004336 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004337 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4338 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004339 goto out_error;
4340 }
4341 }
4342 /* read some data: consider handshake completed */
4343 goto reneg_ok;
4344 }
4345
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004346 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004347 if (ret != 1) {
4348 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004349 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004350
4351 if (ret == SSL_ERROR_WANT_WRITE) {
4352 /* SSL handshake needs to write, L4 connection may not be ready */
4353 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004354 __conn_sock_want_send(conn);
4355 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004356 return 0;
4357 }
4358 else if (ret == SSL_ERROR_WANT_READ) {
4359 /* SSL handshake needs to read, L4 connection is ready */
4360 if (conn->flags & CO_FL_WAIT_L4_CONN)
4361 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4362 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004363 __conn_sock_want_recv(conn);
4364 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004365 return 0;
4366 }
Willy Tarreau89230192012-09-28 20:22:13 +02004367 else if (ret == SSL_ERROR_SYSCALL) {
4368 /* if errno is null, then connection was successfully established */
4369 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4370 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004371 if (!conn->err_code) {
4372#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4373 conn->err_code = CO_ER_SSL_HANDSHAKE;
4374#else
4375 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004376#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004377 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4378 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004379#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004380 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004381#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004382 if (empty_handshake) {
4383 if (!errno) {
4384 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4385 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4386 else
4387 conn->err_code = CO_ER_SSL_EMPTY;
4388 }
4389 else {
4390 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4391 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4392 else
4393 conn->err_code = CO_ER_SSL_ABORT;
4394 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004395 }
4396 else {
4397 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4398 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4399 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004400 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004401 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004402#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004403 }
Willy Tarreau89230192012-09-28 20:22:13 +02004404 goto out_error;
4405 }
Emeric Brun46591952012-05-18 15:47:34 +02004406 else {
4407 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004408 /* Note: OpenSSL may leave unread bytes in the socket's
4409 * buffer, causing an RST to be emitted upon close() on
4410 * TCP sockets. We first try to drain possibly pending
4411 * data to avoid this as much as possible.
4412 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004413 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004414 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004415 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4416 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004417 goto out_error;
4418 }
4419 }
4420
Emeric Brun674b7432012-11-08 19:21:55 +01004421reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004422 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004423 if (!SSL_session_reused(conn->xprt_ctx)) {
4424 if (objt_server(conn->target)) {
4425 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4426 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4427 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4428
Emeric Brun46591952012-05-18 15:47:34 +02004429 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004430 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004431 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004432 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4433 }
Emeric Brun46591952012-05-18 15:47:34 +02004434
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004435 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4436 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004437 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004438 else {
4439 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4440 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4441 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4442 }
Emeric Brun46591952012-05-18 15:47:34 +02004443 }
4444
4445 /* The connection is now established at both layers, it's time to leave */
4446 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4447 return 1;
4448
4449 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004450 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004451 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004452 ERR_clear_error();
4453
Emeric Brun9fa89732012-10-04 17:09:56 +02004454 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004455 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4456 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4457 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004458 }
4459
Emeric Brun46591952012-05-18 15:47:34 +02004460 /* Fail on all other handshake errors */
4461 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004462 if (!conn->err_code)
4463 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004464 return 0;
4465}
4466
4467/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004468 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004469 * buffer wraps, in which case a second call may be performed. The connection's
4470 * flags are updated with whatever special event is detected (error, read0,
4471 * empty). The caller is responsible for taking care of those events and
4472 * avoiding the call if inappropriate. The function does not call the
4473 * connection's polling update function, so the caller is responsible for this.
4474 */
4475static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4476{
4477 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004478 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004479
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004480 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004481 goto out_error;
4482
4483 if (conn->flags & CO_FL_HANDSHAKE)
4484 /* a handshake was requested */
4485 return 0;
4486
Willy Tarreauabf08d92014-01-14 11:31:27 +01004487 /* let's realign the buffer to optimize I/O */
4488 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004489 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004490
4491 /* read the largest possible block. For this, we perform only one call
4492 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4493 * in which case we accept to do it once again. A new attempt is made on
4494 * EINTR too.
4495 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004496 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004497 /* first check if we have some room after p+i */
4498 try = buf->data + buf->size - (buf->p + buf->i);
4499 /* otherwise continue between data and p-o */
4500 if (try <= 0) {
4501 try = buf->p - (buf->data + buf->o);
4502 if (try <= 0)
4503 break;
4504 }
4505 if (try > count)
4506 try = count;
4507
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004508 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004509 if (conn->flags & CO_FL_ERROR) {
4510 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004511 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004512 }
Emeric Brun46591952012-05-18 15:47:34 +02004513 if (ret > 0) {
4514 buf->i += ret;
4515 done += ret;
4516 if (ret < try)
4517 break;
4518 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004519 }
4520 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004521 ret = SSL_get_error(conn->xprt_ctx, ret);
4522 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004523 /* error on protocol or underlying transport */
4524 if ((ret != SSL_ERROR_SYSCALL)
4525 || (errno && (errno != EAGAIN)))
4526 conn->flags |= CO_FL_ERROR;
4527
Emeric Brun644cde02012-12-14 11:21:13 +01004528 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004529 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004530 ERR_clear_error();
4531 }
Emeric Brun46591952012-05-18 15:47:34 +02004532 goto read0;
4533 }
4534 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004535 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004536 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004537 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004538 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004539 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004540 break;
4541 }
4542 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004543 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4544 /* handshake is running, and it may need to re-enable read */
4545 conn->flags |= CO_FL_SSL_WAIT_HS;
4546 __conn_sock_want_recv(conn);
4547 break;
4548 }
Emeric Brun46591952012-05-18 15:47:34 +02004549 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004550 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004551 break;
4552 }
4553 /* otherwise it's a real error */
4554 goto out_error;
4555 }
4556 }
4557 return done;
4558
4559 read0:
4560 conn_sock_read0(conn);
4561 return done;
4562 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004563 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004564 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004565 ERR_clear_error();
4566
Emeric Brun46591952012-05-18 15:47:34 +02004567 conn->flags |= CO_FL_ERROR;
4568 return done;
4569}
4570
4571
4572/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004573 * <flags> may contain some CO_SFL_* flags to hint the system about other
4574 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004575 * Only one call to send() is performed, unless the buffer wraps, in which case
4576 * a second call may be performed. The connection's flags are updated with
4577 * whatever special event is detected (error, empty). The caller is responsible
4578 * for taking care of those events and avoiding the call if inappropriate. The
4579 * function does not call the connection's polling update function, so the caller
4580 * is responsible for this.
4581 */
4582static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4583{
4584 int ret, try, done;
4585
4586 done = 0;
4587
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004588 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004589 goto out_error;
4590
4591 if (conn->flags & CO_FL_HANDSHAKE)
4592 /* a handshake was requested */
4593 return 0;
4594
4595 /* send the largest possible block. For this we perform only one call
4596 * to send() unless the buffer wraps and we exactly fill the first hunk,
4597 * in which case we accept to do it once again.
4598 */
4599 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004600 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004601
Willy Tarreau7bed9452014-02-02 02:00:24 +01004602 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004603 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004604 global_ssl.max_record && try > global_ssl.max_record) {
4605 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004606 }
4607 else {
4608 /* we need to keep the information about the fact that
4609 * we're not limiting the upcoming send(), because if it
4610 * fails, we'll have to retry with at least as many data.
4611 */
4612 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4613 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004614
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004615 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004616
Emeric Brune1f38db2012-09-03 20:36:47 +02004617 if (conn->flags & CO_FL_ERROR) {
4618 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004619 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004620 }
Emeric Brun46591952012-05-18 15:47:34 +02004621 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004622 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4623
Emeric Brun46591952012-05-18 15:47:34 +02004624 buf->o -= ret;
4625 done += ret;
4626
Willy Tarreau5fb38032012-12-16 19:39:09 +01004627 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004628 /* optimize data alignment in the buffer */
4629 buf->p = buf->data;
4630
4631 /* if the system buffer is full, don't insist */
4632 if (ret < try)
4633 break;
4634 }
4635 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004636 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004637 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004638 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4639 /* handshake is running, and it may need to re-enable write */
4640 conn->flags |= CO_FL_SSL_WAIT_HS;
4641 __conn_sock_want_send(conn);
4642 break;
4643 }
Emeric Brun46591952012-05-18 15:47:34 +02004644 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004645 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004646 break;
4647 }
4648 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004649 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004650 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004651 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004652 break;
4653 }
4654 goto out_error;
4655 }
4656 }
4657 return done;
4658
4659 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004660 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004661 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004662 ERR_clear_error();
4663
Emeric Brun46591952012-05-18 15:47:34 +02004664 conn->flags |= CO_FL_ERROR;
4665 return done;
4666}
4667
Emeric Brun46591952012-05-18 15:47:34 +02004668static void ssl_sock_close(struct connection *conn) {
4669
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004670 if (conn->xprt_ctx) {
4671 SSL_free(conn->xprt_ctx);
4672 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004673 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004674 }
Emeric Brun46591952012-05-18 15:47:34 +02004675}
4676
4677/* This function tries to perform a clean shutdown on an SSL connection, and in
4678 * any case, flags the connection as reusable if no handshake was in progress.
4679 */
4680static void ssl_sock_shutw(struct connection *conn, int clean)
4681{
4682 if (conn->flags & CO_FL_HANDSHAKE)
4683 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004684 if (!clean)
4685 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004686 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004687 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004688 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004689 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004690 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004691 ERR_clear_error();
4692 }
Emeric Brun46591952012-05-18 15:47:34 +02004693}
4694
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004695/* used for logging, may be changed for a sample fetch later */
4696const char *ssl_sock_get_cipher_name(struct connection *conn)
4697{
4698 if (!conn->xprt && !conn->xprt_ctx)
4699 return NULL;
4700 return SSL_get_cipher_name(conn->xprt_ctx);
4701}
4702
4703/* used for logging, may be changed for a sample fetch later */
4704const char *ssl_sock_get_proto_version(struct connection *conn)
4705{
4706 if (!conn->xprt && !conn->xprt_ctx)
4707 return NULL;
4708 return SSL_get_version(conn->xprt_ctx);
4709}
4710
Willy Tarreau8d598402012-10-22 17:58:39 +02004711/* Extract a serial from a cert, and copy it to a chunk.
4712 * Returns 1 if serial is found and copied, 0 if no serial found and
4713 * -1 if output is not large enough.
4714 */
4715static int
4716ssl_sock_get_serial(X509 *crt, struct chunk *out)
4717{
4718 ASN1_INTEGER *serial;
4719
4720 serial = X509_get_serialNumber(crt);
4721 if (!serial)
4722 return 0;
4723
4724 if (out->size < serial->length)
4725 return -1;
4726
4727 memcpy(out->str, serial->data, serial->length);
4728 out->len = serial->length;
4729 return 1;
4730}
4731
Emeric Brun43e79582014-10-29 19:03:26 +01004732/* Extract a cert to der, and copy it to a chunk.
4733 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4734 * -1 if output is not large enough.
4735 */
4736static int
4737ssl_sock_crt2der(X509 *crt, struct chunk *out)
4738{
4739 int len;
4740 unsigned char *p = (unsigned char *)out->str;;
4741
4742 len =i2d_X509(crt, NULL);
4743 if (len <= 0)
4744 return 1;
4745
4746 if (out->size < len)
4747 return -1;
4748
4749 i2d_X509(crt,&p);
4750 out->len = len;
4751 return 1;
4752}
4753
Emeric Brunce5ad802012-10-22 14:11:22 +02004754
4755/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4756 * Returns 1 if serial is found and copied, 0 if no valid time found
4757 * and -1 if output is not large enough.
4758 */
4759static int
4760ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4761{
4762 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4763 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4764
4765 if (gentm->length < 12)
4766 return 0;
4767 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4768 return 0;
4769 if (out->size < gentm->length-2)
4770 return -1;
4771
4772 memcpy(out->str, gentm->data+2, gentm->length-2);
4773 out->len = gentm->length-2;
4774 return 1;
4775 }
4776 else if (tm->type == V_ASN1_UTCTIME) {
4777 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4778
4779 if (utctm->length < 10)
4780 return 0;
4781 if (utctm->data[0] >= 0x35)
4782 return 0;
4783 if (out->size < utctm->length)
4784 return -1;
4785
4786 memcpy(out->str, utctm->data, utctm->length);
4787 out->len = utctm->length;
4788 return 1;
4789 }
4790
4791 return 0;
4792}
4793
Emeric Brun87855892012-10-17 17:39:35 +02004794/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4795 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4796 */
4797static int
4798ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4799{
4800 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004801 ASN1_OBJECT *obj;
4802 ASN1_STRING *data;
4803 const unsigned char *data_ptr;
4804 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004805 int i, j, n;
4806 int cur = 0;
4807 const char *s;
4808 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004809 int name_count;
4810
4811 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004812
4813 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004814 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004815 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004816 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004817 else
4818 j = i;
4819
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004820 ne = X509_NAME_get_entry(a, j);
4821 obj = X509_NAME_ENTRY_get_object(ne);
4822 data = X509_NAME_ENTRY_get_data(ne);
4823 data_ptr = ASN1_STRING_get0_data(data);
4824 data_len = ASN1_STRING_length(data);
4825 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004826 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004827 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004828 s = tmp;
4829 }
4830
4831 if (chunk_strcasecmp(entry, s) != 0)
4832 continue;
4833
4834 if (pos < 0)
4835 cur--;
4836 else
4837 cur++;
4838
4839 if (cur != pos)
4840 continue;
4841
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004842 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004843 return -1;
4844
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004845 memcpy(out->str, data_ptr, data_len);
4846 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004847 return 1;
4848 }
4849
4850 return 0;
4851
4852}
4853
4854/* Extract and format full DN from a X509_NAME and copy result into a chunk
4855 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4856 */
4857static int
4858ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4859{
4860 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004861 ASN1_OBJECT *obj;
4862 ASN1_STRING *data;
4863 const unsigned char *data_ptr;
4864 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004865 int i, n, ln;
4866 int l = 0;
4867 const char *s;
4868 char *p;
4869 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004870 int name_count;
4871
4872
4873 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004874
4875 out->len = 0;
4876 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004877 for (i = 0; i < name_count; i++) {
4878 ne = X509_NAME_get_entry(a, i);
4879 obj = X509_NAME_ENTRY_get_object(ne);
4880 data = X509_NAME_ENTRY_get_data(ne);
4881 data_ptr = ASN1_STRING_get0_data(data);
4882 data_len = ASN1_STRING_length(data);
4883 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004884 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004885 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004886 s = tmp;
4887 }
4888 ln = strlen(s);
4889
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004890 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004891 if (l > out->size)
4892 return -1;
4893 out->len = l;
4894
4895 *(p++)='/';
4896 memcpy(p, s, ln);
4897 p += ln;
4898 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004899 memcpy(p, data_ptr, data_len);
4900 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004901 }
4902
4903 if (!out->len)
4904 return 0;
4905
4906 return 1;
4907}
4908
David Safb76832014-05-08 23:42:08 -04004909char *ssl_sock_get_version(struct connection *conn)
4910{
4911 if (!ssl_sock_is_ssl(conn))
4912 return NULL;
4913
4914 return (char *)SSL_get_version(conn->xprt_ctx);
4915}
4916
Willy Tarreau119a4082016-12-22 21:58:38 +01004917/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4918 * to disable SNI.
4919 */
Willy Tarreau63076412015-07-10 11:33:32 +02004920void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4921{
4922#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004923 char *prev_name;
4924
Willy Tarreau63076412015-07-10 11:33:32 +02004925 if (!ssl_sock_is_ssl(conn))
4926 return;
4927
Willy Tarreau119a4082016-12-22 21:58:38 +01004928 /* if the SNI changes, we must destroy the reusable context so that a
4929 * new connection will present a new SNI. As an optimization we could
4930 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4931 * server.
4932 */
4933 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4934 if ((!prev_name && hostname) ||
4935 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4936 SSL_set_session(conn->xprt_ctx, NULL);
4937
Willy Tarreau63076412015-07-10 11:33:32 +02004938 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4939#endif
4940}
4941
Emeric Brun0abf8362014-06-24 18:26:41 +02004942/* Extract peer certificate's common name into the chunk dest
4943 * Returns
4944 * the len of the extracted common name
4945 * or 0 if no CN found in DN
4946 * or -1 on error case (i.e. no peer certificate)
4947 */
4948int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004949{
4950 X509 *crt = NULL;
4951 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004952 const char find_cn[] = "CN";
4953 const struct chunk find_cn_chunk = {
4954 .str = (char *)&find_cn,
4955 .len = sizeof(find_cn)-1
4956 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004957 int result = -1;
David Safb76832014-05-08 23:42:08 -04004958
4959 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004960 goto out;
David Safb76832014-05-08 23:42:08 -04004961
4962 /* SSL_get_peer_certificate, it increase X509 * ref count */
4963 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4964 if (!crt)
4965 goto out;
4966
4967 name = X509_get_subject_name(crt);
4968 if (!name)
4969 goto out;
David Safb76832014-05-08 23:42:08 -04004970
Emeric Brun0abf8362014-06-24 18:26:41 +02004971 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4972out:
David Safb76832014-05-08 23:42:08 -04004973 if (crt)
4974 X509_free(crt);
4975
4976 return result;
4977}
4978
Dave McCowan328fb582014-07-30 10:39:13 -04004979/* returns 1 if client passed a certificate for this session, 0 if not */
4980int ssl_sock_get_cert_used_sess(struct connection *conn)
4981{
4982 X509 *crt = NULL;
4983
4984 if (!ssl_sock_is_ssl(conn))
4985 return 0;
4986
4987 /* SSL_get_peer_certificate, it increase X509 * ref count */
4988 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4989 if (!crt)
4990 return 0;
4991
4992 X509_free(crt);
4993 return 1;
4994}
4995
4996/* returns 1 if client passed a certificate for this connection, 0 if not */
4997int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004998{
4999 if (!ssl_sock_is_ssl(conn))
5000 return 0;
5001
5002 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
5003}
5004
5005/* returns result from SSL verify */
5006unsigned int ssl_sock_get_verify_result(struct connection *conn)
5007{
5008 if (!ssl_sock_is_ssl(conn))
5009 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
5010
5011 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
5012}
5013
Willy Tarreau7875d092012-09-10 08:20:03 +02005014/***** Below are some sample fetching functions for ACL/patterns *****/
5015
Emeric Brune64aef12012-09-21 13:15:06 +02005016/* boolean, returns true if client cert was present */
5017static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005018smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02005019{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005020 struct connection *conn;
5021
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005022 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005023 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02005024 return 0;
5025
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005026 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02005027 smp->flags |= SMP_F_MAY_CHANGE;
5028 return 0;
5029 }
5030
5031 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005032 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005033 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02005034
5035 return 1;
5036}
5037
Emeric Brun43e79582014-10-29 19:03:26 +01005038/* binary, returns a certificate in a binary chunk (der/raw).
5039 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5040 * should be use.
5041 */
5042static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005043smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01005044{
5045 int cert_peer = (kw[4] == 'c') ? 1 : 0;
5046 X509 *crt = NULL;
5047 int ret = 0;
5048 struct chunk *smp_trash;
5049 struct connection *conn;
5050
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005051 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01005052 if (!conn || conn->xprt != &ssl_sock)
5053 return 0;
5054
5055 if (!(conn->flags & CO_FL_CONNECTED)) {
5056 smp->flags |= SMP_F_MAY_CHANGE;
5057 return 0;
5058 }
5059
5060 if (cert_peer)
5061 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5062 else
5063 crt = SSL_get_certificate(conn->xprt_ctx);
5064
5065 if (!crt)
5066 goto out;
5067
5068 smp_trash = get_trash_chunk();
5069 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
5070 goto out;
5071
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005072 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005073 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01005074 ret = 1;
5075out:
5076 /* SSL_get_peer_certificate, it increase X509 * ref count */
5077 if (cert_peer && crt)
5078 X509_free(crt);
5079 return ret;
5080}
5081
Emeric Brunba841a12014-04-30 17:05:08 +02005082/* binary, returns serial of certificate in a binary chunk.
5083 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5084 * should be use.
5085 */
Willy Tarreau8d598402012-10-22 17:58:39 +02005086static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005087smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02005088{
Emeric Brunba841a12014-04-30 17:05:08 +02005089 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02005090 X509 *crt = NULL;
5091 int ret = 0;
5092 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005093 struct connection *conn;
5094
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005095 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005096 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02005097 return 0;
5098
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005099 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02005100 smp->flags |= SMP_F_MAY_CHANGE;
5101 return 0;
5102 }
5103
Emeric Brunba841a12014-04-30 17:05:08 +02005104 if (cert_peer)
5105 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5106 else
5107 crt = SSL_get_certificate(conn->xprt_ctx);
5108
Willy Tarreau8d598402012-10-22 17:58:39 +02005109 if (!crt)
5110 goto out;
5111
Willy Tarreau47ca5452012-12-23 20:22:19 +01005112 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005113 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5114 goto out;
5115
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005116 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005117 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005118 ret = 1;
5119out:
Emeric Brunba841a12014-04-30 17:05:08 +02005120 /* SSL_get_peer_certificate, it increase X509 * ref count */
5121 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005122 X509_free(crt);
5123 return ret;
5124}
Emeric Brune64aef12012-09-21 13:15:06 +02005125
Emeric Brunba841a12014-04-30 17:05:08 +02005126/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5127 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5128 * should be use.
5129 */
James Votha051b4a2013-05-14 20:37:59 +02005130static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005131smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005132{
Emeric Brunba841a12014-04-30 17:05:08 +02005133 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005134 X509 *crt = NULL;
5135 const EVP_MD *digest;
5136 int ret = 0;
5137 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005138 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005139
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005140 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005141 if (!conn || conn->xprt != &ssl_sock)
5142 return 0;
5143
5144 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005145 smp->flags |= SMP_F_MAY_CHANGE;
5146 return 0;
5147 }
5148
Emeric Brunba841a12014-04-30 17:05:08 +02005149 if (cert_peer)
5150 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5151 else
5152 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005153 if (!crt)
5154 goto out;
5155
5156 smp_trash = get_trash_chunk();
5157 digest = EVP_sha1();
5158 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5159
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005160 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005161 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005162 ret = 1;
5163out:
Emeric Brunba841a12014-04-30 17:05:08 +02005164 /* SSL_get_peer_certificate, it increase X509 * ref count */
5165 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005166 X509_free(crt);
5167 return ret;
5168}
5169
Emeric Brunba841a12014-04-30 17:05:08 +02005170/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5171 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5172 * should be use.
5173 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005174static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005175smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005176{
Emeric Brunba841a12014-04-30 17:05:08 +02005177 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005178 X509 *crt = NULL;
5179 int ret = 0;
5180 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005181 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005182
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005183 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005184 if (!conn || conn->xprt != &ssl_sock)
5185 return 0;
5186
5187 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005188 smp->flags |= SMP_F_MAY_CHANGE;
5189 return 0;
5190 }
5191
Emeric Brunba841a12014-04-30 17:05:08 +02005192 if (cert_peer)
5193 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5194 else
5195 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005196 if (!crt)
5197 goto out;
5198
Willy Tarreau47ca5452012-12-23 20:22:19 +01005199 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005200 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5201 goto out;
5202
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005203 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005204 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005205 ret = 1;
5206out:
Emeric Brunba841a12014-04-30 17:05:08 +02005207 /* SSL_get_peer_certificate, it increase X509 * ref count */
5208 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005209 X509_free(crt);
5210 return ret;
5211}
5212
Emeric Brunba841a12014-04-30 17:05:08 +02005213/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5214 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5215 * should be use.
5216 */
Emeric Brun87855892012-10-17 17:39:35 +02005217static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005218smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005219{
Emeric Brunba841a12014-04-30 17:05:08 +02005220 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005221 X509 *crt = NULL;
5222 X509_NAME *name;
5223 int ret = 0;
5224 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005225 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005226
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005227 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005228 if (!conn || conn->xprt != &ssl_sock)
5229 return 0;
5230
5231 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005232 smp->flags |= SMP_F_MAY_CHANGE;
5233 return 0;
5234 }
5235
Emeric Brunba841a12014-04-30 17:05:08 +02005236 if (cert_peer)
5237 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5238 else
5239 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005240 if (!crt)
5241 goto out;
5242
5243 name = X509_get_issuer_name(crt);
5244 if (!name)
5245 goto out;
5246
Willy Tarreau47ca5452012-12-23 20:22:19 +01005247 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005248 if (args && args[0].type == ARGT_STR) {
5249 int pos = 1;
5250
5251 if (args[1].type == ARGT_SINT)
5252 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005253
5254 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5255 goto out;
5256 }
5257 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5258 goto out;
5259
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005260 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005261 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005262 ret = 1;
5263out:
Emeric Brunba841a12014-04-30 17:05:08 +02005264 /* SSL_get_peer_certificate, it increase X509 * ref count */
5265 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005266 X509_free(crt);
5267 return ret;
5268}
5269
Emeric Brunba841a12014-04-30 17:05:08 +02005270/* string, returns notbefore date in ASN1_UTCTIME format.
5271 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5272 * should be use.
5273 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005274static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005275smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005276{
Emeric Brunba841a12014-04-30 17:05:08 +02005277 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005278 X509 *crt = NULL;
5279 int ret = 0;
5280 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005281 struct connection *conn;
5282
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005283 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005284 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005285 return 0;
5286
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005287 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005288 smp->flags |= SMP_F_MAY_CHANGE;
5289 return 0;
5290 }
5291
Emeric Brunba841a12014-04-30 17:05:08 +02005292 if (cert_peer)
5293 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5294 else
5295 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005296 if (!crt)
5297 goto out;
5298
Willy Tarreau47ca5452012-12-23 20:22:19 +01005299 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005300 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5301 goto out;
5302
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005303 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005304 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005305 ret = 1;
5306out:
Emeric Brunba841a12014-04-30 17:05:08 +02005307 /* SSL_get_peer_certificate, it increase X509 * ref count */
5308 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005309 X509_free(crt);
5310 return ret;
5311}
5312
Emeric Brunba841a12014-04-30 17:05:08 +02005313/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5314 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5315 * should be use.
5316 */
Emeric Brun87855892012-10-17 17:39:35 +02005317static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005318smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005319{
Emeric Brunba841a12014-04-30 17:05:08 +02005320 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005321 X509 *crt = NULL;
5322 X509_NAME *name;
5323 int ret = 0;
5324 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005325 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005326
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005327 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005328 if (!conn || conn->xprt != &ssl_sock)
5329 return 0;
5330
5331 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005332 smp->flags |= SMP_F_MAY_CHANGE;
5333 return 0;
5334 }
5335
Emeric Brunba841a12014-04-30 17:05:08 +02005336 if (cert_peer)
5337 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5338 else
5339 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005340 if (!crt)
5341 goto out;
5342
5343 name = X509_get_subject_name(crt);
5344 if (!name)
5345 goto out;
5346
Willy Tarreau47ca5452012-12-23 20:22:19 +01005347 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005348 if (args && args[0].type == ARGT_STR) {
5349 int pos = 1;
5350
5351 if (args[1].type == ARGT_SINT)
5352 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005353
5354 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5355 goto out;
5356 }
5357 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5358 goto out;
5359
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005360 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005361 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005362 ret = 1;
5363out:
Emeric Brunba841a12014-04-30 17:05:08 +02005364 /* SSL_get_peer_certificate, it increase X509 * ref count */
5365 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005366 X509_free(crt);
5367 return ret;
5368}
Emeric Brun9143d372012-12-20 15:44:16 +01005369
5370/* integer, returns true if current session use a client certificate */
5371static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005372smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005373{
5374 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005375 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005376
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005377 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005378 if (!conn || conn->xprt != &ssl_sock)
5379 return 0;
5380
5381 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005382 smp->flags |= SMP_F_MAY_CHANGE;
5383 return 0;
5384 }
5385
5386 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005387 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005388 if (crt) {
5389 X509_free(crt);
5390 }
5391
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005392 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005393 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005394 return 1;
5395}
5396
Emeric Brunba841a12014-04-30 17:05:08 +02005397/* integer, returns the certificate version
5398 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5399 * should be use.
5400 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005401static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005402smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005403{
Emeric Brunba841a12014-04-30 17:05:08 +02005404 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005405 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005406 struct connection *conn;
5407
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005408 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005409 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005410 return 0;
5411
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005412 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005413 smp->flags |= SMP_F_MAY_CHANGE;
5414 return 0;
5415 }
5416
Emeric Brunba841a12014-04-30 17:05:08 +02005417 if (cert_peer)
5418 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5419 else
5420 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005421 if (!crt)
5422 return 0;
5423
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005424 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005425 /* SSL_get_peer_certificate increase X509 * ref count */
5426 if (cert_peer)
5427 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005428 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005429
5430 return 1;
5431}
5432
Emeric Brunba841a12014-04-30 17:05:08 +02005433/* string, returns the certificate's signature algorithm.
5434 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5435 * should be use.
5436 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005437static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005438smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005439{
Emeric Brunba841a12014-04-30 17:05:08 +02005440 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005441 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005442 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005443 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005444 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005445
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005446 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005447 if (!conn || conn->xprt != &ssl_sock)
5448 return 0;
5449
5450 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005451 smp->flags |= SMP_F_MAY_CHANGE;
5452 return 0;
5453 }
5454
Emeric Brunba841a12014-04-30 17:05:08 +02005455 if (cert_peer)
5456 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5457 else
5458 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005459 if (!crt)
5460 return 0;
5461
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005462 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5463 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005464
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005465 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5466 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005467 /* SSL_get_peer_certificate increase X509 * ref count */
5468 if (cert_peer)
5469 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005470 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005471 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005472
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005473 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005474 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005475 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005476 /* SSL_get_peer_certificate increase X509 * ref count */
5477 if (cert_peer)
5478 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005479
5480 return 1;
5481}
5482
Emeric Brunba841a12014-04-30 17:05:08 +02005483/* string, returns the certificate's key algorithm.
5484 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5485 * should be use.
5486 */
Emeric Brun521a0112012-10-22 12:22:55 +02005487static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005488smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005489{
Emeric Brunba841a12014-04-30 17:05:08 +02005490 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005491 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005492 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005493 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005494 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005495
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005496 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005497 if (!conn || conn->xprt != &ssl_sock)
5498 return 0;
5499
5500 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005501 smp->flags |= SMP_F_MAY_CHANGE;
5502 return 0;
5503 }
5504
Emeric Brunba841a12014-04-30 17:05:08 +02005505 if (cert_peer)
5506 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5507 else
5508 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005509 if (!crt)
5510 return 0;
5511
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005512 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5513 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005514
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005515 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5516 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005517 /* SSL_get_peer_certificate increase X509 * ref count */
5518 if (cert_peer)
5519 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005520 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005521 }
Emeric Brun521a0112012-10-22 12:22:55 +02005522
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005523 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005524 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005525 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005526 if (cert_peer)
5527 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005528
5529 return 1;
5530}
5531
Emeric Brun645ae792014-04-30 14:21:06 +02005532/* boolean, returns true if front conn. transport layer is SSL.
5533 * This function is also usable on backend conn if the fetch keyword 5th
5534 * char is 'b'.
5535 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005536static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005537smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005538{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005539 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5540 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005541
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005542 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005543 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005544 return 1;
5545}
5546
Emeric Brun2525b6b2012-10-18 15:59:43 +02005547/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005548static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005549smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005550{
5551#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005552 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005553
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005554 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005555 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005556 conn->xprt_ctx &&
5557 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005558 return 1;
5559#else
5560 return 0;
5561#endif
5562}
5563
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005564/* boolean, returns true if client session has been resumed */
5565static int
5566smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5567{
5568 struct connection *conn = objt_conn(smp->sess->origin);
5569
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005570 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005571 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005572 conn->xprt_ctx &&
5573 SSL_session_reused(conn->xprt_ctx);
5574 return 1;
5575}
5576
Emeric Brun645ae792014-04-30 14:21:06 +02005577/* string, returns the used cipher if front conn. transport layer is SSL.
5578 * This function is also usable on backend conn if the fetch keyword 5th
5579 * char is 'b'.
5580 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005581static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005582smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005583{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005584 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5585 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005586
Willy Tarreaube508f12016-03-10 11:47:01 +01005587 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005588 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005589 return 0;
5590
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005591 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5592 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005593 return 0;
5594
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005595 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005596 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005597 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005598
5599 return 1;
5600}
5601
Emeric Brun645ae792014-04-30 14:21:06 +02005602/* integer, returns the algoritm's keysize if front conn. transport layer
5603 * is SSL.
5604 * This function is also usable on backend conn if the fetch keyword 5th
5605 * char is 'b'.
5606 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005607static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005608smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005609{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005610 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5611 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005612
Willy Tarreaue237fe12016-03-10 17:05:28 +01005613 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005614
Emeric Brun589fcad2012-10-16 14:13:26 +02005615 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005616 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005617 return 0;
5618
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005619 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005620 return 0;
5621
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005622 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005623 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005624
5625 return 1;
5626}
5627
Emeric Brun645ae792014-04-30 14:21:06 +02005628/* integer, returns the used keysize if front conn. transport layer 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_use_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 Tarreaube508f12016-03-10 11:47:01 +01005637
Emeric Brun589fcad2012-10-16 14:13:26 +02005638 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005639 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5640 return 0;
5641
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005642 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5643 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005644 return 0;
5645
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005646 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005647
5648 return 1;
5649}
5650
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005651#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005652static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005653smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005654{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005655 struct connection *conn;
5656
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005657 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005658 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005659
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005660 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005661 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5662 return 0;
5663
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005664 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005665 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005666 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005667
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005668 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005669 return 0;
5670
5671 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005672}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005673#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005674
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005675#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005676static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005677smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005678{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005679 struct connection *conn;
5680
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005681 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005682 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005683
Willy Tarreaue26bf052015-05-12 10:30:12 +02005684 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005685 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005686 return 0;
5687
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005688 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005689 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005690 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005691
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005692 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005693 return 0;
5694
5695 return 1;
5696}
5697#endif
5698
Emeric Brun645ae792014-04-30 14:21:06 +02005699/* string, returns the used protocol if front conn. transport layer is SSL.
5700 * This function is also usable on backend conn if the fetch keyword 5th
5701 * char is 'b'.
5702 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005703static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005704smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005705{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005706 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5707 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005708
Emeric Brun589fcad2012-10-16 14:13:26 +02005709 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005710 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5711 return 0;
5712
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005713 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5714 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005715 return 0;
5716
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005717 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005718 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005719 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005720
5721 return 1;
5722}
5723
Willy Tarreau87b09662015-04-03 00:22:06 +02005724/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005725 * This function is also usable on backend conn if the fetch keyword 5th
5726 * char is 'b'.
5727 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005728static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005729smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005730{
5731#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005732 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5733 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005734
Willy Tarreaue237fe12016-03-10 17:05:28 +01005735 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005736
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005737 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005738 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005739
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005740 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5741 return 0;
5742
Willy Tarreau192252e2015-04-04 01:47:55 +02005743 ssl_sess = SSL_get_session(conn->xprt_ctx);
5744 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005745 return 0;
5746
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005747 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5748 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005749 return 0;
5750
5751 return 1;
5752#else
5753 return 0;
5754#endif
5755}
5756
5757static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005758smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005759{
5760#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005761 struct connection *conn;
5762
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005763 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005764 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005765
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005766 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005767 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5768 return 0;
5769
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005770 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5771 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005772 return 0;
5773
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005774 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005775 return 1;
5776#else
5777 return 0;
5778#endif
5779}
5780
David Sc1ad52e2014-04-08 18:48:47 -04005781static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005782smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
5783{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005784 struct connection *conn;
5785 struct ssl_capture *capture;
5786
5787 conn = objt_conn(smp->sess->origin);
5788 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5789 return 0;
5790
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005791 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005792 if (!capture)
5793 return 0;
5794
5795 smp->flags = SMP_F_CONST;
5796 smp->data.type = SMP_T_BIN;
5797 smp->data.u.str.str = capture->ciphersuite;
5798 smp->data.u.str.len = capture->ciphersuite_len;
5799 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005800}
5801
5802static int
5803smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
5804{
5805 struct chunk *data;
5806
5807 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5808 return 0;
5809
5810 data = get_trash_chunk();
5811 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
5812 smp->data.type = SMP_T_BIN;
5813 smp->data.u.str = *data;
5814 return 1;
5815}
5816
5817static int
5818smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
5819{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005820 struct connection *conn;
5821 struct ssl_capture *capture;
5822
5823 conn = objt_conn(smp->sess->origin);
5824 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5825 return 0;
5826
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005827 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005828 if (!capture)
5829 return 0;
5830
5831 smp->data.type = SMP_T_SINT;
5832 smp->data.u.sint = capture->xxh64;
5833 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005834}
5835
5836static int
5837smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
5838{
5839#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
5840 struct chunk *data;
5841 SSL_CIPHER cipher;
5842 int i;
5843 const char *str;
5844 unsigned char *bin;
5845
5846 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5847 return 0;
5848
5849 /* The cipher algorith must not be SSL_SSLV2, because this
5850 * SSL version seems to not have the same cipher encoding,
5851 * and it is not supported by OpenSSL. Unfortunately, the
5852 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
5853 * with standard defines. We just set the variable to 0,
5854 * ensure that the match with SSL_SSLV2 fails.
5855 */
5856 cipher.algorithm_ssl = 0;
5857
5858 data = get_trash_chunk();
5859 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
5860 bin = (unsigned char *)smp->data.u.str.str + i;
5861 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
5862 str = SSL_CIPHER_standard_name(&cipher);
5863 if (!str || strcmp(str, "UNKNOWN") == 0)
5864 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
5865 else
5866 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
5867 }
5868 smp->data.type = SMP_T_STR;
5869 smp->data.u.str = *data;
5870 return 1;
5871#else
5872 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
5873#endif
5874}
5875
5876static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005877smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005878{
5879#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005880 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5881 smp->strm ? smp->strm->si[1].end : NULL);
5882
David Sc1ad52e2014-04-08 18:48:47 -04005883 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005884 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005885
5886 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005887 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5888 return 0;
5889
5890 if (!(conn->flags & CO_FL_CONNECTED)) {
5891 smp->flags |= SMP_F_MAY_CHANGE;
5892 return 0;
5893 }
5894
5895 finished_trash = get_trash_chunk();
5896 if (!SSL_session_reused(conn->xprt_ctx))
5897 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5898 else
5899 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5900
5901 if (!finished_len)
5902 return 0;
5903
Emeric Brunb73a9b02014-04-30 18:49:19 +02005904 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005905 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005906 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005907
5908 return 1;
5909#else
5910 return 0;
5911#endif
5912}
5913
Emeric Brun2525b6b2012-10-18 15:59:43 +02005914/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005915static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005916smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005917{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005918 struct connection *conn;
5919
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005920 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005921 if (!conn || conn->xprt != &ssl_sock)
5922 return 0;
5923
5924 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005925 smp->flags = SMP_F_MAY_CHANGE;
5926 return 0;
5927 }
5928
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005929 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005930 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005931 smp->flags = 0;
5932
5933 return 1;
5934}
5935
Emeric Brun2525b6b2012-10-18 15:59:43 +02005936/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005937static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005938smp_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 +02005939{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005940 struct connection *conn;
5941
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005942 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005943 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005944 return 0;
5945
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005946 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005947 smp->flags = SMP_F_MAY_CHANGE;
5948 return 0;
5949 }
5950
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005951 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005952 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005953 smp->flags = 0;
5954
5955 return 1;
5956}
5957
Emeric Brun2525b6b2012-10-18 15:59:43 +02005958/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005959static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005960smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005961{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005962 struct connection *conn;
5963
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005964 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005965 if (!conn || conn->xprt != &ssl_sock)
5966 return 0;
5967
5968 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005969 smp->flags = SMP_F_MAY_CHANGE;
5970 return 0;
5971 }
5972
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005973 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005974 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005975 smp->flags = 0;
5976
5977 return 1;
5978}
5979
Emeric Brun2525b6b2012-10-18 15:59:43 +02005980/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005981static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005982smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005983{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005984 struct connection *conn;
5985
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005986 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005987 if (!conn || conn->xprt != &ssl_sock)
5988 return 0;
5989
5990 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005991 smp->flags = SMP_F_MAY_CHANGE;
5992 return 0;
5993 }
5994
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005995 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005996 return 0;
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_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02006000 smp->flags = 0;
6001
6002 return 1;
6003}
6004
Emeric Brunfb510ea2012-10-05 12:00:26 +02006005/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006006static 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 +02006007{
6008 if (!*args[cur_arg + 1]) {
6009 if (err)
6010 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6011 return ERR_ALERT | ERR_FATAL;
6012 }
6013
Willy Tarreauef934602016-12-22 23:12:01 +01006014 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6015 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006016 else
6017 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006018
Emeric Brund94b3fe2012-09-20 18:23:56 +02006019 return 0;
6020}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006021static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6022{
6023 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
6024}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006025
Christopher Faulet31af49d2015-06-09 17:29:50 +02006026/* parse the "ca-sign-file" bind keyword */
6027static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6028{
6029 if (!*args[cur_arg + 1]) {
6030 if (err)
6031 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
6032 return ERR_ALERT | ERR_FATAL;
6033 }
6034
Willy Tarreauef934602016-12-22 23:12:01 +01006035 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6036 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02006037 else
6038 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
6039
6040 return 0;
6041}
6042
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006043/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006044static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6045{
6046 if (!*args[cur_arg + 1]) {
6047 if (err)
6048 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
6049 return ERR_ALERT | ERR_FATAL;
6050 }
6051 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
6052 return 0;
6053}
6054
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006055/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006056static 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 +02006057{
6058 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006059 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006060 return ERR_ALERT | ERR_FATAL;
6061 }
6062
Emeric Brun76d88952012-10-05 15:47:31 +02006063 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02006064 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006065 return 0;
6066}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006067static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6068{
6069 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
6070}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006071/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006072static 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 +02006073{
Willy Tarreau38011032013-08-13 16:59:39 +02006074 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02006075
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006076 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006077 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006078 return ERR_ALERT | ERR_FATAL;
6079 }
6080
Willy Tarreauef934602016-12-22 23:12:01 +01006081 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
6082 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02006083 memprintf(err, "'%s' : path too long", args[cur_arg]);
6084 return ERR_ALERT | ERR_FATAL;
6085 }
Willy Tarreauef934602016-12-22 23:12:01 +01006086 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01006087 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02006088 return ERR_ALERT | ERR_FATAL;
6089
6090 return 0;
6091 }
6092
Willy Tarreau03209342016-12-22 17:08:28 +01006093 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006094 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006095
6096 return 0;
6097}
6098
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006099/* parse the "crt-list" bind keyword */
6100static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6101{
6102 if (!*args[cur_arg + 1]) {
6103 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
6104 return ERR_ALERT | ERR_FATAL;
6105 }
6106
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006107 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006108 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006109 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006110 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006111
6112 return 0;
6113}
6114
Emeric Brunfb510ea2012-10-05 12:00:26 +02006115/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006116static 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 +02006117{
Emeric Brun051cdab2012-10-02 19:25:50 +02006118#ifndef X509_V_FLAG_CRL_CHECK
6119 if (err)
6120 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6121 return ERR_ALERT | ERR_FATAL;
6122#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006123 if (!*args[cur_arg + 1]) {
6124 if (err)
6125 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6126 return ERR_ALERT | ERR_FATAL;
6127 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006128
Willy Tarreauef934602016-12-22 23:12:01 +01006129 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6130 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006131 else
6132 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006133
Emeric Brun2b58d042012-09-20 17:10:03 +02006134 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006135#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006136}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006137static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6138{
6139 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6140}
Emeric Brun2b58d042012-09-20 17:10:03 +02006141
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006142/* parse the "curves" bind keyword keyword */
6143static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6144{
6145#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6146 if (!*args[cur_arg + 1]) {
6147 if (err)
6148 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6149 return ERR_ALERT | ERR_FATAL;
6150 }
6151 conf->curves = strdup(args[cur_arg + 1]);
6152 return 0;
6153#else
6154 if (err)
6155 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6156 return ERR_ALERT | ERR_FATAL;
6157#endif
6158}
6159static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6160{
6161 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6162}
6163
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006164/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006165static 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 +02006166{
6167#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6168 if (err)
6169 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6170 return ERR_ALERT | ERR_FATAL;
6171#elif defined(OPENSSL_NO_ECDH)
6172 if (err)
6173 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6174 return ERR_ALERT | ERR_FATAL;
6175#else
6176 if (!*args[cur_arg + 1]) {
6177 if (err)
6178 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6179 return ERR_ALERT | ERR_FATAL;
6180 }
6181
6182 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006183
6184 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006185#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006186}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006187static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6188{
6189 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6190}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006191
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006192/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006193static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6194{
6195 int code;
6196 char *p = args[cur_arg + 1];
6197 unsigned long long *ignerr = &conf->crt_ignerr;
6198
6199 if (!*p) {
6200 if (err)
6201 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6202 return ERR_ALERT | ERR_FATAL;
6203 }
6204
6205 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6206 ignerr = &conf->ca_ignerr;
6207
6208 if (strcmp(p, "all") == 0) {
6209 *ignerr = ~0ULL;
6210 return 0;
6211 }
6212
6213 while (p) {
6214 code = atoi(p);
6215 if ((code <= 0) || (code > 63)) {
6216 if (err)
6217 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6218 args[cur_arg], code, args[cur_arg + 1]);
6219 return ERR_ALERT | ERR_FATAL;
6220 }
6221 *ignerr |= 1ULL << code;
6222 p = strchr(p, ',');
6223 if (p)
6224 p++;
6225 }
6226
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006227 return 0;
6228}
6229
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006230/* parse tls_method_options "no-xxx" and "force-xxx" */
6231static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006232{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006233 uint16_t v;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006234 char *p;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006235 p = strchr(arg, '-');
6236 if (!p)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006237 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006238 p++;
6239 if (!strcmp(p, "sslv3"))
6240 v = CONF_SSLV3;
6241 else if (!strcmp(p, "tlsv10"))
6242 v = CONF_TLSV10;
6243 else if (!strcmp(p, "tlsv11"))
6244 v = CONF_TLSV11;
6245 else if (!strcmp(p, "tlsv12"))
6246 v = CONF_TLSV12;
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02006247 else if (!strcmp(p, "tlsv13"))
6248 v = CONF_TLSV13;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006249 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006250 goto fail;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006251 if (!strncmp(arg, "no-", 3))
6252 methods->flags |= methodVersions[v].flag;
6253 else if (!strncmp(arg, "force-", 6))
6254 methods->min = methods->max = v;
6255 else
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006256 goto fail;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006257 return 0;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006258 fail:
6259 if (err)
6260 memprintf(err, "'%s' : option not implemented", arg);
6261 return ERR_ALERT | ERR_FATAL;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006262}
6263
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006264static 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 +02006265{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006266 return parse_tls_method_options(args[cur_arg], &conf->ssl_methods, err);
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006267}
6268
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006269static 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 +02006270{
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006271 return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
6272}
6273
6274/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
6275static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
6276{
6277 uint16_t i, v = 0;
6278 char *argv = args[cur_arg + 1];
6279 if (!*argv) {
6280 if (err)
6281 memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
6282 return ERR_ALERT | ERR_FATAL;
6283 }
6284 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
6285 if (!strcmp(argv, methodVersions[i].name))
6286 v = i;
6287 if (!v) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006288 if (err)
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006289 memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006290 return ERR_ALERT | ERR_FATAL;
6291 }
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006292 if (!strcmp("ssl-min-ver", args[cur_arg]))
6293 methods->min = v;
6294 else if (!strcmp("ssl-max-ver", args[cur_arg]))
6295 methods->max = v;
6296 else {
6297 if (err)
6298 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
6299 return ERR_ALERT | ERR_FATAL;
6300 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006301 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006302}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006303
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006304static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6305{
6306 return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
6307}
6308
6309static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6310{
6311 return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
6312}
6313
Emeric Brun2d0c4822012-10-02 13:45:20 +02006314/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006315static 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 +02006316{
Emeric Brun89675492012-10-05 13:48:26 +02006317 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006318 return 0;
6319}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006320
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006321/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006322static 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 +02006323{
6324#ifdef OPENSSL_NPN_NEGOTIATED
6325 char *p1, *p2;
6326
6327 if (!*args[cur_arg + 1]) {
6328 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6329 return ERR_ALERT | ERR_FATAL;
6330 }
6331
6332 free(conf->npn_str);
6333
Willy Tarreau3724da12016-02-12 17:11:12 +01006334 /* the NPN string is built as a suite of (<len> <name>)*,
6335 * so we reuse each comma to store the next <len> and need
6336 * one more for the end of the string.
6337 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006338 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006339 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006340 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6341
6342 /* replace commas with the name length */
6343 p1 = conf->npn_str;
6344 p2 = p1 + 1;
6345 while (1) {
6346 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6347 if (!p2)
6348 p2 = p1 + 1 + strlen(p1 + 1);
6349
6350 if (p2 - (p1 + 1) > 255) {
6351 *p2 = '\0';
6352 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6353 return ERR_ALERT | ERR_FATAL;
6354 }
6355
6356 *p1 = p2 - (p1 + 1);
6357 p1 = p2;
6358
6359 if (!*p2)
6360 break;
6361
6362 *(p2++) = '\0';
6363 }
6364 return 0;
6365#else
6366 if (err)
6367 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6368 return ERR_ALERT | ERR_FATAL;
6369#endif
6370}
6371
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006372static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6373{
6374 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6375}
6376
Willy Tarreauab861d32013-04-02 02:30:41 +02006377/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006378static 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 +02006379{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006380#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006381 char *p1, *p2;
6382
6383 if (!*args[cur_arg + 1]) {
6384 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6385 return ERR_ALERT | ERR_FATAL;
6386 }
6387
6388 free(conf->alpn_str);
6389
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006390 /* the ALPN string is built as a suite of (<len> <name>)*,
6391 * so we reuse each comma to store the next <len> and need
6392 * one more for the end of the string.
6393 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006394 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006395 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006396 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6397
6398 /* replace commas with the name length */
6399 p1 = conf->alpn_str;
6400 p2 = p1 + 1;
6401 while (1) {
6402 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6403 if (!p2)
6404 p2 = p1 + 1 + strlen(p1 + 1);
6405
6406 if (p2 - (p1 + 1) > 255) {
6407 *p2 = '\0';
6408 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6409 return ERR_ALERT | ERR_FATAL;
6410 }
6411
6412 *p1 = p2 - (p1 + 1);
6413 p1 = p2;
6414
6415 if (!*p2)
6416 break;
6417
6418 *(p2++) = '\0';
6419 }
6420 return 0;
6421#else
6422 if (err)
6423 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6424 return ERR_ALERT | ERR_FATAL;
6425#endif
6426}
6427
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006428static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6429{
6430 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6431}
6432
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006433/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006434static 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 +02006435{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006436 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006437 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006438
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006439 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6440 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006441 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006442 conf->ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
6443 if (!conf->ssl_methods.min)
6444 conf->ssl_methods.min = global_ssl.listen_default_sslmethods.min;
6445 if (!conf->ssl_methods.max)
6446 conf->ssl_methods.max = global_ssl.listen_default_sslmethods.max;
Emeric Brun76d88952012-10-05 15:47:31 +02006447
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006448 return 0;
6449}
6450
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006451/* parse the "prefer-client-ciphers" bind keyword */
6452static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6453{
6454 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
6455 return 0;
6456}
6457
Christopher Faulet31af49d2015-06-09 17:29:50 +02006458/* parse the "generate-certificates" bind keyword */
6459static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6460{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006461#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006462 conf->generate_certs = 1;
6463#else
6464 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6465 err && *err ? *err : "");
6466#endif
6467 return 0;
6468}
6469
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006470/* parse the "strict-sni" bind keyword */
6471static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6472{
6473 conf->strict_sni = 1;
6474 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006475}
6476
6477/* parse the "tls-ticket-keys" bind keyword */
6478static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6479{
6480#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6481 FILE *f;
6482 int i = 0;
6483 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006484 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006485
6486 if (!*args[cur_arg + 1]) {
6487 if (err)
6488 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6489 return ERR_ALERT | ERR_FATAL;
6490 }
6491
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006492 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6493 if(keys_ref) {
6494 conf->keys_ref = keys_ref;
6495 return 0;
6496 }
6497
Vincent Bernat02779b62016-04-03 13:48:43 +02006498 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006499 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006500
6501 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6502 if (err)
6503 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6504 return ERR_ALERT | ERR_FATAL;
6505 }
6506
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006507 keys_ref->filename = strdup(args[cur_arg + 1]);
6508
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006509 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6510 int len = strlen(thisline);
6511 /* Strip newline characters from the end */
6512 if(thisline[len - 1] == '\n')
6513 thisline[--len] = 0;
6514
6515 if(thisline[len - 1] == '\r')
6516 thisline[--len] = 0;
6517
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006518 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 +01006519 if (err)
6520 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006521 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006522 return ERR_ALERT | ERR_FATAL;
6523 }
6524 i++;
6525 }
6526
6527 if (i < TLS_TICKETS_NO) {
6528 if (err)
6529 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 +02006530 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006531 return ERR_ALERT | ERR_FATAL;
6532 }
6533
6534 fclose(f);
6535
6536 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006537 i -= 2;
6538 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006539 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006540 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006541
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006542 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6543
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006544 return 0;
6545#else
6546 if (err)
6547 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6548 return ERR_ALERT | ERR_FATAL;
6549#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006550}
6551
Emeric Brund94b3fe2012-09-20 18:23:56 +02006552/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006553static 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 +02006554{
6555 if (!*args[cur_arg + 1]) {
6556 if (err)
6557 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6558 return ERR_ALERT | ERR_FATAL;
6559 }
6560
6561 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006562 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006563 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006564 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006565 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006566 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006567 else {
6568 if (err)
6569 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6570 args[cur_arg], args[cur_arg + 1]);
6571 return ERR_ALERT | ERR_FATAL;
6572 }
6573
6574 return 0;
6575}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006576static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6577{
6578 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6579}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006580
Willy Tarreau92faadf2012-10-10 23:04:25 +02006581/************** "server" keywords ****************/
6582
Emeric Brunef42d922012-10-11 16:11:36 +02006583/* parse the "ca-file" server keyword */
6584static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6585{
6586 if (!*args[*cur_arg + 1]) {
6587 if (err)
6588 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6589 return ERR_ALERT | ERR_FATAL;
6590 }
6591
Willy Tarreauef934602016-12-22 23:12:01 +01006592 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6593 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006594 else
6595 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6596
6597 return 0;
6598}
6599
Willy Tarreau92faadf2012-10-10 23:04:25 +02006600/* parse the "check-ssl" server keyword */
6601static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6602{
6603 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006604 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6605 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6606 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006607 newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
6608 if (!newsrv->ssl_ctx.methods.min)
6609 newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
6610 if (!newsrv->ssl_ctx.methods.max)
6611 newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
6612
Willy Tarreau92faadf2012-10-10 23:04:25 +02006613 return 0;
6614}
6615
6616/* parse the "ciphers" server keyword */
6617static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6618{
6619 if (!*args[*cur_arg + 1]) {
6620 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6621 return ERR_ALERT | ERR_FATAL;
6622 }
6623
6624 free(newsrv->ssl_ctx.ciphers);
6625 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6626 return 0;
6627}
6628
Emeric Brunef42d922012-10-11 16:11:36 +02006629/* parse the "crl-file" server keyword */
6630static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6631{
6632#ifndef X509_V_FLAG_CRL_CHECK
6633 if (err)
6634 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6635 return ERR_ALERT | ERR_FATAL;
6636#else
6637 if (!*args[*cur_arg + 1]) {
6638 if (err)
6639 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6640 return ERR_ALERT | ERR_FATAL;
6641 }
6642
Willy Tarreauef934602016-12-22 23:12:01 +01006643 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6644 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006645 else
6646 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6647
6648 return 0;
6649#endif
6650}
6651
Emeric Bruna7aa3092012-10-26 12:58:00 +02006652/* parse the "crt" server keyword */
6653static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6654{
6655 if (!*args[*cur_arg + 1]) {
6656 if (err)
6657 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6658 return ERR_ALERT | ERR_FATAL;
6659 }
6660
Willy Tarreauef934602016-12-22 23:12:01 +01006661 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6662 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006663 else
6664 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6665
6666 return 0;
6667}
Emeric Brunef42d922012-10-11 16:11:36 +02006668
Frédéric Lécaille340ae602017-03-13 10:38:04 +01006669/* parse the "no-check-ssl" server keyword */
6670static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6671{
6672 newsrv->check.use_ssl = 0;
6673 free(newsrv->ssl_ctx.ciphers);
6674 newsrv->ssl_ctx.ciphers = NULL;
6675 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
6676 return 0;
6677}
6678
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01006679/* parse the "no-send-proxy-v2-ssl" server keyword */
6680static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6681{
6682 newsrv->pp_opts &= ~SRV_PP_V2;
6683 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
6684 return 0;
6685}
6686
6687/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
6688static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6689{
6690 newsrv->pp_opts &= ~SRV_PP_V2;
6691 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
6692 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
6693 return 0;
6694}
6695
Frédéric Lécaillee381d762017-03-13 11:54:17 +01006696/* parse the "no-ssl" server keyword */
6697static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6698{
6699 newsrv->use_ssl = 0;
6700 free(newsrv->ssl_ctx.ciphers);
6701 newsrv->ssl_ctx.ciphers = NULL;
6702 return 0;
6703}
6704
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006705/* parse the "no-ssl-reuse" server keyword */
6706static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6707{
6708 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6709 return 0;
6710}
6711
Emeric Brunf9c5c472012-10-11 15:28:34 +02006712/* parse the "no-tls-tickets" server keyword */
6713static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6714{
6715 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6716 return 0;
6717}
David Safb76832014-05-08 23:42:08 -04006718/* parse the "send-proxy-v2-ssl" server keyword */
6719static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6720{
6721 newsrv->pp_opts |= SRV_PP_V2;
6722 newsrv->pp_opts |= SRV_PP_V2_SSL;
6723 return 0;
6724}
6725
6726/* parse the "send-proxy-v2-ssl-cn" server keyword */
6727static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6728{
6729 newsrv->pp_opts |= SRV_PP_V2;
6730 newsrv->pp_opts |= SRV_PP_V2_SSL;
6731 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6732 return 0;
6733}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006734
Willy Tarreau732eac42015-07-09 11:40:25 +02006735/* parse the "sni" server keyword */
6736static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6737{
6738#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6739 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6740 return ERR_ALERT | ERR_FATAL;
6741#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006742 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02006743
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006744 arg = args[*cur_arg + 1];
6745 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02006746 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6747 return ERR_ALERT | ERR_FATAL;
6748 }
6749
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006750 free(newsrv->sni_expr);
6751 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02006752
Willy Tarreau732eac42015-07-09 11:40:25 +02006753 return 0;
6754#endif
6755}
6756
Willy Tarreau92faadf2012-10-10 23:04:25 +02006757/* parse the "ssl" server keyword */
6758static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6759{
6760 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006761 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6762 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006763 return 0;
6764}
6765
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01006766/* parse the "ssl-reuse" server keyword */
6767static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6768{
6769 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
6770 return 0;
6771}
6772
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01006773/* parse the "tls-tickets" server keyword */
6774static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6775{
6776 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
6777 return 0;
6778}
6779
Emeric Brunef42d922012-10-11 16:11:36 +02006780/* parse the "verify" server keyword */
6781static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6782{
6783 if (!*args[*cur_arg + 1]) {
6784 if (err)
6785 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6786 return ERR_ALERT | ERR_FATAL;
6787 }
6788
6789 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006790 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006791 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006792 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006793 else {
6794 if (err)
6795 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6796 args[*cur_arg], args[*cur_arg + 1]);
6797 return ERR_ALERT | ERR_FATAL;
6798 }
6799
Evan Broderbe554312013-06-27 00:05:25 -07006800 return 0;
6801}
6802
6803/* parse the "verifyhost" server keyword */
6804static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6805{
6806 if (!*args[*cur_arg + 1]) {
6807 if (err)
6808 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6809 return ERR_ALERT | ERR_FATAL;
6810 }
6811
Frédéric Lécaille273f3212017-03-13 15:52:01 +01006812 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07006813 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6814
Emeric Brunef42d922012-10-11 16:11:36 +02006815 return 0;
6816}
6817
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006818/* parse the "ssl-default-bind-options" keyword in global section */
6819static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6820 struct proxy *defpx, const char *file, int line,
6821 char **err) {
6822 int i = 1;
6823
6824 if (*(args[i]) == 0) {
6825 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6826 return -1;
6827 }
6828 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006829 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006830 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006831 else if (!strcmp(args[i], "prefer-client-ciphers"))
6832 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006833 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
6834 if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
6835 i++;
6836 else {
6837 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
6838 return -1;
6839 }
6840 }
6841 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006842 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6843 return -1;
6844 }
6845 i++;
6846 }
6847 return 0;
6848}
6849
6850/* parse the "ssl-default-server-options" keyword in global section */
6851static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6852 struct proxy *defpx, const char *file, int line,
6853 char **err) {
6854 int i = 1;
6855
6856 if (*(args[i]) == 0) {
6857 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6858 return -1;
6859 }
6860 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006861 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006862 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02006863 else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
6864 if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
6865 i++;
6866 else {
6867 memprintf(err, "%s on global statement '%s'.", *err, args[0]);
6868 return -1;
6869 }
6870 }
6871 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006872 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6873 return -1;
6874 }
6875 i++;
6876 }
6877 return 0;
6878}
6879
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006880/* parse the "ca-base" / "crt-base" keywords in global section.
6881 * Returns <0 on alert, >0 on warning, 0 on success.
6882 */
6883static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6884 struct proxy *defpx, const char *file, int line,
6885 char **err)
6886{
6887 char **target;
6888
Willy Tarreauef934602016-12-22 23:12:01 +01006889 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006890
6891 if (too_many_args(1, args, err, NULL))
6892 return -1;
6893
6894 if (*target) {
6895 memprintf(err, "'%s' already specified.", args[0]);
6896 return -1;
6897 }
6898
6899 if (*(args[1]) == 0) {
6900 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6901 return -1;
6902 }
6903 *target = strdup(args[1]);
6904 return 0;
6905}
6906
Willy Tarreauf22e9682016-12-21 23:23:19 +01006907/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6908 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6909 */
6910static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6911 struct proxy *defpx, const char *file, int line,
6912 char **err)
6913{
6914 char **target;
6915
Willy Tarreauef934602016-12-22 23:12:01 +01006916 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006917
6918 if (too_many_args(1, args, err, NULL))
6919 return -1;
6920
6921 if (*(args[1]) == 0) {
6922 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6923 return -1;
6924 }
6925
6926 free(*target);
6927 *target = strdup(args[1]);
6928 return 0;
6929}
6930
Willy Tarreau9ceda382016-12-21 23:13:03 +01006931/* parse various global tune.ssl settings consisting in positive integers.
6932 * Returns <0 on alert, >0 on warning, 0 on success.
6933 */
6934static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6935 struct proxy *defpx, const char *file, int line,
6936 char **err)
6937{
6938 int *target;
6939
6940 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6941 target = &global.tune.sslcachesize;
6942 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006943 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006944 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006945 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006946 else if (strcmp(args[0], "maxsslconn") == 0)
6947 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006948 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
6949 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006950 else {
6951 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6952 return -1;
6953 }
6954
6955 if (too_many_args(1, args, err, NULL))
6956 return -1;
6957
6958 if (*(args[1]) == 0) {
6959 memprintf(err, "'%s' expects an integer argument.", args[0]);
6960 return -1;
6961 }
6962
6963 *target = atoi(args[1]);
6964 if (*target < 0) {
6965 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6966 return -1;
6967 }
6968 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006969}
6970
6971static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
6972 struct proxy *defpx, const char *file, int line,
6973 char **err)
6974{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006975 int ret;
6976
6977 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
6978 if (ret != 0)
6979 return ret;
6980
6981 if (pool2_ssl_capture) {
6982 memprintf(err, "'%s' is already configured.", args[0]);
6983 return -1;
6984 }
6985
6986 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
6987 if (!pool2_ssl_capture) {
6988 memprintf(err, "Out of memory error.");
6989 return -1;
6990 }
6991 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006992}
6993
6994/* parse "ssl.force-private-cache".
6995 * Returns <0 on alert, >0 on warning, 0 on success.
6996 */
6997static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6998 struct proxy *defpx, const char *file, int line,
6999 char **err)
7000{
7001 if (too_many_args(0, args, err, NULL))
7002 return -1;
7003
Willy Tarreauef934602016-12-22 23:12:01 +01007004 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007005 return 0;
7006}
7007
7008/* parse "ssl.lifetime".
7009 * Returns <0 on alert, >0 on warning, 0 on success.
7010 */
7011static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
7012 struct proxy *defpx, const char *file, int line,
7013 char **err)
7014{
7015 const char *res;
7016
7017 if (too_many_args(1, args, err, NULL))
7018 return -1;
7019
7020 if (*(args[1]) == 0) {
7021 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
7022 return -1;
7023 }
7024
Willy Tarreauef934602016-12-22 23:12:01 +01007025 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01007026 if (res) {
7027 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
7028 return -1;
7029 }
7030 return 0;
7031}
7032
7033#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01007034/* parse "ssl-dh-param-file".
7035 * Returns <0 on alert, >0 on warning, 0 on success.
7036 */
7037static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
7038 struct proxy *defpx, const char *file, int line,
7039 char **err)
7040{
7041 if (too_many_args(1, args, err, NULL))
7042 return -1;
7043
7044 if (*(args[1]) == 0) {
7045 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
7046 return -1;
7047 }
7048
7049 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
7050 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
7051 return -1;
7052 }
7053 return 0;
7054}
7055
Willy Tarreau9ceda382016-12-21 23:13:03 +01007056/* parse "ssl.default-dh-param".
7057 * Returns <0 on alert, >0 on warning, 0 on success.
7058 */
7059static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
7060 struct proxy *defpx, const char *file, int line,
7061 char **err)
7062{
7063 if (too_many_args(1, args, err, NULL))
7064 return -1;
7065
7066 if (*(args[1]) == 0) {
7067 memprintf(err, "'%s' expects an integer argument.", args[0]);
7068 return -1;
7069 }
7070
Willy Tarreauef934602016-12-22 23:12:01 +01007071 global_ssl.default_dh_param = atoi(args[1]);
7072 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01007073 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
7074 return -1;
7075 }
7076 return 0;
7077}
7078#endif
7079
7080
William Lallemand32af2032016-10-29 18:09:35 +02007081/* This function is used with TLS ticket keys management. It permits to browse
7082 * each reference. The variable <getnext> must contain the current node,
7083 * <end> point to the root node.
7084 */
7085#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7086static inline
7087struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
7088{
7089 struct tls_keys_ref *ref = getnext;
7090
7091 while (1) {
7092
7093 /* Get next list entry. */
7094 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
7095
7096 /* If the entry is the last of the list, return NULL. */
7097 if (&ref->list == end)
7098 return NULL;
7099
7100 return ref;
7101 }
7102}
7103
7104static inline
7105struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7106{
7107 int id;
7108 char *error;
7109
7110 /* If the reference starts by a '#', this is numeric id. */
7111 if (reference[0] == '#') {
7112 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7113 id = strtol(reference + 1, &error, 10);
7114 if (*error != '\0')
7115 return NULL;
7116
7117 /* Perform the unique id lookup. */
7118 return tlskeys_ref_lookupid(id);
7119 }
7120
7121 /* Perform the string lookup. */
7122 return tlskeys_ref_lookup(reference);
7123}
7124#endif
7125
7126
7127#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7128
7129static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7130
7131static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7132 return cli_io_handler_tlskeys_files(appctx);
7133}
7134
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007135/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7136 * (next index to be dumped), and cli.p0 (next key reference).
7137 */
William Lallemand32af2032016-10-29 18:09:35 +02007138static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7139
7140 struct stream_interface *si = appctx->owner;
7141
7142 switch (appctx->st2) {
7143 case STAT_ST_INIT:
7144 /* Display the column headers. If the message cannot be sent,
7145 * quit the fucntion with returning 0. The function is called
7146 * later and restart at the state "STAT_ST_INIT".
7147 */
7148 chunk_reset(&trash);
7149
7150 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7151 chunk_appendf(&trash, "# id secret\n");
7152 else
7153 chunk_appendf(&trash, "# id (file)\n");
7154
7155 if (bi_putchk(si_ic(si), &trash) == -1) {
7156 si_applet_cant_put(si);
7157 return 0;
7158 }
7159
William Lallemand32af2032016-10-29 18:09:35 +02007160 /* Now, we start the browsing of the references lists.
7161 * Note that the following call to LIST_ELEM return bad pointer. The only
7162 * available field of this pointer is <list>. It is used with the function
7163 * tlskeys_list_get_next() for retruning the first available entry
7164 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007165 if (appctx->ctx.cli.p0 == NULL) {
7166 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7167 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007168 }
7169
7170 appctx->st2 = STAT_ST_LIST;
7171 /* fall through */
7172
7173 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007174 while (appctx->ctx.cli.p0) {
7175 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7176 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007177
7178 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007179 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007180 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007181
7182 if (appctx->ctx.cli.i1 == 0)
7183 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7184
William Lallemand32af2032016-10-29 18:09:35 +02007185 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007186 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007187 struct chunk *t2 = get_trash_chunk();
7188
7189 chunk_reset(t2);
7190 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007191 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007192 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007193 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007194
7195 if (bi_putchk(si_ic(si), &trash) == -1) {
7196 /* let's try again later from this stream. We add ourselves into
7197 * this stream's users so that it can remove us upon termination.
7198 */
7199 si_applet_cant_put(si);
7200 return 0;
7201 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007202 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007203 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007204 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007205 }
7206 if (bi_putchk(si_ic(si), &trash) == -1) {
7207 /* let's try again later from this stream. We add ourselves into
7208 * this stream's users so that it can remove us upon termination.
7209 */
7210 si_applet_cant_put(si);
7211 return 0;
7212 }
7213
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007214 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007215 break;
7216
7217 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007218 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007219 }
7220
7221 appctx->st2 = STAT_ST_FIN;
7222 /* fall through */
7223
7224 default:
7225 appctx->st2 = STAT_ST_FIN;
7226 return 1;
7227 }
7228 return 0;
7229}
7230
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007231/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007232static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7233{
William Lallemand32af2032016-10-29 18:09:35 +02007234 /* no parameter, shows only file list */
7235 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007236 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007237 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007238 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007239 }
7240
7241 if (args[2][0] == '*') {
7242 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007243 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007244 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007245 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7246 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007247 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007248 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007249 return 1;
7250 }
7251 }
William Lallemand32af2032016-10-29 18:09:35 +02007252 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007253 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007254}
7255
William Lallemand32af2032016-10-29 18:09:35 +02007256static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7257{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007258 struct tls_keys_ref *ref;
7259
William Lallemand32af2032016-10-29 18:09:35 +02007260 /* Expect two parameters: the filename and the new new TLS key in encoding */
7261 if (!*args[3] || !*args[4]) {
7262 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 +01007263 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007264 return 1;
7265 }
7266
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007267 ref = tlskeys_ref_lookup_ref(args[3]);
7268 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007269 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007270 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007271 return 1;
7272 }
7273
7274 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7275 if (trash.len != sizeof(struct tls_sess_key)) {
7276 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007277 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007278 return 1;
7279 }
7280
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007281 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7282 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007283
7284 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007285 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007286 return 1;
7287
7288}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007289#endif
William Lallemand32af2032016-10-29 18:09:35 +02007290
7291static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7292{
7293#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7294 char *err = NULL;
7295
7296 /* Expect one parameter: the new response in base64 encoding */
7297 if (!*args[3]) {
7298 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007299 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007300 return 1;
7301 }
7302
7303 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7304 if (trash.len < 0) {
7305 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007306 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007307 return 1;
7308 }
7309
7310 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7311 if (err) {
7312 memprintf(&err, "%s.\n", err);
7313 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007314 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007315 }
7316 return 1;
7317 }
7318 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007319 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007320 return 1;
7321#else
7322 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 +01007323 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007324 return 1;
7325#endif
7326
7327}
7328
7329/* register cli keywords */
7330static struct cli_kw_list cli_kws = {{ },{
7331#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7332 { { "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 },
7333 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007334#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007335 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007336 { { NULL }, NULL, NULL, NULL }
7337}};
7338
7339
Willy Tarreau7875d092012-09-10 08:20:03 +02007340/* Note: must not be declared <const> as its list will be overwritten.
7341 * Please take care of keeping this list alphabetically sorted.
7342 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007343static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007344 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007345 { "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 +02007346 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7347 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007348 { "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 +02007349 { "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 +02007350 { "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 +02007351 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7352 { "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 +01007353 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007354 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007355 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7356 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7357 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7358 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7359 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7360 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7361 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7362 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007363 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007364 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7365 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007366 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007367 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7368 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7369 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7370 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7371 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7372 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7373 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007374 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007375 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007376 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007377 { "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 +01007378 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007379 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7380 { "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 +02007381 { "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 +02007382#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007383 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007384#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007385#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007386 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007387#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007388 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007389 { "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 +02007390 { "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 +01007391 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7392 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007393 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7394 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7395 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7396 { "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 +02007397 { NULL, NULL, 0, 0, 0 },
7398}};
7399
7400/* Note: must not be declared <const> as its list will be overwritten.
7401 * Please take care of keeping this list alphabetically sorted.
7402 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007403static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007404 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7405 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007406 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007407}};
7408
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007409/* Note: must not be declared <const> as its list will be overwritten.
7410 * Please take care of keeping this list alphabetically sorted, doing so helps
7411 * all code contributors.
7412 * Optional keywords are also declared with a NULL ->parse() function so that
7413 * the config parser can report an appropriate error when a known keyword was
7414 * not enabled.
7415 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007416static struct ssl_bind_kw ssl_bind_kws[] = {
7417 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7418 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7419 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7420 { "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 +01007421 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007422 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007423 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7424 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7425 { NULL, NULL, 0 },
7426};
7427
Willy Tarreau51fb7652012-09-18 18:24:39 +02007428static struct bind_kw_list bind_kws = { "SSL", { }, {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007429 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7430 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7431 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
7432 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7433 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
7434 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7435 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7436 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7437 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7438 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
7439 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
7440 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7441 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
7442 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
7443 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
7444 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02007445 { "force-tlsv13", bind_parse_tls_method_options, 0 }, /* force TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007446 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
7447 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
7448 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
7449 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
7450 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
Emmanuel Hocdet42fb9802017-03-30 19:29:39 +02007451 { "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007452 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7453 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007454 { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
7455 { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007456 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7457 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7458 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7459 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
7460 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007461 { NULL, NULL, 0 },
7462}};
Emeric Brun46591952012-05-18 15:47:34 +02007463
Willy Tarreau92faadf2012-10-10 23:04:25 +02007464/* Note: must not be declared <const> as its list will be overwritten.
7465 * Please take care of keeping this list alphabetically sorted, doing so helps
7466 * all code contributors.
7467 * Optional keywords are also declared with a NULL ->parse() function so that
7468 * the config parser can report an appropriate error when a known keyword was
7469 * not enabled.
7470 */
7471static struct srv_kw_list srv_kws = { "SSL", { }, {
Emmanuel Hocdete1c722b2017-03-31 15:02:54 +02007472 { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
7473 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
7474 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
7475 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
7476 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
7477 { "force-sslv3", srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
7478 { "force-tlsv10", srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
7479 { "force-tlsv11", srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
7480 { "force-tlsv12", srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
7481 { "force-tlsv13", srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
7482 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
7483 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
7484 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
7485 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
7486 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
7487 { "no-sslv3", srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
7488 { "no-tlsv10", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
7489 { "no-tlsv11", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
7490 { "no-tlsv12", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
7491 { "no-tlsv13", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
7492 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
7493 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
7494 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
7495 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
7496 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
7497 { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1 }, /* minimum version */
7498 { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1 }, /* maximum version */
7499 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
7500 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
7501 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
7502 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007503 { NULL, NULL, 0, 0 },
7504}};
7505
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007506static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007507 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7508 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007509 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007510 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7511 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007512#ifndef OPENSSL_NO_DH
7513 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7514#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007515 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7516#ifndef OPENSSL_NO_DH
7517 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7518#endif
7519 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7520 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7521 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7522 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007523 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007524 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7525 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007526 { 0, NULL, NULL },
7527}};
7528
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007529/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007530static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007531 .snd_buf = ssl_sock_from_buf,
7532 .rcv_buf = ssl_sock_to_buf,
7533 .rcv_pipe = NULL,
7534 .snd_pipe = NULL,
7535 .shutr = NULL,
7536 .shutw = ssl_sock_shutw,
7537 .close = ssl_sock_close,
7538 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007539 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007540 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007541 .prepare_srv = ssl_sock_prepare_srv_ctx,
7542 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007543 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007544};
7545
Daniel Jakots54ffb912015-11-06 20:02:41 +01007546#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007547
7548static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7549{
7550 if (ptr) {
7551 chunk_destroy(ptr);
7552 free(ptr);
7553 }
7554}
7555
7556#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007557static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7558{
7559 pool_free2(pool2_ssl_capture, ptr);
7560}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007561
Emeric Brun46591952012-05-18 15:47:34 +02007562__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007563static void __ssl_sock_init(void)
7564{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007565 char *ptr;
7566
Emeric Brun46591952012-05-18 15:47:34 +02007567 STACK_OF(SSL_COMP)* cm;
7568
Willy Tarreauef934602016-12-22 23:12:01 +01007569 if (global_ssl.listen_default_ciphers)
7570 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7571 if (global_ssl.connect_default_ciphers)
7572 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007573
Willy Tarreau13e14102016-12-22 20:25:26 +01007574 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007575 SSL_library_init();
7576 cm = SSL_COMP_get_compression_methods();
7577 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007578#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007579 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7580#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007581 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 +02007582 sample_register_fetches(&sample_fetch_keywords);
7583 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007584 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007585 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007586 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007587 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007588#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7589 hap_register_post_check(tlskeys_finalize_config);
7590#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007591
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007592 ptr = NULL;
7593 memprintf(&ptr, "Built with OpenSSL version : "
7594#ifdef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01007595 "BoringSSL");
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007596#else /* OPENSSL_IS_BORINGSSL */
7597 OPENSSL_VERSION_TEXT
7598 "\nRunning on OpenSSL version : %s%s",
7599 SSLeay_version(SSLEAY_VERSION),
7600 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7601#endif
7602 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7603#if OPENSSL_VERSION_NUMBER < 0x00907000L
7604 "no (library version too old)"
7605#elif defined(OPENSSL_NO_TLSEXT)
7606 "no (disabled via OPENSSL_NO_TLSEXT)"
7607#else
7608 "yes"
7609#endif
7610 "", ptr);
7611
7612 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7613#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7614 "yes"
7615#else
7616#ifdef OPENSSL_NO_TLSEXT
7617 "no (because of OPENSSL_NO_TLSEXT)"
7618#else
7619 "no (version might be too old, 0.9.8f min needed)"
7620#endif
7621#endif
7622 "", ptr);
7623
Emmanuel Hocdet50e25e12017-03-24 15:20:03 +01007624 memprintf(&ptr, "%s\nOpenSSL library supports : "
7625#if SSL_OP_NO_SSLv3
7626 "SSLv3 "
7627#endif
7628#if SSL_OP_NO_TLSv1
7629 "TLSv1.0 "
7630#endif
7631#if SSL_OP_NO_TLSv1_1
7632 "TLSv1.1 "
7633#endif
7634#if SSL_OP_NO_TLSv1_2
7635 "TLSv1.2 "
7636#endif
7637#if SSL_OP_NO_TLSv1_3
7638 "TLSv1.3"
7639#endif
7640 "", ptr);
7641
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007642 hap_register_build_opts(ptr, 1);
7643
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007644 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7645 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007646
7647#ifndef OPENSSL_NO_DH
7648 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7649#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007650
7651 /* Load SSL string for the verbose & debug mode. */
7652 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007653}
7654
Remi Gacogned3a23c32015-05-28 16:39:47 +02007655__attribute__((destructor))
7656static void __ssl_sock_deinit(void)
7657{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007658#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007659 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007660#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007661
Remi Gacogned3a23c32015-05-28 16:39:47 +02007662#ifndef OPENSSL_NO_DH
7663 if (local_dh_1024) {
7664 DH_free(local_dh_1024);
7665 local_dh_1024 = NULL;
7666 }
7667
7668 if (local_dh_2048) {
7669 DH_free(local_dh_2048);
7670 local_dh_2048 = NULL;
7671 }
7672
7673 if (local_dh_4096) {
7674 DH_free(local_dh_4096);
7675 local_dh_4096 = NULL;
7676 }
7677
Remi Gacogne47783ef2015-05-29 15:53:22 +02007678 if (global_dh) {
7679 DH_free(global_dh);
7680 global_dh = NULL;
7681 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007682#endif
7683
7684 ERR_remove_state(0);
7685 ERR_free_strings();
7686
7687 EVP_cleanup();
7688
7689#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7690 CRYPTO_cleanup_all_ex_data();
7691#endif
7692}
7693
7694
Emeric Brun46591952012-05-18 15:47:34 +02007695/*
7696 * Local variables:
7697 * c-indent-level: 8
7698 * c-basic-offset: 8
7699 * End:
7700 */