blob: c43a330847fe36a361dd7498f5af6329379a3028 [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 */
129
130/* ssl_methods versions */
131enum {
132 CONF_TLSV_NONE = 0,
133 CONF_TLSV_MIN = 1,
134 CONF_SSLV3 = 1,
135 CONF_TLSV10 = 2,
136 CONF_TLSV11 = 3,
137 CONF_TLSV12 = 4,
138 CONF_TLSV_MAX = 4,
139};
140
Emeric Brun850efd52014-01-29 12:24:34 +0100141/* server and bind verify method, it uses a global value as default */
142enum {
143 SSL_SOCK_VERIFY_DEFAULT = 0,
144 SSL_SOCK_VERIFY_REQUIRED = 1,
145 SSL_SOCK_VERIFY_OPTIONAL = 2,
146 SSL_SOCK_VERIFY_NONE = 3,
147};
148
Willy Tarreau71b734c2014-01-28 15:19:44 +0100149int sslconns = 0;
150int totalsslconns = 0;
Willy Tarreaud9f5cca2016-12-22 21:08:52 +0100151static struct xprt_ops ssl_sock;
Emeric Brune1f38db2012-09-03 20:36:47 +0200152
Willy Tarreauef934602016-12-22 23:12:01 +0100153static struct {
154 char *crt_base; /* base directory path for certificates */
155 char *ca_base; /* base directory path for CAs and CRLs */
156
157 char *listen_default_ciphers;
158 char *connect_default_ciphers;
159 int listen_default_ssloptions;
160 int connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200161 struct tls_version_filter listen_default_sslmethods;
162 struct tls_version_filter connect_default_sslmethods;
Willy Tarreauef934602016-12-22 23:12:01 +0100163
164 int private_cache; /* Force to use a private session cache even if nbproc > 1 */
165 unsigned int life_time; /* SSL session lifetime in seconds */
166 unsigned int max_record; /* SSL max record size */
167 unsigned int default_dh_param; /* SSL maximum DH parameter size */
168 int ctx_cache; /* max number of entries in the ssl_ctx cache. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100169 int capture_cipherlist; /* Size of the cipherlist buffer. */
Willy Tarreauef934602016-12-22 23:12:01 +0100170} global_ssl = {
171#ifdef LISTEN_DEFAULT_CIPHERS
172 .listen_default_ciphers = LISTEN_DEFAULT_CIPHERS,
173#endif
174#ifdef CONNECT_DEFAULT_CIPHERS
175 .connect_default_ciphers = CONNECT_DEFAULT_CIPHERS,
176#endif
177 .listen_default_ssloptions = BC_SSL_O_NONE,
178 .connect_default_ssloptions = SRV_SSL_O_NONE,
179
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +0200180 .listen_default_sslmethods.flags = MC_SSL_O_ALL,
181 .listen_default_sslmethods.min = CONF_TLSV_NONE,
182 .listen_default_sslmethods.max = CONF_TLSV_NONE,
183 .connect_default_sslmethods.flags = MC_SSL_O_ALL,
184 .connect_default_sslmethods.min = CONF_TLSV_NONE,
185 .connect_default_sslmethods.max = CONF_TLSV_NONE,
186
Willy Tarreauef934602016-12-22 23:12:01 +0100187#ifdef DEFAULT_SSL_MAX_RECORD
188 .max_record = DEFAULT_SSL_MAX_RECORD,
189#endif
190 .default_dh_param = SSL_DEFAULT_DH_PARAM,
191 .ctx_cache = DEFAULT_SSL_CTX_CACHE,
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100192 .capture_cipherlist = 0,
Willy Tarreauef934602016-12-22 23:12:01 +0100193};
194
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100195/* This memory pool is used for capturing clienthello parameters. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100196struct ssl_capture {
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100197 unsigned long long int xxh64;
198 unsigned char ciphersuite_len;
199 char ciphersuite[0];
200};
201struct pool_head *pool2_ssl_capture = NULL;
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100202static int ssl_capture_ptr_index = -1;
Willy Tarreauef934602016-12-22 23:12:01 +0100203
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200204#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
205struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
206#endif
207
Remi Gacogne8de54152014-07-15 11:36:40 +0200208#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200209static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200210static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200211static DH *local_dh_1024 = NULL;
212static DH *local_dh_2048 = NULL;
213static DH *local_dh_4096 = NULL;
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +0100214static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
Remi Gacogne8de54152014-07-15 11:36:40 +0200215#endif /* OPENSSL_NO_DH */
216
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100217#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +0200218/* X509V3 Extensions that will be added on generated certificates */
219#define X509V3_EXT_SIZE 5
220static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
221 "basicConstraints",
222 "nsComment",
223 "subjectKeyIdentifier",
224 "authorityKeyIdentifier",
225 "keyUsage",
226};
227static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
228 "CA:FALSE",
229 "\"OpenSSL Generated Certificate\"",
230 "hash",
231 "keyid,issuer:always",
232 "nonRepudiation,digitalSignature,keyEncipherment"
233};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200234/* LRU cache to store generated certificate */
235static struct lru64_head *ssl_ctx_lru_tree = NULL;
236static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200237#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
238
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100239static struct ssl_bind_kw ssl_bind_kws[];
240
yanbzhube2774d2015-12-10 15:07:30 -0500241#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
242/* The order here matters for picking a default context,
243 * keep the most common keytype at the bottom of the list
244 */
245const char *SSL_SOCK_KEYTYPE_NAMES[] = {
246 "dsa",
247 "ecdsa",
248 "rsa"
249};
250#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100251#else
252#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500253#endif
254
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100255/*
256 * This function gives the detail of the SSL error. It is used only
257 * if the debug mode and the verbose mode are activated. It dump all
258 * the SSL error until the stack was empty.
259 */
260static forceinline void ssl_sock_dump_errors(struct connection *conn)
261{
262 unsigned long ret;
263
264 if (unlikely(global.mode & MODE_DEBUG)) {
265 while(1) {
266 ret = ERR_get_error();
267 if (ret == 0)
268 return;
269 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
270 (unsigned short)conn->t.sock.fd, ret,
271 ERR_func_error_string(ret), ERR_reason_error_string(ret));
272 }
273 }
274}
275
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200276#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500277/*
278 * struct alignment works here such that the key.key is the same as key_data
279 * Do not change the placement of key_data
280 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200281struct certificate_ocsp {
282 struct ebmb_node key;
283 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
284 struct chunk response;
285 long expire;
286};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200287
yanbzhube2774d2015-12-10 15:07:30 -0500288struct ocsp_cbk_arg {
289 int is_single;
290 int single_kt;
291 union {
292 struct certificate_ocsp *s_ocsp;
293 /*
294 * m_ocsp will have multiple entries dependent on key type
295 * Entry 0 - DSA
296 * Entry 1 - ECDSA
297 * Entry 2 - RSA
298 */
299 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
300 };
301};
302
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200303/*
304 * This function returns the number of seconds elapsed
305 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
306 * date presented un ASN1_GENERALIZEDTIME.
307 *
308 * In parsing error case, it returns -1.
309 */
310static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
311{
312 long epoch;
313 char *p, *end;
314 const unsigned short month_offset[12] = {
315 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
316 };
317 int year, month;
318
319 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
320
321 p = (char *)d->data;
322 end = p + d->length;
323
324 if (end - p < 4) return -1;
325 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
326 p += 4;
327 if (end - p < 2) return -1;
328 month = 10 * (p[0] - '0') + p[1] - '0';
329 if (month < 1 || month > 12) return -1;
330 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
331 We consider leap years and the current month (<marsh or not) */
332 epoch = ( ((year - 1970) * 365)
333 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
334 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
335 + month_offset[month-1]
336 ) * 24 * 60 * 60;
337 p += 2;
338 if (end - p < 2) return -1;
339 /* Add the number of seconds of completed days of current month */
340 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
341 p += 2;
342 if (end - p < 2) return -1;
343 /* Add the completed hours of the current day */
344 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
345 p += 2;
346 if (end - p < 2) return -1;
347 /* Add the completed minutes of the current hour */
348 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
349 p += 2;
350 if (p == end) return -1;
351 /* Test if there is available seconds */
352 if (p[0] < '0' || p[0] > '9')
353 goto nosec;
354 if (end - p < 2) return -1;
355 /* Add the seconds of the current minute */
356 epoch += 10 * (p[0] - '0') + p[1] - '0';
357 p += 2;
358 if (p == end) return -1;
359 /* Ignore seconds float part if present */
360 if (p[0] == '.') {
361 do {
362 if (++p == end) return -1;
363 } while (p[0] >= '0' && p[0] <= '9');
364 }
365
366nosec:
367 if (p[0] == 'Z') {
368 if (end - p != 1) return -1;
369 return epoch;
370 }
371 else if (p[0] == '+') {
372 if (end - p != 5) return -1;
373 /* Apply timezone offset */
374 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
375 }
376 else if (p[0] == '-') {
377 if (end - p != 5) return -1;
378 /* Apply timezone offset */
379 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
380 }
381
382 return -1;
383}
384
Emeric Brun1d3865b2014-06-20 15:37:32 +0200385static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200386
387/* This function starts to check if the OCSP response (in DER format) contained
388 * in chunk 'ocsp_response' is valid (else exits on error).
389 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
390 * contained in the OCSP Response and exits on error if no match.
391 * If it's a valid OCSP Response:
392 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
393 * pointed by 'ocsp'.
394 * If 'ocsp' is NULL, the function looks up into the OCSP response's
395 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
396 * from the response) and exits on error if not found. Finally, If an OCSP response is
397 * already present in the container, it will be overwritten.
398 *
399 * Note: OCSP response containing more than one OCSP Single response is not
400 * considered valid.
401 *
402 * Returns 0 on success, 1 in error case.
403 */
404static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
405{
406 OCSP_RESPONSE *resp;
407 OCSP_BASICRESP *bs = NULL;
408 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200409 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200410 unsigned char *p = (unsigned char *)ocsp_response->str;
411 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200412 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200413 int reason;
414 int ret = 1;
415
416 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
417 if (!resp) {
418 memprintf(err, "Unable to parse OCSP response");
419 goto out;
420 }
421
422 rc = OCSP_response_status(resp);
423 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
424 memprintf(err, "OCSP response status not successful");
425 goto out;
426 }
427
428 bs = OCSP_response_get1_basic(resp);
429 if (!bs) {
430 memprintf(err, "Failed to get basic response from OCSP Response");
431 goto out;
432 }
433
434 count_sr = OCSP_resp_count(bs);
435 if (count_sr > 1) {
436 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
437 goto out;
438 }
439
440 sr = OCSP_resp_get0(bs, 0);
441 if (!sr) {
442 memprintf(err, "Failed to get OCSP single response");
443 goto out;
444 }
445
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200446 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
447
Emeric Brun4147b2e2014-06-16 18:36:30 +0200448 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
449 if (rc != V_OCSP_CERTSTATUS_GOOD) {
450 memprintf(err, "OCSP single response: certificate status not good");
451 goto out;
452 }
453
Emeric Brun13a6b482014-06-20 15:44:34 +0200454 if (!nextupd) {
455 memprintf(err, "OCSP single response: missing nextupdate");
456 goto out;
457 }
458
Emeric Brunc8b27b62014-06-19 14:16:17 +0200459 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200460 if (!rc) {
461 memprintf(err, "OCSP single response: no longer valid.");
462 goto out;
463 }
464
465 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200466 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200467 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
468 goto out;
469 }
470 }
471
472 if (!ocsp) {
473 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
474 unsigned char *p;
475
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200476 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200477 if (!rc) {
478 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
479 goto out;
480 }
481
482 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
483 memprintf(err, "OCSP single response: Certificate ID too long");
484 goto out;
485 }
486
487 p = key;
488 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200489 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200490 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
491 if (!ocsp) {
492 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
493 goto out;
494 }
495 }
496
497 /* According to comments on "chunk_dup", the
498 previous chunk buffer will be freed */
499 if (!chunk_dup(&ocsp->response, ocsp_response)) {
500 memprintf(err, "OCSP response: Memory allocation error");
501 goto out;
502 }
503
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200504 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
505
Emeric Brun4147b2e2014-06-16 18:36:30 +0200506 ret = 0;
507out:
Janusz Dziemidowicz8d710492017-03-08 16:59:41 +0100508 ERR_clear_error();
509
Emeric Brun4147b2e2014-06-16 18:36:30 +0200510 if (bs)
511 OCSP_BASICRESP_free(bs);
512
513 if (resp)
514 OCSP_RESPONSE_free(resp);
515
516 return ret;
517}
518/*
519 * External function use to update the OCSP response in the OCSP response's
520 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
521 * to update in DER format.
522 *
523 * Returns 0 on success, 1 in error case.
524 */
525int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
526{
527 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
528}
529
530/*
531 * This function load the OCSP Resonse in DER format contained in file at
532 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
533 *
534 * Returns 0 on success, 1 in error case.
535 */
536static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
537{
538 int fd = -1;
539 int r = 0;
540 int ret = 1;
541
542 fd = open(ocsp_path, O_RDONLY);
543 if (fd == -1) {
544 memprintf(err, "Error opening OCSP response file");
545 goto end;
546 }
547
548 trash.len = 0;
549 while (trash.len < trash.size) {
550 r = read(fd, trash.str + trash.len, trash.size - trash.len);
551 if (r < 0) {
552 if (errno == EINTR)
553 continue;
554
555 memprintf(err, "Error reading OCSP response from file");
556 goto end;
557 }
558 else if (r == 0) {
559 break;
560 }
561 trash.len += r;
562 }
563
564 close(fd);
565 fd = -1;
566
567 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
568end:
569 if (fd != -1)
570 close(fd);
571
572 return ret;
573}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100574#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200575
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100576#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
577static 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)
578{
579 struct tls_sess_key *keys;
580 struct connection *conn;
581 int head;
582 int i;
583
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200584 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200585 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
586 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100587
588 if (enc) {
589 memcpy(key_name, keys[head].name, 16);
590
591 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
592 return -1;
593
594 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
595 return -1;
596
597 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
598
599 return 1;
600 } else {
601 for (i = 0; i < TLS_TICKETS_NO; i++) {
602 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
603 goto found;
604 }
605 return 0;
606
607 found:
608 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
609 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
610 return -1;
611 /* 2 for key renewal, 1 if current key is still valid */
612 return i ? 2 : 1;
613 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200614}
615
616struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
617{
618 struct tls_keys_ref *ref;
619
620 list_for_each_entry(ref, &tlskeys_reference, list)
621 if (ref->filename && strcmp(filename, ref->filename) == 0)
622 return ref;
623 return NULL;
624}
625
626struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
627{
628 struct tls_keys_ref *ref;
629
630 list_for_each_entry(ref, &tlskeys_reference, list)
631 if (ref->unique_id == unique_id)
632 return ref;
633 return NULL;
634}
635
636int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
637 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
638
639 if(!ref) {
640 memprintf(err, "Unable to locate the referenced filename: %s", filename);
641 return 1;
642 }
643
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530644 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
645 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200646
647 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100648}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200649
650/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100651 * automatic ids. It's called just after the basic checks. It returns
652 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200653 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100654static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200655{
656 int i = 0;
657 struct tls_keys_ref *ref, *ref2, *ref3;
658 struct list tkr = LIST_HEAD_INIT(tkr);
659
660 list_for_each_entry(ref, &tlskeys_reference, list) {
661 if (ref->unique_id == -1) {
662 /* Look for the first free id. */
663 while (1) {
664 list_for_each_entry(ref2, &tlskeys_reference, list) {
665 if (ref2->unique_id == i) {
666 i++;
667 break;
668 }
669 }
670 if (&ref2->list == &tlskeys_reference)
671 break;
672 }
673
674 /* Uses the unique id and increment it for the next entry. */
675 ref->unique_id = i;
676 i++;
677 }
678 }
679
680 /* This sort the reference list by id. */
681 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
682 LIST_DEL(&ref->list);
683 list_for_each_entry(ref3, &tkr, list) {
684 if (ref->unique_id < ref3->unique_id) {
685 LIST_ADDQ(&ref3->list, &ref->list);
686 break;
687 }
688 }
689 if (&ref3->list == &tkr)
690 LIST_ADDQ(&tkr, &ref->list);
691 }
692
693 /* swap root */
694 LIST_ADD(&tkr, &tlskeys_reference);
695 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100696 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200697}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100698#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
699
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100700#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500701int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
702{
703 switch (evp_keytype) {
704 case EVP_PKEY_RSA:
705 return 2;
706 case EVP_PKEY_DSA:
707 return 0;
708 case EVP_PKEY_EC:
709 return 1;
710 }
711
712 return -1;
713}
714
Emeric Brun4147b2e2014-06-16 18:36:30 +0200715/*
716 * Callback used to set OCSP status extension content in server hello.
717 */
718int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
719{
yanbzhube2774d2015-12-10 15:07:30 -0500720 struct certificate_ocsp *ocsp;
721 struct ocsp_cbk_arg *ocsp_arg;
722 char *ssl_buf;
723 EVP_PKEY *ssl_pkey;
724 int key_type;
725 int index;
726
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200727 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500728
729 ssl_pkey = SSL_get_privatekey(ssl);
730 if (!ssl_pkey)
731 return SSL_TLSEXT_ERR_NOACK;
732
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200733 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500734
735 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
736 ocsp = ocsp_arg->s_ocsp;
737 else {
738 /* For multiple certs per context, we have to find the correct OCSP response based on
739 * the certificate type
740 */
741 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
742
743 if (index < 0)
744 return SSL_TLSEXT_ERR_NOACK;
745
746 ocsp = ocsp_arg->m_ocsp[index];
747
748 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200749
750 if (!ocsp ||
751 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200752 !ocsp->response.len ||
753 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200754 return SSL_TLSEXT_ERR_NOACK;
755
756 ssl_buf = OPENSSL_malloc(ocsp->response.len);
757 if (!ssl_buf)
758 return SSL_TLSEXT_ERR_NOACK;
759
760 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
761 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
762
763 return SSL_TLSEXT_ERR_OK;
764}
765
766/*
767 * This function enables the handling of OCSP status extension on 'ctx' if a
768 * file name 'cert_path' suffixed using ".ocsp" is present.
769 * To enable OCSP status extension, the issuer's certificate is mandatory.
770 * It should be present in the certificate's extra chain builded from file
771 * 'cert_path'. If not found, the issuer certificate is loaded from a file
772 * named 'cert_path' suffixed using '.issuer'.
773 *
774 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
775 * response. If file is empty or content is not a valid OCSP response,
776 * OCSP status extension is enabled but OCSP response is ignored (a warning
777 * is displayed).
778 *
779 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
780 * succesfully enabled, or -1 in other error case.
781 */
782static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
783{
784
785 BIO *in = NULL;
786 X509 *x, *xi = NULL, *issuer = NULL;
787 STACK_OF(X509) *chain = NULL;
788 OCSP_CERTID *cid = NULL;
789 SSL *ssl;
790 char ocsp_path[MAXPATHLEN+1];
791 int i, ret = -1;
792 struct stat st;
793 struct certificate_ocsp *ocsp = NULL, *iocsp;
794 char *warn = NULL;
795 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200796 pem_password_cb *passwd_cb;
797 void *passwd_cb_userdata;
798 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200799
800 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
801
802 if (stat(ocsp_path, &st))
803 return 1;
804
805 ssl = SSL_new(ctx);
806 if (!ssl)
807 goto out;
808
809 x = SSL_get_certificate(ssl);
810 if (!x)
811 goto out;
812
813 /* Try to lookup for issuer in certificate extra chain */
814#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
815 SSL_CTX_get_extra_chain_certs(ctx, &chain);
816#else
817 chain = ctx->extra_certs;
818#endif
819 for (i = 0; i < sk_X509_num(chain); i++) {
820 issuer = sk_X509_value(chain, i);
821 if (X509_check_issued(issuer, x) == X509_V_OK)
822 break;
823 else
824 issuer = NULL;
825 }
826
827 /* If not found try to load issuer from a suffixed file */
828 if (!issuer) {
829 char issuer_path[MAXPATHLEN+1];
830
831 in = BIO_new(BIO_s_file());
832 if (!in)
833 goto out;
834
835 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
836 if (BIO_read_filename(in, issuer_path) <= 0)
837 goto out;
838
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200839 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
840 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
841
842 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200843 if (!xi)
844 goto out;
845
846 if (X509_check_issued(xi, x) != X509_V_OK)
847 goto out;
848
849 issuer = xi;
850 }
851
852 cid = OCSP_cert_to_id(0, x, issuer);
853 if (!cid)
854 goto out;
855
856 i = i2d_OCSP_CERTID(cid, NULL);
857 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
858 goto out;
859
Vincent Bernat02779b62016-04-03 13:48:43 +0200860 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200861 if (!ocsp)
862 goto out;
863
864 p = ocsp->key_data;
865 i2d_OCSP_CERTID(cid, &p);
866
867 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
868 if (iocsp == ocsp)
869 ocsp = NULL;
870
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200871#ifndef SSL_CTX_get_tlsext_status_cb
872# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
873 *cb = (void (*) (void))ctx->tlsext_status_cb;
874#endif
875 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
876
877 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200878 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100879 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500880
881 cb_arg->is_single = 1;
882 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200883
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100884 pkey = X509_get_pubkey(x);
885 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
886 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500887
888 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
889 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
890 } else {
891 /*
892 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
893 * Update that cb_arg with the new cert's staple
894 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200895 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500896 struct certificate_ocsp *tmp_ocsp;
897 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200898 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100899 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200900
901#ifdef SSL_CTX_get_tlsext_status_arg
902 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
903#else
904 cb_arg = ctx->tlsext_status_arg;
905#endif
yanbzhube2774d2015-12-10 15:07:30 -0500906
907 /*
908 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
909 * the order of operations below matter, take care when changing it
910 */
911 tmp_ocsp = cb_arg->s_ocsp;
912 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
913 cb_arg->s_ocsp = NULL;
914 cb_arg->m_ocsp[index] = tmp_ocsp;
915 cb_arg->is_single = 0;
916 cb_arg->single_kt = 0;
917
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100918 pkey = X509_get_pubkey(x);
919 key_type = EVP_PKEY_base_id(pkey);
920 EVP_PKEY_free(pkey);
921
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200922 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500923 if (index >= 0 && !cb_arg->m_ocsp[index])
924 cb_arg->m_ocsp[index] = iocsp;
925
926 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200927
928 ret = 0;
929
930 warn = NULL;
931 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
932 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
933 Warning("%s.\n", warn);
934 }
935
936out:
937 if (ssl)
938 SSL_free(ssl);
939
940 if (in)
941 BIO_free(in);
942
943 if (xi)
944 X509_free(xi);
945
946 if (cid)
947 OCSP_CERTID_free(cid);
948
949 if (ocsp)
950 free(ocsp);
951
952 if (warn)
953 free(warn);
954
955
956 return ret;
957}
958
959#endif
960
Daniel Jakots54ffb912015-11-06 20:02:41 +0100961#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100962
963#define CT_EXTENSION_TYPE 18
964
965static int sctl_ex_index = -1;
966
967/*
968 * Try to parse Signed Certificate Timestamp List structure. This function
969 * makes only basic test if the data seems like SCTL. No signature validation
970 * is performed.
971 */
972static int ssl_sock_parse_sctl(struct chunk *sctl)
973{
974 int ret = 1;
975 int len, pos, sct_len;
976 unsigned char *data;
977
978 if (sctl->len < 2)
979 goto out;
980
981 data = (unsigned char *)sctl->str;
982 len = (data[0] << 8) | data[1];
983
984 if (len + 2 != sctl->len)
985 goto out;
986
987 data = data + 2;
988 pos = 0;
989 while (pos < len) {
990 if (len - pos < 2)
991 goto out;
992
993 sct_len = (data[pos] << 8) | data[pos + 1];
994 if (pos + sct_len + 2 > len)
995 goto out;
996
997 pos += sct_len + 2;
998 }
999
1000 ret = 0;
1001
1002out:
1003 return ret;
1004}
1005
1006static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
1007{
1008 int fd = -1;
1009 int r = 0;
1010 int ret = 1;
1011
1012 *sctl = NULL;
1013
1014 fd = open(sctl_path, O_RDONLY);
1015 if (fd == -1)
1016 goto end;
1017
1018 trash.len = 0;
1019 while (trash.len < trash.size) {
1020 r = read(fd, trash.str + trash.len, trash.size - trash.len);
1021 if (r < 0) {
1022 if (errno == EINTR)
1023 continue;
1024
1025 goto end;
1026 }
1027 else if (r == 0) {
1028 break;
1029 }
1030 trash.len += r;
1031 }
1032
1033 ret = ssl_sock_parse_sctl(&trash);
1034 if (ret)
1035 goto end;
1036
Vincent Bernat02779b62016-04-03 13:48:43 +02001037 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001038 if (!chunk_dup(*sctl, &trash)) {
1039 free(*sctl);
1040 *sctl = NULL;
1041 goto end;
1042 }
1043
1044end:
1045 if (fd != -1)
1046 close(fd);
1047
1048 return ret;
1049}
1050
1051int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1052{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001053 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001054
1055 *out = (unsigned char *)sctl->str;
1056 *outlen = sctl->len;
1057
1058 return 1;
1059}
1060
1061int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1062{
1063 return 1;
1064}
1065
1066static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1067{
1068 char sctl_path[MAXPATHLEN+1];
1069 int ret = -1;
1070 struct stat st;
1071 struct chunk *sctl = NULL;
1072
1073 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1074
1075 if (stat(sctl_path, &st))
1076 return 1;
1077
1078 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1079 goto out;
1080
1081 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1082 free(sctl);
1083 goto out;
1084 }
1085
1086 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1087
1088 ret = 0;
1089
1090out:
1091 return ret;
1092}
1093
1094#endif
1095
Emeric Brune1f38db2012-09-03 20:36:47 +02001096void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1097{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001098 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001099 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001100 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001101
1102 if (where & SSL_CB_HANDSHAKE_START) {
1103 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001104 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001105 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001106 conn->err_code = CO_ER_SSL_RENEG;
1107 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001108 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001109
1110 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1111 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1112 /* Long certificate chains optimz
1113 If write and read bios are differents, we
1114 consider that the buffering was activated,
1115 so we rise the output buffer size from 4k
1116 to 16k */
1117 write_bio = SSL_get_wbio(ssl);
1118 if (write_bio != SSL_get_rbio(ssl)) {
1119 BIO_set_write_buffer_size(write_bio, 16384);
1120 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1121 }
1122 }
1123 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001124}
1125
Emeric Brune64aef12012-09-21 13:15:06 +02001126/* Callback is called for each certificate of the chain during a verify
1127 ok is set to 1 if preverify detect no error on current certificate.
1128 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001129int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001130{
1131 SSL *ssl;
1132 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001133 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001134
1135 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001136 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001137
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001138 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001139
Emeric Brun81c00f02012-09-21 14:31:21 +02001140 if (ok) /* no errors */
1141 return ok;
1142
1143 depth = X509_STORE_CTX_get_error_depth(x_store);
1144 err = X509_STORE_CTX_get_error(x_store);
1145
1146 /* check if CA error needs to be ignored */
1147 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001148 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1149 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1150 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001151 }
1152
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001153 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001154 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001155 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001156 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001157 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001158
Willy Tarreau20879a02012-12-03 16:32:10 +01001159 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001160 return 0;
1161 }
1162
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001163 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1164 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001165
Emeric Brun81c00f02012-09-21 14:31:21 +02001166 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001167 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001168 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001169 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001170 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001171 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001172
Willy Tarreau20879a02012-12-03 16:32:10 +01001173 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001174 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001175}
1176
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001177static inline
1178void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001179 const void *buf, size_t len, SSL *ssl)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001180{
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001181 struct ssl_capture *capture;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001182 unsigned char *msg;
1183 unsigned char *end;
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001184 size_t rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001185
1186 /* This function is called for "from client" and "to server"
1187 * connections. The combination of write_p == 0 and content_type == 22
1188 * is only avalaible during "from client" connection.
1189 */
1190
1191 /* "write_p" is set to 0 is the bytes are received messages,
1192 * otherwise it is set to 1.
1193 */
1194 if (write_p != 0)
1195 return;
1196
1197 /* content_type contains the type of message received or sent
1198 * according with the SSL/TLS protocol spec. This message is
1199 * encoded with one byte. The value 256 (two bytes) is used
1200 * for designing the SSL/TLS record layer. According with the
1201 * rfc6101, the expected message (other than 256) are:
1202 * - change_cipher_spec(20)
1203 * - alert(21)
1204 * - handshake(22)
1205 * - application_data(23)
1206 * - (255)
1207 * We are interessed by the handshake and specially the client
1208 * hello.
1209 */
1210 if (content_type != 22)
1211 return;
1212
1213 /* The message length is at least 4 bytes, containing the
1214 * message type and the message length.
1215 */
1216 if (len < 4)
1217 return;
1218
1219 /* First byte of the handshake message id the type of
1220 * message. The konwn types are:
1221 * - hello_request(0)
1222 * - client_hello(1)
1223 * - server_hello(2)
1224 * - certificate(11)
1225 * - server_key_exchange (12)
1226 * - certificate_request(13)
1227 * - server_hello_done(14)
1228 * We are interested by the client hello.
1229 */
1230 msg = (unsigned char *)buf;
1231 if (msg[0] != 1)
1232 return;
1233
1234 /* Next three bytes are the length of the message. The total length
1235 * must be this decoded length + 4. If the length given as argument
1236 * is not the same, we abort the protocol dissector.
1237 */
1238 rec_len = (msg[1] << 16) + (msg[2] << 8) + msg[3];
1239 if (len < rec_len + 4)
1240 return;
1241 msg += 4;
1242 end = msg + rec_len;
1243 if (end < msg)
1244 return;
1245
1246 /* Expect 2 bytes for protocol version (1 byte for major and 1 byte
1247 * for minor, the random, composed by 4 bytes for the unix time and
1248 * 28 bytes for unix payload, and them 1 byte for the session id. So
1249 * we jump 1 + 1 + 4 + 28 + 1 bytes.
1250 */
1251 msg += 1 + 1 + 4 + 28 + 1;
1252 if (msg > end)
1253 return;
1254
1255 /* Next two bytes are the ciphersuite length. */
1256 if (msg + 2 > end)
1257 return;
1258 rec_len = (msg[0] << 8) + msg[1];
1259 msg += 2;
1260 if (msg + rec_len > end || msg + rec_len < msg)
1261 return;
1262
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001263 capture = pool_alloc_dirty(pool2_ssl_capture);
1264 if (!capture)
1265 return;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001266 /* Compute the xxh64 of the ciphersuite. */
1267 capture->xxh64 = XXH64(msg, rec_len, 0);
1268
1269 /* Capture the ciphersuite. */
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001270 capture->ciphersuite_len = (global_ssl.capture_cipherlist < rec_len) ?
1271 global_ssl.capture_cipherlist : rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001272 memcpy(capture->ciphersuite, msg, capture->ciphersuite_len);
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001273
1274 SSL_set_ex_data(ssl, ssl_capture_ptr_index, capture);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001275}
1276
Emeric Brun29f037d2014-04-25 19:05:36 +02001277/* Callback is called for ssl protocol analyse */
1278void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1279{
Emeric Brun29f037d2014-04-25 19:05:36 +02001280#ifdef TLS1_RT_HEARTBEAT
1281 /* test heartbeat received (write_p is set to 0
1282 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001283 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001284 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001285 const unsigned char *p = buf;
1286 unsigned int payload;
1287
Emeric Brun29f037d2014-04-25 19:05:36 +02001288 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001289
1290 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1291 if (*p != TLS1_HB_REQUEST)
1292 return;
1293
Willy Tarreauaeed6722014-04-25 23:59:58 +02001294 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001295 goto kill_it;
1296
1297 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001298 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001299 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001300 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001301 /* We have a clear heartbleed attack (CVE-2014-0160), the
1302 * advertised payload is larger than the advertised packet
1303 * length, so we have garbage in the buffer between the
1304 * payload and the end of the buffer (p+len). We can't know
1305 * if the SSL stack is patched, and we don't know if we can
1306 * safely wipe out the area between p+3+len and payload.
1307 * So instead, we prevent the response from being sent by
1308 * setting the max_send_fragment to 0 and we report an SSL
1309 * error, which will kill this connection. It will be reported
1310 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001311 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1312 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001313 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001314 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1315 return;
1316 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001317#endif
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001318 if (global_ssl.capture_cipherlist > 0)
1319 ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
Emeric Brun29f037d2014-04-25 19:05:36 +02001320}
1321
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001322#ifdef OPENSSL_NPN_NEGOTIATED
1323/* This callback is used so that the server advertises the list of
1324 * negociable protocols for NPN.
1325 */
1326static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1327 unsigned int *len, void *arg)
1328{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001329 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001330
1331 *data = (const unsigned char *)conf->npn_str;
1332 *len = conf->npn_len;
1333 return SSL_TLSEXT_ERR_OK;
1334}
1335#endif
1336
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001337#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001338/* This callback is used so that the server advertises the list of
1339 * negociable protocols for ALPN.
1340 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001341static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1342 unsigned char *outlen,
1343 const unsigned char *server,
1344 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001345{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001346 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001347
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001348 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1349 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1350 return SSL_TLSEXT_ERR_NOACK;
1351 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001352 return SSL_TLSEXT_ERR_OK;
1353}
1354#endif
1355
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001356#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001357#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001358
Christopher Faulet30548802015-06-11 13:39:32 +02001359/* Create a X509 certificate with the specified servername and serial. This
1360 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001361static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001362ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001363{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001364 static unsigned int serial = 0;
1365
Christopher Faulet7969a332015-10-09 11:15:03 +02001366 X509 *cacert = bind_conf->ca_sign_cert;
1367 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001368 SSL_CTX *ssl_ctx = NULL;
1369 X509 *newcrt = NULL;
1370 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001371 X509_NAME *name;
1372 const EVP_MD *digest;
1373 X509V3_CTX ctx;
1374 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001375 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001376
Christopher Faulet7969a332015-10-09 11:15:03 +02001377 /* Get the private key of the defautl certificate and use it */
1378 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001379 goto mkcert_error;
1380
1381 /* Create the certificate */
1382 if (!(newcrt = X509_new()))
1383 goto mkcert_error;
1384
1385 /* Set version number for the certificate (X509v3) and the serial
1386 * number */
1387 if (X509_set_version(newcrt, 2L) != 1)
1388 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001389 if (!serial)
1390 serial = now_ms;
1391 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001392
1393 /* Set duration for the certificate */
1394 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1395 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1396 goto mkcert_error;
1397
1398 /* set public key in the certificate */
1399 if (X509_set_pubkey(newcrt, pkey) != 1)
1400 goto mkcert_error;
1401
1402 /* Set issuer name from the CA */
1403 if (!(name = X509_get_subject_name(cacert)))
1404 goto mkcert_error;
1405 if (X509_set_issuer_name(newcrt, name) != 1)
1406 goto mkcert_error;
1407
1408 /* Set the subject name using the same, but the CN */
1409 name = X509_NAME_dup(name);
1410 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1411 (const unsigned char *)servername,
1412 -1, -1, 0) != 1) {
1413 X509_NAME_free(name);
1414 goto mkcert_error;
1415 }
1416 if (X509_set_subject_name(newcrt, name) != 1) {
1417 X509_NAME_free(name);
1418 goto mkcert_error;
1419 }
1420 X509_NAME_free(name);
1421
1422 /* Add x509v3 extensions as specified */
1423 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1424 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1425 X509_EXTENSION *ext;
1426
1427 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1428 goto mkcert_error;
1429 if (!X509_add_ext(newcrt, ext, -1)) {
1430 X509_EXTENSION_free(ext);
1431 goto mkcert_error;
1432 }
1433 X509_EXTENSION_free(ext);
1434 }
1435
1436 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001437
1438 key_type = EVP_PKEY_base_id(capkey);
1439
1440 if (key_type == EVP_PKEY_DSA)
1441 digest = EVP_sha1();
1442 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001443 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001444 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001445 digest = EVP_sha256();
1446 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001447#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001448 int nid;
1449
1450 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1451 goto mkcert_error;
1452 if (!(digest = EVP_get_digestbynid(nid)))
1453 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001454#else
1455 goto mkcert_error;
1456#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001457 }
1458
Christopher Faulet31af49d2015-06-09 17:29:50 +02001459 if (!(X509_sign(newcrt, capkey, digest)))
1460 goto mkcert_error;
1461
1462 /* Create and set the new SSL_CTX */
1463 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1464 goto mkcert_error;
1465 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1466 goto mkcert_error;
1467 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1468 goto mkcert_error;
1469 if (!SSL_CTX_check_private_key(ssl_ctx))
1470 goto mkcert_error;
1471
1472 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001473
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001474#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001475 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001476#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001477#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1478 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001479 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001480 EC_KEY *ecc;
1481 int nid;
1482
1483 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1484 goto end;
1485 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1486 goto end;
1487 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1488 EC_KEY_free(ecc);
1489 }
1490#endif
1491 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001492 return ssl_ctx;
1493
1494 mkcert_error:
1495 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1496 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001497 return NULL;
1498}
1499
Christopher Faulet7969a332015-10-09 11:15:03 +02001500SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001501ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001502{
1503 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001504
1505 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001506}
1507
Christopher Faulet30548802015-06-11 13:39:32 +02001508/* Do a lookup for a certificate in the LRU cache used to store generated
1509 * certificates. */
1510SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001511ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001512{
1513 struct lru64 *lru = NULL;
1514
1515 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001516 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001517 if (lru && lru->domain)
1518 return (SSL_CTX *)lru->data;
1519 }
1520 return NULL;
1521}
1522
Christopher Fauletd2cab922015-07-28 16:03:47 +02001523/* Set a certificate int the LRU cache used to store generated
1524 * certificate. Return 0 on success, otherwise -1 */
1525int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001526ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001527{
1528 struct lru64 *lru = NULL;
1529
1530 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001531 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001532 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001533 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001534 if (lru->domain && lru->data)
1535 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001536 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001537 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001538 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001539 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001540}
1541
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001542/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001543unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001544ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001545{
1546 return XXH32(data, len, ssl_ctx_lru_seed);
1547}
1548
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001549/* Generate a cert and immediately assign it to the SSL session so that the cert's
1550 * refcount is maintained regardless of the cert's presence in the LRU cache.
1551 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001552static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001553ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001554{
1555 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001556 SSL_CTX *ssl_ctx = NULL;
1557 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001558 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001559
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001560 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001561 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001562 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001563 if (lru && lru->domain)
1564 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001565 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001566 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001567 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001568 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001569 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001570 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001571 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001572 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001573 SSL_set_SSL_CTX(ssl, ssl_ctx);
1574 /* No LRU cache, this CTX will be released as soon as the session dies */
1575 SSL_CTX_free(ssl_ctx);
1576 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001577 return ssl_ctx;
1578}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001579#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001580
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001581static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1582{
1583 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1584 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1585 SSL_set_SSL_CTX(ssl, ctx);
1586}
1587
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001588#ifdef OPENSSL_IS_BORINGSSL
1589
1590static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1591{
1592 (void)al; /* shut gcc stupid warning */
1593 (void)priv;
1594
1595 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1596 return SSL_TLSEXT_ERR_NOACK;
1597 return SSL_TLSEXT_ERR_OK;
1598}
1599
1600static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1601{
1602 struct connection *conn;
1603 struct bind_conf *s;
1604 const uint8_t *extension_data;
1605 size_t extension_len;
1606 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1607 const SSL_CIPHER *cipher;
1608 uint16_t cipher_suite;
1609 uint8_t name_type, hash, sign;
1610 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1611
1612 char *wildp = NULL;
1613 const uint8_t *servername;
1614 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1615 int i;
1616
1617 conn = SSL_get_app_data(ctx->ssl);
1618 s = objt_listener(conn->target)->bind_conf;
1619
1620 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1621 &extension_data, &extension_len)) {
1622 CBS_init(&extension, extension_data, extension_len);
1623
1624 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1625 || !CBS_get_u8(&server_name_list, &name_type)
1626 /* Although the server_name extension was intended to be extensible to
1627 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1628 * different name types will cause an error. Further, RFC 4366 originally
1629 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1630 * adding new name types is no longer feasible.
1631 *
1632 * Act as if the extensibility does not exist to simplify parsing. */
1633 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1634 || CBS_len(&server_name_list) != 0
1635 || CBS_len(&extension) != 0
1636 || name_type != TLSEXT_NAMETYPE_host_name
1637 || CBS_len(&host_name) == 0
1638 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1639 || CBS_contains_zero_byte(&host_name)) {
1640 goto abort;
1641 }
1642 } else {
1643 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001644 if (!s->strict_sni) {
1645 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001646 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001647 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001648 goto abort;
1649 }
1650
1651 /* extract/check clientHello informations */
1652 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
1653 CBS_init(&extension, extension_data, extension_len);
1654
1655 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
1656 || CBS_len(&sig_algs) == 0
1657 || CBS_len(&extension) != 0) {
1658 goto abort;
1659 }
1660 if (CBS_len(&sig_algs) % 2 != 0) {
1661 goto abort;
1662 }
1663 while (CBS_len(&sig_algs) != 0) {
1664 if (!CBS_get_u8(&sig_algs, &hash)
1665 || !CBS_get_u8(&sig_algs, &sign)) {
1666 goto abort;
1667 }
1668 switch (sign) {
1669 case TLSEXT_signature_rsa:
1670 has_rsa = 1;
1671 break;
1672 case TLSEXT_signature_ecdsa:
1673 has_ecdsa_sig = 1;
1674 break;
1675 default:
1676 continue;
1677 }
1678 if (has_ecdsa_sig && has_rsa)
1679 break;
1680 }
1681 } else {
1682 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
1683 has_rsa = 1;
1684 }
1685 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
1686 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
1687
1688 while (CBS_len(&cipher_suites) != 0) {
1689 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1690 goto abort;
1691 }
1692 cipher = SSL_get_cipher_by_value(cipher_suite);
1693 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
1694 has_ecdsa = 1;
1695 break;
1696 }
1697 }
1698 }
1699
1700 servername = CBS_data(&host_name);
1701 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
1702 trash.str[i] = tolower(servername[i]);
1703 if (!wildp && (trash.str[i] == '.'))
1704 wildp = &trash.str[i];
1705 }
1706 trash.str[i] = 0;
1707
1708 /* lookup in full qualified names */
1709 node = ebst_lookup(&s->sni_ctx, trash.str);
1710
1711 /* lookup a not neg filter */
1712 for (n = node; n; n = ebmb_next_dup(n)) {
1713 if (!container_of(n, struct sni_ctx, name)->neg) {
1714 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1715 case TLSEXT_signature_ecdsa:
1716 if (has_ecdsa) {
1717 node_ecdsa = n;
1718 goto find_one;
1719 }
1720 break;
1721 case TLSEXT_signature_rsa:
1722 if (has_rsa && !node_rsa) {
1723 node_rsa = n;
1724 if (!has_ecdsa)
1725 goto find_one;
1726 }
1727 break;
1728 default: /* TLSEXT_signature_anonymous */
1729 if (!node_anonymous)
1730 node_anonymous = n;
1731 break;
1732 }
1733 }
1734 }
1735 if (wildp) {
1736 /* lookup in wildcards names */
1737 node = ebst_lookup(&s->sni_w_ctx, wildp);
1738 for (n = node; n; n = ebmb_next_dup(n)) {
1739 if (!container_of(n, struct sni_ctx, name)->neg) {
1740 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1741 case TLSEXT_signature_ecdsa:
1742 if (has_ecdsa) {
1743 node_ecdsa = n;
1744 goto find_one;
1745 }
1746 break;
1747 case TLSEXT_signature_rsa:
1748 if (has_rsa && !node_rsa) {
1749 node_rsa = n;
1750 if (!has_ecdsa)
1751 goto find_one;
1752 }
1753 break;
1754 default: /* TLSEXT_signature_anonymous */
1755 if (!node_anonymous)
1756 node_anonymous = n;
1757 break;
1758 }
1759 }
1760 }
1761 }
1762 find_one:
1763 /* select by key_signature priority order */
1764 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
1765
1766 if (node) {
1767 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001768 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001769 return 1;
1770 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001771 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001772 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001773 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001774 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001775 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001776 abort:
1777 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
1778 conn->err_code = CO_ER_SSL_HANDSHAKE;
1779 return -1;
1780}
1781
1782#else /* OPENSSL_IS_BORINGSSL */
1783
Emeric Brunfc0421f2012-09-07 17:30:07 +02001784/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1785 * warning when no match is found, which implies the default (first) cert
1786 * will keep being used.
1787 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001788static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001789{
1790 const char *servername;
1791 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001792 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001793 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001794 int i;
1795 (void)al; /* shut gcc stupid warning */
1796
1797 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001798 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001799#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02001800 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001801 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001802 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001803 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001804
Willy Tarreauf6721452015-07-07 18:04:38 +02001805 conn_get_to_addr(conn);
1806 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001807 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1808 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001809 if (ctx) {
1810 /* switch ctx */
1811 SSL_set_SSL_CTX(ssl, ctx);
1812 return SSL_TLSEXT_ERR_OK;
1813 }
Christopher Faulet30548802015-06-11 13:39:32 +02001814 }
1815 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001816#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001817 if (s->strict_sni)
1818 return SSL_TLSEXT_ERR_ALERT_FATAL;
1819 ssl_sock_switchctx_set(ssl, s->default_ctx);
1820 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001821 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001822
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001823 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001824 if (!servername[i])
1825 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001826 trash.str[i] = tolower(servername[i]);
1827 if (!wildp && (trash.str[i] == '.'))
1828 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001829 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001830 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001831
1832 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001833 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001834
1835 /* lookup a not neg filter */
1836 for (n = node; n; n = ebmb_next_dup(n)) {
1837 if (!container_of(n, struct sni_ctx, name)->neg) {
1838 node = n;
1839 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001840 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001841 }
1842 if (!node && wildp) {
1843 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001844 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001845 }
1846 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001847#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001848 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001849 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001850 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001851 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001852 return SSL_TLSEXT_ERR_OK;
1853 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001854#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001855 if (s->strict_sni)
1856 return SSL_TLSEXT_ERR_ALERT_FATAL;
1857 ssl_sock_switchctx_set(ssl, s->default_ctx);
1858 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001859 }
1860
1861 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001862 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001863 return SSL_TLSEXT_ERR_OK;
1864}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001865#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001866#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1867
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001868#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001869
1870static DH * ssl_get_dh_1024(void)
1871{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001872 static unsigned char dh1024_p[]={
1873 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1874 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1875 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1876 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1877 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1878 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1879 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1880 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1881 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1882 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1883 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1884 };
1885 static unsigned char dh1024_g[]={
1886 0x02,
1887 };
1888
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001889 BIGNUM *p;
1890 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001891 DH *dh = DH_new();
1892 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001893 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1894 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001895
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001896 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001897 DH_free(dh);
1898 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001899 } else {
1900 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001901 }
1902 }
1903 return dh;
1904}
1905
1906static DH *ssl_get_dh_2048(void)
1907{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001908 static unsigned char dh2048_p[]={
1909 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1910 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1911 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1912 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1913 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1914 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1915 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1916 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1917 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1918 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1919 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1920 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1921 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1922 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1923 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1924 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1925 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1926 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1927 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1928 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1929 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1930 0xB7,0x1F,0x77,0xF3,
1931 };
1932 static unsigned char dh2048_g[]={
1933 0x02,
1934 };
1935
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001936 BIGNUM *p;
1937 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001938 DH *dh = DH_new();
1939 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001940 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1941 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001942
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001943 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001944 DH_free(dh);
1945 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001946 } else {
1947 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001948 }
1949 }
1950 return dh;
1951}
1952
1953static DH *ssl_get_dh_4096(void)
1954{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001955 static unsigned char dh4096_p[]={
1956 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1957 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1958 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1959 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1960 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1961 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1962 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1963 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1964 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1965 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1966 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1967 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1968 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1969 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1970 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1971 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1972 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1973 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1974 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1975 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1976 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1977 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1978 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1979 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1980 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1981 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1982 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1983 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1984 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1985 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1986 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1987 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1988 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1989 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1990 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1991 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1992 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1993 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1994 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1995 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1996 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1997 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1998 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001999 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02002000 static unsigned char dh4096_g[]={
2001 0x02,
2002 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002003
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002004 BIGNUM *p;
2005 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002006 DH *dh = DH_new();
2007 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002008 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
2009 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02002010
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002011 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002012 DH_free(dh);
2013 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002014 } else {
2015 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002016 }
2017 }
2018 return dh;
2019}
2020
2021/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01002022 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002023static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
2024{
2025 DH *dh = NULL;
2026 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002027 int type;
2028
2029 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002030
2031 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2032 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2033 */
2034 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2035 keylen = EVP_PKEY_bits(pkey);
2036 }
2037
Willy Tarreauef934602016-12-22 23:12:01 +01002038 if (keylen > global_ssl.default_dh_param) {
2039 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002040 }
2041
Remi Gacogned3a341a2015-05-29 16:26:17 +02002042 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002043 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002044 }
2045 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002046 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002047 }
2048 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002049 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002050 }
2051
2052 return dh;
2053}
2054
Remi Gacogne47783ef2015-05-29 15:53:22 +02002055static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002056{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002057 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002058 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002059
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002060 if (in == NULL)
2061 goto end;
2062
Remi Gacogne47783ef2015-05-29 15:53:22 +02002063 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002064 goto end;
2065
Remi Gacogne47783ef2015-05-29 15:53:22 +02002066 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2067
2068end:
2069 if (in)
2070 BIO_free(in);
2071
2072 return dh;
2073}
2074
2075int ssl_sock_load_global_dh_param_from_file(const char *filename)
2076{
2077 global_dh = ssl_sock_get_dh_from_file(filename);
2078
2079 if (global_dh) {
2080 return 0;
2081 }
2082
2083 return -1;
2084}
2085
2086/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2087 if an error occured, and 0 if parameter not found. */
2088int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2089{
2090 int ret = -1;
2091 DH *dh = ssl_sock_get_dh_from_file(file);
2092
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002093 if (dh) {
2094 ret = 1;
2095 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002096
2097 if (ssl_dh_ptr_index >= 0) {
2098 /* store a pointer to the DH params to avoid complaining about
2099 ssl-default-dh-param not being set for this SSL_CTX */
2100 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2101 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002102 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002103 else if (global_dh) {
2104 SSL_CTX_set_tmp_dh(ctx, global_dh);
2105 ret = 0; /* DH params not found */
2106 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002107 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002108 /* Clear openssl global errors stack */
2109 ERR_clear_error();
2110
Willy Tarreauef934602016-12-22 23:12:01 +01002111 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002112 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002113 if (local_dh_1024 == NULL)
2114 local_dh_1024 = ssl_get_dh_1024();
2115
Remi Gacogne8de54152014-07-15 11:36:40 +02002116 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002117 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002118
Remi Gacogne8de54152014-07-15 11:36:40 +02002119 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002120 }
2121 else {
2122 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2123 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002124
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002125 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002126 }
Emeric Brun644cde02012-12-14 11:21:13 +01002127
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002128end:
2129 if (dh)
2130 DH_free(dh);
2131
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002132 return ret;
2133}
2134#endif
2135
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002136static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2137 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002138{
2139 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002140 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002141 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002142
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002143 if (*name == '!') {
2144 neg = 1;
2145 name++;
2146 }
2147 if (*name == '*') {
2148 wild = 1;
2149 name++;
2150 }
2151 /* !* filter is a nop */
2152 if (neg && wild)
2153 return order;
2154 if (*name) {
2155 int j, len;
2156 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002157 for (j = 0; j < len && j < trash.size; j++)
2158 trash.str[j] = tolower(name[j]);
2159 if (j >= trash.size)
2160 return order;
2161 trash.str[j] = 0;
2162
2163 /* Check for duplicates. */
2164 if (wild)
2165 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2166 else
2167 node = ebst_lookup(&s->sni_ctx, trash.str);
2168 for (; node; node = ebmb_next_dup(node)) {
2169 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002170 if (sc->ctx == ctx && sc->conf == conf &&
2171 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002172 return order;
2173 }
2174
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002175 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002176 if (!sc)
2177 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002178 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002179 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002180 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002181 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002182 sc->order = order++;
2183 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002184 if (wild)
2185 ebst_insert(&s->sni_w_ctx, &sc->name);
2186 else
2187 ebst_insert(&s->sni_ctx, &sc->name);
2188 }
2189 return order;
2190}
2191
yanbzhu488a4d22015-12-01 15:16:07 -05002192
2193/* The following code is used for loading multiple crt files into
2194 * SSL_CTX's based on CN/SAN
2195 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002196#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002197/* This is used to preload the certifcate, private key
2198 * and Cert Chain of a file passed in via the crt
2199 * argument
2200 *
2201 * This way, we do not have to read the file multiple times
2202 */
2203struct cert_key_and_chain {
2204 X509 *cert;
2205 EVP_PKEY *key;
2206 unsigned int num_chain_certs;
2207 /* This is an array of X509 pointers */
2208 X509 **chain_certs;
2209};
2210
yanbzhu08ce6ab2015-12-02 13:01:29 -05002211#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2212
2213struct key_combo_ctx {
2214 SSL_CTX *ctx;
2215 int order;
2216};
2217
2218/* Map used for processing multiple keypairs for a single purpose
2219 *
2220 * This maps CN/SNI name to certificate type
2221 */
2222struct sni_keytype {
2223 int keytypes; /* BITMASK for keytypes */
2224 struct ebmb_node name; /* node holding the servername value */
2225};
2226
2227
yanbzhu488a4d22015-12-01 15:16:07 -05002228/* Frees the contents of a cert_key_and_chain
2229 */
2230static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2231{
2232 int i;
2233
2234 if (!ckch)
2235 return;
2236
2237 /* Free the certificate and set pointer to NULL */
2238 if (ckch->cert)
2239 X509_free(ckch->cert);
2240 ckch->cert = NULL;
2241
2242 /* Free the key and set pointer to NULL */
2243 if (ckch->key)
2244 EVP_PKEY_free(ckch->key);
2245 ckch->key = NULL;
2246
2247 /* Free each certificate in the chain */
2248 for (i = 0; i < ckch->num_chain_certs; i++) {
2249 if (ckch->chain_certs[i])
2250 X509_free(ckch->chain_certs[i]);
2251 }
2252
2253 /* Free the chain obj itself and set to NULL */
2254 if (ckch->num_chain_certs > 0) {
2255 free(ckch->chain_certs);
2256 ckch->num_chain_certs = 0;
2257 ckch->chain_certs = NULL;
2258 }
2259
2260}
2261
2262/* checks if a key and cert exists in the ckch
2263 */
2264static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2265{
2266 return (ckch->cert != NULL && ckch->key != NULL);
2267}
2268
2269
2270/* Loads the contents of a crt file (path) into a cert_key_and_chain
2271 * This allows us to carry the contents of the file without having to
2272 * read the file multiple times.
2273 *
2274 * returns:
2275 * 0 on Success
2276 * 1 on SSL Failure
2277 * 2 on file not found
2278 */
2279static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2280{
2281
2282 BIO *in;
2283 X509 *ca = NULL;
2284 int ret = 1;
2285
2286 ssl_sock_free_cert_key_and_chain_contents(ckch);
2287
2288 in = BIO_new(BIO_s_file());
2289 if (in == NULL)
2290 goto end;
2291
2292 if (BIO_read_filename(in, path) <= 0)
2293 goto end;
2294
yanbzhu488a4d22015-12-01 15:16:07 -05002295 /* Read Private Key */
2296 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2297 if (ckch->key == NULL) {
2298 memprintf(err, "%sunable to load private key from file '%s'.\n",
2299 err && *err ? *err : "", path);
2300 goto end;
2301 }
2302
Willy Tarreaubb137a82016-04-06 19:02:38 +02002303 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002304 if (BIO_reset(in) == -1) {
2305 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2306 err && *err ? *err : "", path);
2307 goto end;
2308 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002309
2310 /* Read Certificate */
2311 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2312 if (ckch->cert == NULL) {
2313 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2314 err && *err ? *err : "", path);
2315 goto end;
2316 }
2317
yanbzhu488a4d22015-12-01 15:16:07 -05002318 /* Read Certificate Chain */
2319 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2320 /* Grow the chain certs */
2321 ckch->num_chain_certs++;
2322 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2323
2324 /* use - 1 here since we just incremented it above */
2325 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2326 }
2327 ret = ERR_get_error();
2328 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2329 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2330 err && *err ? *err : "", path);
2331 ret = 1;
2332 goto end;
2333 }
2334
2335 ret = 0;
2336
2337end:
2338
2339 ERR_clear_error();
2340 if (in)
2341 BIO_free(in);
2342
2343 /* Something went wrong in one of the reads */
2344 if (ret != 0)
2345 ssl_sock_free_cert_key_and_chain_contents(ckch);
2346
2347 return ret;
2348}
2349
2350/* Loads the info in ckch into ctx
2351 * Currently, this does not process any information about ocsp, dhparams or
2352 * sctl
2353 * Returns
2354 * 0 on success
2355 * 1 on failure
2356 */
2357static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2358{
2359 int i = 0;
2360
2361 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2362 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2363 err && *err ? *err : "", path);
2364 return 1;
2365 }
2366
2367 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2368 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2369 err && *err ? *err : "", path);
2370 return 1;
2371 }
2372
yanbzhu488a4d22015-12-01 15:16:07 -05002373 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2374 for (i = 0; i < ckch->num_chain_certs; i++) {
2375 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002376 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2377 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002378 return 1;
2379 }
2380 }
2381
2382 if (SSL_CTX_check_private_key(ctx) <= 0) {
2383 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2384 err && *err ? *err : "", path);
2385 return 1;
2386 }
2387
2388 return 0;
2389}
2390
yanbzhu08ce6ab2015-12-02 13:01:29 -05002391
2392static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2393{
2394 struct sni_keytype *s_kt = NULL;
2395 struct ebmb_node *node;
2396 int i;
2397
2398 for (i = 0; i < trash.size; i++) {
2399 if (!str[i])
2400 break;
2401 trash.str[i] = tolower(str[i]);
2402 }
2403 trash.str[i] = 0;
2404 node = ebst_lookup(sni_keytypes, trash.str);
2405 if (!node) {
2406 /* CN not found in tree */
2407 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2408 /* Using memcpy here instead of strncpy.
2409 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2410 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2411 */
2412 memcpy(s_kt->name.key, trash.str, i+1);
2413 s_kt->keytypes = 0;
2414 ebst_insert(sni_keytypes, &s_kt->name);
2415 } else {
2416 /* CN found in tree */
2417 s_kt = container_of(node, struct sni_keytype, name);
2418 }
2419
2420 /* Mark that this CN has the keytype of key_index via keytypes mask */
2421 s_kt->keytypes |= 1<<key_index;
2422
2423}
2424
2425
2426/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2427 * If any are found, group these files into a set of SSL_CTX*
2428 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2429 *
2430 * This will allow the user to explictly group multiple cert/keys for a single purpose
2431 *
2432 * Returns
2433 * 0 on success
2434 * 1 on failure
2435 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002436static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2437 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002438{
2439 char fp[MAXPATHLEN+1] = {0};
2440 int n = 0;
2441 int i = 0;
2442 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2443 struct eb_root sni_keytypes_map = { {0} };
2444 struct ebmb_node *node;
2445 struct ebmb_node *next;
2446 /* Array of SSL_CTX pointers corresponding to each possible combo
2447 * of keytypes
2448 */
2449 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2450 int rv = 0;
2451 X509_NAME *xname = NULL;
2452 char *str = NULL;
2453#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2454 STACK_OF(GENERAL_NAME) *names = NULL;
2455#endif
2456
2457 /* Load all possible certs and keys */
2458 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2459 struct stat buf;
2460
2461 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2462 if (stat(fp, &buf) == 0) {
2463 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2464 rv = 1;
2465 goto end;
2466 }
2467 }
2468 }
2469
2470 /* Process each ckch and update keytypes for each CN/SAN
2471 * for example, if CN/SAN www.a.com is associated with
2472 * certs with keytype 0 and 2, then at the end of the loop,
2473 * www.a.com will have:
2474 * keyindex = 0 | 1 | 4 = 5
2475 */
2476 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2477
2478 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2479 continue;
2480
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002481 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002482 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002483 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2484 } else {
2485 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2486 * so the line that contains logic is marked via comments
2487 */
2488 xname = X509_get_subject_name(certs_and_keys[n].cert);
2489 i = -1;
2490 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2491 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002492 ASN1_STRING *value;
2493 value = X509_NAME_ENTRY_get_data(entry);
2494 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002495 /* Important line is here */
2496 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002497
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002498 OPENSSL_free(str);
2499 str = NULL;
2500 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002501 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002502
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002503 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002504#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002505 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2506 if (names) {
2507 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2508 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002509
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002510 if (name->type == GEN_DNS) {
2511 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2512 /* Important line is here */
2513 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002514
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002515 OPENSSL_free(str);
2516 str = NULL;
2517 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002518 }
2519 }
2520 }
2521 }
2522#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2523 }
2524
2525 /* If no files found, return error */
2526 if (eb_is_empty(&sni_keytypes_map)) {
2527 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2528 err && *err ? *err : "", path);
2529 rv = 1;
2530 goto end;
2531 }
2532
2533 /* We now have a map of CN/SAN to keytypes that are loaded in
2534 * Iterate through the map to create the SSL_CTX's (if needed)
2535 * and add each CTX to the SNI tree
2536 *
2537 * Some math here:
2538 * There are 2^n - 1 possibile combinations, each unique
2539 * combination is denoted by the key in the map. Each key
2540 * has a value between 1 and 2^n - 1. Conveniently, the array
2541 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2542 * entry in the array to correspond to the unique combo (key)
2543 * associated with i. This unique key combo (i) will be associated
2544 * with combos[i-1]
2545 */
2546
2547 node = ebmb_first(&sni_keytypes_map);
2548 while (node) {
2549 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002550 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002551
2552 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2553 i = container_of(node, struct sni_keytype, name)->keytypes;
2554 cur_ctx = key_combos[i-1].ctx;
2555
2556 if (cur_ctx == NULL) {
2557 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002558 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002559 if (cur_ctx == NULL) {
2560 memprintf(err, "%sunable to allocate SSL context.\n",
2561 err && *err ? *err : "");
2562 rv = 1;
2563 goto end;
2564 }
2565
yanbzhube2774d2015-12-10 15:07:30 -05002566 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002567 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2568 if (i & (1<<n)) {
2569 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002570 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2571 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002572 SSL_CTX_free(cur_ctx);
2573 rv = 1;
2574 goto end;
2575 }
yanbzhube2774d2015-12-10 15:07:30 -05002576
2577#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2578 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002579 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002580 if (err)
2581 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 +00002582 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002583 SSL_CTX_free(cur_ctx);
2584 rv = 1;
2585 goto end;
2586 }
2587#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002588 }
2589 }
2590
2591 /* Load DH params into the ctx to support DHE keys */
2592#ifndef OPENSSL_NO_DH
2593 if (ssl_dh_ptr_index >= 0)
2594 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2595
2596 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2597 if (rv < 0) {
2598 if (err)
2599 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2600 *err ? *err : "", path);
2601 rv = 1;
2602 goto end;
2603 }
2604#endif
2605
2606 /* Update key_combos */
2607 key_combos[i-1].ctx = cur_ctx;
2608 }
2609
2610 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002611 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2612 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002613 node = ebmb_next(node);
2614 }
2615
2616
2617 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2618 if (!bind_conf->default_ctx) {
2619 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2620 if (key_combos[i].ctx) {
2621 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002622 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002623 break;
2624 }
2625 }
2626 }
2627
2628end:
2629
2630 if (names)
2631 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2632
2633 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2634 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2635
2636 node = ebmb_first(&sni_keytypes_map);
2637 while (node) {
2638 next = ebmb_next(node);
2639 ebmb_delete(node);
2640 node = next;
2641 }
2642
2643 return rv;
2644}
2645#else
2646/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002647static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2648 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002649{
2650 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2651 err && *err ? *err : "", path, strerror(errno));
2652 return 1;
2653}
2654
yanbzhu488a4d22015-12-01 15:16:07 -05002655#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2656
Emeric Brunfc0421f2012-09-07 17:30:07 +02002657/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2658 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2659 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002660static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2661 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002662{
2663 BIO *in;
2664 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002665 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002666 int ret = -1;
2667 int order = 0;
2668 X509_NAME *xname;
2669 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002670 pem_password_cb *passwd_cb;
2671 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002672 EVP_PKEY *pkey;
2673 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002674
Emeric Brunfc0421f2012-09-07 17:30:07 +02002675#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2676 STACK_OF(GENERAL_NAME) *names;
2677#endif
2678
2679 in = BIO_new(BIO_s_file());
2680 if (in == NULL)
2681 goto end;
2682
2683 if (BIO_read_filename(in, file) <= 0)
2684 goto end;
2685
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002686
2687 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2688 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2689
2690 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002691 if (x == NULL)
2692 goto end;
2693
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002694 pkey = X509_get_pubkey(x);
2695 if (pkey) {
2696 switch(EVP_PKEY_base_id(pkey)) {
2697 case EVP_PKEY_RSA:
2698 key_sig = TLSEXT_signature_rsa;
2699 break;
2700 case EVP_PKEY_EC:
2701 key_sig = TLSEXT_signature_ecdsa;
2702 break;
2703 }
2704 EVP_PKEY_free(pkey);
2705 }
2706
Emeric Brun50bcecc2013-04-22 13:05:23 +02002707 if (fcount) {
2708 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002709 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002710 }
2711 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002712#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002713 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2714 if (names) {
2715 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2716 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2717 if (name->type == GEN_DNS) {
2718 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002719 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002720 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002721 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002722 }
2723 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002724 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002725 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002726#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002727 xname = X509_get_subject_name(x);
2728 i = -1;
2729 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2730 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002731 ASN1_STRING *value;
2732
2733 value = X509_NAME_ENTRY_get_data(entry);
2734 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002735 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002736 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002737 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002738 }
2739 }
2740
2741 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2742 if (!SSL_CTX_use_certificate(ctx, x))
2743 goto end;
2744
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002745#ifdef SSL_CTX_clear_extra_chain_certs
2746 SSL_CTX_clear_extra_chain_certs(ctx);
2747#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002748 if (ctx->extra_certs != NULL) {
2749 sk_X509_pop_free(ctx->extra_certs, X509_free);
2750 ctx->extra_certs = NULL;
2751 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002752#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002753
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002754 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002755 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2756 X509_free(ca);
2757 goto end;
2758 }
2759 }
2760
2761 err = ERR_get_error();
2762 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2763 /* we successfully reached the last cert in the file */
2764 ret = 1;
2765 }
2766 ERR_clear_error();
2767
2768end:
2769 if (x)
2770 X509_free(x);
2771
2772 if (in)
2773 BIO_free(in);
2774
2775 return ret;
2776}
2777
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002778static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2779 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002780{
2781 int ret;
2782 SSL_CTX *ctx;
2783
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002784 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02002785 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002786 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2787 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002788 return 1;
2789 }
2790
2791 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002792 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2793 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002794 SSL_CTX_free(ctx);
2795 return 1;
2796 }
2797
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002798 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002799 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002800 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2801 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002802 if (ret < 0) /* serious error, must do that ourselves */
2803 SSL_CTX_free(ctx);
2804 return 1;
2805 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002806
2807 if (SSL_CTX_check_private_key(ctx) <= 0) {
2808 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2809 err && *err ? *err : "", path);
2810 return 1;
2811 }
2812
Emeric Brunfc0421f2012-09-07 17:30:07 +02002813 /* we must not free the SSL_CTX anymore below, since it's already in
2814 * the tree, so it will be discovered and cleaned in time.
2815 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002816#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002817 /* store a NULL pointer to indicate we have not yet loaded
2818 a custom DH param file */
2819 if (ssl_dh_ptr_index >= 0) {
2820 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2821 }
2822
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002823 ret = ssl_sock_load_dh_params(ctx, path);
2824 if (ret < 0) {
2825 if (err)
2826 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2827 *err ? *err : "", path);
2828 return 1;
2829 }
2830#endif
2831
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002832#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002833 ret = ssl_sock_load_ocsp(ctx, path);
2834 if (ret < 0) {
2835 if (err)
2836 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",
2837 *err ? *err : "", path);
2838 return 1;
2839 }
2840#endif
2841
Daniel Jakots54ffb912015-11-06 20:02:41 +01002842#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002843 if (sctl_ex_index >= 0) {
2844 ret = ssl_sock_load_sctl(ctx, path);
2845 if (ret < 0) {
2846 if (err)
2847 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2848 *err ? *err : "", path);
2849 return 1;
2850 }
2851 }
2852#endif
2853
Emeric Brunfc0421f2012-09-07 17:30:07 +02002854#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002855 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002856 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2857 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002858 return 1;
2859 }
2860#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002861 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002862 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002863 bind_conf->default_ssl_conf = ssl_conf;
2864 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002865
2866 return 0;
2867}
2868
Willy Tarreau03209342016-12-22 17:08:28 +01002869int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002870{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002871 struct dirent **de_list;
2872 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002873 DIR *dir;
2874 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002875 char *end;
2876 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002877 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002878#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2879 int is_bundle;
2880 int j;
2881#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002882
yanbzhu08ce6ab2015-12-02 13:01:29 -05002883 if (stat(path, &buf) == 0) {
2884 dir = opendir(path);
2885 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002886 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002887
yanbzhu08ce6ab2015-12-02 13:01:29 -05002888 /* strip trailing slashes, including first one */
2889 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2890 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002891
yanbzhu08ce6ab2015-12-02 13:01:29 -05002892 n = scandir(path, &de_list, 0, alphasort);
2893 if (n < 0) {
2894 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2895 err && *err ? *err : "", path, strerror(errno));
2896 cfgerr++;
2897 }
2898 else {
2899 for (i = 0; i < n; i++) {
2900 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002901
yanbzhu08ce6ab2015-12-02 13:01:29 -05002902 end = strrchr(de->d_name, '.');
2903 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2904 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002905
yanbzhu08ce6ab2015-12-02 13:01:29 -05002906 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2907 if (stat(fp, &buf) != 0) {
2908 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2909 err && *err ? *err : "", fp, strerror(errno));
2910 cfgerr++;
2911 goto ignore_entry;
2912 }
2913 if (!S_ISREG(buf.st_mode))
2914 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002915
2916#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2917 is_bundle = 0;
2918 /* Check if current entry in directory is part of a multi-cert bundle */
2919
2920 if (end) {
2921 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2922 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2923 is_bundle = 1;
2924 break;
2925 }
2926 }
2927
2928 if (is_bundle) {
2929 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2930 int dp_len;
2931
2932 dp_len = end - de->d_name;
2933 snprintf(dp, dp_len + 1, "%s", de->d_name);
2934
2935 /* increment i and free de until we get to a non-bundle cert
2936 * Note here that we look at de_list[i + 1] before freeing de
2937 * this is important since ignore_entry will free de
2938 */
2939 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2940 free(de);
2941 i++;
2942 de = de_list[i];
2943 }
2944
2945 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002946 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002947
2948 /* Successfully processed the bundle */
2949 goto ignore_entry;
2950 }
2951 }
2952
2953#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002954 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002955ignore_entry:
2956 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002957 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002958 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002959 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002960 closedir(dir);
2961 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002962 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002963
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002964 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002965
Emeric Brunfc0421f2012-09-07 17:30:07 +02002966 return cfgerr;
2967}
2968
Thierry Fournier383085f2013-01-24 14:15:43 +01002969/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2970 * done once. Zero is returned if the operation fails. No error is returned
2971 * if the random is said as not implemented, because we expect that openssl
2972 * will use another method once needed.
2973 */
2974static int ssl_initialize_random()
2975{
2976 unsigned char random;
2977 static int random_initialized = 0;
2978
2979 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2980 random_initialized = 1;
2981
2982 return random_initialized;
2983}
2984
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002985/* release ssl bind conf */
2986void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002987{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002988 if (conf) {
2989#ifdef OPENSSL_NPN_NEGOTIATED
2990 free(conf->npn_str);
2991 conf->npn_str = NULL;
2992#endif
2993#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2994 free(conf->alpn_str);
2995 conf->alpn_str = NULL;
2996#endif
2997 free(conf->ca_file);
2998 conf->ca_file = NULL;
2999 free(conf->crl_file);
3000 conf->crl_file = NULL;
3001 free(conf->ciphers);
3002 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003003 free(conf->curves);
3004 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003005 free(conf->ecdhe);
3006 conf->ecdhe = NULL;
3007 }
3008}
3009
3010int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
3011{
3012 char thisline[CRT_LINESIZE];
3013 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003014 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05003015 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003016 int linenum = 0;
3017 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003018
Willy Tarreauad1731d2013-04-02 17:35:58 +02003019 if ((f = fopen(file, "r")) == NULL) {
3020 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003021 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003022 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003023
3024 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003025 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003026 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003027 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003028 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003029 char *crt_path;
3030 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003031
3032 linenum++;
3033 end = line + strlen(line);
3034 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3035 /* Check if we reached the limit and the last char is not \n.
3036 * Watch out for the last line without the terminating '\n'!
3037 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003038 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3039 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003040 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003041 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003042 }
3043
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003044 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003045 newarg = 1;
3046 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003047 if (*line == '#' || *line == '\n' || *line == '\r') {
3048 /* end of string, end of loop */
3049 *line = 0;
3050 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003051 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003052 newarg = 1;
3053 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003054 } else if (*line == '[') {
3055 if (ssl_b) {
3056 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3057 cfgerr = 1;
3058 break;
3059 }
3060 if (!arg) {
3061 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3062 cfgerr = 1;
3063 break;
3064 }
3065 ssl_b = arg;
3066 newarg = 1;
3067 *line = 0;
3068 } else if (*line == ']') {
3069 if (ssl_e) {
3070 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003071 cfgerr = 1;
3072 break;
3073 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003074 if (!ssl_b) {
3075 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3076 cfgerr = 1;
3077 break;
3078 }
3079 ssl_e = arg;
3080 newarg = 1;
3081 *line = 0;
3082 } else if (newarg) {
3083 if (arg == MAX_CRT_ARGS) {
3084 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3085 cfgerr = 1;
3086 break;
3087 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003088 newarg = 0;
3089 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003090 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003091 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003092 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003093 if (cfgerr)
3094 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003095 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003096
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003097 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003098 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003099 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003100
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003101 crt_path = args[0];
3102 if (*crt_path != '/' && global_ssl.crt_base) {
3103 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3104 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3105 crt_path, linenum, file);
3106 cfgerr = 1;
3107 break;
3108 }
3109 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3110 crt_path = path;
3111 }
3112
3113 ssl_conf = calloc(1, sizeof *ssl_conf);
3114 cur_arg = ssl_b ? ssl_b : 1;
3115 while (cur_arg < ssl_e) {
3116 newarg = 0;
3117 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3118 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3119 newarg = 1;
3120 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3121 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3122 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3123 args[cur_arg], linenum, file);
3124 cfgerr = 1;
3125 }
3126 cur_arg += 1 + ssl_bind_kws[i].skip;
3127 break;
3128 }
3129 }
3130 if (!cfgerr && !newarg) {
3131 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3132 args[cur_arg], linenum, file);
3133 cfgerr = 1;
3134 break;
3135 }
3136 }
3137 if (cfgerr) {
3138 ssl_sock_free_ssl_conf(ssl_conf);
3139 free(ssl_conf);
3140 ssl_conf = NULL;
3141 break;
3142 }
3143
3144 if (stat(crt_path, &buf) == 0) {
3145 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3146 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003147 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003148 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3149 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003150 }
3151
Willy Tarreauad1731d2013-04-02 17:35:58 +02003152 if (cfgerr) {
3153 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003154 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003155 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003156 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003157 fclose(f);
3158 return cfgerr;
3159}
3160
Emeric Brunfc0421f2012-09-07 17:30:07 +02003161#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
3162#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
3163#endif
3164
3165#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
3166#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01003167#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02003168#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003169#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
3170#define SSL_OP_SINGLE_ECDH_USE 0
3171#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02003172#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
3173#define SSL_OP_NO_TICKET 0
3174#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003175#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
3176#define SSL_OP_NO_COMPRESSION 0
3177#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02003178#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
3179#define SSL_OP_NO_TLSv1_1 0
3180#endif
3181#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
3182#define SSL_OP_NO_TLSv1_2 0
3183#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003184#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
3185#define SSL_OP_SINGLE_DH_USE 0
3186#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003187#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
3188#define SSL_OP_SINGLE_ECDH_USE 0
3189#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003190#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
3191#define SSL_MODE_RELEASE_BUFFERS 0
3192#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01003193#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
3194#define SSL_MODE_SMALL_BUFFERS 0
3195#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003196
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003197#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3198static void ssl_set_SSLv3_func(SSL_CTX *ctx, int is_server)
3199{
3200#if SSL_OP_NO_SSLv3
3201 is_server ? SSL_CTX_set_ssl_version(ctx, SSLv3_server_method())
3202 : SSL_CTX_set_ssl_version(ctx, SSLv3_client_method());
3203#endif
3204}
3205static void ssl_set_TLSv10_func(SSL_CTX *ctx, int is_server) {
3206 is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_server_method())
3207 : SSL_CTX_set_ssl_version(ctx, TLSv1_client_method());
3208}
3209static void ssl_set_TLSv11_func(SSL_CTX *ctx, int is_server) {
3210#if SSL_OP_NO_TLSv1_1
3211 is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method())
3212 : SSL_CTX_set_ssl_version(ctx, TLSv1_1_client_method());
3213#endif
3214}
3215static void ssl_set_TLSv12_func(SSL_CTX *ctx, int is_server) {
3216#if SSL_OP_NO_TLSv1_2
3217 is_server ? SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method())
3218 : SSL_CTX_set_ssl_version(ctx, TLSv1_2_client_method());
3219#endif
3220}
3221#else /* openssl >= 1.1.0 */
3222static void ssl_set_SSLv3_func(SSL_CTX *ctx, int is_max) {
3223 is_max ? SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION)
3224 : SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
3225}
3226static void ssl_set_TLSv10_func(SSL_CTX *ctx, int is_max) {
3227 is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION)
3228 : SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
3229}
3230static void ssl_set_TLSv11_func(SSL_CTX *ctx, int is_max) {
3231 is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION)
3232 : SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
3233}
3234static void ssl_set_TLSv12_func(SSL_CTX *ctx, int is_max) {
3235 is_max ? SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)
3236 : SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
3237}
3238#endif
3239static void ssl_set_None_func(SSL_CTX *ctx, int i) {
3240}
3241
3242static struct {
3243 int option;
3244 uint16_t flag;
3245 void (*set_version)(SSL_CTX *, int);
3246 const char *name;
3247} methodVersions[] = {
3248 {0, 0, ssl_set_None_func, "NONE"}, /* CONF_TLSV_NONE */
3249 {SSL_OP_NO_SSLv3, MC_SSL_O_NO_SSLV3, ssl_set_SSLv3_func, "SSLv3"}, /* CONF_SSLV3 */
3250 {SSL_OP_NO_TLSv1, MC_SSL_O_NO_TLSV10, ssl_set_TLSv10_func, "TLSv1.0"}, /* CONF_TLSV10 */
3251 {SSL_OP_NO_TLSv1_1, MC_SSL_O_NO_TLSV11, ssl_set_TLSv11_func, "TLSv1.1"}, /* CONF_TLSV11 */
3252 {SSL_OP_NO_TLSv1_2, MC_SSL_O_NO_TLSV12, ssl_set_TLSv12_func, "TLSv1.2"}, /* CONF_TLSV12 */
3253};
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003254
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003255/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003256static SSL_CTX *
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003257ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003258{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003259 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003260 long options =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003261 SSL_OP_ALL | /* all known workarounds for bugs */
3262 SSL_OP_NO_SSLv2 |
3263 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003264 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003265 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003266 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3267 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003268 long mode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003269 SSL_MODE_ENABLE_PARTIAL_WRITE |
3270 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003271 SSL_MODE_RELEASE_BUFFERS |
3272 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003273 struct tls_version_filter *conf_ssl_methods = &bind_conf->ssl_methods;
3274 int i, min, max;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003275
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003276 ctx = SSL_CTX_new(SSLv23_server_method());
3277
3278 /* set options per default */
3279 /* XXX need check hole */
3280 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3281 if (conf_ssl_methods->flags & methodVersions[i].flag)
3282 options |= methodVersions[i].option;
3283
3284 /* XXX min and max can be CONF_TLSV_NONE or unavailable in openssl.
3285 Real min and max should be determinate with conf + openssl's capabilities
3286 */
3287 min = conf_ssl_methods->min;
3288 max = conf_ssl_methods->max;
3289#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3290 /* Keep force-xxx implementation as it is in older haproxy. It's a
3291 precautionary measure to avoid any suprise with older openssl version. */
3292 if (min == max)
3293 methodVersions[min].set_version(ctx, 1 /* server */);
3294#else /* openssl >= 1.1.0 */
3295 methodVersions[min].set_version(ctx, 0);
3296 methodVersions[max].set_version(ctx, 1);
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003297#endif
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003298
3299 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3300 options |= SSL_OP_NO_TICKET;
3301 if (bind_conf->ssl_options & BC_SSL_O_PREF_CLIE_CIPH)
3302 options &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
3303 SSL_CTX_set_options(ctx, options);
3304 SSL_CTX_set_mode(ctx, mode);
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003305 if (global_ssl.life_time)
3306 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003307
3308#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3309#ifdef OPENSSL_IS_BORINGSSL
3310 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3311 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3312#else
3313 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3314 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3315#endif
3316#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003317 return ctx;
3318}
3319
3320int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3321{
3322 struct proxy *curproxy = bind_conf->frontend;
3323 int cfgerr = 0;
3324 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003325 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003326 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003327 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003328
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003329 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003330 case SSL_SOCK_VERIFY_NONE:
3331 verify = SSL_VERIFY_NONE;
3332 break;
3333 case SSL_SOCK_VERIFY_OPTIONAL:
3334 verify = SSL_VERIFY_PEER;
3335 break;
3336 case SSL_SOCK_VERIFY_REQUIRED:
3337 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3338 break;
3339 }
3340 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3341 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003342 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3343 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3344 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003345 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003346 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003347 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003348 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003349 cfgerr++;
3350 }
3351 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003352 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003353 }
Emeric Brun850efd52014-01-29 12:24:34 +01003354 else {
3355 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3356 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3357 cfgerr++;
3358 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003359#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003360 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003361 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3362
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003363 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003364 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003365 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003366 cfgerr++;
3367 }
Emeric Brun561e5742012-10-02 15:20:55 +02003368 else {
3369 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3370 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003371 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003372#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003373 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003374 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003375#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003376 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003377 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3378 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3379 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3380 cfgerr++;
3381 }
3382 }
3383#endif
3384
Emeric Brunfc0421f2012-09-07 17:30:07 +02003385 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003386 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3387 if (conf_ciphers &&
3388 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003389 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 +01003390 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003391 cfgerr++;
3392 }
3393
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003394#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003395 /* If tune.ssl.default-dh-param has not been set,
3396 neither has ssl-default-dh-file and no static DH
3397 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003398 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003399 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003400 (ssl_dh_ptr_index == -1 ||
3401 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003402 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3403 const SSL_CIPHER * cipher = NULL;
3404 char cipher_description[128];
3405 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3406 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3407 which is not ephemeral DH. */
3408 const char dhe_description[] = " Kx=DH ";
3409 const char dhe_export_description[] = " Kx=DH(";
3410 int idx = 0;
3411 int dhe_found = 0;
3412 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003413
Remi Gacogne23d5d372014-10-10 17:04:26 +02003414 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003415
Remi Gacogne23d5d372014-10-10 17:04:26 +02003416 if (ssl) {
3417 ciphers = SSL_get_ciphers(ssl);
3418
3419 if (ciphers) {
3420 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3421 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3422 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3423 if (strstr(cipher_description, dhe_description) != NULL ||
3424 strstr(cipher_description, dhe_export_description) != NULL) {
3425 dhe_found = 1;
3426 break;
3427 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003428 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003429 }
3430 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003431 SSL_free(ssl);
3432 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003433 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003434
Lukas Tribus90132722014-08-18 00:56:33 +02003435 if (dhe_found) {
3436 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 +02003437 }
3438
Willy Tarreauef934602016-12-22 23:12:01 +01003439 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003440 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003441
Willy Tarreauef934602016-12-22 23:12:01 +01003442 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003443 if (local_dh_1024 == NULL) {
3444 local_dh_1024 = ssl_get_dh_1024();
3445 }
Willy Tarreauef934602016-12-22 23:12:01 +01003446 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003447 if (local_dh_2048 == NULL) {
3448 local_dh_2048 = ssl_get_dh_2048();
3449 }
Willy Tarreauef934602016-12-22 23:12:01 +01003450 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003451 if (local_dh_4096 == NULL) {
3452 local_dh_4096 = ssl_get_dh_4096();
3453 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003454 }
3455 }
3456 }
3457#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003458
Emeric Brunfc0421f2012-09-07 17:30:07 +02003459 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003460#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003461 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003462#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003463
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003464#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003465 ssl_conf_cur = NULL;
3466 if (ssl_conf && ssl_conf->npn_str)
3467 ssl_conf_cur = ssl_conf;
3468 else if (bind_conf->ssl_conf.npn_str)
3469 ssl_conf_cur = &bind_conf->ssl_conf;
3470 if (ssl_conf_cur)
3471 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003472#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003473#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003474 ssl_conf_cur = NULL;
3475 if (ssl_conf && ssl_conf->alpn_str)
3476 ssl_conf_cur = ssl_conf;
3477 else if (bind_conf->ssl_conf.alpn_str)
3478 ssl_conf_cur = &bind_conf->ssl_conf;
3479 if (ssl_conf_cur)
3480 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003481#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003482#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3483 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3484 if (conf_curves) {
3485 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3486 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3487 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3488 cfgerr++;
3489 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003490#if defined(SSL_CTX_set_ecdh_auto)
3491 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3492#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003493 }
3494#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003495#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003496 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003497 int i;
3498 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003499 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3500 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003501
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003502 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003503 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3504 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 +01003505 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003506 cfgerr++;
3507 }
3508 else {
3509 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3510 EC_KEY_free(ecdh);
3511 }
3512 }
3513#endif
3514
Emeric Brunfc0421f2012-09-07 17:30:07 +02003515 return cfgerr;
3516}
3517
Evan Broderbe554312013-06-27 00:05:25 -07003518static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3519{
3520 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3521 size_t prefixlen, suffixlen;
3522
3523 /* Trivial case */
3524 if (strcmp(pattern, hostname) == 0)
3525 return 1;
3526
Evan Broderbe554312013-06-27 00:05:25 -07003527 /* The rest of this logic is based on RFC 6125, section 6.4.3
3528 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3529
Emeric Bruna848dae2013-10-08 11:27:28 +02003530 pattern_wildcard = NULL;
3531 pattern_left_label_end = pattern;
3532 while (*pattern_left_label_end != '.') {
3533 switch (*pattern_left_label_end) {
3534 case 0:
3535 /* End of label not found */
3536 return 0;
3537 case '*':
3538 /* If there is more than one wildcards */
3539 if (pattern_wildcard)
3540 return 0;
3541 pattern_wildcard = pattern_left_label_end;
3542 break;
3543 }
3544 pattern_left_label_end++;
3545 }
3546
3547 /* If it's not trivial and there is no wildcard, it can't
3548 * match */
3549 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003550 return 0;
3551
3552 /* Make sure all labels match except the leftmost */
3553 hostname_left_label_end = strchr(hostname, '.');
3554 if (!hostname_left_label_end
3555 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3556 return 0;
3557
3558 /* Make sure the leftmost label of the hostname is long enough
3559 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003560 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003561 return 0;
3562
3563 /* Finally compare the string on either side of the
3564 * wildcard */
3565 prefixlen = pattern_wildcard - pattern;
3566 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003567 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3568 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003569 return 0;
3570
3571 return 1;
3572}
3573
3574static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3575{
3576 SSL *ssl;
3577 struct connection *conn;
3578 char *servername;
3579
3580 int depth;
3581 X509 *cert;
3582 STACK_OF(GENERAL_NAME) *alt_names;
3583 int i;
3584 X509_NAME *cert_subject;
3585 char *str;
3586
3587 if (ok == 0)
3588 return ok;
3589
3590 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003591 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003592
3593 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3594
3595 /* We only need to verify the CN on the actual server cert,
3596 * not the indirect CAs */
3597 depth = X509_STORE_CTX_get_error_depth(ctx);
3598 if (depth != 0)
3599 return ok;
3600
3601 /* At this point, the cert is *not* OK unless we can find a
3602 * hostname match */
3603 ok = 0;
3604
3605 cert = X509_STORE_CTX_get_current_cert(ctx);
3606 /* It seems like this might happen if verify peer isn't set */
3607 if (!cert)
3608 return ok;
3609
3610 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3611 if (alt_names) {
3612 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3613 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3614 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003615#if OPENSSL_VERSION_NUMBER < 0x00907000L
3616 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3617#else
Evan Broderbe554312013-06-27 00:05:25 -07003618 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003619#endif
Evan Broderbe554312013-06-27 00:05:25 -07003620 ok = ssl_sock_srv_hostcheck(str, servername);
3621 OPENSSL_free(str);
3622 }
3623 }
3624 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003625 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003626 }
3627
3628 cert_subject = X509_get_subject_name(cert);
3629 i = -1;
3630 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3631 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003632 ASN1_STRING *value;
3633 value = X509_NAME_ENTRY_get_data(entry);
3634 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003635 ok = ssl_sock_srv_hostcheck(str, servername);
3636 OPENSSL_free(str);
3637 }
3638 }
3639
3640 return ok;
3641}
3642
Emeric Brun94324a42012-10-11 14:00:19 +02003643/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003644int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003645{
Willy Tarreau03209342016-12-22 17:08:28 +01003646 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003647 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003648 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003649 SSL_OP_ALL | /* all known workarounds for bugs */
3650 SSL_OP_NO_SSLv2 |
3651 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003652 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003653 SSL_MODE_ENABLE_PARTIAL_WRITE |
3654 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003655 SSL_MODE_RELEASE_BUFFERS |
3656 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003657 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003658 SSL_CTX *ctx = NULL;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003659 struct tls_version_filter *conf_ssl_methods = &srv->ssl_ctx.methods;
3660 int i, min, max;
Emeric Brun94324a42012-10-11 14:00:19 +02003661
Thierry Fournier383085f2013-01-24 14:15:43 +01003662 /* Make sure openssl opens /dev/urandom before the chroot */
3663 if (!ssl_initialize_random()) {
3664 Alert("OpenSSL random data generator initialization failed.\n");
3665 cfgerr++;
3666 }
3667
Willy Tarreaufce03112015-01-15 21:32:40 +01003668 /* Automatic memory computations need to know we use SSL there */
3669 global.ssl_used_backend = 1;
3670
3671 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003672 srv->ssl_ctx.reused_sess = NULL;
3673 if (srv->use_ssl)
3674 srv->xprt = &ssl_sock;
3675 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003676 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003677
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003678 ctx = SSL_CTX_new(SSLv23_client_method());
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003679 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02003680 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3681 proxy_type_str(curproxy), curproxy->id,
3682 srv->id);
3683 cfgerr++;
3684 return cfgerr;
3685 }
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02003686
3687 /* set options per default */
3688 /* XXX need check hole */
3689 for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
3690 if (conf_ssl_methods->flags & methodVersions[i].flag)
3691 options |= methodVersions[i].option;
3692
3693 /* XXX min and max can be CONF_TLSV_NONE or unavailable in openssl.
3694 Real min and max should be determinate with conf + openssl's capabilities
3695 */
3696 min = conf_ssl_methods->min;
3697 max = conf_ssl_methods->max;
3698#if (OPENSSL_VERSION_NUMBER < 0x1010000fL) && !defined(OPENSSL_IS_BORINGSSL)
3699 /* Keep force-xxx implementation as it is in older haproxy. It's a
3700 precautionary measure to avoid any suprise with older openssl version. */
3701 if (min == max)
3702 methodVersions[min].set_version(ctx, 0 /* client */);
3703#else /* openssl >= 1.1.0 */
3704 methodVersions[min].set_version(ctx, 0);
3705 methodVersions[max].set_version(ctx, 1);
3706#endif
3707
3708 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3709 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003710 SSL_CTX_set_options(ctx, options);
3711 SSL_CTX_set_mode(ctx, mode);
3712 srv->ssl_ctx.ctx = ctx;
3713
Emeric Bruna7aa3092012-10-26 12:58:00 +02003714 if (srv->ssl_ctx.client_crt) {
3715 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3716 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3717 proxy_type_str(curproxy), curproxy->id,
3718 srv->id, srv->ssl_ctx.client_crt);
3719 cfgerr++;
3720 }
3721 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3722 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3723 proxy_type_str(curproxy), curproxy->id,
3724 srv->id, srv->ssl_ctx.client_crt);
3725 cfgerr++;
3726 }
3727 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3728 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3729 proxy_type_str(curproxy), curproxy->id,
3730 srv->id, srv->ssl_ctx.client_crt);
3731 cfgerr++;
3732 }
3733 }
Emeric Brun94324a42012-10-11 14:00:19 +02003734
Emeric Brun850efd52014-01-29 12:24:34 +01003735 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3736 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01003737 switch (srv->ssl_ctx.verify) {
3738 case SSL_SOCK_VERIFY_NONE:
3739 verify = SSL_VERIFY_NONE;
3740 break;
3741 case SSL_SOCK_VERIFY_REQUIRED:
3742 verify = SSL_VERIFY_PEER;
3743 break;
3744 }
Evan Broderbe554312013-06-27 00:05:25 -07003745 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003746 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003747 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003748 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003749 if (srv->ssl_ctx.ca_file) {
3750 /* load CAfile to verify */
3751 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003752 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003753 curproxy->id, srv->id,
3754 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3755 cfgerr++;
3756 }
3757 }
Emeric Brun850efd52014-01-29 12:24:34 +01003758 else {
3759 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003760 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 +01003761 curproxy->id, srv->id,
3762 srv->conf.file, srv->conf.line);
3763 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003764 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003765 curproxy->id, srv->id,
3766 srv->conf.file, srv->conf.line);
3767 cfgerr++;
3768 }
Emeric Brunef42d922012-10-11 16:11:36 +02003769#ifdef X509_V_FLAG_CRL_CHECK
3770 if (srv->ssl_ctx.crl_file) {
3771 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3772
3773 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003774 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003775 curproxy->id, srv->id,
3776 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3777 cfgerr++;
3778 }
3779 else {
3780 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3781 }
3782 }
3783#endif
3784 }
3785
Emeric Brun94324a42012-10-11 14:00:19 +02003786 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3787 if (srv->ssl_ctx.ciphers &&
3788 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3789 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3790 curproxy->id, srv->id,
3791 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3792 cfgerr++;
3793 }
3794
3795 return cfgerr;
3796}
3797
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003798/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003799 * be NULL, in which case nothing is done. Returns the number of errors
3800 * encountered.
3801 */
Willy Tarreau03209342016-12-22 17:08:28 +01003802int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003803{
3804 struct ebmb_node *node;
3805 struct sni_ctx *sni;
3806 int err = 0;
3807
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003808 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003809 return 0;
3810
Willy Tarreaufce03112015-01-15 21:32:40 +01003811 /* Automatic memory computations need to know we use SSL there */
3812 global.ssl_used_frontend = 1;
3813
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003814 /* Make sure openssl opens /dev/urandom before the chroot */
3815 if (!ssl_initialize_random()) {
3816 Alert("OpenSSL random data generator initialization failed.\n");
3817 err++;
3818 }
3819 /* Create initial_ctx used to start the ssl connection before do switchctx */
3820 if (!bind_conf->initial_ctx) {
3821 bind_conf->initial_ctx = ssl_sock_initial_ctx(bind_conf);
3822 /* It should not be necessary to call this function, but it's
3823 necessary first to check and move all initialisation related
3824 to initial_ctx in ssl_sock_initial_ctx. */
3825 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
3826 }
Emeric Brun0bed9942014-10-30 19:25:24 +01003827 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003828 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003829
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003830 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003831 while (node) {
3832 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003833 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3834 /* only initialize the CTX on its first occurrence and
3835 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003836 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003837 node = ebmb_next(node);
3838 }
3839
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003840 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003841 while (node) {
3842 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003843 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3844 /* only initialize the CTX on its first occurrence and
3845 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003846 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003847 node = ebmb_next(node);
3848 }
3849 return err;
3850}
3851
Willy Tarreau55d37912016-12-21 23:38:39 +01003852/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3853 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3854 * alerts are directly emitted since the rest of the stack does it below.
3855 */
3856int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3857{
3858 struct proxy *px = bind_conf->frontend;
3859 int alloc_ctx;
3860 int err;
3861
3862 if (!bind_conf->is_ssl) {
3863 if (bind_conf->default_ctx) {
3864 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3865 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3866 }
3867 return 0;
3868 }
3869 if (!bind_conf->default_ctx) {
3870 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3871 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3872 return -1;
3873 }
3874
Willy Tarreauef934602016-12-22 23:12:01 +01003875 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003876 if (alloc_ctx < 0) {
3877 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3878 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");
3879 else
3880 Alert("Unable to allocate SSL session cache.\n");
3881 return -1;
3882 }
3883
3884 err = 0;
3885 /* initialize all certificate contexts */
3886 err += ssl_sock_prepare_all_ctx(bind_conf);
3887
3888 /* initialize CA variables if the certificates generation is enabled */
3889 err += ssl_sock_load_ca(bind_conf);
3890
3891 return -err;
3892}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003893
3894/* release ssl context allocated for servers. */
3895void ssl_sock_free_srv_ctx(struct server *srv)
3896{
3897 if (srv->ssl_ctx.ctx)
3898 SSL_CTX_free(srv->ssl_ctx.ctx);
3899}
3900
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003901/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003902 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3903 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003904void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003905{
3906 struct ebmb_node *node, *back;
3907 struct sni_ctx *sni;
3908
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003909 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003910 return;
3911
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003912 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003913 while (node) {
3914 sni = ebmb_entry(node, struct sni_ctx, name);
3915 back = ebmb_next(node);
3916 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003917 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003918 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003919 ssl_sock_free_ssl_conf(sni->conf);
3920 free(sni->conf);
3921 sni->conf = NULL;
3922 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003923 free(sni);
3924 node = back;
3925 }
3926
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003927 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003928 while (node) {
3929 sni = ebmb_entry(node, struct sni_ctx, name);
3930 back = ebmb_next(node);
3931 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003932 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003933 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003934 ssl_sock_free_ssl_conf(sni->conf);
3935 free(sni->conf);
3936 sni->conf = NULL;
3937 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003938 free(sni);
3939 node = back;
3940 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003941 SSL_CTX_free(bind_conf->initial_ctx);
3942 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003943 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003944 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003945}
3946
Willy Tarreau795cdab2016-12-22 17:30:54 +01003947/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3948void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3949{
3950 ssl_sock_free_ca(bind_conf);
3951 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003952 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003953 free(bind_conf->ca_sign_file);
3954 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003955 if (bind_conf->keys_ref) {
3956 free(bind_conf->keys_ref->filename);
3957 free(bind_conf->keys_ref->tlskeys);
3958 LIST_DEL(&bind_conf->keys_ref->list);
3959 free(bind_conf->keys_ref);
3960 }
3961 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003962 bind_conf->ca_sign_pass = NULL;
3963 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003964}
3965
Christopher Faulet31af49d2015-06-09 17:29:50 +02003966/* Load CA cert file and private key used to generate certificates */
3967int
Willy Tarreau03209342016-12-22 17:08:28 +01003968ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003969{
Willy Tarreau03209342016-12-22 17:08:28 +01003970 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003971 FILE *fp;
3972 X509 *cacert = NULL;
3973 EVP_PKEY *capkey = NULL;
3974 int err = 0;
3975
3976 if (!bind_conf || !bind_conf->generate_certs)
3977 return err;
3978
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003979#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01003980 if (global_ssl.ctx_cache)
3981 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003982 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003983#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003984
Christopher Faulet31af49d2015-06-09 17:29:50 +02003985 if (!bind_conf->ca_sign_file) {
3986 Alert("Proxy '%s': cannot enable certificate generation, "
3987 "no CA certificate File configured at [%s:%d].\n",
3988 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003989 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003990 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003991
3992 /* read in the CA certificate */
3993 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3994 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3995 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003996 goto load_error;
3997 }
3998 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3999 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
4000 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004001 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004002 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004003 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004004 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
4005 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
4006 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004007 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004008 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02004009
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004010 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004011 bind_conf->ca_sign_cert = cacert;
4012 bind_conf->ca_sign_pkey = capkey;
4013 return err;
4014
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004015 read_error:
4016 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02004017 if (capkey) EVP_PKEY_free(capkey);
4018 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02004019 load_error:
4020 bind_conf->generate_certs = 0;
4021 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004022 return err;
4023}
4024
4025/* Release CA cert and private key used to generate certificated */
4026void
4027ssl_sock_free_ca(struct bind_conf *bind_conf)
4028{
4029 if (!bind_conf)
4030 return;
4031
4032 if (bind_conf->ca_sign_pkey)
4033 EVP_PKEY_free(bind_conf->ca_sign_pkey);
4034 if (bind_conf->ca_sign_cert)
4035 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01004036 bind_conf->ca_sign_pkey = NULL;
4037 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02004038}
4039
Emeric Brun46591952012-05-18 15:47:34 +02004040/*
4041 * This function is called if SSL * context is not yet allocated. The function
4042 * is designed to be called before any other data-layer operation and sets the
4043 * handshake flag on the connection. It is safe to call it multiple times.
4044 * It returns 0 on success and -1 in error case.
4045 */
4046static int ssl_sock_init(struct connection *conn)
4047{
4048 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004049 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004050 return 0;
4051
Willy Tarreau3c728722014-01-23 13:50:42 +01004052 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004053 return 0;
4054
Willy Tarreau20879a02012-12-03 16:32:10 +01004055 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4056 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004057 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004058 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004059
Emeric Brun46591952012-05-18 15:47:34 +02004060 /* If it is in client mode initiate SSL session
4061 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004062 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004063 int may_retry = 1;
4064
4065 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004066 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004067 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004068 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004069 if (may_retry--) {
4070 pool_gc2();
4071 goto retry_connect;
4072 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004073 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004074 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004075 }
Emeric Brun46591952012-05-18 15:47:34 +02004076
Emeric Brun46591952012-05-18 15:47:34 +02004077 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004078 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4079 SSL_free(conn->xprt_ctx);
4080 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004081 if (may_retry--) {
4082 pool_gc2();
4083 goto retry_connect;
4084 }
Emeric Brun55476152014-11-12 17:35:37 +01004085 conn->err_code = CO_ER_SSL_NO_MEM;
4086 return -1;
4087 }
Emeric Brun46591952012-05-18 15:47:34 +02004088
Evan Broderbe554312013-06-27 00:05:25 -07004089 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004090 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4091 SSL_free(conn->xprt_ctx);
4092 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004093 if (may_retry--) {
4094 pool_gc2();
4095 goto retry_connect;
4096 }
Emeric Brun55476152014-11-12 17:35:37 +01004097 conn->err_code = CO_ER_SSL_NO_MEM;
4098 return -1;
4099 }
4100
4101 SSL_set_connect_state(conn->xprt_ctx);
4102 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4103 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4104 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4105 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4106 }
4107 }
Evan Broderbe554312013-06-27 00:05:25 -07004108
Emeric Brun46591952012-05-18 15:47:34 +02004109 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004110 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004111
4112 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004113 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004114 return 0;
4115 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004116 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004117 int may_retry = 1;
4118
4119 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004120 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004121 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004122 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004123 if (may_retry--) {
4124 pool_gc2();
4125 goto retry_accept;
4126 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004127 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004128 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004129 }
Emeric Brun46591952012-05-18 15:47:34 +02004130
Emeric Brun46591952012-05-18 15:47:34 +02004131 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004132 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4133 SSL_free(conn->xprt_ctx);
4134 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004135 if (may_retry--) {
4136 pool_gc2();
4137 goto retry_accept;
4138 }
Emeric Brun55476152014-11-12 17:35:37 +01004139 conn->err_code = CO_ER_SSL_NO_MEM;
4140 return -1;
4141 }
Emeric Brun46591952012-05-18 15:47:34 +02004142
Emeric Brune1f38db2012-09-03 20:36:47 +02004143 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004144 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4145 SSL_free(conn->xprt_ctx);
4146 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004147 if (may_retry--) {
4148 pool_gc2();
4149 goto retry_accept;
4150 }
Emeric Brun55476152014-11-12 17:35:37 +01004151 conn->err_code = CO_ER_SSL_NO_MEM;
4152 return -1;
4153 }
4154
4155 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004156
Emeric Brun46591952012-05-18 15:47:34 +02004157 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004158 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004159
4160 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004161 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004162 return 0;
4163 }
4164 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004165 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004166 return -1;
4167}
4168
4169
4170/* This is the callback which is used when an SSL handshake is pending. It
4171 * updates the FD status if it wants some polling before being called again.
4172 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4173 * otherwise it returns non-zero and removes itself from the connection's
4174 * flags (the bit is provided in <flag> by the caller).
4175 */
4176int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4177{
4178 int ret;
4179
Willy Tarreau3c728722014-01-23 13:50:42 +01004180 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004181 return 0;
4182
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004183 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004184 goto out_error;
4185
Emeric Brun674b7432012-11-08 19:21:55 +01004186 /* If we use SSL_do_handshake to process a reneg initiated by
4187 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4188 * Usually SSL_write and SSL_read are used and process implicitly
4189 * the reneg handshake.
4190 * Here we use SSL_peek as a workaround for reneg.
4191 */
4192 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4193 char c;
4194
4195 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4196 if (ret <= 0) {
4197 /* handshake may have not been completed, let's find why */
4198 ret = SSL_get_error(conn->xprt_ctx, ret);
4199 if (ret == SSL_ERROR_WANT_WRITE) {
4200 /* SSL handshake needs to write, L4 connection may not be ready */
4201 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004202 __conn_sock_want_send(conn);
4203 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004204 return 0;
4205 }
4206 else if (ret == SSL_ERROR_WANT_READ) {
4207 /* handshake may have been completed but we have
4208 * no more data to read.
4209 */
4210 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4211 ret = 1;
4212 goto reneg_ok;
4213 }
4214 /* SSL handshake needs to read, L4 connection is ready */
4215 if (conn->flags & CO_FL_WAIT_L4_CONN)
4216 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4217 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004218 __conn_sock_want_recv(conn);
4219 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004220 return 0;
4221 }
4222 else if (ret == SSL_ERROR_SYSCALL) {
4223 /* if errno is null, then connection was successfully established */
4224 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4225 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004226 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004227#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4228 conn->err_code = CO_ER_SSL_HANDSHAKE;
4229#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004230 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004231#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004232 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4233 empty_handshake = state == TLS_ST_BEFORE;
4234#else
4235 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4236#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004237 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004238 if (!errno) {
4239 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4240 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4241 else
4242 conn->err_code = CO_ER_SSL_EMPTY;
4243 }
4244 else {
4245 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4246 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4247 else
4248 conn->err_code = CO_ER_SSL_ABORT;
4249 }
4250 }
4251 else {
4252 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4253 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004254 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004255 conn->err_code = CO_ER_SSL_HANDSHAKE;
4256 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004257#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004258 }
Emeric Brun674b7432012-11-08 19:21:55 +01004259 goto out_error;
4260 }
4261 else {
4262 /* Fail on all other handshake errors */
4263 /* Note: OpenSSL may leave unread bytes in the socket's
4264 * buffer, causing an RST to be emitted upon close() on
4265 * TCP sockets. We first try to drain possibly pending
4266 * data to avoid this as much as possible.
4267 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004268 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004269 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004270 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4271 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004272 goto out_error;
4273 }
4274 }
4275 /* read some data: consider handshake completed */
4276 goto reneg_ok;
4277 }
4278
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004279 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004280 if (ret != 1) {
4281 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004282 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004283
4284 if (ret == SSL_ERROR_WANT_WRITE) {
4285 /* SSL handshake needs to write, L4 connection may not be ready */
4286 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004287 __conn_sock_want_send(conn);
4288 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004289 return 0;
4290 }
4291 else if (ret == SSL_ERROR_WANT_READ) {
4292 /* SSL handshake needs to read, L4 connection is ready */
4293 if (conn->flags & CO_FL_WAIT_L4_CONN)
4294 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4295 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004296 __conn_sock_want_recv(conn);
4297 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004298 return 0;
4299 }
Willy Tarreau89230192012-09-28 20:22:13 +02004300 else if (ret == SSL_ERROR_SYSCALL) {
4301 /* if errno is null, then connection was successfully established */
4302 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4303 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004304 if (!conn->err_code) {
4305#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4306 conn->err_code = CO_ER_SSL_HANDSHAKE;
4307#else
4308 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004309#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004310 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4311 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004312#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004313 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004314#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004315 if (empty_handshake) {
4316 if (!errno) {
4317 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4318 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4319 else
4320 conn->err_code = CO_ER_SSL_EMPTY;
4321 }
4322 else {
4323 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4324 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4325 else
4326 conn->err_code = CO_ER_SSL_ABORT;
4327 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004328 }
4329 else {
4330 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4331 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4332 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004333 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004334 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004335#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004336 }
Willy Tarreau89230192012-09-28 20:22:13 +02004337 goto out_error;
4338 }
Emeric Brun46591952012-05-18 15:47:34 +02004339 else {
4340 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004341 /* Note: OpenSSL may leave unread bytes in the socket's
4342 * buffer, causing an RST to be emitted upon close() on
4343 * TCP sockets. We first try to drain possibly pending
4344 * data to avoid this as much as possible.
4345 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004346 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004347 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004348 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4349 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004350 goto out_error;
4351 }
4352 }
4353
Emeric Brun674b7432012-11-08 19:21:55 +01004354reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004355 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004356 if (!SSL_session_reused(conn->xprt_ctx)) {
4357 if (objt_server(conn->target)) {
4358 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4359 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4360 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4361
Emeric Brun46591952012-05-18 15:47:34 +02004362 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004363 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004364 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004365 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4366 }
Emeric Brun46591952012-05-18 15:47:34 +02004367
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004368 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4369 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004370 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004371 else {
4372 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4373 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4374 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4375 }
Emeric Brun46591952012-05-18 15:47:34 +02004376 }
4377
4378 /* The connection is now established at both layers, it's time to leave */
4379 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4380 return 1;
4381
4382 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004383 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004384 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004385 ERR_clear_error();
4386
Emeric Brun9fa89732012-10-04 17:09:56 +02004387 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004388 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4389 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4390 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004391 }
4392
Emeric Brun46591952012-05-18 15:47:34 +02004393 /* Fail on all other handshake errors */
4394 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004395 if (!conn->err_code)
4396 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004397 return 0;
4398}
4399
4400/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004401 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004402 * buffer wraps, in which case a second call may be performed. The connection's
4403 * flags are updated with whatever special event is detected (error, read0,
4404 * empty). The caller is responsible for taking care of those events and
4405 * avoiding the call if inappropriate. The function does not call the
4406 * connection's polling update function, so the caller is responsible for this.
4407 */
4408static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4409{
4410 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004411 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004412
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004413 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004414 goto out_error;
4415
4416 if (conn->flags & CO_FL_HANDSHAKE)
4417 /* a handshake was requested */
4418 return 0;
4419
Willy Tarreauabf08d92014-01-14 11:31:27 +01004420 /* let's realign the buffer to optimize I/O */
4421 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004422 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004423
4424 /* read the largest possible block. For this, we perform only one call
4425 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4426 * in which case we accept to do it once again. A new attempt is made on
4427 * EINTR too.
4428 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004429 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004430 /* first check if we have some room after p+i */
4431 try = buf->data + buf->size - (buf->p + buf->i);
4432 /* otherwise continue between data and p-o */
4433 if (try <= 0) {
4434 try = buf->p - (buf->data + buf->o);
4435 if (try <= 0)
4436 break;
4437 }
4438 if (try > count)
4439 try = count;
4440
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004441 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004442 if (conn->flags & CO_FL_ERROR) {
4443 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004444 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004445 }
Emeric Brun46591952012-05-18 15:47:34 +02004446 if (ret > 0) {
4447 buf->i += ret;
4448 done += ret;
4449 if (ret < try)
4450 break;
4451 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004452 }
4453 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004454 ret = SSL_get_error(conn->xprt_ctx, ret);
4455 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004456 /* error on protocol or underlying transport */
4457 if ((ret != SSL_ERROR_SYSCALL)
4458 || (errno && (errno != EAGAIN)))
4459 conn->flags |= CO_FL_ERROR;
4460
Emeric Brun644cde02012-12-14 11:21:13 +01004461 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004462 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004463 ERR_clear_error();
4464 }
Emeric Brun46591952012-05-18 15:47:34 +02004465 goto read0;
4466 }
4467 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004468 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004469 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004470 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004471 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004472 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004473 break;
4474 }
4475 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004476 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4477 /* handshake is running, and it may need to re-enable read */
4478 conn->flags |= CO_FL_SSL_WAIT_HS;
4479 __conn_sock_want_recv(conn);
4480 break;
4481 }
Emeric Brun46591952012-05-18 15:47:34 +02004482 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004483 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004484 break;
4485 }
4486 /* otherwise it's a real error */
4487 goto out_error;
4488 }
4489 }
4490 return done;
4491
4492 read0:
4493 conn_sock_read0(conn);
4494 return done;
4495 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004496 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004497 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004498 ERR_clear_error();
4499
Emeric Brun46591952012-05-18 15:47:34 +02004500 conn->flags |= CO_FL_ERROR;
4501 return done;
4502}
4503
4504
4505/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004506 * <flags> may contain some CO_SFL_* flags to hint the system about other
4507 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004508 * Only one call to send() is performed, unless the buffer wraps, in which case
4509 * a second call may be performed. The connection's flags are updated with
4510 * whatever special event is detected (error, empty). The caller is responsible
4511 * for taking care of those events and avoiding the call if inappropriate. The
4512 * function does not call the connection's polling update function, so the caller
4513 * is responsible for this.
4514 */
4515static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4516{
4517 int ret, try, done;
4518
4519 done = 0;
4520
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004521 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004522 goto out_error;
4523
4524 if (conn->flags & CO_FL_HANDSHAKE)
4525 /* a handshake was requested */
4526 return 0;
4527
4528 /* send the largest possible block. For this we perform only one call
4529 * to send() unless the buffer wraps and we exactly fill the first hunk,
4530 * in which case we accept to do it once again.
4531 */
4532 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004533 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004534
Willy Tarreau7bed9452014-02-02 02:00:24 +01004535 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004536 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004537 global_ssl.max_record && try > global_ssl.max_record) {
4538 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004539 }
4540 else {
4541 /* we need to keep the information about the fact that
4542 * we're not limiting the upcoming send(), because if it
4543 * fails, we'll have to retry with at least as many data.
4544 */
4545 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4546 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004547
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004548 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004549
Emeric Brune1f38db2012-09-03 20:36:47 +02004550 if (conn->flags & CO_FL_ERROR) {
4551 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004552 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004553 }
Emeric Brun46591952012-05-18 15:47:34 +02004554 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004555 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4556
Emeric Brun46591952012-05-18 15:47:34 +02004557 buf->o -= ret;
4558 done += ret;
4559
Willy Tarreau5fb38032012-12-16 19:39:09 +01004560 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004561 /* optimize data alignment in the buffer */
4562 buf->p = buf->data;
4563
4564 /* if the system buffer is full, don't insist */
4565 if (ret < try)
4566 break;
4567 }
4568 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004569 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004570 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004571 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4572 /* handshake is running, and it may need to re-enable write */
4573 conn->flags |= CO_FL_SSL_WAIT_HS;
4574 __conn_sock_want_send(conn);
4575 break;
4576 }
Emeric Brun46591952012-05-18 15:47:34 +02004577 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004578 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004579 break;
4580 }
4581 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004582 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004583 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004584 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004585 break;
4586 }
4587 goto out_error;
4588 }
4589 }
4590 return done;
4591
4592 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004593 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004594 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004595 ERR_clear_error();
4596
Emeric Brun46591952012-05-18 15:47:34 +02004597 conn->flags |= CO_FL_ERROR;
4598 return done;
4599}
4600
Emeric Brun46591952012-05-18 15:47:34 +02004601static void ssl_sock_close(struct connection *conn) {
4602
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004603 if (conn->xprt_ctx) {
4604 SSL_free(conn->xprt_ctx);
4605 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004606 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004607 }
Emeric Brun46591952012-05-18 15:47:34 +02004608}
4609
4610/* This function tries to perform a clean shutdown on an SSL connection, and in
4611 * any case, flags the connection as reusable if no handshake was in progress.
4612 */
4613static void ssl_sock_shutw(struct connection *conn, int clean)
4614{
4615 if (conn->flags & CO_FL_HANDSHAKE)
4616 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004617 if (!clean)
4618 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004619 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004620 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004621 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004622 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004623 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004624 ERR_clear_error();
4625 }
Emeric Brun46591952012-05-18 15:47:34 +02004626}
4627
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004628/* used for logging, may be changed for a sample fetch later */
4629const char *ssl_sock_get_cipher_name(struct connection *conn)
4630{
4631 if (!conn->xprt && !conn->xprt_ctx)
4632 return NULL;
4633 return SSL_get_cipher_name(conn->xprt_ctx);
4634}
4635
4636/* used for logging, may be changed for a sample fetch later */
4637const char *ssl_sock_get_proto_version(struct connection *conn)
4638{
4639 if (!conn->xprt && !conn->xprt_ctx)
4640 return NULL;
4641 return SSL_get_version(conn->xprt_ctx);
4642}
4643
Willy Tarreau8d598402012-10-22 17:58:39 +02004644/* Extract a serial from a cert, and copy it to a chunk.
4645 * Returns 1 if serial is found and copied, 0 if no serial found and
4646 * -1 if output is not large enough.
4647 */
4648static int
4649ssl_sock_get_serial(X509 *crt, struct chunk *out)
4650{
4651 ASN1_INTEGER *serial;
4652
4653 serial = X509_get_serialNumber(crt);
4654 if (!serial)
4655 return 0;
4656
4657 if (out->size < serial->length)
4658 return -1;
4659
4660 memcpy(out->str, serial->data, serial->length);
4661 out->len = serial->length;
4662 return 1;
4663}
4664
Emeric Brun43e79582014-10-29 19:03:26 +01004665/* Extract a cert to der, and copy it to a chunk.
4666 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4667 * -1 if output is not large enough.
4668 */
4669static int
4670ssl_sock_crt2der(X509 *crt, struct chunk *out)
4671{
4672 int len;
4673 unsigned char *p = (unsigned char *)out->str;;
4674
4675 len =i2d_X509(crt, NULL);
4676 if (len <= 0)
4677 return 1;
4678
4679 if (out->size < len)
4680 return -1;
4681
4682 i2d_X509(crt,&p);
4683 out->len = len;
4684 return 1;
4685}
4686
Emeric Brunce5ad802012-10-22 14:11:22 +02004687
4688/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4689 * Returns 1 if serial is found and copied, 0 if no valid time found
4690 * and -1 if output is not large enough.
4691 */
4692static int
4693ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4694{
4695 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4696 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4697
4698 if (gentm->length < 12)
4699 return 0;
4700 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4701 return 0;
4702 if (out->size < gentm->length-2)
4703 return -1;
4704
4705 memcpy(out->str, gentm->data+2, gentm->length-2);
4706 out->len = gentm->length-2;
4707 return 1;
4708 }
4709 else if (tm->type == V_ASN1_UTCTIME) {
4710 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4711
4712 if (utctm->length < 10)
4713 return 0;
4714 if (utctm->data[0] >= 0x35)
4715 return 0;
4716 if (out->size < utctm->length)
4717 return -1;
4718
4719 memcpy(out->str, utctm->data, utctm->length);
4720 out->len = utctm->length;
4721 return 1;
4722 }
4723
4724 return 0;
4725}
4726
Emeric Brun87855892012-10-17 17:39:35 +02004727/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4728 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4729 */
4730static int
4731ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4732{
4733 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004734 ASN1_OBJECT *obj;
4735 ASN1_STRING *data;
4736 const unsigned char *data_ptr;
4737 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004738 int i, j, n;
4739 int cur = 0;
4740 const char *s;
4741 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004742 int name_count;
4743
4744 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004745
4746 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004747 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004748 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004749 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004750 else
4751 j = i;
4752
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004753 ne = X509_NAME_get_entry(a, j);
4754 obj = X509_NAME_ENTRY_get_object(ne);
4755 data = X509_NAME_ENTRY_get_data(ne);
4756 data_ptr = ASN1_STRING_get0_data(data);
4757 data_len = ASN1_STRING_length(data);
4758 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004759 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004760 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004761 s = tmp;
4762 }
4763
4764 if (chunk_strcasecmp(entry, s) != 0)
4765 continue;
4766
4767 if (pos < 0)
4768 cur--;
4769 else
4770 cur++;
4771
4772 if (cur != pos)
4773 continue;
4774
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004775 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004776 return -1;
4777
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004778 memcpy(out->str, data_ptr, data_len);
4779 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004780 return 1;
4781 }
4782
4783 return 0;
4784
4785}
4786
4787/* Extract and format full DN from a X509_NAME and copy result into a chunk
4788 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4789 */
4790static int
4791ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4792{
4793 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004794 ASN1_OBJECT *obj;
4795 ASN1_STRING *data;
4796 const unsigned char *data_ptr;
4797 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004798 int i, n, ln;
4799 int l = 0;
4800 const char *s;
4801 char *p;
4802 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004803 int name_count;
4804
4805
4806 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004807
4808 out->len = 0;
4809 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004810 for (i = 0; i < name_count; i++) {
4811 ne = X509_NAME_get_entry(a, i);
4812 obj = X509_NAME_ENTRY_get_object(ne);
4813 data = X509_NAME_ENTRY_get_data(ne);
4814 data_ptr = ASN1_STRING_get0_data(data);
4815 data_len = ASN1_STRING_length(data);
4816 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004817 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004818 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004819 s = tmp;
4820 }
4821 ln = strlen(s);
4822
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004823 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004824 if (l > out->size)
4825 return -1;
4826 out->len = l;
4827
4828 *(p++)='/';
4829 memcpy(p, s, ln);
4830 p += ln;
4831 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004832 memcpy(p, data_ptr, data_len);
4833 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004834 }
4835
4836 if (!out->len)
4837 return 0;
4838
4839 return 1;
4840}
4841
David Safb76832014-05-08 23:42:08 -04004842char *ssl_sock_get_version(struct connection *conn)
4843{
4844 if (!ssl_sock_is_ssl(conn))
4845 return NULL;
4846
4847 return (char *)SSL_get_version(conn->xprt_ctx);
4848}
4849
Willy Tarreau119a4082016-12-22 21:58:38 +01004850/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4851 * to disable SNI.
4852 */
Willy Tarreau63076412015-07-10 11:33:32 +02004853void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4854{
4855#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004856 char *prev_name;
4857
Willy Tarreau63076412015-07-10 11:33:32 +02004858 if (!ssl_sock_is_ssl(conn))
4859 return;
4860
Willy Tarreau119a4082016-12-22 21:58:38 +01004861 /* if the SNI changes, we must destroy the reusable context so that a
4862 * new connection will present a new SNI. As an optimization we could
4863 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4864 * server.
4865 */
4866 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4867 if ((!prev_name && hostname) ||
4868 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4869 SSL_set_session(conn->xprt_ctx, NULL);
4870
Willy Tarreau63076412015-07-10 11:33:32 +02004871 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4872#endif
4873}
4874
Emeric Brun0abf8362014-06-24 18:26:41 +02004875/* Extract peer certificate's common name into the chunk dest
4876 * Returns
4877 * the len of the extracted common name
4878 * or 0 if no CN found in DN
4879 * or -1 on error case (i.e. no peer certificate)
4880 */
4881int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004882{
4883 X509 *crt = NULL;
4884 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004885 const char find_cn[] = "CN";
4886 const struct chunk find_cn_chunk = {
4887 .str = (char *)&find_cn,
4888 .len = sizeof(find_cn)-1
4889 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004890 int result = -1;
David Safb76832014-05-08 23:42:08 -04004891
4892 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004893 goto out;
David Safb76832014-05-08 23:42:08 -04004894
4895 /* SSL_get_peer_certificate, it increase X509 * ref count */
4896 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4897 if (!crt)
4898 goto out;
4899
4900 name = X509_get_subject_name(crt);
4901 if (!name)
4902 goto out;
David Safb76832014-05-08 23:42:08 -04004903
Emeric Brun0abf8362014-06-24 18:26:41 +02004904 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4905out:
David Safb76832014-05-08 23:42:08 -04004906 if (crt)
4907 X509_free(crt);
4908
4909 return result;
4910}
4911
Dave McCowan328fb582014-07-30 10:39:13 -04004912/* returns 1 if client passed a certificate for this session, 0 if not */
4913int ssl_sock_get_cert_used_sess(struct connection *conn)
4914{
4915 X509 *crt = NULL;
4916
4917 if (!ssl_sock_is_ssl(conn))
4918 return 0;
4919
4920 /* SSL_get_peer_certificate, it increase X509 * ref count */
4921 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4922 if (!crt)
4923 return 0;
4924
4925 X509_free(crt);
4926 return 1;
4927}
4928
4929/* returns 1 if client passed a certificate for this connection, 0 if not */
4930int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004931{
4932 if (!ssl_sock_is_ssl(conn))
4933 return 0;
4934
4935 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4936}
4937
4938/* returns result from SSL verify */
4939unsigned int ssl_sock_get_verify_result(struct connection *conn)
4940{
4941 if (!ssl_sock_is_ssl(conn))
4942 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4943
4944 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4945}
4946
Willy Tarreau7875d092012-09-10 08:20:03 +02004947/***** Below are some sample fetching functions for ACL/patterns *****/
4948
Emeric Brune64aef12012-09-21 13:15:06 +02004949/* boolean, returns true if client cert was present */
4950static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004951smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004952{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004953 struct connection *conn;
4954
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004955 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004956 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004957 return 0;
4958
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004959 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004960 smp->flags |= SMP_F_MAY_CHANGE;
4961 return 0;
4962 }
4963
4964 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004965 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004966 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004967
4968 return 1;
4969}
4970
Emeric Brun43e79582014-10-29 19:03:26 +01004971/* binary, returns a certificate in a binary chunk (der/raw).
4972 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4973 * should be use.
4974 */
4975static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004976smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004977{
4978 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4979 X509 *crt = NULL;
4980 int ret = 0;
4981 struct chunk *smp_trash;
4982 struct connection *conn;
4983
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004984 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004985 if (!conn || conn->xprt != &ssl_sock)
4986 return 0;
4987
4988 if (!(conn->flags & CO_FL_CONNECTED)) {
4989 smp->flags |= SMP_F_MAY_CHANGE;
4990 return 0;
4991 }
4992
4993 if (cert_peer)
4994 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4995 else
4996 crt = SSL_get_certificate(conn->xprt_ctx);
4997
4998 if (!crt)
4999 goto out;
5000
5001 smp_trash = get_trash_chunk();
5002 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
5003 goto out;
5004
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005005 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005006 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01005007 ret = 1;
5008out:
5009 /* SSL_get_peer_certificate, it increase X509 * ref count */
5010 if (cert_peer && crt)
5011 X509_free(crt);
5012 return ret;
5013}
5014
Emeric Brunba841a12014-04-30 17:05:08 +02005015/* binary, returns serial of certificate in a binary chunk.
5016 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5017 * should be use.
5018 */
Willy Tarreau8d598402012-10-22 17:58:39 +02005019static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005020smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02005021{
Emeric Brunba841a12014-04-30 17:05:08 +02005022 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02005023 X509 *crt = NULL;
5024 int ret = 0;
5025 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005026 struct connection *conn;
5027
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005028 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005029 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02005030 return 0;
5031
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005032 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02005033 smp->flags |= SMP_F_MAY_CHANGE;
5034 return 0;
5035 }
5036
Emeric Brunba841a12014-04-30 17:05:08 +02005037 if (cert_peer)
5038 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5039 else
5040 crt = SSL_get_certificate(conn->xprt_ctx);
5041
Willy Tarreau8d598402012-10-22 17:58:39 +02005042 if (!crt)
5043 goto out;
5044
Willy Tarreau47ca5452012-12-23 20:22:19 +01005045 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005046 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5047 goto out;
5048
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005049 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005050 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005051 ret = 1;
5052out:
Emeric Brunba841a12014-04-30 17:05:08 +02005053 /* SSL_get_peer_certificate, it increase X509 * ref count */
5054 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005055 X509_free(crt);
5056 return ret;
5057}
Emeric Brune64aef12012-09-21 13:15:06 +02005058
Emeric Brunba841a12014-04-30 17:05:08 +02005059/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5060 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5061 * should be use.
5062 */
James Votha051b4a2013-05-14 20:37:59 +02005063static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005064smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005065{
Emeric Brunba841a12014-04-30 17:05:08 +02005066 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005067 X509 *crt = NULL;
5068 const EVP_MD *digest;
5069 int ret = 0;
5070 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005071 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005072
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005073 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005074 if (!conn || conn->xprt != &ssl_sock)
5075 return 0;
5076
5077 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005078 smp->flags |= SMP_F_MAY_CHANGE;
5079 return 0;
5080 }
5081
Emeric Brunba841a12014-04-30 17:05:08 +02005082 if (cert_peer)
5083 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5084 else
5085 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005086 if (!crt)
5087 goto out;
5088
5089 smp_trash = get_trash_chunk();
5090 digest = EVP_sha1();
5091 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5092
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005093 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005094 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005095 ret = 1;
5096out:
Emeric Brunba841a12014-04-30 17:05:08 +02005097 /* SSL_get_peer_certificate, it increase X509 * ref count */
5098 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005099 X509_free(crt);
5100 return ret;
5101}
5102
Emeric Brunba841a12014-04-30 17:05:08 +02005103/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5104 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5105 * should be use.
5106 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005107static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005108smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005109{
Emeric Brunba841a12014-04-30 17:05:08 +02005110 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005111 X509 *crt = NULL;
5112 int ret = 0;
5113 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005114 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005115
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005116 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005117 if (!conn || conn->xprt != &ssl_sock)
5118 return 0;
5119
5120 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005121 smp->flags |= SMP_F_MAY_CHANGE;
5122 return 0;
5123 }
5124
Emeric Brunba841a12014-04-30 17:05:08 +02005125 if (cert_peer)
5126 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5127 else
5128 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005129 if (!crt)
5130 goto out;
5131
Willy Tarreau47ca5452012-12-23 20:22:19 +01005132 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005133 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5134 goto out;
5135
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005136 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005137 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005138 ret = 1;
5139out:
Emeric Brunba841a12014-04-30 17:05:08 +02005140 /* SSL_get_peer_certificate, it increase X509 * ref count */
5141 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005142 X509_free(crt);
5143 return ret;
5144}
5145
Emeric Brunba841a12014-04-30 17:05:08 +02005146/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5147 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5148 * should be use.
5149 */
Emeric Brun87855892012-10-17 17:39:35 +02005150static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005151smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005152{
Emeric Brunba841a12014-04-30 17:05:08 +02005153 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005154 X509 *crt = NULL;
5155 X509_NAME *name;
5156 int ret = 0;
5157 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005158 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005159
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005160 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005161 if (!conn || conn->xprt != &ssl_sock)
5162 return 0;
5163
5164 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005165 smp->flags |= SMP_F_MAY_CHANGE;
5166 return 0;
5167 }
5168
Emeric Brunba841a12014-04-30 17:05:08 +02005169 if (cert_peer)
5170 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5171 else
5172 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005173 if (!crt)
5174 goto out;
5175
5176 name = X509_get_issuer_name(crt);
5177 if (!name)
5178 goto out;
5179
Willy Tarreau47ca5452012-12-23 20:22:19 +01005180 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005181 if (args && args[0].type == ARGT_STR) {
5182 int pos = 1;
5183
5184 if (args[1].type == ARGT_SINT)
5185 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005186
5187 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5188 goto out;
5189 }
5190 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5191 goto out;
5192
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005193 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005194 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005195 ret = 1;
5196out:
Emeric Brunba841a12014-04-30 17:05:08 +02005197 /* SSL_get_peer_certificate, it increase X509 * ref count */
5198 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005199 X509_free(crt);
5200 return ret;
5201}
5202
Emeric Brunba841a12014-04-30 17:05:08 +02005203/* string, returns notbefore date in ASN1_UTCTIME format.
5204 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5205 * should be use.
5206 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005207static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005208smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005209{
Emeric Brunba841a12014-04-30 17:05:08 +02005210 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005211 X509 *crt = NULL;
5212 int ret = 0;
5213 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005214 struct connection *conn;
5215
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005216 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005217 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005218 return 0;
5219
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005220 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005221 smp->flags |= SMP_F_MAY_CHANGE;
5222 return 0;
5223 }
5224
Emeric Brunba841a12014-04-30 17:05:08 +02005225 if (cert_peer)
5226 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5227 else
5228 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005229 if (!crt)
5230 goto out;
5231
Willy Tarreau47ca5452012-12-23 20:22:19 +01005232 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005233 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5234 goto out;
5235
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005236 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005237 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005238 ret = 1;
5239out:
Emeric Brunba841a12014-04-30 17:05:08 +02005240 /* SSL_get_peer_certificate, it increase X509 * ref count */
5241 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005242 X509_free(crt);
5243 return ret;
5244}
5245
Emeric Brunba841a12014-04-30 17:05:08 +02005246/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5247 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5248 * should be use.
5249 */
Emeric Brun87855892012-10-17 17:39:35 +02005250static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005251smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005252{
Emeric Brunba841a12014-04-30 17:05:08 +02005253 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005254 X509 *crt = NULL;
5255 X509_NAME *name;
5256 int ret = 0;
5257 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005258 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005259
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005260 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005261 if (!conn || conn->xprt != &ssl_sock)
5262 return 0;
5263
5264 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005265 smp->flags |= SMP_F_MAY_CHANGE;
5266 return 0;
5267 }
5268
Emeric Brunba841a12014-04-30 17:05:08 +02005269 if (cert_peer)
5270 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5271 else
5272 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005273 if (!crt)
5274 goto out;
5275
5276 name = X509_get_subject_name(crt);
5277 if (!name)
5278 goto out;
5279
Willy Tarreau47ca5452012-12-23 20:22:19 +01005280 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005281 if (args && args[0].type == ARGT_STR) {
5282 int pos = 1;
5283
5284 if (args[1].type == ARGT_SINT)
5285 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005286
5287 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5288 goto out;
5289 }
5290 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5291 goto out;
5292
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005293 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005294 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005295 ret = 1;
5296out:
Emeric Brunba841a12014-04-30 17:05:08 +02005297 /* SSL_get_peer_certificate, it increase X509 * ref count */
5298 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005299 X509_free(crt);
5300 return ret;
5301}
Emeric Brun9143d372012-12-20 15:44:16 +01005302
5303/* integer, returns true if current session use a client certificate */
5304static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005305smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005306{
5307 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005308 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005309
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005310 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005311 if (!conn || conn->xprt != &ssl_sock)
5312 return 0;
5313
5314 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005315 smp->flags |= SMP_F_MAY_CHANGE;
5316 return 0;
5317 }
5318
5319 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005320 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005321 if (crt) {
5322 X509_free(crt);
5323 }
5324
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005325 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005326 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005327 return 1;
5328}
5329
Emeric Brunba841a12014-04-30 17:05:08 +02005330/* integer, returns the certificate version
5331 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5332 * should be use.
5333 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005334static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005335smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005336{
Emeric Brunba841a12014-04-30 17:05:08 +02005337 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005338 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005339 struct connection *conn;
5340
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005341 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005342 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005343 return 0;
5344
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005345 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005346 smp->flags |= SMP_F_MAY_CHANGE;
5347 return 0;
5348 }
5349
Emeric Brunba841a12014-04-30 17:05:08 +02005350 if (cert_peer)
5351 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5352 else
5353 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005354 if (!crt)
5355 return 0;
5356
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005357 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005358 /* SSL_get_peer_certificate increase X509 * ref count */
5359 if (cert_peer)
5360 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005361 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005362
5363 return 1;
5364}
5365
Emeric Brunba841a12014-04-30 17:05:08 +02005366/* string, returns the certificate's signature algorithm.
5367 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5368 * should be use.
5369 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005370static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005371smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005372{
Emeric Brunba841a12014-04-30 17:05:08 +02005373 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005374 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005375 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005376 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005377 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005378
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005379 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005380 if (!conn || conn->xprt != &ssl_sock)
5381 return 0;
5382
5383 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005384 smp->flags |= SMP_F_MAY_CHANGE;
5385 return 0;
5386 }
5387
Emeric Brunba841a12014-04-30 17:05:08 +02005388 if (cert_peer)
5389 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5390 else
5391 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005392 if (!crt)
5393 return 0;
5394
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005395 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5396 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005397
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005398 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5399 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005400 /* SSL_get_peer_certificate increase X509 * ref count */
5401 if (cert_peer)
5402 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005403 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005404 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005405
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005406 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005407 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005408 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005409 /* SSL_get_peer_certificate increase X509 * ref count */
5410 if (cert_peer)
5411 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005412
5413 return 1;
5414}
5415
Emeric Brunba841a12014-04-30 17:05:08 +02005416/* string, returns the certificate's key algorithm.
5417 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5418 * should be use.
5419 */
Emeric Brun521a0112012-10-22 12:22:55 +02005420static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005421smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005422{
Emeric Brunba841a12014-04-30 17:05:08 +02005423 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005424 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005425 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005426 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005427 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005428
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005429 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005430 if (!conn || conn->xprt != &ssl_sock)
5431 return 0;
5432
5433 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005434 smp->flags |= SMP_F_MAY_CHANGE;
5435 return 0;
5436 }
5437
Emeric Brunba841a12014-04-30 17:05:08 +02005438 if (cert_peer)
5439 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5440 else
5441 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005442 if (!crt)
5443 return 0;
5444
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005445 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5446 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005447
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005448 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5449 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005450 /* SSL_get_peer_certificate increase X509 * ref count */
5451 if (cert_peer)
5452 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005453 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005454 }
Emeric Brun521a0112012-10-22 12:22:55 +02005455
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005456 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005457 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005458 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005459 if (cert_peer)
5460 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005461
5462 return 1;
5463}
5464
Emeric Brun645ae792014-04-30 14:21:06 +02005465/* boolean, returns true if front conn. transport layer is SSL.
5466 * This function is also usable on backend conn if the fetch keyword 5th
5467 * char is 'b'.
5468 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005469static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005470smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005471{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005472 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5473 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005474
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005475 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005476 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005477 return 1;
5478}
5479
Emeric Brun2525b6b2012-10-18 15:59:43 +02005480/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005481static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005482smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005483{
5484#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005485 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005486
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005487 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005488 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005489 conn->xprt_ctx &&
5490 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005491 return 1;
5492#else
5493 return 0;
5494#endif
5495}
5496
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005497/* boolean, returns true if client session has been resumed */
5498static int
5499smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5500{
5501 struct connection *conn = objt_conn(smp->sess->origin);
5502
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005503 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005504 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005505 conn->xprt_ctx &&
5506 SSL_session_reused(conn->xprt_ctx);
5507 return 1;
5508}
5509
Emeric Brun645ae792014-04-30 14:21:06 +02005510/* string, returns the used cipher if front conn. transport layer is SSL.
5511 * This function is also usable on backend conn if the fetch keyword 5th
5512 * char is 'b'.
5513 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005514static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005515smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005516{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005517 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5518 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005519
Willy Tarreaube508f12016-03-10 11:47:01 +01005520 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005521 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005522 return 0;
5523
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005524 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5525 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005526 return 0;
5527
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005528 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005529 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005530 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005531
5532 return 1;
5533}
5534
Emeric Brun645ae792014-04-30 14:21:06 +02005535/* integer, returns the algoritm's keysize if front conn. transport layer
5536 * is SSL.
5537 * This function is also usable on backend conn if the fetch keyword 5th
5538 * char is 'b'.
5539 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005540static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005541smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005542{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005543 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5544 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005545
Willy Tarreaue237fe12016-03-10 17:05:28 +01005546 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005547
Emeric Brun589fcad2012-10-16 14:13:26 +02005548 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005549 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005550 return 0;
5551
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005552 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005553 return 0;
5554
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005555 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005556 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005557
5558 return 1;
5559}
5560
Emeric Brun645ae792014-04-30 14:21:06 +02005561/* integer, returns the used keysize if front conn. transport layer is SSL.
5562 * This function is also usable on backend conn if the fetch keyword 5th
5563 * char is 'b'.
5564 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005565static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005566smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005567{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005568 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5569 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005570
Emeric Brun589fcad2012-10-16 14:13:26 +02005571 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005572 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5573 return 0;
5574
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005575 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5576 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005577 return 0;
5578
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005579 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005580
5581 return 1;
5582}
5583
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005584#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005585static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005586smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005587{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005588 struct connection *conn;
5589
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005590 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005591 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005592
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005593 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005594 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5595 return 0;
5596
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005597 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005598 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005599 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005600
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005601 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005602 return 0;
5603
5604 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005605}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005606#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005607
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005608#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005609static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005610smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005611{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005612 struct connection *conn;
5613
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005614 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005615 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005616
Willy Tarreaue26bf052015-05-12 10:30:12 +02005617 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005618 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005619 return 0;
5620
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005621 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005622 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005623 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005624
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005625 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005626 return 0;
5627
5628 return 1;
5629}
5630#endif
5631
Emeric Brun645ae792014-04-30 14:21:06 +02005632/* string, returns the used protocol if front conn. transport layer is SSL.
5633 * This function is also usable on backend conn if the fetch keyword 5th
5634 * char is 'b'.
5635 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005636static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005637smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005638{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005639 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5640 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005641
Emeric Brun589fcad2012-10-16 14:13:26 +02005642 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005643 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5644 return 0;
5645
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005646 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5647 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005648 return 0;
5649
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005650 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005651 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005652 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005653
5654 return 1;
5655}
5656
Willy Tarreau87b09662015-04-03 00:22:06 +02005657/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005658 * This function is also usable on backend conn if the fetch keyword 5th
5659 * char is 'b'.
5660 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005661static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005662smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005663{
5664#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005665 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5666 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005667
Willy Tarreaue237fe12016-03-10 17:05:28 +01005668 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005669
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005670 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005671 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005672
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005673 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5674 return 0;
5675
Willy Tarreau192252e2015-04-04 01:47:55 +02005676 ssl_sess = SSL_get_session(conn->xprt_ctx);
5677 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005678 return 0;
5679
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005680 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5681 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005682 return 0;
5683
5684 return 1;
5685#else
5686 return 0;
5687#endif
5688}
5689
5690static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005691smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005692{
5693#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005694 struct connection *conn;
5695
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005696 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005697 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005698
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005699 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005700 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5701 return 0;
5702
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005703 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5704 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005705 return 0;
5706
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005707 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005708 return 1;
5709#else
5710 return 0;
5711#endif
5712}
5713
David Sc1ad52e2014-04-08 18:48:47 -04005714static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005715smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
5716{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005717 struct connection *conn;
5718 struct ssl_capture *capture;
5719
5720 conn = objt_conn(smp->sess->origin);
5721 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5722 return 0;
5723
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005724 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005725 if (!capture)
5726 return 0;
5727
5728 smp->flags = SMP_F_CONST;
5729 smp->data.type = SMP_T_BIN;
5730 smp->data.u.str.str = capture->ciphersuite;
5731 smp->data.u.str.len = capture->ciphersuite_len;
5732 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005733}
5734
5735static int
5736smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
5737{
5738 struct chunk *data;
5739
5740 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5741 return 0;
5742
5743 data = get_trash_chunk();
5744 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
5745 smp->data.type = SMP_T_BIN;
5746 smp->data.u.str = *data;
5747 return 1;
5748}
5749
5750static int
5751smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
5752{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005753 struct connection *conn;
5754 struct ssl_capture *capture;
5755
5756 conn = objt_conn(smp->sess->origin);
5757 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5758 return 0;
5759
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005760 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005761 if (!capture)
5762 return 0;
5763
5764 smp->data.type = SMP_T_SINT;
5765 smp->data.u.sint = capture->xxh64;
5766 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005767}
5768
5769static int
5770smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
5771{
5772#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
5773 struct chunk *data;
5774 SSL_CIPHER cipher;
5775 int i;
5776 const char *str;
5777 unsigned char *bin;
5778
5779 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5780 return 0;
5781
5782 /* The cipher algorith must not be SSL_SSLV2, because this
5783 * SSL version seems to not have the same cipher encoding,
5784 * and it is not supported by OpenSSL. Unfortunately, the
5785 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
5786 * with standard defines. We just set the variable to 0,
5787 * ensure that the match with SSL_SSLV2 fails.
5788 */
5789 cipher.algorithm_ssl = 0;
5790
5791 data = get_trash_chunk();
5792 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
5793 bin = (unsigned char *)smp->data.u.str.str + i;
5794 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
5795 str = SSL_CIPHER_standard_name(&cipher);
5796 if (!str || strcmp(str, "UNKNOWN") == 0)
5797 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
5798 else
5799 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
5800 }
5801 smp->data.type = SMP_T_STR;
5802 smp->data.u.str = *data;
5803 return 1;
5804#else
5805 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
5806#endif
5807}
5808
5809static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005810smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005811{
5812#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005813 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5814 smp->strm ? smp->strm->si[1].end : NULL);
5815
David Sc1ad52e2014-04-08 18:48:47 -04005816 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005817 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005818
5819 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005820 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5821 return 0;
5822
5823 if (!(conn->flags & CO_FL_CONNECTED)) {
5824 smp->flags |= SMP_F_MAY_CHANGE;
5825 return 0;
5826 }
5827
5828 finished_trash = get_trash_chunk();
5829 if (!SSL_session_reused(conn->xprt_ctx))
5830 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5831 else
5832 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5833
5834 if (!finished_len)
5835 return 0;
5836
Emeric Brunb73a9b02014-04-30 18:49:19 +02005837 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005838 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005839 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005840
5841 return 1;
5842#else
5843 return 0;
5844#endif
5845}
5846
Emeric Brun2525b6b2012-10-18 15:59:43 +02005847/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005848static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005849smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005850{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005851 struct connection *conn;
5852
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005853 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005854 if (!conn || conn->xprt != &ssl_sock)
5855 return 0;
5856
5857 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005858 smp->flags = SMP_F_MAY_CHANGE;
5859 return 0;
5860 }
5861
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005862 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005863 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005864 smp->flags = 0;
5865
5866 return 1;
5867}
5868
Emeric Brun2525b6b2012-10-18 15:59:43 +02005869/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005870static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005871smp_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 +02005872{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005873 struct connection *conn;
5874
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005875 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005876 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005877 return 0;
5878
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005879 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005880 smp->flags = SMP_F_MAY_CHANGE;
5881 return 0;
5882 }
5883
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005884 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005885 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005886 smp->flags = 0;
5887
5888 return 1;
5889}
5890
Emeric Brun2525b6b2012-10-18 15:59:43 +02005891/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005892static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005893smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005894{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005895 struct connection *conn;
5896
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005897 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005898 if (!conn || conn->xprt != &ssl_sock)
5899 return 0;
5900
5901 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005902 smp->flags = SMP_F_MAY_CHANGE;
5903 return 0;
5904 }
5905
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005906 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005907 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005908 smp->flags = 0;
5909
5910 return 1;
5911}
5912
Emeric Brun2525b6b2012-10-18 15:59:43 +02005913/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005914static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005915smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005916{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005917 struct connection *conn;
5918
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005919 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005920 if (!conn || conn->xprt != &ssl_sock)
5921 return 0;
5922
5923 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005924 smp->flags = SMP_F_MAY_CHANGE;
5925 return 0;
5926 }
5927
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005928 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005929 return 0;
5930
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005931 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005932 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005933 smp->flags = 0;
5934
5935 return 1;
5936}
5937
Emeric Brunfb510ea2012-10-05 12:00:26 +02005938/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005939static 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 +02005940{
5941 if (!*args[cur_arg + 1]) {
5942 if (err)
5943 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5944 return ERR_ALERT | ERR_FATAL;
5945 }
5946
Willy Tarreauef934602016-12-22 23:12:01 +01005947 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5948 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005949 else
5950 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005951
Emeric Brund94b3fe2012-09-20 18:23:56 +02005952 return 0;
5953}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005954static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5955{
5956 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5957}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005958
Christopher Faulet31af49d2015-06-09 17:29:50 +02005959/* parse the "ca-sign-file" bind keyword */
5960static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5961{
5962 if (!*args[cur_arg + 1]) {
5963 if (err)
5964 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5965 return ERR_ALERT | ERR_FATAL;
5966 }
5967
Willy Tarreauef934602016-12-22 23:12:01 +01005968 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5969 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005970 else
5971 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5972
5973 return 0;
5974}
5975
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005976/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005977static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5978{
5979 if (!*args[cur_arg + 1]) {
5980 if (err)
5981 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5982 return ERR_ALERT | ERR_FATAL;
5983 }
5984 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5985 return 0;
5986}
5987
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005988/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005989static 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 +02005990{
5991 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005992 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005993 return ERR_ALERT | ERR_FATAL;
5994 }
5995
Emeric Brun76d88952012-10-05 15:47:31 +02005996 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005997 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005998 return 0;
5999}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006000static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6001{
6002 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
6003}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006004/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006005static 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 +02006006{
Willy Tarreau38011032013-08-13 16:59:39 +02006007 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02006008
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006009 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02006010 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006011 return ERR_ALERT | ERR_FATAL;
6012 }
6013
Willy Tarreauef934602016-12-22 23:12:01 +01006014 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
6015 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02006016 memprintf(err, "'%s' : path too long", args[cur_arg]);
6017 return ERR_ALERT | ERR_FATAL;
6018 }
Willy Tarreauef934602016-12-22 23:12:01 +01006019 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01006020 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02006021 return ERR_ALERT | ERR_FATAL;
6022
6023 return 0;
6024 }
6025
Willy Tarreau03209342016-12-22 17:08:28 +01006026 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006027 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006028
6029 return 0;
6030}
6031
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006032/* parse the "crt-list" bind keyword */
6033static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6034{
6035 if (!*args[cur_arg + 1]) {
6036 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
6037 return ERR_ALERT | ERR_FATAL;
6038 }
6039
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006040 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006041 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006042 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006043 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006044
6045 return 0;
6046}
6047
Emeric Brunfb510ea2012-10-05 12:00:26 +02006048/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006049static 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 +02006050{
Emeric Brun051cdab2012-10-02 19:25:50 +02006051#ifndef X509_V_FLAG_CRL_CHECK
6052 if (err)
6053 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6054 return ERR_ALERT | ERR_FATAL;
6055#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006056 if (!*args[cur_arg + 1]) {
6057 if (err)
6058 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6059 return ERR_ALERT | ERR_FATAL;
6060 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006061
Willy Tarreauef934602016-12-22 23:12:01 +01006062 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6063 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006064 else
6065 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006066
Emeric Brun2b58d042012-09-20 17:10:03 +02006067 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006068#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006069}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006070static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6071{
6072 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6073}
Emeric Brun2b58d042012-09-20 17:10:03 +02006074
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006075/* parse the "curves" bind keyword keyword */
6076static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6077{
6078#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6079 if (!*args[cur_arg + 1]) {
6080 if (err)
6081 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6082 return ERR_ALERT | ERR_FATAL;
6083 }
6084 conf->curves = strdup(args[cur_arg + 1]);
6085 return 0;
6086#else
6087 if (err)
6088 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6089 return ERR_ALERT | ERR_FATAL;
6090#endif
6091}
6092static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6093{
6094 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6095}
6096
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006097/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006098static 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 +02006099{
6100#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6101 if (err)
6102 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6103 return ERR_ALERT | ERR_FATAL;
6104#elif defined(OPENSSL_NO_ECDH)
6105 if (err)
6106 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6107 return ERR_ALERT | ERR_FATAL;
6108#else
6109 if (!*args[cur_arg + 1]) {
6110 if (err)
6111 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6112 return ERR_ALERT | ERR_FATAL;
6113 }
6114
6115 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006116
6117 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006118#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006119}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006120static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6121{
6122 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6123}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006124
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006125/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006126static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6127{
6128 int code;
6129 char *p = args[cur_arg + 1];
6130 unsigned long long *ignerr = &conf->crt_ignerr;
6131
6132 if (!*p) {
6133 if (err)
6134 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6135 return ERR_ALERT | ERR_FATAL;
6136 }
6137
6138 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6139 ignerr = &conf->ca_ignerr;
6140
6141 if (strcmp(p, "all") == 0) {
6142 *ignerr = ~0ULL;
6143 return 0;
6144 }
6145
6146 while (p) {
6147 code = atoi(p);
6148 if ((code <= 0) || (code > 63)) {
6149 if (err)
6150 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6151 args[cur_arg], code, args[cur_arg + 1]);
6152 return ERR_ALERT | ERR_FATAL;
6153 }
6154 *ignerr |= 1ULL << code;
6155 p = strchr(p, ',');
6156 if (p)
6157 p++;
6158 }
6159
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006160 return 0;
6161}
6162
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006163/* parse tls_method_options */
6164static int parse_tls_method_options(char *arg, struct tls_version_filter *methods)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006165{
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006166 char *p;
6167 int v;
6168 p = strchr(arg, '-');
6169 if (!p)
6170 return 1;
6171 p++;
6172 if (!strcmp(p, "sslv3"))
6173 v = CONF_SSLV3;
6174 else if (!strcmp(p, "tlsv10"))
6175 v = CONF_TLSV10;
6176 else if (!strcmp(p, "tlsv11"))
6177 v = CONF_TLSV11;
6178 else if (!strcmp(p, "tlsv12"))
6179 v = CONF_TLSV12;
6180 else
6181 return 1;
6182 if (!strncmp(arg, "no-", 3))
6183 methods->flags |= methodVersions[v].flag;
6184 else if (!strncmp(arg, "force-", 6))
6185 methods->min = methods->max = v;
6186 else
6187 return 1;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006188 return 0;
6189}
6190
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006191static 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 +02006192{
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006193 if (parse_tls_method_options(args[cur_arg], &conf->ssl_methods)) {
6194 if (err)
6195 memprintf(err, "'%s' : option not implemented", args[cur_arg]);
6196 return ERR_ALERT | ERR_FATAL;
6197 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006198 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006199}
6200
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006201static 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 +02006202{
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006203 if (parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods)) {
6204 if (err)
6205 memprintf(err, "'%s' : option not implemented", args[*cur_arg]);
6206 return ERR_ALERT | ERR_FATAL;
6207 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006208 return 0;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006209}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006210
Emeric Brun2d0c4822012-10-02 13:45:20 +02006211/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006212static 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 +02006213{
Emeric Brun89675492012-10-05 13:48:26 +02006214 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006215 return 0;
6216}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006217
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006218/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006219static 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 +02006220{
6221#ifdef OPENSSL_NPN_NEGOTIATED
6222 char *p1, *p2;
6223
6224 if (!*args[cur_arg + 1]) {
6225 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6226 return ERR_ALERT | ERR_FATAL;
6227 }
6228
6229 free(conf->npn_str);
6230
Willy Tarreau3724da12016-02-12 17:11:12 +01006231 /* the NPN string is built as a suite of (<len> <name>)*,
6232 * so we reuse each comma to store the next <len> and need
6233 * one more for the end of the string.
6234 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006235 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006236 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006237 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6238
6239 /* replace commas with the name length */
6240 p1 = conf->npn_str;
6241 p2 = p1 + 1;
6242 while (1) {
6243 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6244 if (!p2)
6245 p2 = p1 + 1 + strlen(p1 + 1);
6246
6247 if (p2 - (p1 + 1) > 255) {
6248 *p2 = '\0';
6249 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6250 return ERR_ALERT | ERR_FATAL;
6251 }
6252
6253 *p1 = p2 - (p1 + 1);
6254 p1 = p2;
6255
6256 if (!*p2)
6257 break;
6258
6259 *(p2++) = '\0';
6260 }
6261 return 0;
6262#else
6263 if (err)
6264 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6265 return ERR_ALERT | ERR_FATAL;
6266#endif
6267}
6268
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006269static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6270{
6271 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6272}
6273
Willy Tarreauab861d32013-04-02 02:30:41 +02006274/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006275static 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 +02006276{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006277#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006278 char *p1, *p2;
6279
6280 if (!*args[cur_arg + 1]) {
6281 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6282 return ERR_ALERT | ERR_FATAL;
6283 }
6284
6285 free(conf->alpn_str);
6286
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006287 /* the ALPN string is built as a suite of (<len> <name>)*,
6288 * so we reuse each comma to store the next <len> and need
6289 * one more for the end of the string.
6290 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006291 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006292 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006293 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6294
6295 /* replace commas with the name length */
6296 p1 = conf->alpn_str;
6297 p2 = p1 + 1;
6298 while (1) {
6299 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6300 if (!p2)
6301 p2 = p1 + 1 + strlen(p1 + 1);
6302
6303 if (p2 - (p1 + 1) > 255) {
6304 *p2 = '\0';
6305 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6306 return ERR_ALERT | ERR_FATAL;
6307 }
6308
6309 *p1 = p2 - (p1 + 1);
6310 p1 = p2;
6311
6312 if (!*p2)
6313 break;
6314
6315 *(p2++) = '\0';
6316 }
6317 return 0;
6318#else
6319 if (err)
6320 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6321 return ERR_ALERT | ERR_FATAL;
6322#endif
6323}
6324
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006325static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6326{
6327 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6328}
6329
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006330/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006331static 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 +02006332{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006333 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006334 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006335
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006336 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6337 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006338 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006339 conf->ssl_methods.flags |= global_ssl.listen_default_sslmethods.flags;
6340 if (!conf->ssl_methods.min)
6341 conf->ssl_methods.min = global_ssl.listen_default_sslmethods.min;
6342 if (!conf->ssl_methods.max)
6343 conf->ssl_methods.max = global_ssl.listen_default_sslmethods.max;
Emeric Brun76d88952012-10-05 15:47:31 +02006344
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006345 return 0;
6346}
6347
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006348/* parse the "prefer-client-ciphers" bind keyword */
6349static int bind_parse_pcc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6350{
6351 conf->ssl_options |= BC_SSL_O_PREF_CLIE_CIPH;
6352 return 0;
6353}
6354
Christopher Faulet31af49d2015-06-09 17:29:50 +02006355/* parse the "generate-certificates" bind keyword */
6356static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6357{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006358#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006359 conf->generate_certs = 1;
6360#else
6361 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6362 err && *err ? *err : "");
6363#endif
6364 return 0;
6365}
6366
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006367/* parse the "strict-sni" bind keyword */
6368static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6369{
6370 conf->strict_sni = 1;
6371 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006372}
6373
6374/* parse the "tls-ticket-keys" bind keyword */
6375static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6376{
6377#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6378 FILE *f;
6379 int i = 0;
6380 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006381 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006382
6383 if (!*args[cur_arg + 1]) {
6384 if (err)
6385 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6386 return ERR_ALERT | ERR_FATAL;
6387 }
6388
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006389 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6390 if(keys_ref) {
6391 conf->keys_ref = keys_ref;
6392 return 0;
6393 }
6394
Vincent Bernat02779b62016-04-03 13:48:43 +02006395 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006396 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006397
6398 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6399 if (err)
6400 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6401 return ERR_ALERT | ERR_FATAL;
6402 }
6403
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006404 keys_ref->filename = strdup(args[cur_arg + 1]);
6405
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006406 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6407 int len = strlen(thisline);
6408 /* Strip newline characters from the end */
6409 if(thisline[len - 1] == '\n')
6410 thisline[--len] = 0;
6411
6412 if(thisline[len - 1] == '\r')
6413 thisline[--len] = 0;
6414
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006415 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 +01006416 if (err)
6417 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006418 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006419 return ERR_ALERT | ERR_FATAL;
6420 }
6421 i++;
6422 }
6423
6424 if (i < TLS_TICKETS_NO) {
6425 if (err)
6426 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 +02006427 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006428 return ERR_ALERT | ERR_FATAL;
6429 }
6430
6431 fclose(f);
6432
6433 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006434 i -= 2;
6435 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006436 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006437 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006438
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006439 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6440
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006441 return 0;
6442#else
6443 if (err)
6444 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6445 return ERR_ALERT | ERR_FATAL;
6446#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006447}
6448
Emeric Brund94b3fe2012-09-20 18:23:56 +02006449/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006450static 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 +02006451{
6452 if (!*args[cur_arg + 1]) {
6453 if (err)
6454 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6455 return ERR_ALERT | ERR_FATAL;
6456 }
6457
6458 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006459 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006460 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006461 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006462 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006463 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006464 else {
6465 if (err)
6466 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6467 args[cur_arg], args[cur_arg + 1]);
6468 return ERR_ALERT | ERR_FATAL;
6469 }
6470
6471 return 0;
6472}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006473static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6474{
6475 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6476}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006477
Willy Tarreau92faadf2012-10-10 23:04:25 +02006478/************** "server" keywords ****************/
6479
Emeric Brunef42d922012-10-11 16:11:36 +02006480/* parse the "ca-file" server keyword */
6481static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6482{
6483 if (!*args[*cur_arg + 1]) {
6484 if (err)
6485 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6486 return ERR_ALERT | ERR_FATAL;
6487 }
6488
Willy Tarreauef934602016-12-22 23:12:01 +01006489 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6490 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006491 else
6492 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6493
6494 return 0;
6495}
6496
Willy Tarreau92faadf2012-10-10 23:04:25 +02006497/* parse the "check-ssl" server keyword */
6498static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6499{
6500 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006501 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6502 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6503 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006504 newsrv->ssl_ctx.methods.flags |= global_ssl.connect_default_sslmethods.flags;
6505 if (!newsrv->ssl_ctx.methods.min)
6506 newsrv->ssl_ctx.methods.min = global_ssl.connect_default_sslmethods.min;
6507 if (!newsrv->ssl_ctx.methods.max)
6508 newsrv->ssl_ctx.methods.max = global_ssl.connect_default_sslmethods.max;
6509
Willy Tarreau92faadf2012-10-10 23:04:25 +02006510 return 0;
6511}
6512
6513/* parse the "ciphers" server keyword */
6514static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6515{
6516 if (!*args[*cur_arg + 1]) {
6517 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6518 return ERR_ALERT | ERR_FATAL;
6519 }
6520
6521 free(newsrv->ssl_ctx.ciphers);
6522 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6523 return 0;
6524}
6525
Emeric Brunef42d922012-10-11 16:11:36 +02006526/* parse the "crl-file" server keyword */
6527static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6528{
6529#ifndef X509_V_FLAG_CRL_CHECK
6530 if (err)
6531 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6532 return ERR_ALERT | ERR_FATAL;
6533#else
6534 if (!*args[*cur_arg + 1]) {
6535 if (err)
6536 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6537 return ERR_ALERT | ERR_FATAL;
6538 }
6539
Willy Tarreauef934602016-12-22 23:12:01 +01006540 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6541 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006542 else
6543 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6544
6545 return 0;
6546#endif
6547}
6548
Emeric Bruna7aa3092012-10-26 12:58:00 +02006549/* parse the "crt" server keyword */
6550static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6551{
6552 if (!*args[*cur_arg + 1]) {
6553 if (err)
6554 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6555 return ERR_ALERT | ERR_FATAL;
6556 }
6557
Willy Tarreauef934602016-12-22 23:12:01 +01006558 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6559 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006560 else
6561 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6562
6563 return 0;
6564}
Emeric Brunef42d922012-10-11 16:11:36 +02006565
Frédéric Lécaille340ae602017-03-13 10:38:04 +01006566/* parse the "no-check-ssl" server keyword */
6567static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6568{
6569 newsrv->check.use_ssl = 0;
6570 free(newsrv->ssl_ctx.ciphers);
6571 newsrv->ssl_ctx.ciphers = NULL;
6572 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
6573 return 0;
6574}
6575
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01006576/* parse the "no-send-proxy-v2-ssl" server keyword */
6577static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6578{
6579 newsrv->pp_opts &= ~SRV_PP_V2;
6580 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
6581 return 0;
6582}
6583
6584/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
6585static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6586{
6587 newsrv->pp_opts &= ~SRV_PP_V2;
6588 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
6589 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
6590 return 0;
6591}
6592
Frédéric Lécaillee381d762017-03-13 11:54:17 +01006593/* parse the "no-ssl" server keyword */
6594static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6595{
6596 newsrv->use_ssl = 0;
6597 free(newsrv->ssl_ctx.ciphers);
6598 newsrv->ssl_ctx.ciphers = NULL;
6599 return 0;
6600}
6601
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006602/* parse the "no-ssl-reuse" server keyword */
6603static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6604{
6605 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6606 return 0;
6607}
6608
Emeric Brunf9c5c472012-10-11 15:28:34 +02006609/* parse the "no-tls-tickets" server keyword */
6610static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6611{
6612 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6613 return 0;
6614}
David Safb76832014-05-08 23:42:08 -04006615/* parse the "send-proxy-v2-ssl" server keyword */
6616static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6617{
6618 newsrv->pp_opts |= SRV_PP_V2;
6619 newsrv->pp_opts |= SRV_PP_V2_SSL;
6620 return 0;
6621}
6622
6623/* parse the "send-proxy-v2-ssl-cn" server keyword */
6624static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6625{
6626 newsrv->pp_opts |= SRV_PP_V2;
6627 newsrv->pp_opts |= SRV_PP_V2_SSL;
6628 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6629 return 0;
6630}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006631
Willy Tarreau732eac42015-07-09 11:40:25 +02006632/* parse the "sni" server keyword */
6633static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6634{
6635#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6636 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6637 return ERR_ALERT | ERR_FATAL;
6638#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006639 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02006640
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006641 arg = args[*cur_arg + 1];
6642 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02006643 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6644 return ERR_ALERT | ERR_FATAL;
6645 }
6646
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006647 free(newsrv->sni_expr);
6648 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02006649
Willy Tarreau732eac42015-07-09 11:40:25 +02006650 return 0;
6651#endif
6652}
6653
Willy Tarreau92faadf2012-10-10 23:04:25 +02006654/* parse the "ssl" server keyword */
6655static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6656{
6657 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006658 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6659 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006660 return 0;
6661}
6662
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01006663/* parse the "ssl-reuse" server keyword */
6664static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6665{
6666 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
6667 return 0;
6668}
6669
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01006670/* parse the "tls-tickets" server keyword */
6671static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6672{
6673 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
6674 return 0;
6675}
6676
Emeric Brunef42d922012-10-11 16:11:36 +02006677/* parse the "verify" server keyword */
6678static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6679{
6680 if (!*args[*cur_arg + 1]) {
6681 if (err)
6682 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6683 return ERR_ALERT | ERR_FATAL;
6684 }
6685
6686 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006687 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006688 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006689 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006690 else {
6691 if (err)
6692 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6693 args[*cur_arg], args[*cur_arg + 1]);
6694 return ERR_ALERT | ERR_FATAL;
6695 }
6696
Evan Broderbe554312013-06-27 00:05:25 -07006697 return 0;
6698}
6699
6700/* parse the "verifyhost" server keyword */
6701static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6702{
6703 if (!*args[*cur_arg + 1]) {
6704 if (err)
6705 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6706 return ERR_ALERT | ERR_FATAL;
6707 }
6708
Frédéric Lécaille273f3212017-03-13 15:52:01 +01006709 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07006710 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6711
Emeric Brunef42d922012-10-11 16:11:36 +02006712 return 0;
6713}
6714
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006715/* parse the "ssl-default-bind-options" keyword in global section */
6716static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6717 struct proxy *defpx, const char *file, int line,
6718 char **err) {
6719 int i = 1;
6720
6721 if (*(args[i]) == 0) {
6722 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6723 return -1;
6724 }
6725 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006726 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006727 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Lukas Tribus53ae85c2017-05-04 15:45:40 +00006728 else if (!strcmp(args[i], "prefer-client-ciphers"))
6729 global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006730 else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006731 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6732 return -1;
6733 }
6734 i++;
6735 }
6736 return 0;
6737}
6738
6739/* parse the "ssl-default-server-options" keyword in global section */
6740static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6741 struct proxy *defpx, const char *file, int line,
6742 char **err) {
6743 int i = 1;
6744
6745 if (*(args[i]) == 0) {
6746 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6747 return -1;
6748 }
6749 while (*(args[i])) {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006750 if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006751 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02006752 else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods)) {
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006753 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6754 return -1;
6755 }
6756 i++;
6757 }
6758 return 0;
6759}
6760
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006761/* parse the "ca-base" / "crt-base" keywords in global section.
6762 * Returns <0 on alert, >0 on warning, 0 on success.
6763 */
6764static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6765 struct proxy *defpx, const char *file, int line,
6766 char **err)
6767{
6768 char **target;
6769
Willy Tarreauef934602016-12-22 23:12:01 +01006770 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006771
6772 if (too_many_args(1, args, err, NULL))
6773 return -1;
6774
6775 if (*target) {
6776 memprintf(err, "'%s' already specified.", args[0]);
6777 return -1;
6778 }
6779
6780 if (*(args[1]) == 0) {
6781 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6782 return -1;
6783 }
6784 *target = strdup(args[1]);
6785 return 0;
6786}
6787
Willy Tarreauf22e9682016-12-21 23:23:19 +01006788/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6789 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6790 */
6791static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6792 struct proxy *defpx, const char *file, int line,
6793 char **err)
6794{
6795 char **target;
6796
Willy Tarreauef934602016-12-22 23:12:01 +01006797 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006798
6799 if (too_many_args(1, args, err, NULL))
6800 return -1;
6801
6802 if (*(args[1]) == 0) {
6803 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6804 return -1;
6805 }
6806
6807 free(*target);
6808 *target = strdup(args[1]);
6809 return 0;
6810}
6811
Willy Tarreau9ceda382016-12-21 23:13:03 +01006812/* parse various global tune.ssl settings consisting in positive integers.
6813 * Returns <0 on alert, >0 on warning, 0 on success.
6814 */
6815static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6816 struct proxy *defpx, const char *file, int line,
6817 char **err)
6818{
6819 int *target;
6820
6821 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6822 target = &global.tune.sslcachesize;
6823 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006824 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006825 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006826 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006827 else if (strcmp(args[0], "maxsslconn") == 0)
6828 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006829 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
6830 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006831 else {
6832 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6833 return -1;
6834 }
6835
6836 if (too_many_args(1, args, err, NULL))
6837 return -1;
6838
6839 if (*(args[1]) == 0) {
6840 memprintf(err, "'%s' expects an integer argument.", args[0]);
6841 return -1;
6842 }
6843
6844 *target = atoi(args[1]);
6845 if (*target < 0) {
6846 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6847 return -1;
6848 }
6849 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006850}
6851
6852static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
6853 struct proxy *defpx, const char *file, int line,
6854 char **err)
6855{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006856 int ret;
6857
6858 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
6859 if (ret != 0)
6860 return ret;
6861
6862 if (pool2_ssl_capture) {
6863 memprintf(err, "'%s' is already configured.", args[0]);
6864 return -1;
6865 }
6866
6867 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
6868 if (!pool2_ssl_capture) {
6869 memprintf(err, "Out of memory error.");
6870 return -1;
6871 }
6872 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006873}
6874
6875/* parse "ssl.force-private-cache".
6876 * Returns <0 on alert, >0 on warning, 0 on success.
6877 */
6878static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6879 struct proxy *defpx, const char *file, int line,
6880 char **err)
6881{
6882 if (too_many_args(0, args, err, NULL))
6883 return -1;
6884
Willy Tarreauef934602016-12-22 23:12:01 +01006885 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006886 return 0;
6887}
6888
6889/* parse "ssl.lifetime".
6890 * Returns <0 on alert, >0 on warning, 0 on success.
6891 */
6892static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6893 struct proxy *defpx, const char *file, int line,
6894 char **err)
6895{
6896 const char *res;
6897
6898 if (too_many_args(1, args, err, NULL))
6899 return -1;
6900
6901 if (*(args[1]) == 0) {
6902 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6903 return -1;
6904 }
6905
Willy Tarreauef934602016-12-22 23:12:01 +01006906 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006907 if (res) {
6908 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6909 return -1;
6910 }
6911 return 0;
6912}
6913
6914#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006915/* parse "ssl-dh-param-file".
6916 * Returns <0 on alert, >0 on warning, 0 on success.
6917 */
6918static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6919 struct proxy *defpx, const char *file, int line,
6920 char **err)
6921{
6922 if (too_many_args(1, args, err, NULL))
6923 return -1;
6924
6925 if (*(args[1]) == 0) {
6926 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6927 return -1;
6928 }
6929
6930 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6931 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6932 return -1;
6933 }
6934 return 0;
6935}
6936
Willy Tarreau9ceda382016-12-21 23:13:03 +01006937/* parse "ssl.default-dh-param".
6938 * Returns <0 on alert, >0 on warning, 0 on success.
6939 */
6940static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6941 struct proxy *defpx, const char *file, int line,
6942 char **err)
6943{
6944 if (too_many_args(1, args, err, NULL))
6945 return -1;
6946
6947 if (*(args[1]) == 0) {
6948 memprintf(err, "'%s' expects an integer argument.", args[0]);
6949 return -1;
6950 }
6951
Willy Tarreauef934602016-12-22 23:12:01 +01006952 global_ssl.default_dh_param = atoi(args[1]);
6953 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006954 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6955 return -1;
6956 }
6957 return 0;
6958}
6959#endif
6960
6961
William Lallemand32af2032016-10-29 18:09:35 +02006962/* This function is used with TLS ticket keys management. It permits to browse
6963 * each reference. The variable <getnext> must contain the current node,
6964 * <end> point to the root node.
6965 */
6966#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6967static inline
6968struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6969{
6970 struct tls_keys_ref *ref = getnext;
6971
6972 while (1) {
6973
6974 /* Get next list entry. */
6975 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6976
6977 /* If the entry is the last of the list, return NULL. */
6978 if (&ref->list == end)
6979 return NULL;
6980
6981 return ref;
6982 }
6983}
6984
6985static inline
6986struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6987{
6988 int id;
6989 char *error;
6990
6991 /* If the reference starts by a '#', this is numeric id. */
6992 if (reference[0] == '#') {
6993 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6994 id = strtol(reference + 1, &error, 10);
6995 if (*error != '\0')
6996 return NULL;
6997
6998 /* Perform the unique id lookup. */
6999 return tlskeys_ref_lookupid(id);
7000 }
7001
7002 /* Perform the string lookup. */
7003 return tlskeys_ref_lookup(reference);
7004}
7005#endif
7006
7007
7008#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7009
7010static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7011
7012static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7013 return cli_io_handler_tlskeys_files(appctx);
7014}
7015
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007016/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7017 * (next index to be dumped), and cli.p0 (next key reference).
7018 */
William Lallemand32af2032016-10-29 18:09:35 +02007019static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7020
7021 struct stream_interface *si = appctx->owner;
7022
7023 switch (appctx->st2) {
7024 case STAT_ST_INIT:
7025 /* Display the column headers. If the message cannot be sent,
7026 * quit the fucntion with returning 0. The function is called
7027 * later and restart at the state "STAT_ST_INIT".
7028 */
7029 chunk_reset(&trash);
7030
7031 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7032 chunk_appendf(&trash, "# id secret\n");
7033 else
7034 chunk_appendf(&trash, "# id (file)\n");
7035
7036 if (bi_putchk(si_ic(si), &trash) == -1) {
7037 si_applet_cant_put(si);
7038 return 0;
7039 }
7040
William Lallemand32af2032016-10-29 18:09:35 +02007041 /* Now, we start the browsing of the references lists.
7042 * Note that the following call to LIST_ELEM return bad pointer. The only
7043 * available field of this pointer is <list>. It is used with the function
7044 * tlskeys_list_get_next() for retruning the first available entry
7045 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007046 if (appctx->ctx.cli.p0 == NULL) {
7047 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7048 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007049 }
7050
7051 appctx->st2 = STAT_ST_LIST;
7052 /* fall through */
7053
7054 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007055 while (appctx->ctx.cli.p0) {
7056 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7057 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007058
7059 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007060 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007061 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007062
7063 if (appctx->ctx.cli.i1 == 0)
7064 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7065
William Lallemand32af2032016-10-29 18:09:35 +02007066 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007067 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007068 struct chunk *t2 = get_trash_chunk();
7069
7070 chunk_reset(t2);
7071 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007072 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007073 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007074 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007075
7076 if (bi_putchk(si_ic(si), &trash) == -1) {
7077 /* let's try again later from this stream. We add ourselves into
7078 * this stream's users so that it can remove us upon termination.
7079 */
7080 si_applet_cant_put(si);
7081 return 0;
7082 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007083 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007084 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007085 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007086 }
7087 if (bi_putchk(si_ic(si), &trash) == -1) {
7088 /* let's try again later from this stream. We add ourselves into
7089 * this stream's users so that it can remove us upon termination.
7090 */
7091 si_applet_cant_put(si);
7092 return 0;
7093 }
7094
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007095 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007096 break;
7097
7098 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007099 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007100 }
7101
7102 appctx->st2 = STAT_ST_FIN;
7103 /* fall through */
7104
7105 default:
7106 appctx->st2 = STAT_ST_FIN;
7107 return 1;
7108 }
7109 return 0;
7110}
7111
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007112/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007113static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7114{
William Lallemand32af2032016-10-29 18:09:35 +02007115 /* no parameter, shows only file list */
7116 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007117 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007118 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007119 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007120 }
7121
7122 if (args[2][0] == '*') {
7123 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007124 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007125 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007126 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7127 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007128 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007129 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007130 return 1;
7131 }
7132 }
William Lallemand32af2032016-10-29 18:09:35 +02007133 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007134 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007135}
7136
William Lallemand32af2032016-10-29 18:09:35 +02007137static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7138{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007139 struct tls_keys_ref *ref;
7140
William Lallemand32af2032016-10-29 18:09:35 +02007141 /* Expect two parameters: the filename and the new new TLS key in encoding */
7142 if (!*args[3] || !*args[4]) {
7143 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 +01007144 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007145 return 1;
7146 }
7147
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007148 ref = tlskeys_ref_lookup_ref(args[3]);
7149 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007150 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007151 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007152 return 1;
7153 }
7154
7155 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7156 if (trash.len != sizeof(struct tls_sess_key)) {
7157 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007158 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007159 return 1;
7160 }
7161
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007162 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7163 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007164
7165 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007166 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007167 return 1;
7168
7169}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007170#endif
William Lallemand32af2032016-10-29 18:09:35 +02007171
7172static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7173{
7174#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7175 char *err = NULL;
7176
7177 /* Expect one parameter: the new response in base64 encoding */
7178 if (!*args[3]) {
7179 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007180 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007181 return 1;
7182 }
7183
7184 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7185 if (trash.len < 0) {
7186 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007187 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007188 return 1;
7189 }
7190
7191 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7192 if (err) {
7193 memprintf(&err, "%s.\n", err);
7194 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007195 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007196 }
7197 return 1;
7198 }
7199 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007200 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007201 return 1;
7202#else
7203 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 +01007204 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007205 return 1;
7206#endif
7207
7208}
7209
7210/* register cli keywords */
7211static struct cli_kw_list cli_kws = {{ },{
7212#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7213 { { "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 },
7214 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007215#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007216 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007217 { { NULL }, NULL, NULL, NULL }
7218}};
7219
7220
Willy Tarreau7875d092012-09-10 08:20:03 +02007221/* Note: must not be declared <const> as its list will be overwritten.
7222 * Please take care of keeping this list alphabetically sorted.
7223 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007224static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007225 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007226 { "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 +02007227 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7228 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007229 { "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 +02007230 { "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 +02007231 { "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 +02007232 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7233 { "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 +01007234 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007235 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007236 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7237 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7238 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7239 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7240 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7241 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7242 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7243 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007244 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007245 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7246 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007247 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007248 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7249 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7250 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7251 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7252 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7253 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7254 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007255 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007256 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007257 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007258 { "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 +01007259 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007260 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7261 { "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 +02007262 { "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 +02007263#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007264 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007265#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007266#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007267 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007268#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007269 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007270 { "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 +02007271 { "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 +01007272 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7273 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007274 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7275 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7276 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7277 { "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 +02007278 { NULL, NULL, 0, 0, 0 },
7279}};
7280
7281/* Note: must not be declared <const> as its list will be overwritten.
7282 * Please take care of keeping this list alphabetically sorted.
7283 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007284static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007285 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7286 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007287 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007288}};
7289
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007290/* Note: must not be declared <const> as its list will be overwritten.
7291 * Please take care of keeping this list alphabetically sorted, doing so helps
7292 * all code contributors.
7293 * Optional keywords are also declared with a NULL ->parse() function so that
7294 * the config parser can report an appropriate error when a known keyword was
7295 * not enabled.
7296 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007297static struct ssl_bind_kw ssl_bind_kws[] = {
7298 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7299 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7300 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7301 { "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 +01007302 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007303 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007304 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7305 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7306 { NULL, NULL, 0 },
7307};
7308
Willy Tarreau51fb7652012-09-18 18:24:39 +02007309static struct bind_kw_list bind_kws = { "SSL", { }, {
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007310 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7311 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7312 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
7313 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7314 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
7315 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7316 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7317 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7318 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7319 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
7320 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
7321 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7322 { "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
7323 { "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
7324 { "force-tlsv11", bind_parse_tls_method_options, 0 }, /* force TLSv11 */
7325 { "force-tlsv12", bind_parse_tls_method_options, 0 }, /* force TLSv12 */
7326 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
7327 { "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
7328 { "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
7329 { "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
7330 { "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
7331 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7332 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
7333 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7334 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7335 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7336 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
7337 { "prefer-client-ciphers", bind_parse_pcc, 0 }, /* prefer client ciphers */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007338 { NULL, NULL, 0 },
7339}};
Emeric Brun46591952012-05-18 15:47:34 +02007340
Willy Tarreau92faadf2012-10-10 23:04:25 +02007341/* Note: must not be declared <const> as its list will be overwritten.
7342 * Please take care of keeping this list alphabetically sorted, doing so helps
7343 * all code contributors.
7344 * Optional keywords are also declared with a NULL ->parse() function so that
7345 * the config parser can report an appropriate error when a known keyword was
7346 * not enabled.
7347 */
7348static struct srv_kw_list srv_kws = { "SSL", { }, {
Frédéric Lécaille5e576432017-03-14 15:52:04 +01007349 { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
Frédéric Lécaille18388c92017-03-13 13:10:59 +01007350 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
Frédéric Lécaillebcaf1d72017-03-15 16:20:02 +01007351 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
Frédéric Lécaille5e576432017-03-14 15:52:04 +01007352 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
7353 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007354 { "force-sslv3", srv_parse_tls_method_options,0, 1 }, /* force SSLv3 */
7355 { "force-tlsv10", srv_parse_tls_method_options,0, 1 }, /* force TLSv10 */
7356 { "force-tlsv11", srv_parse_tls_method_options,0, 1 }, /* force TLSv11 */
7357 { "force-tlsv12", srv_parse_tls_method_options,0, 1 }, /* force TLSv12 */
Frédéric Lécaille18388c92017-03-13 13:10:59 +01007358 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01007359 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
7360 { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
Frédéric Lécaille18388c92017-03-13 13:10:59 +01007361 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
7362 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
Emmanuel Hocdet5db33cb2017-03-30 19:19:37 +02007363 { "no-sslv3", srv_parse_tls_method_options,0, 0 }, /* disable SSLv3 */
7364 { "no-tlsv10", srv_parse_tls_method_options,0, 0 }, /* disable TLSv10 */
7365 { "no-tlsv11", srv_parse_tls_method_options,0, 0 }, /* disable TLSv11 */
7366 { "no-tlsv12", srv_parse_tls_method_options,0, 0 }, /* disable TLSv12 */
Frédéric Lécaille18388c92017-03-13 13:10:59 +01007367 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
7368 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
7369 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01007370 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
Frédéric Lécaille18388c92017-03-13 13:10:59 +01007371 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
7372 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
Frédéric Lécaille18388c92017-03-13 13:10:59 +01007373 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
Frédéric Lécaille7c8cd582017-03-13 13:41:16 +01007374 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
Frédéric Lécaille273f3212017-03-13 15:52:01 +01007375 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007376 { NULL, NULL, 0, 0 },
7377}};
7378
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007379static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007380 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7381 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007382 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007383 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7384 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007385#ifndef OPENSSL_NO_DH
7386 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7387#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007388 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7389#ifndef OPENSSL_NO_DH
7390 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7391#endif
7392 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7393 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7394 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7395 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007396 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007397 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7398 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007399 { 0, NULL, NULL },
7400}};
7401
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007402/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007403static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007404 .snd_buf = ssl_sock_from_buf,
7405 .rcv_buf = ssl_sock_to_buf,
7406 .rcv_pipe = NULL,
7407 .snd_pipe = NULL,
7408 .shutr = NULL,
7409 .shutw = ssl_sock_shutw,
7410 .close = ssl_sock_close,
7411 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007412 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007413 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007414 .prepare_srv = ssl_sock_prepare_srv_ctx,
7415 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007416 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007417};
7418
Daniel Jakots54ffb912015-11-06 20:02:41 +01007419#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007420
7421static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7422{
7423 if (ptr) {
7424 chunk_destroy(ptr);
7425 free(ptr);
7426 }
7427}
7428
7429#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007430static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7431{
7432 pool_free2(pool2_ssl_capture, ptr);
7433}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007434
Emeric Brun46591952012-05-18 15:47:34 +02007435__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007436static void __ssl_sock_init(void)
7437{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007438 char *ptr;
7439
Emeric Brun46591952012-05-18 15:47:34 +02007440 STACK_OF(SSL_COMP)* cm;
7441
Willy Tarreauef934602016-12-22 23:12:01 +01007442 if (global_ssl.listen_default_ciphers)
7443 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7444 if (global_ssl.connect_default_ciphers)
7445 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007446
Willy Tarreau13e14102016-12-22 20:25:26 +01007447 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007448 SSL_library_init();
7449 cm = SSL_COMP_get_compression_methods();
7450 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007451#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007452 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7453#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007454 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 +02007455 sample_register_fetches(&sample_fetch_keywords);
7456 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007457 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007458 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007459 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007460 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007461#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7462 hap_register_post_check(tlskeys_finalize_config);
7463#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007464
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007465 ptr = NULL;
7466 memprintf(&ptr, "Built with OpenSSL version : "
7467#ifdef OPENSSL_IS_BORINGSSL
7468 "BoringSSL\n");
7469#else /* OPENSSL_IS_BORINGSSL */
7470 OPENSSL_VERSION_TEXT
7471 "\nRunning on OpenSSL version : %s%s",
7472 SSLeay_version(SSLEAY_VERSION),
7473 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7474#endif
7475 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7476#if OPENSSL_VERSION_NUMBER < 0x00907000L
7477 "no (library version too old)"
7478#elif defined(OPENSSL_NO_TLSEXT)
7479 "no (disabled via OPENSSL_NO_TLSEXT)"
7480#else
7481 "yes"
7482#endif
7483 "", ptr);
7484
7485 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7486#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7487 "yes"
7488#else
7489#ifdef OPENSSL_NO_TLSEXT
7490 "no (because of OPENSSL_NO_TLSEXT)"
7491#else
7492 "no (version might be too old, 0.9.8f min needed)"
7493#endif
7494#endif
7495 "", ptr);
7496
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007497 hap_register_build_opts(ptr, 1);
7498
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007499 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7500 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007501
7502#ifndef OPENSSL_NO_DH
7503 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7504#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007505
7506 /* Load SSL string for the verbose & debug mode. */
7507 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007508}
7509
Remi Gacogned3a23c32015-05-28 16:39:47 +02007510__attribute__((destructor))
7511static void __ssl_sock_deinit(void)
7512{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007513#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007514 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007515#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007516
Remi Gacogned3a23c32015-05-28 16:39:47 +02007517#ifndef OPENSSL_NO_DH
7518 if (local_dh_1024) {
7519 DH_free(local_dh_1024);
7520 local_dh_1024 = NULL;
7521 }
7522
7523 if (local_dh_2048) {
7524 DH_free(local_dh_2048);
7525 local_dh_2048 = NULL;
7526 }
7527
7528 if (local_dh_4096) {
7529 DH_free(local_dh_4096);
7530 local_dh_4096 = NULL;
7531 }
7532
Remi Gacogne47783ef2015-05-29 15:53:22 +02007533 if (global_dh) {
7534 DH_free(global_dh);
7535 global_dh = NULL;
7536 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007537#endif
7538
7539 ERR_remove_state(0);
7540 ERR_free_strings();
7541
7542 EVP_cleanup();
7543
7544#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7545 CRYPTO_cleanup_all_ex_data();
7546#endif
7547}
7548
7549
Emeric Brun46591952012-05-18 15:47:34 +02007550/*
7551 * Local variables:
7552 * c-indent-level: 8
7553 * c-basic-offset: 8
7554 * End:
7555 */