blob: 48ad1b26e294c66ef1f90103aa88be542888aaa7 [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
Emeric Brun850efd52014-01-29 12:24:34 +0100123/* server and bind verify method, it uses a global value as default */
124enum {
125 SSL_SOCK_VERIFY_DEFAULT = 0,
126 SSL_SOCK_VERIFY_REQUIRED = 1,
127 SSL_SOCK_VERIFY_OPTIONAL = 2,
128 SSL_SOCK_VERIFY_NONE = 3,
129};
130
Willy Tarreau71b734c2014-01-28 15:19:44 +0100131int sslconns = 0;
132int totalsslconns = 0;
Willy Tarreaud9f5cca2016-12-22 21:08:52 +0100133static struct xprt_ops ssl_sock;
Emeric Brune1f38db2012-09-03 20:36:47 +0200134
Willy Tarreauef934602016-12-22 23:12:01 +0100135static struct {
136 char *crt_base; /* base directory path for certificates */
137 char *ca_base; /* base directory path for CAs and CRLs */
138
139 char *listen_default_ciphers;
140 char *connect_default_ciphers;
141 int listen_default_ssloptions;
142 int connect_default_ssloptions;
143
144 int private_cache; /* Force to use a private session cache even if nbproc > 1 */
145 unsigned int life_time; /* SSL session lifetime in seconds */
146 unsigned int max_record; /* SSL max record size */
147 unsigned int default_dh_param; /* SSL maximum DH parameter size */
148 int ctx_cache; /* max number of entries in the ssl_ctx cache. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100149 int capture_cipherlist; /* Size of the cipherlist buffer. */
Willy Tarreauef934602016-12-22 23:12:01 +0100150} global_ssl = {
151#ifdef LISTEN_DEFAULT_CIPHERS
152 .listen_default_ciphers = LISTEN_DEFAULT_CIPHERS,
153#endif
154#ifdef CONNECT_DEFAULT_CIPHERS
155 .connect_default_ciphers = CONNECT_DEFAULT_CIPHERS,
156#endif
157 .listen_default_ssloptions = BC_SSL_O_NONE,
158 .connect_default_ssloptions = SRV_SSL_O_NONE,
159
160#ifdef DEFAULT_SSL_MAX_RECORD
161 .max_record = DEFAULT_SSL_MAX_RECORD,
162#endif
163 .default_dh_param = SSL_DEFAULT_DH_PARAM,
164 .ctx_cache = DEFAULT_SSL_CTX_CACHE,
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100165 .capture_cipherlist = 0,
Willy Tarreauef934602016-12-22 23:12:01 +0100166};
167
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100168/* This memory pool is used for capturing clienthello parameters. */
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100169struct ssl_capture {
Thierry FOURNIER5bf77322017-02-25 12:45:22 +0100170 unsigned long long int xxh64;
171 unsigned char ciphersuite_len;
172 char ciphersuite[0];
173};
174struct pool_head *pool2_ssl_capture = NULL;
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +0100175static int ssl_capture_ptr_index = -1;
Willy Tarreauef934602016-12-22 23:12:01 +0100176
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200177#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
178struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
179#endif
180
Remi Gacogne8de54152014-07-15 11:36:40 +0200181#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200182static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200183static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200184static DH *local_dh_1024 = NULL;
185static DH *local_dh_2048 = NULL;
186static DH *local_dh_4096 = NULL;
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +0100187static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
Remi Gacogne8de54152014-07-15 11:36:40 +0200188#endif /* OPENSSL_NO_DH */
189
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100190#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +0200191/* X509V3 Extensions that will be added on generated certificates */
192#define X509V3_EXT_SIZE 5
193static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
194 "basicConstraints",
195 "nsComment",
196 "subjectKeyIdentifier",
197 "authorityKeyIdentifier",
198 "keyUsage",
199};
200static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
201 "CA:FALSE",
202 "\"OpenSSL Generated Certificate\"",
203 "hash",
204 "keyid,issuer:always",
205 "nonRepudiation,digitalSignature,keyEncipherment"
206};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200207/* LRU cache to store generated certificate */
208static struct lru64_head *ssl_ctx_lru_tree = NULL;
209static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200210#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
211
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100212static struct ssl_bind_kw ssl_bind_kws[];
213
yanbzhube2774d2015-12-10 15:07:30 -0500214#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
215/* The order here matters for picking a default context,
216 * keep the most common keytype at the bottom of the list
217 */
218const char *SSL_SOCK_KEYTYPE_NAMES[] = {
219 "dsa",
220 "ecdsa",
221 "rsa"
222};
223#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100224#else
225#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500226#endif
227
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100228/*
229 * This function gives the detail of the SSL error. It is used only
230 * if the debug mode and the verbose mode are activated. It dump all
231 * the SSL error until the stack was empty.
232 */
233static forceinline void ssl_sock_dump_errors(struct connection *conn)
234{
235 unsigned long ret;
236
237 if (unlikely(global.mode & MODE_DEBUG)) {
238 while(1) {
239 ret = ERR_get_error();
240 if (ret == 0)
241 return;
242 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
243 (unsigned short)conn->t.sock.fd, ret,
244 ERR_func_error_string(ret), ERR_reason_error_string(ret));
245 }
246 }
247}
248
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200249#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500250/*
251 * struct alignment works here such that the key.key is the same as key_data
252 * Do not change the placement of key_data
253 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200254struct certificate_ocsp {
255 struct ebmb_node key;
256 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
257 struct chunk response;
258 long expire;
259};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200260
yanbzhube2774d2015-12-10 15:07:30 -0500261struct ocsp_cbk_arg {
262 int is_single;
263 int single_kt;
264 union {
265 struct certificate_ocsp *s_ocsp;
266 /*
267 * m_ocsp will have multiple entries dependent on key type
268 * Entry 0 - DSA
269 * Entry 1 - ECDSA
270 * Entry 2 - RSA
271 */
272 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
273 };
274};
275
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200276/*
277 * This function returns the number of seconds elapsed
278 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
279 * date presented un ASN1_GENERALIZEDTIME.
280 *
281 * In parsing error case, it returns -1.
282 */
283static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
284{
285 long epoch;
286 char *p, *end;
287 const unsigned short month_offset[12] = {
288 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
289 };
290 int year, month;
291
292 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
293
294 p = (char *)d->data;
295 end = p + d->length;
296
297 if (end - p < 4) return -1;
298 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
299 p += 4;
300 if (end - p < 2) return -1;
301 month = 10 * (p[0] - '0') + p[1] - '0';
302 if (month < 1 || month > 12) return -1;
303 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
304 We consider leap years and the current month (<marsh or not) */
305 epoch = ( ((year - 1970) * 365)
306 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
307 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
308 + month_offset[month-1]
309 ) * 24 * 60 * 60;
310 p += 2;
311 if (end - p < 2) return -1;
312 /* Add the number of seconds of completed days of current month */
313 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
314 p += 2;
315 if (end - p < 2) return -1;
316 /* Add the completed hours of the current day */
317 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
318 p += 2;
319 if (end - p < 2) return -1;
320 /* Add the completed minutes of the current hour */
321 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
322 p += 2;
323 if (p == end) return -1;
324 /* Test if there is available seconds */
325 if (p[0] < '0' || p[0] > '9')
326 goto nosec;
327 if (end - p < 2) return -1;
328 /* Add the seconds of the current minute */
329 epoch += 10 * (p[0] - '0') + p[1] - '0';
330 p += 2;
331 if (p == end) return -1;
332 /* Ignore seconds float part if present */
333 if (p[0] == '.') {
334 do {
335 if (++p == end) return -1;
336 } while (p[0] >= '0' && p[0] <= '9');
337 }
338
339nosec:
340 if (p[0] == 'Z') {
341 if (end - p != 1) return -1;
342 return epoch;
343 }
344 else if (p[0] == '+') {
345 if (end - p != 5) return -1;
346 /* Apply timezone offset */
347 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
348 }
349 else if (p[0] == '-') {
350 if (end - p != 5) return -1;
351 /* Apply timezone offset */
352 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
353 }
354
355 return -1;
356}
357
Emeric Brun1d3865b2014-06-20 15:37:32 +0200358static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200359
360/* This function starts to check if the OCSP response (in DER format) contained
361 * in chunk 'ocsp_response' is valid (else exits on error).
362 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
363 * contained in the OCSP Response and exits on error if no match.
364 * If it's a valid OCSP Response:
365 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
366 * pointed by 'ocsp'.
367 * If 'ocsp' is NULL, the function looks up into the OCSP response's
368 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
369 * from the response) and exits on error if not found. Finally, If an OCSP response is
370 * already present in the container, it will be overwritten.
371 *
372 * Note: OCSP response containing more than one OCSP Single response is not
373 * considered valid.
374 *
375 * Returns 0 on success, 1 in error case.
376 */
377static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
378{
379 OCSP_RESPONSE *resp;
380 OCSP_BASICRESP *bs = NULL;
381 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200382 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200383 unsigned char *p = (unsigned char *)ocsp_response->str;
384 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200385 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200386 int reason;
387 int ret = 1;
388
389 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
390 if (!resp) {
391 memprintf(err, "Unable to parse OCSP response");
392 goto out;
393 }
394
395 rc = OCSP_response_status(resp);
396 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
397 memprintf(err, "OCSP response status not successful");
398 goto out;
399 }
400
401 bs = OCSP_response_get1_basic(resp);
402 if (!bs) {
403 memprintf(err, "Failed to get basic response from OCSP Response");
404 goto out;
405 }
406
407 count_sr = OCSP_resp_count(bs);
408 if (count_sr > 1) {
409 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
410 goto out;
411 }
412
413 sr = OCSP_resp_get0(bs, 0);
414 if (!sr) {
415 memprintf(err, "Failed to get OCSP single response");
416 goto out;
417 }
418
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200419 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
420
Emeric Brun4147b2e2014-06-16 18:36:30 +0200421 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
422 if (rc != V_OCSP_CERTSTATUS_GOOD) {
423 memprintf(err, "OCSP single response: certificate status not good");
424 goto out;
425 }
426
Emeric Brun13a6b482014-06-20 15:44:34 +0200427 if (!nextupd) {
428 memprintf(err, "OCSP single response: missing nextupdate");
429 goto out;
430 }
431
Emeric Brunc8b27b62014-06-19 14:16:17 +0200432 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200433 if (!rc) {
434 memprintf(err, "OCSP single response: no longer valid.");
435 goto out;
436 }
437
438 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200439 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200440 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
441 goto out;
442 }
443 }
444
445 if (!ocsp) {
446 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
447 unsigned char *p;
448
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200449 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200450 if (!rc) {
451 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
452 goto out;
453 }
454
455 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
456 memprintf(err, "OCSP single response: Certificate ID too long");
457 goto out;
458 }
459
460 p = key;
461 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200462 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200463 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
464 if (!ocsp) {
465 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
466 goto out;
467 }
468 }
469
470 /* According to comments on "chunk_dup", the
471 previous chunk buffer will be freed */
472 if (!chunk_dup(&ocsp->response, ocsp_response)) {
473 memprintf(err, "OCSP response: Memory allocation error");
474 goto out;
475 }
476
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200477 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
478
Emeric Brun4147b2e2014-06-16 18:36:30 +0200479 ret = 0;
480out:
Janusz Dziemidowicz8d710492017-03-08 16:59:41 +0100481 ERR_clear_error();
482
Emeric Brun4147b2e2014-06-16 18:36:30 +0200483 if (bs)
484 OCSP_BASICRESP_free(bs);
485
486 if (resp)
487 OCSP_RESPONSE_free(resp);
488
489 return ret;
490}
491/*
492 * External function use to update the OCSP response in the OCSP response's
493 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
494 * to update in DER format.
495 *
496 * Returns 0 on success, 1 in error case.
497 */
498int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
499{
500 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
501}
502
503/*
504 * This function load the OCSP Resonse in DER format contained in file at
505 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
506 *
507 * Returns 0 on success, 1 in error case.
508 */
509static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
510{
511 int fd = -1;
512 int r = 0;
513 int ret = 1;
514
515 fd = open(ocsp_path, O_RDONLY);
516 if (fd == -1) {
517 memprintf(err, "Error opening OCSP response file");
518 goto end;
519 }
520
521 trash.len = 0;
522 while (trash.len < trash.size) {
523 r = read(fd, trash.str + trash.len, trash.size - trash.len);
524 if (r < 0) {
525 if (errno == EINTR)
526 continue;
527
528 memprintf(err, "Error reading OCSP response from file");
529 goto end;
530 }
531 else if (r == 0) {
532 break;
533 }
534 trash.len += r;
535 }
536
537 close(fd);
538 fd = -1;
539
540 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
541end:
542 if (fd != -1)
543 close(fd);
544
545 return ret;
546}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100547#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200548
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100549#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
550static 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)
551{
552 struct tls_sess_key *keys;
553 struct connection *conn;
554 int head;
555 int i;
556
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200557 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200558 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
559 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100560
561 if (enc) {
562 memcpy(key_name, keys[head].name, 16);
563
564 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
565 return -1;
566
567 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
568 return -1;
569
570 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
571
572 return 1;
573 } else {
574 for (i = 0; i < TLS_TICKETS_NO; i++) {
575 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
576 goto found;
577 }
578 return 0;
579
580 found:
581 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
582 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
583 return -1;
584 /* 2 for key renewal, 1 if current key is still valid */
585 return i ? 2 : 1;
586 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200587}
588
589struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
590{
591 struct tls_keys_ref *ref;
592
593 list_for_each_entry(ref, &tlskeys_reference, list)
594 if (ref->filename && strcmp(filename, ref->filename) == 0)
595 return ref;
596 return NULL;
597}
598
599struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
600{
601 struct tls_keys_ref *ref;
602
603 list_for_each_entry(ref, &tlskeys_reference, list)
604 if (ref->unique_id == unique_id)
605 return ref;
606 return NULL;
607}
608
609int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
610 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
611
612 if(!ref) {
613 memprintf(err, "Unable to locate the referenced filename: %s", filename);
614 return 1;
615 }
616
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530617 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
618 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200619
620 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100621}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200622
623/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100624 * automatic ids. It's called just after the basic checks. It returns
625 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200626 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100627static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200628{
629 int i = 0;
630 struct tls_keys_ref *ref, *ref2, *ref3;
631 struct list tkr = LIST_HEAD_INIT(tkr);
632
633 list_for_each_entry(ref, &tlskeys_reference, list) {
634 if (ref->unique_id == -1) {
635 /* Look for the first free id. */
636 while (1) {
637 list_for_each_entry(ref2, &tlskeys_reference, list) {
638 if (ref2->unique_id == i) {
639 i++;
640 break;
641 }
642 }
643 if (&ref2->list == &tlskeys_reference)
644 break;
645 }
646
647 /* Uses the unique id and increment it for the next entry. */
648 ref->unique_id = i;
649 i++;
650 }
651 }
652
653 /* This sort the reference list by id. */
654 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
655 LIST_DEL(&ref->list);
656 list_for_each_entry(ref3, &tkr, list) {
657 if (ref->unique_id < ref3->unique_id) {
658 LIST_ADDQ(&ref3->list, &ref->list);
659 break;
660 }
661 }
662 if (&ref3->list == &tkr)
663 LIST_ADDQ(&tkr, &ref->list);
664 }
665
666 /* swap root */
667 LIST_ADD(&tkr, &tlskeys_reference);
668 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100669 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200670}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100671#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
672
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100673#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500674int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
675{
676 switch (evp_keytype) {
677 case EVP_PKEY_RSA:
678 return 2;
679 case EVP_PKEY_DSA:
680 return 0;
681 case EVP_PKEY_EC:
682 return 1;
683 }
684
685 return -1;
686}
687
Emeric Brun4147b2e2014-06-16 18:36:30 +0200688/*
689 * Callback used to set OCSP status extension content in server hello.
690 */
691int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
692{
yanbzhube2774d2015-12-10 15:07:30 -0500693 struct certificate_ocsp *ocsp;
694 struct ocsp_cbk_arg *ocsp_arg;
695 char *ssl_buf;
696 EVP_PKEY *ssl_pkey;
697 int key_type;
698 int index;
699
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200700 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500701
702 ssl_pkey = SSL_get_privatekey(ssl);
703 if (!ssl_pkey)
704 return SSL_TLSEXT_ERR_NOACK;
705
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200706 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500707
708 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
709 ocsp = ocsp_arg->s_ocsp;
710 else {
711 /* For multiple certs per context, we have to find the correct OCSP response based on
712 * the certificate type
713 */
714 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
715
716 if (index < 0)
717 return SSL_TLSEXT_ERR_NOACK;
718
719 ocsp = ocsp_arg->m_ocsp[index];
720
721 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200722
723 if (!ocsp ||
724 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200725 !ocsp->response.len ||
726 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200727 return SSL_TLSEXT_ERR_NOACK;
728
729 ssl_buf = OPENSSL_malloc(ocsp->response.len);
730 if (!ssl_buf)
731 return SSL_TLSEXT_ERR_NOACK;
732
733 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
734 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
735
736 return SSL_TLSEXT_ERR_OK;
737}
738
739/*
740 * This function enables the handling of OCSP status extension on 'ctx' if a
741 * file name 'cert_path' suffixed using ".ocsp" is present.
742 * To enable OCSP status extension, the issuer's certificate is mandatory.
743 * It should be present in the certificate's extra chain builded from file
744 * 'cert_path'. If not found, the issuer certificate is loaded from a file
745 * named 'cert_path' suffixed using '.issuer'.
746 *
747 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
748 * response. If file is empty or content is not a valid OCSP response,
749 * OCSP status extension is enabled but OCSP response is ignored (a warning
750 * is displayed).
751 *
752 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
753 * succesfully enabled, or -1 in other error case.
754 */
755static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
756{
757
758 BIO *in = NULL;
759 X509 *x, *xi = NULL, *issuer = NULL;
760 STACK_OF(X509) *chain = NULL;
761 OCSP_CERTID *cid = NULL;
762 SSL *ssl;
763 char ocsp_path[MAXPATHLEN+1];
764 int i, ret = -1;
765 struct stat st;
766 struct certificate_ocsp *ocsp = NULL, *iocsp;
767 char *warn = NULL;
768 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200769 pem_password_cb *passwd_cb;
770 void *passwd_cb_userdata;
771 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200772
773 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
774
775 if (stat(ocsp_path, &st))
776 return 1;
777
778 ssl = SSL_new(ctx);
779 if (!ssl)
780 goto out;
781
782 x = SSL_get_certificate(ssl);
783 if (!x)
784 goto out;
785
786 /* Try to lookup for issuer in certificate extra chain */
787#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
788 SSL_CTX_get_extra_chain_certs(ctx, &chain);
789#else
790 chain = ctx->extra_certs;
791#endif
792 for (i = 0; i < sk_X509_num(chain); i++) {
793 issuer = sk_X509_value(chain, i);
794 if (X509_check_issued(issuer, x) == X509_V_OK)
795 break;
796 else
797 issuer = NULL;
798 }
799
800 /* If not found try to load issuer from a suffixed file */
801 if (!issuer) {
802 char issuer_path[MAXPATHLEN+1];
803
804 in = BIO_new(BIO_s_file());
805 if (!in)
806 goto out;
807
808 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
809 if (BIO_read_filename(in, issuer_path) <= 0)
810 goto out;
811
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200812 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
813 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
814
815 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200816 if (!xi)
817 goto out;
818
819 if (X509_check_issued(xi, x) != X509_V_OK)
820 goto out;
821
822 issuer = xi;
823 }
824
825 cid = OCSP_cert_to_id(0, x, issuer);
826 if (!cid)
827 goto out;
828
829 i = i2d_OCSP_CERTID(cid, NULL);
830 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
831 goto out;
832
Vincent Bernat02779b62016-04-03 13:48:43 +0200833 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200834 if (!ocsp)
835 goto out;
836
837 p = ocsp->key_data;
838 i2d_OCSP_CERTID(cid, &p);
839
840 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
841 if (iocsp == ocsp)
842 ocsp = NULL;
843
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200844#ifndef SSL_CTX_get_tlsext_status_cb
845# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
846 *cb = (void (*) (void))ctx->tlsext_status_cb;
847#endif
848 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
849
850 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200851 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100852 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500853
854 cb_arg->is_single = 1;
855 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200856
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100857 pkey = X509_get_pubkey(x);
858 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
859 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500860
861 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
862 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
863 } else {
864 /*
865 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
866 * Update that cb_arg with the new cert's staple
867 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200868 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500869 struct certificate_ocsp *tmp_ocsp;
870 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200871 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100872 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200873
874#ifdef SSL_CTX_get_tlsext_status_arg
875 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
876#else
877 cb_arg = ctx->tlsext_status_arg;
878#endif
yanbzhube2774d2015-12-10 15:07:30 -0500879
880 /*
881 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
882 * the order of operations below matter, take care when changing it
883 */
884 tmp_ocsp = cb_arg->s_ocsp;
885 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
886 cb_arg->s_ocsp = NULL;
887 cb_arg->m_ocsp[index] = tmp_ocsp;
888 cb_arg->is_single = 0;
889 cb_arg->single_kt = 0;
890
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100891 pkey = X509_get_pubkey(x);
892 key_type = EVP_PKEY_base_id(pkey);
893 EVP_PKEY_free(pkey);
894
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200895 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500896 if (index >= 0 && !cb_arg->m_ocsp[index])
897 cb_arg->m_ocsp[index] = iocsp;
898
899 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200900
901 ret = 0;
902
903 warn = NULL;
904 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
905 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
906 Warning("%s.\n", warn);
907 }
908
909out:
910 if (ssl)
911 SSL_free(ssl);
912
913 if (in)
914 BIO_free(in);
915
916 if (xi)
917 X509_free(xi);
918
919 if (cid)
920 OCSP_CERTID_free(cid);
921
922 if (ocsp)
923 free(ocsp);
924
925 if (warn)
926 free(warn);
927
928
929 return ret;
930}
931
932#endif
933
Daniel Jakots54ffb912015-11-06 20:02:41 +0100934#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100935
936#define CT_EXTENSION_TYPE 18
937
938static int sctl_ex_index = -1;
939
940/*
941 * Try to parse Signed Certificate Timestamp List structure. This function
942 * makes only basic test if the data seems like SCTL. No signature validation
943 * is performed.
944 */
945static int ssl_sock_parse_sctl(struct chunk *sctl)
946{
947 int ret = 1;
948 int len, pos, sct_len;
949 unsigned char *data;
950
951 if (sctl->len < 2)
952 goto out;
953
954 data = (unsigned char *)sctl->str;
955 len = (data[0] << 8) | data[1];
956
957 if (len + 2 != sctl->len)
958 goto out;
959
960 data = data + 2;
961 pos = 0;
962 while (pos < len) {
963 if (len - pos < 2)
964 goto out;
965
966 sct_len = (data[pos] << 8) | data[pos + 1];
967 if (pos + sct_len + 2 > len)
968 goto out;
969
970 pos += sct_len + 2;
971 }
972
973 ret = 0;
974
975out:
976 return ret;
977}
978
979static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
980{
981 int fd = -1;
982 int r = 0;
983 int ret = 1;
984
985 *sctl = NULL;
986
987 fd = open(sctl_path, O_RDONLY);
988 if (fd == -1)
989 goto end;
990
991 trash.len = 0;
992 while (trash.len < trash.size) {
993 r = read(fd, trash.str + trash.len, trash.size - trash.len);
994 if (r < 0) {
995 if (errno == EINTR)
996 continue;
997
998 goto end;
999 }
1000 else if (r == 0) {
1001 break;
1002 }
1003 trash.len += r;
1004 }
1005
1006 ret = ssl_sock_parse_sctl(&trash);
1007 if (ret)
1008 goto end;
1009
Vincent Bernat02779b62016-04-03 13:48:43 +02001010 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001011 if (!chunk_dup(*sctl, &trash)) {
1012 free(*sctl);
1013 *sctl = NULL;
1014 goto end;
1015 }
1016
1017end:
1018 if (fd != -1)
1019 close(fd);
1020
1021 return ret;
1022}
1023
1024int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1025{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001026 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001027
1028 *out = (unsigned char *)sctl->str;
1029 *outlen = sctl->len;
1030
1031 return 1;
1032}
1033
1034int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1035{
1036 return 1;
1037}
1038
1039static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1040{
1041 char sctl_path[MAXPATHLEN+1];
1042 int ret = -1;
1043 struct stat st;
1044 struct chunk *sctl = NULL;
1045
1046 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1047
1048 if (stat(sctl_path, &st))
1049 return 1;
1050
1051 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1052 goto out;
1053
1054 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1055 free(sctl);
1056 goto out;
1057 }
1058
1059 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1060
1061 ret = 0;
1062
1063out:
1064 return ret;
1065}
1066
1067#endif
1068
Emeric Brune1f38db2012-09-03 20:36:47 +02001069void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1070{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001071 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001072 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001073 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001074
1075 if (where & SSL_CB_HANDSHAKE_START) {
1076 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001077 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001078 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001079 conn->err_code = CO_ER_SSL_RENEG;
1080 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001081 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001082
1083 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1084 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1085 /* Long certificate chains optimz
1086 If write and read bios are differents, we
1087 consider that the buffering was activated,
1088 so we rise the output buffer size from 4k
1089 to 16k */
1090 write_bio = SSL_get_wbio(ssl);
1091 if (write_bio != SSL_get_rbio(ssl)) {
1092 BIO_set_write_buffer_size(write_bio, 16384);
1093 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1094 }
1095 }
1096 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001097}
1098
Emeric Brune64aef12012-09-21 13:15:06 +02001099/* Callback is called for each certificate of the chain during a verify
1100 ok is set to 1 if preverify detect no error on current certificate.
1101 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001102int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001103{
1104 SSL *ssl;
1105 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001106 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001107
1108 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001109 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001110
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001111 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001112
Emeric Brun81c00f02012-09-21 14:31:21 +02001113 if (ok) /* no errors */
1114 return ok;
1115
1116 depth = X509_STORE_CTX_get_error_depth(x_store);
1117 err = X509_STORE_CTX_get_error(x_store);
1118
1119 /* check if CA error needs to be ignored */
1120 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001121 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1122 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1123 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001124 }
1125
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001126 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001127 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001128 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001129 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001130 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001131
Willy Tarreau20879a02012-12-03 16:32:10 +01001132 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001133 return 0;
1134 }
1135
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001136 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1137 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001138
Emeric Brun81c00f02012-09-21 14:31:21 +02001139 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001140 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001141 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001142 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001143 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001144 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001145
Willy Tarreau20879a02012-12-03 16:32:10 +01001146 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001147 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001148}
1149
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001150static inline
1151void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001152 const void *buf, size_t len, SSL *ssl)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001153{
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001154 struct ssl_capture *capture;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001155 unsigned char *msg;
1156 unsigned char *end;
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001157 size_t rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001158
1159 /* This function is called for "from client" and "to server"
1160 * connections. The combination of write_p == 0 and content_type == 22
1161 * is only avalaible during "from client" connection.
1162 */
1163
1164 /* "write_p" is set to 0 is the bytes are received messages,
1165 * otherwise it is set to 1.
1166 */
1167 if (write_p != 0)
1168 return;
1169
1170 /* content_type contains the type of message received or sent
1171 * according with the SSL/TLS protocol spec. This message is
1172 * encoded with one byte. The value 256 (two bytes) is used
1173 * for designing the SSL/TLS record layer. According with the
1174 * rfc6101, the expected message (other than 256) are:
1175 * - change_cipher_spec(20)
1176 * - alert(21)
1177 * - handshake(22)
1178 * - application_data(23)
1179 * - (255)
1180 * We are interessed by the handshake and specially the client
1181 * hello.
1182 */
1183 if (content_type != 22)
1184 return;
1185
1186 /* The message length is at least 4 bytes, containing the
1187 * message type and the message length.
1188 */
1189 if (len < 4)
1190 return;
1191
1192 /* First byte of the handshake message id the type of
1193 * message. The konwn types are:
1194 * - hello_request(0)
1195 * - client_hello(1)
1196 * - server_hello(2)
1197 * - certificate(11)
1198 * - server_key_exchange (12)
1199 * - certificate_request(13)
1200 * - server_hello_done(14)
1201 * We are interested by the client hello.
1202 */
1203 msg = (unsigned char *)buf;
1204 if (msg[0] != 1)
1205 return;
1206
1207 /* Next three bytes are the length of the message. The total length
1208 * must be this decoded length + 4. If the length given as argument
1209 * is not the same, we abort the protocol dissector.
1210 */
1211 rec_len = (msg[1] << 16) + (msg[2] << 8) + msg[3];
1212 if (len < rec_len + 4)
1213 return;
1214 msg += 4;
1215 end = msg + rec_len;
1216 if (end < msg)
1217 return;
1218
1219 /* Expect 2 bytes for protocol version (1 byte for major and 1 byte
1220 * for minor, the random, composed by 4 bytes for the unix time and
1221 * 28 bytes for unix payload, and them 1 byte for the session id. So
1222 * we jump 1 + 1 + 4 + 28 + 1 bytes.
1223 */
1224 msg += 1 + 1 + 4 + 28 + 1;
1225 if (msg > end)
1226 return;
1227
1228 /* Next two bytes are the ciphersuite length. */
1229 if (msg + 2 > end)
1230 return;
1231 rec_len = (msg[0] << 8) + msg[1];
1232 msg += 2;
1233 if (msg + rec_len > end || msg + rec_len < msg)
1234 return;
1235
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001236 capture = pool_alloc_dirty(pool2_ssl_capture);
1237 if (!capture)
1238 return;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001239 /* Compute the xxh64 of the ciphersuite. */
1240 capture->xxh64 = XXH64(msg, rec_len, 0);
1241
1242 /* Capture the ciphersuite. */
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001243 capture->ciphersuite_len = (global_ssl.capture_cipherlist < rec_len) ?
1244 global_ssl.capture_cipherlist : rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001245 memcpy(capture->ciphersuite, msg, capture->ciphersuite_len);
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001246
1247 SSL_set_ex_data(ssl, ssl_capture_ptr_index, capture);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001248}
1249
Emeric Brun29f037d2014-04-25 19:05:36 +02001250/* Callback is called for ssl protocol analyse */
1251void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1252{
Emeric Brun29f037d2014-04-25 19:05:36 +02001253#ifdef TLS1_RT_HEARTBEAT
1254 /* test heartbeat received (write_p is set to 0
1255 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001256 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001257 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001258 const unsigned char *p = buf;
1259 unsigned int payload;
1260
Emeric Brun29f037d2014-04-25 19:05:36 +02001261 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001262
1263 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1264 if (*p != TLS1_HB_REQUEST)
1265 return;
1266
Willy Tarreauaeed6722014-04-25 23:59:58 +02001267 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001268 goto kill_it;
1269
1270 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001271 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001272 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001273 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001274 /* We have a clear heartbleed attack (CVE-2014-0160), the
1275 * advertised payload is larger than the advertised packet
1276 * length, so we have garbage in the buffer between the
1277 * payload and the end of the buffer (p+len). We can't know
1278 * if the SSL stack is patched, and we don't know if we can
1279 * safely wipe out the area between p+3+len and payload.
1280 * So instead, we prevent the response from being sent by
1281 * setting the max_send_fragment to 0 and we report an SSL
1282 * error, which will kill this connection. It will be reported
1283 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001284 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1285 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001286 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001287 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1288 return;
1289 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001290#endif
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001291 if (global_ssl.capture_cipherlist > 0)
1292 ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
Emeric Brun29f037d2014-04-25 19:05:36 +02001293}
1294
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001295#ifdef OPENSSL_NPN_NEGOTIATED
1296/* This callback is used so that the server advertises the list of
1297 * negociable protocols for NPN.
1298 */
1299static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1300 unsigned int *len, void *arg)
1301{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001302 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001303
1304 *data = (const unsigned char *)conf->npn_str;
1305 *len = conf->npn_len;
1306 return SSL_TLSEXT_ERR_OK;
1307}
1308#endif
1309
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001310#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001311/* This callback is used so that the server advertises the list of
1312 * negociable protocols for ALPN.
1313 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001314static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1315 unsigned char *outlen,
1316 const unsigned char *server,
1317 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001318{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001319 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001320
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001321 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1322 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1323 return SSL_TLSEXT_ERR_NOACK;
1324 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001325 return SSL_TLSEXT_ERR_OK;
1326}
1327#endif
1328
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001329#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001330#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001331
Christopher Faulet30548802015-06-11 13:39:32 +02001332/* Create a X509 certificate with the specified servername and serial. This
1333 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001334static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001335ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001336{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001337 static unsigned int serial = 0;
1338
Christopher Faulet7969a332015-10-09 11:15:03 +02001339 X509 *cacert = bind_conf->ca_sign_cert;
1340 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001341 SSL_CTX *ssl_ctx = NULL;
1342 X509 *newcrt = NULL;
1343 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001344 X509_NAME *name;
1345 const EVP_MD *digest;
1346 X509V3_CTX ctx;
1347 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001348 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001349
Christopher Faulet7969a332015-10-09 11:15:03 +02001350 /* Get the private key of the defautl certificate and use it */
1351 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001352 goto mkcert_error;
1353
1354 /* Create the certificate */
1355 if (!(newcrt = X509_new()))
1356 goto mkcert_error;
1357
1358 /* Set version number for the certificate (X509v3) and the serial
1359 * number */
1360 if (X509_set_version(newcrt, 2L) != 1)
1361 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001362 if (!serial)
1363 serial = now_ms;
1364 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001365
1366 /* Set duration for the certificate */
1367 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1368 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1369 goto mkcert_error;
1370
1371 /* set public key in the certificate */
1372 if (X509_set_pubkey(newcrt, pkey) != 1)
1373 goto mkcert_error;
1374
1375 /* Set issuer name from the CA */
1376 if (!(name = X509_get_subject_name(cacert)))
1377 goto mkcert_error;
1378 if (X509_set_issuer_name(newcrt, name) != 1)
1379 goto mkcert_error;
1380
1381 /* Set the subject name using the same, but the CN */
1382 name = X509_NAME_dup(name);
1383 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1384 (const unsigned char *)servername,
1385 -1, -1, 0) != 1) {
1386 X509_NAME_free(name);
1387 goto mkcert_error;
1388 }
1389 if (X509_set_subject_name(newcrt, name) != 1) {
1390 X509_NAME_free(name);
1391 goto mkcert_error;
1392 }
1393 X509_NAME_free(name);
1394
1395 /* Add x509v3 extensions as specified */
1396 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1397 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1398 X509_EXTENSION *ext;
1399
1400 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1401 goto mkcert_error;
1402 if (!X509_add_ext(newcrt, ext, -1)) {
1403 X509_EXTENSION_free(ext);
1404 goto mkcert_error;
1405 }
1406 X509_EXTENSION_free(ext);
1407 }
1408
1409 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001410
1411 key_type = EVP_PKEY_base_id(capkey);
1412
1413 if (key_type == EVP_PKEY_DSA)
1414 digest = EVP_sha1();
1415 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001416 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001417 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001418 digest = EVP_sha256();
1419 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001420#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001421 int nid;
1422
1423 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1424 goto mkcert_error;
1425 if (!(digest = EVP_get_digestbynid(nid)))
1426 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001427#else
1428 goto mkcert_error;
1429#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001430 }
1431
Christopher Faulet31af49d2015-06-09 17:29:50 +02001432 if (!(X509_sign(newcrt, capkey, digest)))
1433 goto mkcert_error;
1434
1435 /* Create and set the new SSL_CTX */
1436 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1437 goto mkcert_error;
1438 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1439 goto mkcert_error;
1440 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1441 goto mkcert_error;
1442 if (!SSL_CTX_check_private_key(ssl_ctx))
1443 goto mkcert_error;
1444
1445 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001446
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001447#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001448 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001449#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001450#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1451 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001452 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001453 EC_KEY *ecc;
1454 int nid;
1455
1456 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1457 goto end;
1458 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1459 goto end;
1460 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1461 EC_KEY_free(ecc);
1462 }
1463#endif
1464 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001465 return ssl_ctx;
1466
1467 mkcert_error:
1468 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1469 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001470 return NULL;
1471}
1472
Christopher Faulet7969a332015-10-09 11:15:03 +02001473SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001474ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001475{
1476 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001477
1478 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001479}
1480
Christopher Faulet30548802015-06-11 13:39:32 +02001481/* Do a lookup for a certificate in the LRU cache used to store generated
1482 * certificates. */
1483SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001484ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001485{
1486 struct lru64 *lru = NULL;
1487
1488 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001489 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001490 if (lru && lru->domain)
1491 return (SSL_CTX *)lru->data;
1492 }
1493 return NULL;
1494}
1495
Christopher Fauletd2cab922015-07-28 16:03:47 +02001496/* Set a certificate int the LRU cache used to store generated
1497 * certificate. Return 0 on success, otherwise -1 */
1498int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001499ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001500{
1501 struct lru64 *lru = NULL;
1502
1503 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001504 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001505 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001506 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001507 if (lru->domain && lru->data)
1508 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001509 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001510 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001511 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001512 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001513}
1514
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001515/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001516unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001517ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001518{
1519 return XXH32(data, len, ssl_ctx_lru_seed);
1520}
1521
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001522/* Generate a cert and immediately assign it to the SSL session so that the cert's
1523 * refcount is maintained regardless of the cert's presence in the LRU cache.
1524 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001525static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001526ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001527{
1528 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001529 SSL_CTX *ssl_ctx = NULL;
1530 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001531 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001532
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001533 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001534 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001535 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001536 if (lru && lru->domain)
1537 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001538 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001539 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001540 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001541 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001542 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001543 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001544 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001545 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001546 SSL_set_SSL_CTX(ssl, ssl_ctx);
1547 /* No LRU cache, this CTX will be released as soon as the session dies */
1548 SSL_CTX_free(ssl_ctx);
1549 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001550 return ssl_ctx;
1551}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001552#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001553
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001554static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1555{
1556 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1557 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1558 SSL_set_SSL_CTX(ssl, ctx);
1559}
1560
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001561#ifdef OPENSSL_IS_BORINGSSL
1562
1563static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1564{
1565 (void)al; /* shut gcc stupid warning */
1566 (void)priv;
1567
1568 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1569 return SSL_TLSEXT_ERR_NOACK;
1570 return SSL_TLSEXT_ERR_OK;
1571}
1572
1573static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1574{
1575 struct connection *conn;
1576 struct bind_conf *s;
1577 const uint8_t *extension_data;
1578 size_t extension_len;
1579 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1580 const SSL_CIPHER *cipher;
1581 uint16_t cipher_suite;
1582 uint8_t name_type, hash, sign;
1583 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1584
1585 char *wildp = NULL;
1586 const uint8_t *servername;
1587 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1588 int i;
1589
1590 conn = SSL_get_app_data(ctx->ssl);
1591 s = objt_listener(conn->target)->bind_conf;
1592
1593 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1594 &extension_data, &extension_len)) {
1595 CBS_init(&extension, extension_data, extension_len);
1596
1597 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1598 || !CBS_get_u8(&server_name_list, &name_type)
1599 /* Although the server_name extension was intended to be extensible to
1600 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1601 * different name types will cause an error. Further, RFC 4366 originally
1602 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1603 * adding new name types is no longer feasible.
1604 *
1605 * Act as if the extensibility does not exist to simplify parsing. */
1606 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1607 || CBS_len(&server_name_list) != 0
1608 || CBS_len(&extension) != 0
1609 || name_type != TLSEXT_NAMETYPE_host_name
1610 || CBS_len(&host_name) == 0
1611 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1612 || CBS_contains_zero_byte(&host_name)) {
1613 goto abort;
1614 }
1615 } else {
1616 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001617 if (!s->strict_sni) {
1618 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001619 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001620 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001621 goto abort;
1622 }
1623
1624 /* extract/check clientHello informations */
1625 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
1626 CBS_init(&extension, extension_data, extension_len);
1627
1628 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
1629 || CBS_len(&sig_algs) == 0
1630 || CBS_len(&extension) != 0) {
1631 goto abort;
1632 }
1633 if (CBS_len(&sig_algs) % 2 != 0) {
1634 goto abort;
1635 }
1636 while (CBS_len(&sig_algs) != 0) {
1637 if (!CBS_get_u8(&sig_algs, &hash)
1638 || !CBS_get_u8(&sig_algs, &sign)) {
1639 goto abort;
1640 }
1641 switch (sign) {
1642 case TLSEXT_signature_rsa:
1643 has_rsa = 1;
1644 break;
1645 case TLSEXT_signature_ecdsa:
1646 has_ecdsa_sig = 1;
1647 break;
1648 default:
1649 continue;
1650 }
1651 if (has_ecdsa_sig && has_rsa)
1652 break;
1653 }
1654 } else {
1655 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
1656 has_rsa = 1;
1657 }
1658 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
1659 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
1660
1661 while (CBS_len(&cipher_suites) != 0) {
1662 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1663 goto abort;
1664 }
1665 cipher = SSL_get_cipher_by_value(cipher_suite);
1666 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
1667 has_ecdsa = 1;
1668 break;
1669 }
1670 }
1671 }
1672
1673 servername = CBS_data(&host_name);
1674 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
1675 trash.str[i] = tolower(servername[i]);
1676 if (!wildp && (trash.str[i] == '.'))
1677 wildp = &trash.str[i];
1678 }
1679 trash.str[i] = 0;
1680
1681 /* lookup in full qualified names */
1682 node = ebst_lookup(&s->sni_ctx, trash.str);
1683
1684 /* lookup a not neg filter */
1685 for (n = node; n; n = ebmb_next_dup(n)) {
1686 if (!container_of(n, struct sni_ctx, name)->neg) {
1687 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1688 case TLSEXT_signature_ecdsa:
1689 if (has_ecdsa) {
1690 node_ecdsa = n;
1691 goto find_one;
1692 }
1693 break;
1694 case TLSEXT_signature_rsa:
1695 if (has_rsa && !node_rsa) {
1696 node_rsa = n;
1697 if (!has_ecdsa)
1698 goto find_one;
1699 }
1700 break;
1701 default: /* TLSEXT_signature_anonymous */
1702 if (!node_anonymous)
1703 node_anonymous = n;
1704 break;
1705 }
1706 }
1707 }
1708 if (wildp) {
1709 /* lookup in wildcards names */
1710 node = ebst_lookup(&s->sni_w_ctx, wildp);
1711 for (n = node; n; n = ebmb_next_dup(n)) {
1712 if (!container_of(n, struct sni_ctx, name)->neg) {
1713 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1714 case TLSEXT_signature_ecdsa:
1715 if (has_ecdsa) {
1716 node_ecdsa = n;
1717 goto find_one;
1718 }
1719 break;
1720 case TLSEXT_signature_rsa:
1721 if (has_rsa && !node_rsa) {
1722 node_rsa = n;
1723 if (!has_ecdsa)
1724 goto find_one;
1725 }
1726 break;
1727 default: /* TLSEXT_signature_anonymous */
1728 if (!node_anonymous)
1729 node_anonymous = n;
1730 break;
1731 }
1732 }
1733 }
1734 }
1735 find_one:
1736 /* select by key_signature priority order */
1737 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
1738
1739 if (node) {
1740 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001741 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001742 return 1;
1743 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001744 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001745 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001746 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001747 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001748 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001749 abort:
1750 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
1751 conn->err_code = CO_ER_SSL_HANDSHAKE;
1752 return -1;
1753}
1754
1755#else /* OPENSSL_IS_BORINGSSL */
1756
Emeric Brunfc0421f2012-09-07 17:30:07 +02001757/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1758 * warning when no match is found, which implies the default (first) cert
1759 * will keep being used.
1760 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001761static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001762{
1763 const char *servername;
1764 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001765 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001766 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001767 int i;
1768 (void)al; /* shut gcc stupid warning */
1769
1770 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001771 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001772#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02001773 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001774 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001775 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001776 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001777
Willy Tarreauf6721452015-07-07 18:04:38 +02001778 conn_get_to_addr(conn);
1779 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001780 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1781 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001782 if (ctx) {
1783 /* switch ctx */
1784 SSL_set_SSL_CTX(ssl, ctx);
1785 return SSL_TLSEXT_ERR_OK;
1786 }
Christopher Faulet30548802015-06-11 13:39:32 +02001787 }
1788 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001789#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001790 if (s->strict_sni)
1791 return SSL_TLSEXT_ERR_ALERT_FATAL;
1792 ssl_sock_switchctx_set(ssl, s->default_ctx);
1793 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001794 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001795
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001796 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001797 if (!servername[i])
1798 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001799 trash.str[i] = tolower(servername[i]);
1800 if (!wildp && (trash.str[i] == '.'))
1801 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001802 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001803 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001804
1805 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001806 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001807
1808 /* lookup a not neg filter */
1809 for (n = node; n; n = ebmb_next_dup(n)) {
1810 if (!container_of(n, struct sni_ctx, name)->neg) {
1811 node = n;
1812 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001813 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001814 }
1815 if (!node && wildp) {
1816 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001817 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001818 }
1819 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001820#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001821 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001822 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001823 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001824 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001825 return SSL_TLSEXT_ERR_OK;
1826 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001827#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001828 if (s->strict_sni)
1829 return SSL_TLSEXT_ERR_ALERT_FATAL;
1830 ssl_sock_switchctx_set(ssl, s->default_ctx);
1831 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001832 }
1833
1834 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001835 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001836 return SSL_TLSEXT_ERR_OK;
1837}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001838#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001839#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1840
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001841#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001842
1843static DH * ssl_get_dh_1024(void)
1844{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001845 static unsigned char dh1024_p[]={
1846 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1847 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1848 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1849 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1850 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1851 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1852 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1853 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1854 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1855 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1856 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1857 };
1858 static unsigned char dh1024_g[]={
1859 0x02,
1860 };
1861
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001862 BIGNUM *p;
1863 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001864 DH *dh = DH_new();
1865 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001866 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1867 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001868
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001869 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001870 DH_free(dh);
1871 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001872 } else {
1873 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001874 }
1875 }
1876 return dh;
1877}
1878
1879static DH *ssl_get_dh_2048(void)
1880{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001881 static unsigned char dh2048_p[]={
1882 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1883 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1884 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1885 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1886 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1887 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1888 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1889 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1890 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1891 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1892 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1893 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1894 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1895 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1896 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1897 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1898 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1899 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1900 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1901 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1902 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1903 0xB7,0x1F,0x77,0xF3,
1904 };
1905 static unsigned char dh2048_g[]={
1906 0x02,
1907 };
1908
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001909 BIGNUM *p;
1910 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001911 DH *dh = DH_new();
1912 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001913 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1914 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001915
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001916 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001917 DH_free(dh);
1918 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001919 } else {
1920 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001921 }
1922 }
1923 return dh;
1924}
1925
1926static DH *ssl_get_dh_4096(void)
1927{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001928 static unsigned char dh4096_p[]={
1929 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1930 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1931 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1932 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1933 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1934 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1935 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1936 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1937 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1938 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1939 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1940 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1941 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1942 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1943 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1944 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1945 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1946 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1947 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1948 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1949 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1950 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1951 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1952 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1953 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1954 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1955 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1956 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1957 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1958 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1959 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1960 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1961 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1962 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1963 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1964 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1965 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1966 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1967 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1968 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1969 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1970 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1971 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001972 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001973 static unsigned char dh4096_g[]={
1974 0x02,
1975 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001976
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001977 BIGNUM *p;
1978 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001979 DH *dh = DH_new();
1980 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001981 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1982 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001983
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001984 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001985 DH_free(dh);
1986 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001987 } else {
1988 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001989 }
1990 }
1991 return dh;
1992}
1993
1994/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001995 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001996static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1997{
1998 DH *dh = NULL;
1999 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002000 int type;
2001
2002 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002003
2004 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2005 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2006 */
2007 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2008 keylen = EVP_PKEY_bits(pkey);
2009 }
2010
Willy Tarreauef934602016-12-22 23:12:01 +01002011 if (keylen > global_ssl.default_dh_param) {
2012 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002013 }
2014
Remi Gacogned3a341a2015-05-29 16:26:17 +02002015 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002016 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002017 }
2018 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002019 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002020 }
2021 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002022 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002023 }
2024
2025 return dh;
2026}
2027
Remi Gacogne47783ef2015-05-29 15:53:22 +02002028static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002029{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002030 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002031 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002032
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002033 if (in == NULL)
2034 goto end;
2035
Remi Gacogne47783ef2015-05-29 15:53:22 +02002036 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002037 goto end;
2038
Remi Gacogne47783ef2015-05-29 15:53:22 +02002039 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2040
2041end:
2042 if (in)
2043 BIO_free(in);
2044
2045 return dh;
2046}
2047
2048int ssl_sock_load_global_dh_param_from_file(const char *filename)
2049{
2050 global_dh = ssl_sock_get_dh_from_file(filename);
2051
2052 if (global_dh) {
2053 return 0;
2054 }
2055
2056 return -1;
2057}
2058
2059/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2060 if an error occured, and 0 if parameter not found. */
2061int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2062{
2063 int ret = -1;
2064 DH *dh = ssl_sock_get_dh_from_file(file);
2065
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002066 if (dh) {
2067 ret = 1;
2068 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002069
2070 if (ssl_dh_ptr_index >= 0) {
2071 /* store a pointer to the DH params to avoid complaining about
2072 ssl-default-dh-param not being set for this SSL_CTX */
2073 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2074 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002075 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002076 else if (global_dh) {
2077 SSL_CTX_set_tmp_dh(ctx, global_dh);
2078 ret = 0; /* DH params not found */
2079 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002080 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002081 /* Clear openssl global errors stack */
2082 ERR_clear_error();
2083
Willy Tarreauef934602016-12-22 23:12:01 +01002084 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002085 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002086 if (local_dh_1024 == NULL)
2087 local_dh_1024 = ssl_get_dh_1024();
2088
Remi Gacogne8de54152014-07-15 11:36:40 +02002089 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002090 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002091
Remi Gacogne8de54152014-07-15 11:36:40 +02002092 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002093 }
2094 else {
2095 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2096 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002097
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002098 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002099 }
Emeric Brun644cde02012-12-14 11:21:13 +01002100
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002101end:
2102 if (dh)
2103 DH_free(dh);
2104
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002105 return ret;
2106}
2107#endif
2108
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002109static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2110 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002111{
2112 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002113 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002114 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002115
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002116 if (*name == '!') {
2117 neg = 1;
2118 name++;
2119 }
2120 if (*name == '*') {
2121 wild = 1;
2122 name++;
2123 }
2124 /* !* filter is a nop */
2125 if (neg && wild)
2126 return order;
2127 if (*name) {
2128 int j, len;
2129 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002130 for (j = 0; j < len && j < trash.size; j++)
2131 trash.str[j] = tolower(name[j]);
2132 if (j >= trash.size)
2133 return order;
2134 trash.str[j] = 0;
2135
2136 /* Check for duplicates. */
2137 if (wild)
2138 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2139 else
2140 node = ebst_lookup(&s->sni_ctx, trash.str);
2141 for (; node; node = ebmb_next_dup(node)) {
2142 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002143 if (sc->ctx == ctx && sc->conf == conf &&
2144 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002145 return order;
2146 }
2147
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002148 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002149 if (!sc)
2150 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002151 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002152 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002153 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002154 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002155 sc->order = order++;
2156 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002157 if (wild)
2158 ebst_insert(&s->sni_w_ctx, &sc->name);
2159 else
2160 ebst_insert(&s->sni_ctx, &sc->name);
2161 }
2162 return order;
2163}
2164
yanbzhu488a4d22015-12-01 15:16:07 -05002165
2166/* The following code is used for loading multiple crt files into
2167 * SSL_CTX's based on CN/SAN
2168 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002169#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002170/* This is used to preload the certifcate, private key
2171 * and Cert Chain of a file passed in via the crt
2172 * argument
2173 *
2174 * This way, we do not have to read the file multiple times
2175 */
2176struct cert_key_and_chain {
2177 X509 *cert;
2178 EVP_PKEY *key;
2179 unsigned int num_chain_certs;
2180 /* This is an array of X509 pointers */
2181 X509 **chain_certs;
2182};
2183
yanbzhu08ce6ab2015-12-02 13:01:29 -05002184#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2185
2186struct key_combo_ctx {
2187 SSL_CTX *ctx;
2188 int order;
2189};
2190
2191/* Map used for processing multiple keypairs for a single purpose
2192 *
2193 * This maps CN/SNI name to certificate type
2194 */
2195struct sni_keytype {
2196 int keytypes; /* BITMASK for keytypes */
2197 struct ebmb_node name; /* node holding the servername value */
2198};
2199
2200
yanbzhu488a4d22015-12-01 15:16:07 -05002201/* Frees the contents of a cert_key_and_chain
2202 */
2203static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2204{
2205 int i;
2206
2207 if (!ckch)
2208 return;
2209
2210 /* Free the certificate and set pointer to NULL */
2211 if (ckch->cert)
2212 X509_free(ckch->cert);
2213 ckch->cert = NULL;
2214
2215 /* Free the key and set pointer to NULL */
2216 if (ckch->key)
2217 EVP_PKEY_free(ckch->key);
2218 ckch->key = NULL;
2219
2220 /* Free each certificate in the chain */
2221 for (i = 0; i < ckch->num_chain_certs; i++) {
2222 if (ckch->chain_certs[i])
2223 X509_free(ckch->chain_certs[i]);
2224 }
2225
2226 /* Free the chain obj itself and set to NULL */
2227 if (ckch->num_chain_certs > 0) {
2228 free(ckch->chain_certs);
2229 ckch->num_chain_certs = 0;
2230 ckch->chain_certs = NULL;
2231 }
2232
2233}
2234
2235/* checks if a key and cert exists in the ckch
2236 */
2237static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2238{
2239 return (ckch->cert != NULL && ckch->key != NULL);
2240}
2241
2242
2243/* Loads the contents of a crt file (path) into a cert_key_and_chain
2244 * This allows us to carry the contents of the file without having to
2245 * read the file multiple times.
2246 *
2247 * returns:
2248 * 0 on Success
2249 * 1 on SSL Failure
2250 * 2 on file not found
2251 */
2252static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2253{
2254
2255 BIO *in;
2256 X509 *ca = NULL;
2257 int ret = 1;
2258
2259 ssl_sock_free_cert_key_and_chain_contents(ckch);
2260
2261 in = BIO_new(BIO_s_file());
2262 if (in == NULL)
2263 goto end;
2264
2265 if (BIO_read_filename(in, path) <= 0)
2266 goto end;
2267
yanbzhu488a4d22015-12-01 15:16:07 -05002268 /* Read Private Key */
2269 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2270 if (ckch->key == NULL) {
2271 memprintf(err, "%sunable to load private key from file '%s'.\n",
2272 err && *err ? *err : "", path);
2273 goto end;
2274 }
2275
Willy Tarreaubb137a82016-04-06 19:02:38 +02002276 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002277 if (BIO_reset(in) == -1) {
2278 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2279 err && *err ? *err : "", path);
2280 goto end;
2281 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002282
2283 /* Read Certificate */
2284 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2285 if (ckch->cert == NULL) {
2286 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2287 err && *err ? *err : "", path);
2288 goto end;
2289 }
2290
yanbzhu488a4d22015-12-01 15:16:07 -05002291 /* Read Certificate Chain */
2292 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2293 /* Grow the chain certs */
2294 ckch->num_chain_certs++;
2295 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2296
2297 /* use - 1 here since we just incremented it above */
2298 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2299 }
2300 ret = ERR_get_error();
2301 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2302 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2303 err && *err ? *err : "", path);
2304 ret = 1;
2305 goto end;
2306 }
2307
2308 ret = 0;
2309
2310end:
2311
2312 ERR_clear_error();
2313 if (in)
2314 BIO_free(in);
2315
2316 /* Something went wrong in one of the reads */
2317 if (ret != 0)
2318 ssl_sock_free_cert_key_and_chain_contents(ckch);
2319
2320 return ret;
2321}
2322
2323/* Loads the info in ckch into ctx
2324 * Currently, this does not process any information about ocsp, dhparams or
2325 * sctl
2326 * Returns
2327 * 0 on success
2328 * 1 on failure
2329 */
2330static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2331{
2332 int i = 0;
2333
2334 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2335 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2336 err && *err ? *err : "", path);
2337 return 1;
2338 }
2339
2340 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2341 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2342 err && *err ? *err : "", path);
2343 return 1;
2344 }
2345
yanbzhu488a4d22015-12-01 15:16:07 -05002346 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2347 for (i = 0; i < ckch->num_chain_certs; i++) {
2348 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002349 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2350 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002351 return 1;
2352 }
2353 }
2354
2355 if (SSL_CTX_check_private_key(ctx) <= 0) {
2356 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2357 err && *err ? *err : "", path);
2358 return 1;
2359 }
2360
2361 return 0;
2362}
2363
yanbzhu08ce6ab2015-12-02 13:01:29 -05002364
2365static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2366{
2367 struct sni_keytype *s_kt = NULL;
2368 struct ebmb_node *node;
2369 int i;
2370
2371 for (i = 0; i < trash.size; i++) {
2372 if (!str[i])
2373 break;
2374 trash.str[i] = tolower(str[i]);
2375 }
2376 trash.str[i] = 0;
2377 node = ebst_lookup(sni_keytypes, trash.str);
2378 if (!node) {
2379 /* CN not found in tree */
2380 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2381 /* Using memcpy here instead of strncpy.
2382 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2383 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2384 */
2385 memcpy(s_kt->name.key, trash.str, i+1);
2386 s_kt->keytypes = 0;
2387 ebst_insert(sni_keytypes, &s_kt->name);
2388 } else {
2389 /* CN found in tree */
2390 s_kt = container_of(node, struct sni_keytype, name);
2391 }
2392
2393 /* Mark that this CN has the keytype of key_index via keytypes mask */
2394 s_kt->keytypes |= 1<<key_index;
2395
2396}
2397
2398
2399/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2400 * If any are found, group these files into a set of SSL_CTX*
2401 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2402 *
2403 * This will allow the user to explictly group multiple cert/keys for a single purpose
2404 *
2405 * Returns
2406 * 0 on success
2407 * 1 on failure
2408 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002409static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2410 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002411{
2412 char fp[MAXPATHLEN+1] = {0};
2413 int n = 0;
2414 int i = 0;
2415 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2416 struct eb_root sni_keytypes_map = { {0} };
2417 struct ebmb_node *node;
2418 struct ebmb_node *next;
2419 /* Array of SSL_CTX pointers corresponding to each possible combo
2420 * of keytypes
2421 */
2422 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2423 int rv = 0;
2424 X509_NAME *xname = NULL;
2425 char *str = NULL;
2426#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2427 STACK_OF(GENERAL_NAME) *names = NULL;
2428#endif
2429
2430 /* Load all possible certs and keys */
2431 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2432 struct stat buf;
2433
2434 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2435 if (stat(fp, &buf) == 0) {
2436 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2437 rv = 1;
2438 goto end;
2439 }
2440 }
2441 }
2442
2443 /* Process each ckch and update keytypes for each CN/SAN
2444 * for example, if CN/SAN www.a.com is associated with
2445 * certs with keytype 0 and 2, then at the end of the loop,
2446 * www.a.com will have:
2447 * keyindex = 0 | 1 | 4 = 5
2448 */
2449 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2450
2451 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2452 continue;
2453
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002454 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002455 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002456 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2457 } else {
2458 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2459 * so the line that contains logic is marked via comments
2460 */
2461 xname = X509_get_subject_name(certs_and_keys[n].cert);
2462 i = -1;
2463 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2464 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002465 ASN1_STRING *value;
2466 value = X509_NAME_ENTRY_get_data(entry);
2467 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002468 /* Important line is here */
2469 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002470
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002471 OPENSSL_free(str);
2472 str = NULL;
2473 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002474 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002475
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002476 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002477#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002478 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2479 if (names) {
2480 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2481 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002482
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002483 if (name->type == GEN_DNS) {
2484 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2485 /* Important line is here */
2486 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002487
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002488 OPENSSL_free(str);
2489 str = NULL;
2490 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002491 }
2492 }
2493 }
2494 }
2495#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2496 }
2497
2498 /* If no files found, return error */
2499 if (eb_is_empty(&sni_keytypes_map)) {
2500 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2501 err && *err ? *err : "", path);
2502 rv = 1;
2503 goto end;
2504 }
2505
2506 /* We now have a map of CN/SAN to keytypes that are loaded in
2507 * Iterate through the map to create the SSL_CTX's (if needed)
2508 * and add each CTX to the SNI tree
2509 *
2510 * Some math here:
2511 * There are 2^n - 1 possibile combinations, each unique
2512 * combination is denoted by the key in the map. Each key
2513 * has a value between 1 and 2^n - 1. Conveniently, the array
2514 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2515 * entry in the array to correspond to the unique combo (key)
2516 * associated with i. This unique key combo (i) will be associated
2517 * with combos[i-1]
2518 */
2519
2520 node = ebmb_first(&sni_keytypes_map);
2521 while (node) {
2522 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002523 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002524
2525 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2526 i = container_of(node, struct sni_keytype, name)->keytypes;
2527 cur_ctx = key_combos[i-1].ctx;
2528
2529 if (cur_ctx == NULL) {
2530 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002531 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002532 if (cur_ctx == NULL) {
2533 memprintf(err, "%sunable to allocate SSL context.\n",
2534 err && *err ? *err : "");
2535 rv = 1;
2536 goto end;
2537 }
2538
yanbzhube2774d2015-12-10 15:07:30 -05002539 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002540 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2541 if (i & (1<<n)) {
2542 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002543 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2544 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002545 SSL_CTX_free(cur_ctx);
2546 rv = 1;
2547 goto end;
2548 }
yanbzhube2774d2015-12-10 15:07:30 -05002549
2550#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2551 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002552 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002553 if (err)
2554 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 +00002555 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002556 SSL_CTX_free(cur_ctx);
2557 rv = 1;
2558 goto end;
2559 }
2560#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002561 }
2562 }
2563
2564 /* Load DH params into the ctx to support DHE keys */
2565#ifndef OPENSSL_NO_DH
2566 if (ssl_dh_ptr_index >= 0)
2567 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2568
2569 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2570 if (rv < 0) {
2571 if (err)
2572 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2573 *err ? *err : "", path);
2574 rv = 1;
2575 goto end;
2576 }
2577#endif
2578
2579 /* Update key_combos */
2580 key_combos[i-1].ctx = cur_ctx;
2581 }
2582
2583 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002584 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2585 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002586 node = ebmb_next(node);
2587 }
2588
2589
2590 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2591 if (!bind_conf->default_ctx) {
2592 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2593 if (key_combos[i].ctx) {
2594 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002595 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002596 break;
2597 }
2598 }
2599 }
2600
2601end:
2602
2603 if (names)
2604 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2605
2606 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2607 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2608
2609 node = ebmb_first(&sni_keytypes_map);
2610 while (node) {
2611 next = ebmb_next(node);
2612 ebmb_delete(node);
2613 node = next;
2614 }
2615
2616 return rv;
2617}
2618#else
2619/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002620static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2621 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002622{
2623 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2624 err && *err ? *err : "", path, strerror(errno));
2625 return 1;
2626}
2627
yanbzhu488a4d22015-12-01 15:16:07 -05002628#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2629
Emeric Brunfc0421f2012-09-07 17:30:07 +02002630/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2631 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2632 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002633static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2634 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002635{
2636 BIO *in;
2637 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002638 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002639 int ret = -1;
2640 int order = 0;
2641 X509_NAME *xname;
2642 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002643 pem_password_cb *passwd_cb;
2644 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002645 EVP_PKEY *pkey;
2646 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002647
Emeric Brunfc0421f2012-09-07 17:30:07 +02002648#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2649 STACK_OF(GENERAL_NAME) *names;
2650#endif
2651
2652 in = BIO_new(BIO_s_file());
2653 if (in == NULL)
2654 goto end;
2655
2656 if (BIO_read_filename(in, file) <= 0)
2657 goto end;
2658
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002659
2660 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2661 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2662
2663 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002664 if (x == NULL)
2665 goto end;
2666
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002667 pkey = X509_get_pubkey(x);
2668 if (pkey) {
2669 switch(EVP_PKEY_base_id(pkey)) {
2670 case EVP_PKEY_RSA:
2671 key_sig = TLSEXT_signature_rsa;
2672 break;
2673 case EVP_PKEY_EC:
2674 key_sig = TLSEXT_signature_ecdsa;
2675 break;
2676 }
2677 EVP_PKEY_free(pkey);
2678 }
2679
Emeric Brun50bcecc2013-04-22 13:05:23 +02002680 if (fcount) {
2681 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002682 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002683 }
2684 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002685#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002686 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2687 if (names) {
2688 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2689 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2690 if (name->type == GEN_DNS) {
2691 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002692 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002693 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002694 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002695 }
2696 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002697 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002698 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002699#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002700 xname = X509_get_subject_name(x);
2701 i = -1;
2702 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2703 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002704 ASN1_STRING *value;
2705
2706 value = X509_NAME_ENTRY_get_data(entry);
2707 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002708 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002709 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002710 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002711 }
2712 }
2713
2714 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2715 if (!SSL_CTX_use_certificate(ctx, x))
2716 goto end;
2717
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002718#ifdef SSL_CTX_clear_extra_chain_certs
2719 SSL_CTX_clear_extra_chain_certs(ctx);
2720#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002721 if (ctx->extra_certs != NULL) {
2722 sk_X509_pop_free(ctx->extra_certs, X509_free);
2723 ctx->extra_certs = NULL;
2724 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002725#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002726
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002727 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002728 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2729 X509_free(ca);
2730 goto end;
2731 }
2732 }
2733
2734 err = ERR_get_error();
2735 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2736 /* we successfully reached the last cert in the file */
2737 ret = 1;
2738 }
2739 ERR_clear_error();
2740
2741end:
2742 if (x)
2743 X509_free(x);
2744
2745 if (in)
2746 BIO_free(in);
2747
2748 return ret;
2749}
2750
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002751static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2752 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002753{
2754 int ret;
2755 SSL_CTX *ctx;
2756
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002757 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02002758 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002759 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2760 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002761 return 1;
2762 }
2763
2764 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002765 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2766 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002767 SSL_CTX_free(ctx);
2768 return 1;
2769 }
2770
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002771 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002772 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002773 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2774 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002775 if (ret < 0) /* serious error, must do that ourselves */
2776 SSL_CTX_free(ctx);
2777 return 1;
2778 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002779
2780 if (SSL_CTX_check_private_key(ctx) <= 0) {
2781 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2782 err && *err ? *err : "", path);
2783 return 1;
2784 }
2785
Emeric Brunfc0421f2012-09-07 17:30:07 +02002786 /* we must not free the SSL_CTX anymore below, since it's already in
2787 * the tree, so it will be discovered and cleaned in time.
2788 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002789#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002790 /* store a NULL pointer to indicate we have not yet loaded
2791 a custom DH param file */
2792 if (ssl_dh_ptr_index >= 0) {
2793 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2794 }
2795
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002796 ret = ssl_sock_load_dh_params(ctx, path);
2797 if (ret < 0) {
2798 if (err)
2799 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2800 *err ? *err : "", path);
2801 return 1;
2802 }
2803#endif
2804
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002805#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002806 ret = ssl_sock_load_ocsp(ctx, path);
2807 if (ret < 0) {
2808 if (err)
2809 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",
2810 *err ? *err : "", path);
2811 return 1;
2812 }
2813#endif
2814
Daniel Jakots54ffb912015-11-06 20:02:41 +01002815#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002816 if (sctl_ex_index >= 0) {
2817 ret = ssl_sock_load_sctl(ctx, path);
2818 if (ret < 0) {
2819 if (err)
2820 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2821 *err ? *err : "", path);
2822 return 1;
2823 }
2824 }
2825#endif
2826
Emeric Brunfc0421f2012-09-07 17:30:07 +02002827#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002828 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002829 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2830 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002831 return 1;
2832 }
2833#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002834 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002835 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002836 bind_conf->default_ssl_conf = ssl_conf;
2837 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002838
2839 return 0;
2840}
2841
Willy Tarreau03209342016-12-22 17:08:28 +01002842int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002843{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002844 struct dirent **de_list;
2845 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002846 DIR *dir;
2847 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002848 char *end;
2849 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002850 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002851#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2852 int is_bundle;
2853 int j;
2854#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002855
yanbzhu08ce6ab2015-12-02 13:01:29 -05002856 if (stat(path, &buf) == 0) {
2857 dir = opendir(path);
2858 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002859 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002860
yanbzhu08ce6ab2015-12-02 13:01:29 -05002861 /* strip trailing slashes, including first one */
2862 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2863 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002864
yanbzhu08ce6ab2015-12-02 13:01:29 -05002865 n = scandir(path, &de_list, 0, alphasort);
2866 if (n < 0) {
2867 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2868 err && *err ? *err : "", path, strerror(errno));
2869 cfgerr++;
2870 }
2871 else {
2872 for (i = 0; i < n; i++) {
2873 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002874
yanbzhu08ce6ab2015-12-02 13:01:29 -05002875 end = strrchr(de->d_name, '.');
2876 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2877 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002878
yanbzhu08ce6ab2015-12-02 13:01:29 -05002879 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2880 if (stat(fp, &buf) != 0) {
2881 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2882 err && *err ? *err : "", fp, strerror(errno));
2883 cfgerr++;
2884 goto ignore_entry;
2885 }
2886 if (!S_ISREG(buf.st_mode))
2887 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002888
2889#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2890 is_bundle = 0;
2891 /* Check if current entry in directory is part of a multi-cert bundle */
2892
2893 if (end) {
2894 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2895 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2896 is_bundle = 1;
2897 break;
2898 }
2899 }
2900
2901 if (is_bundle) {
2902 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2903 int dp_len;
2904
2905 dp_len = end - de->d_name;
2906 snprintf(dp, dp_len + 1, "%s", de->d_name);
2907
2908 /* increment i and free de until we get to a non-bundle cert
2909 * Note here that we look at de_list[i + 1] before freeing de
2910 * this is important since ignore_entry will free de
2911 */
2912 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2913 free(de);
2914 i++;
2915 de = de_list[i];
2916 }
2917
2918 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002919 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002920
2921 /* Successfully processed the bundle */
2922 goto ignore_entry;
2923 }
2924 }
2925
2926#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002927 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002928ignore_entry:
2929 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002930 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002931 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002932 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002933 closedir(dir);
2934 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002935 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002936
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002937 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002938
Emeric Brunfc0421f2012-09-07 17:30:07 +02002939 return cfgerr;
2940}
2941
Thierry Fournier383085f2013-01-24 14:15:43 +01002942/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2943 * done once. Zero is returned if the operation fails. No error is returned
2944 * if the random is said as not implemented, because we expect that openssl
2945 * will use another method once needed.
2946 */
2947static int ssl_initialize_random()
2948{
2949 unsigned char random;
2950 static int random_initialized = 0;
2951
2952 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2953 random_initialized = 1;
2954
2955 return random_initialized;
2956}
2957
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002958/* release ssl bind conf */
2959void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002960{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002961 if (conf) {
2962#ifdef OPENSSL_NPN_NEGOTIATED
2963 free(conf->npn_str);
2964 conf->npn_str = NULL;
2965#endif
2966#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2967 free(conf->alpn_str);
2968 conf->alpn_str = NULL;
2969#endif
2970 free(conf->ca_file);
2971 conf->ca_file = NULL;
2972 free(conf->crl_file);
2973 conf->crl_file = NULL;
2974 free(conf->ciphers);
2975 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002976 free(conf->curves);
2977 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002978 free(conf->ecdhe);
2979 conf->ecdhe = NULL;
2980 }
2981}
2982
2983int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2984{
2985 char thisline[CRT_LINESIZE];
2986 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002987 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002988 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002989 int linenum = 0;
2990 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002991
Willy Tarreauad1731d2013-04-02 17:35:58 +02002992 if ((f = fopen(file, "r")) == NULL) {
2993 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002994 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002995 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002996
2997 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002998 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002999 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003000 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003001 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003002 char *crt_path;
3003 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003004
3005 linenum++;
3006 end = line + strlen(line);
3007 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3008 /* Check if we reached the limit and the last char is not \n.
3009 * Watch out for the last line without the terminating '\n'!
3010 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003011 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3012 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003013 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003014 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003015 }
3016
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003017 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003018 newarg = 1;
3019 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003020 if (*line == '#' || *line == '\n' || *line == '\r') {
3021 /* end of string, end of loop */
3022 *line = 0;
3023 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003024 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003025 newarg = 1;
3026 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003027 } else if (*line == '[') {
3028 if (ssl_b) {
3029 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3030 cfgerr = 1;
3031 break;
3032 }
3033 if (!arg) {
3034 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3035 cfgerr = 1;
3036 break;
3037 }
3038 ssl_b = arg;
3039 newarg = 1;
3040 *line = 0;
3041 } else if (*line == ']') {
3042 if (ssl_e) {
3043 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003044 cfgerr = 1;
3045 break;
3046 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003047 if (!ssl_b) {
3048 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3049 cfgerr = 1;
3050 break;
3051 }
3052 ssl_e = arg;
3053 newarg = 1;
3054 *line = 0;
3055 } else if (newarg) {
3056 if (arg == MAX_CRT_ARGS) {
3057 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3058 cfgerr = 1;
3059 break;
3060 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003061 newarg = 0;
3062 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003063 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003064 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003065 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003066 if (cfgerr)
3067 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003068 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003069
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003070 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003071 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003072 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003073
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003074 crt_path = args[0];
3075 if (*crt_path != '/' && global_ssl.crt_base) {
3076 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3077 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3078 crt_path, linenum, file);
3079 cfgerr = 1;
3080 break;
3081 }
3082 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3083 crt_path = path;
3084 }
3085
3086 ssl_conf = calloc(1, sizeof *ssl_conf);
3087 cur_arg = ssl_b ? ssl_b : 1;
3088 while (cur_arg < ssl_e) {
3089 newarg = 0;
3090 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3091 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3092 newarg = 1;
3093 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3094 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3095 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3096 args[cur_arg], linenum, file);
3097 cfgerr = 1;
3098 }
3099 cur_arg += 1 + ssl_bind_kws[i].skip;
3100 break;
3101 }
3102 }
3103 if (!cfgerr && !newarg) {
3104 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3105 args[cur_arg], linenum, file);
3106 cfgerr = 1;
3107 break;
3108 }
3109 }
3110 if (cfgerr) {
3111 ssl_sock_free_ssl_conf(ssl_conf);
3112 free(ssl_conf);
3113 ssl_conf = NULL;
3114 break;
3115 }
3116
3117 if (stat(crt_path, &buf) == 0) {
3118 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3119 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003120 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003121 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3122 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003123 }
3124
Willy Tarreauad1731d2013-04-02 17:35:58 +02003125 if (cfgerr) {
3126 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003127 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003128 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003129 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003130 fclose(f);
3131 return cfgerr;
3132}
3133
Emeric Brunfc0421f2012-09-07 17:30:07 +02003134#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
3135#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
3136#endif
3137
3138#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
3139#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01003140#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02003141#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003142#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
3143#define SSL_OP_SINGLE_ECDH_USE 0
3144#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02003145#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
3146#define SSL_OP_NO_TICKET 0
3147#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003148#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
3149#define SSL_OP_NO_COMPRESSION 0
3150#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02003151#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
3152#define SSL_OP_NO_TLSv1_1 0
3153#endif
3154#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
3155#define SSL_OP_NO_TLSv1_2 0
3156#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003157#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
3158#define SSL_OP_SINGLE_DH_USE 0
3159#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003160#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
3161#define SSL_OP_SINGLE_ECDH_USE 0
3162#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003163#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
3164#define SSL_MODE_RELEASE_BUFFERS 0
3165#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01003166#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
3167#define SSL_MODE_SMALL_BUFFERS 0
3168#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003169
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003170
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003171/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003172static SSL_CTX *
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003173ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003174{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003175 SSL_CTX *ctx = NULL;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003176 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003177 SSL_OP_ALL | /* all known workarounds for bugs */
3178 SSL_OP_NO_SSLv2 |
3179 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003180 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003181 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003182 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3183 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003184 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003185 SSL_MODE_ENABLE_PARTIAL_WRITE |
3186 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003187 SSL_MODE_RELEASE_BUFFERS |
3188 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01003189 int conf_ssl_options = bind_conf->ssl_options;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003190
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003191#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL || defined OPENSSL_IS_BORINGSSL)
3192 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV12) {
3193 ctx = SSL_CTX_new(TLS_server_method());
3194 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
3195 SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
3196 }
3197 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV11) {
3198 ctx = SSL_CTX_new(TLS_server_method());
3199 SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
3200 SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION);
3201 }
3202 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV10) {
3203 ctx = SSL_CTX_new(TLS_server_method());
3204 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
3205 SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION);
3206 }
3207 if (!ctx && conf_ssl_options & BC_SSL_O_USE_SSLV3) {
3208 ctx = SSL_CTX_new(TLS_server_method());
3209 SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
3210 SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION);
3211 }
3212#else
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003213#if SSL_OP_NO_TLSv1_2
3214 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV12)
3215 ctx = SSL_CTX_new(TLSv1_2_server_method());
3216#endif
3217#if SSL_OP_NO_TLSv1_1
3218 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV11)
3219 ctx = SSL_CTX_new(TLSv1_1_server_method());
3220#endif
3221 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV10)
3222 ctx = SSL_CTX_new(TLSv1_server_method());
3223#ifndef OPENSSL_NO_SSL3
3224 if (!ctx && conf_ssl_options & BC_SSL_O_USE_SSLV3)
3225 ctx = SSL_CTX_new(SSLv3_server_method());
3226#endif
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003227#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003228 if (!ctx) {
3229 ctx = SSL_CTX_new(SSLv23_server_method());
3230 if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
3231 ssloptions |= SSL_OP_NO_SSLv3;
3232 if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
3233 ssloptions |= SSL_OP_NO_TLSv1;
3234 if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
3235 ssloptions |= SSL_OP_NO_TLSv1_1;
3236 if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
3237 ssloptions |= SSL_OP_NO_TLSv1_2;
3238 }
3239 if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3240 ssloptions |= SSL_OP_NO_TICKET;
3241 SSL_CTX_set_options(ctx, ssloptions);
3242 SSL_CTX_set_mode(ctx, sslmode);
3243 if (global_ssl.life_time)
3244 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003245
3246#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3247#ifdef OPENSSL_IS_BORINGSSL
3248 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3249 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3250#else
3251 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3252 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3253#endif
3254#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003255 return ctx;
3256}
3257
3258int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3259{
3260 struct proxy *curproxy = bind_conf->frontend;
3261 int cfgerr = 0;
3262 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003263 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003264 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003265 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003266
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003267 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003268 case SSL_SOCK_VERIFY_NONE:
3269 verify = SSL_VERIFY_NONE;
3270 break;
3271 case SSL_SOCK_VERIFY_OPTIONAL:
3272 verify = SSL_VERIFY_PEER;
3273 break;
3274 case SSL_SOCK_VERIFY_REQUIRED:
3275 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3276 break;
3277 }
3278 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3279 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003280 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3281 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3282 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003283 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003284 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003285 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003286 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003287 cfgerr++;
3288 }
3289 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003290 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003291 }
Emeric Brun850efd52014-01-29 12:24:34 +01003292 else {
3293 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3294 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3295 cfgerr++;
3296 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003297#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003298 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003299 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3300
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003301 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003302 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003303 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003304 cfgerr++;
3305 }
Emeric Brun561e5742012-10-02 15:20:55 +02003306 else {
3307 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3308 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003309 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003310#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003311 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003312 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003313#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003314 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003315 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3316 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3317 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3318 cfgerr++;
3319 }
3320 }
3321#endif
3322
Emeric Brunfc0421f2012-09-07 17:30:07 +02003323 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003324 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3325 if (conf_ciphers &&
3326 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003327 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 +01003328 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003329 cfgerr++;
3330 }
3331
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003332#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003333 /* If tune.ssl.default-dh-param has not been set,
3334 neither has ssl-default-dh-file and no static DH
3335 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003336 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003337 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003338 (ssl_dh_ptr_index == -1 ||
3339 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003340 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3341 const SSL_CIPHER * cipher = NULL;
3342 char cipher_description[128];
3343 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3344 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3345 which is not ephemeral DH. */
3346 const char dhe_description[] = " Kx=DH ";
3347 const char dhe_export_description[] = " Kx=DH(";
3348 int idx = 0;
3349 int dhe_found = 0;
3350 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003351
Remi Gacogne23d5d372014-10-10 17:04:26 +02003352 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003353
Remi Gacogne23d5d372014-10-10 17:04:26 +02003354 if (ssl) {
3355 ciphers = SSL_get_ciphers(ssl);
3356
3357 if (ciphers) {
3358 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3359 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3360 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3361 if (strstr(cipher_description, dhe_description) != NULL ||
3362 strstr(cipher_description, dhe_export_description) != NULL) {
3363 dhe_found = 1;
3364 break;
3365 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003366 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003367 }
3368 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003369 SSL_free(ssl);
3370 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003371 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003372
Lukas Tribus90132722014-08-18 00:56:33 +02003373 if (dhe_found) {
3374 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 +02003375 }
3376
Willy Tarreauef934602016-12-22 23:12:01 +01003377 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003378 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003379
Willy Tarreauef934602016-12-22 23:12:01 +01003380 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003381 if (local_dh_1024 == NULL) {
3382 local_dh_1024 = ssl_get_dh_1024();
3383 }
Willy Tarreauef934602016-12-22 23:12:01 +01003384 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003385 if (local_dh_2048 == NULL) {
3386 local_dh_2048 = ssl_get_dh_2048();
3387 }
Willy Tarreauef934602016-12-22 23:12:01 +01003388 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003389 if (local_dh_4096 == NULL) {
3390 local_dh_4096 = ssl_get_dh_4096();
3391 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003392 }
3393 }
3394 }
3395#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003396
Emeric Brunfc0421f2012-09-07 17:30:07 +02003397 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003398#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003399 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003400#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003401
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003402#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003403 ssl_conf_cur = NULL;
3404 if (ssl_conf && ssl_conf->npn_str)
3405 ssl_conf_cur = ssl_conf;
3406 else if (bind_conf->ssl_conf.npn_str)
3407 ssl_conf_cur = &bind_conf->ssl_conf;
3408 if (ssl_conf_cur)
3409 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003410#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003411#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003412 ssl_conf_cur = NULL;
3413 if (ssl_conf && ssl_conf->alpn_str)
3414 ssl_conf_cur = ssl_conf;
3415 else if (bind_conf->ssl_conf.alpn_str)
3416 ssl_conf_cur = &bind_conf->ssl_conf;
3417 if (ssl_conf_cur)
3418 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003419#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003420#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3421 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3422 if (conf_curves) {
3423 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3424 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3425 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3426 cfgerr++;
3427 }
Emmanuel Hocdeta52bb152017-03-20 11:11:49 +01003428#if defined(SSL_CTX_set_ecdh_auto)
3429 (void)SSL_CTX_set_ecdh_auto(ctx, 1);
3430#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003431 }
3432#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003433#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003434 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003435 int i;
3436 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003437 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3438 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003439
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003440 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003441 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3442 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 +01003443 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003444 cfgerr++;
3445 }
3446 else {
3447 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3448 EC_KEY_free(ecdh);
3449 }
3450 }
3451#endif
3452
Emeric Brunfc0421f2012-09-07 17:30:07 +02003453 return cfgerr;
3454}
3455
Evan Broderbe554312013-06-27 00:05:25 -07003456static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3457{
3458 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3459 size_t prefixlen, suffixlen;
3460
3461 /* Trivial case */
3462 if (strcmp(pattern, hostname) == 0)
3463 return 1;
3464
Evan Broderbe554312013-06-27 00:05:25 -07003465 /* The rest of this logic is based on RFC 6125, section 6.4.3
3466 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3467
Emeric Bruna848dae2013-10-08 11:27:28 +02003468 pattern_wildcard = NULL;
3469 pattern_left_label_end = pattern;
3470 while (*pattern_left_label_end != '.') {
3471 switch (*pattern_left_label_end) {
3472 case 0:
3473 /* End of label not found */
3474 return 0;
3475 case '*':
3476 /* If there is more than one wildcards */
3477 if (pattern_wildcard)
3478 return 0;
3479 pattern_wildcard = pattern_left_label_end;
3480 break;
3481 }
3482 pattern_left_label_end++;
3483 }
3484
3485 /* If it's not trivial and there is no wildcard, it can't
3486 * match */
3487 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003488 return 0;
3489
3490 /* Make sure all labels match except the leftmost */
3491 hostname_left_label_end = strchr(hostname, '.');
3492 if (!hostname_left_label_end
3493 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3494 return 0;
3495
3496 /* Make sure the leftmost label of the hostname is long enough
3497 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003498 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003499 return 0;
3500
3501 /* Finally compare the string on either side of the
3502 * wildcard */
3503 prefixlen = pattern_wildcard - pattern;
3504 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003505 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3506 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003507 return 0;
3508
3509 return 1;
3510}
3511
3512static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3513{
3514 SSL *ssl;
3515 struct connection *conn;
3516 char *servername;
3517
3518 int depth;
3519 X509 *cert;
3520 STACK_OF(GENERAL_NAME) *alt_names;
3521 int i;
3522 X509_NAME *cert_subject;
3523 char *str;
3524
3525 if (ok == 0)
3526 return ok;
3527
3528 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003529 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003530
3531 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3532
3533 /* We only need to verify the CN on the actual server cert,
3534 * not the indirect CAs */
3535 depth = X509_STORE_CTX_get_error_depth(ctx);
3536 if (depth != 0)
3537 return ok;
3538
3539 /* At this point, the cert is *not* OK unless we can find a
3540 * hostname match */
3541 ok = 0;
3542
3543 cert = X509_STORE_CTX_get_current_cert(ctx);
3544 /* It seems like this might happen if verify peer isn't set */
3545 if (!cert)
3546 return ok;
3547
3548 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3549 if (alt_names) {
3550 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3551 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3552 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003553#if OPENSSL_VERSION_NUMBER < 0x00907000L
3554 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3555#else
Evan Broderbe554312013-06-27 00:05:25 -07003556 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003557#endif
Evan Broderbe554312013-06-27 00:05:25 -07003558 ok = ssl_sock_srv_hostcheck(str, servername);
3559 OPENSSL_free(str);
3560 }
3561 }
3562 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003563 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003564 }
3565
3566 cert_subject = X509_get_subject_name(cert);
3567 i = -1;
3568 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3569 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003570 ASN1_STRING *value;
3571 value = X509_NAME_ENTRY_get_data(entry);
3572 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003573 ok = ssl_sock_srv_hostcheck(str, servername);
3574 OPENSSL_free(str);
3575 }
3576 }
3577
3578 return ok;
3579}
3580
Emeric Brun94324a42012-10-11 14:00:19 +02003581/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003582int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003583{
Willy Tarreau03209342016-12-22 17:08:28 +01003584 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003585 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003586 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003587 SSL_OP_ALL | /* all known workarounds for bugs */
3588 SSL_OP_NO_SSLv2 |
3589 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003590 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003591 SSL_MODE_ENABLE_PARTIAL_WRITE |
3592 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003593 SSL_MODE_RELEASE_BUFFERS |
3594 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003595 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003596 SSL_CTX *ctx = NULL;
Emeric Brun94324a42012-10-11 14:00:19 +02003597
Thierry Fournier383085f2013-01-24 14:15:43 +01003598 /* Make sure openssl opens /dev/urandom before the chroot */
3599 if (!ssl_initialize_random()) {
3600 Alert("OpenSSL random data generator initialization failed.\n");
3601 cfgerr++;
3602 }
3603
Willy Tarreaufce03112015-01-15 21:32:40 +01003604 /* Automatic memory computations need to know we use SSL there */
3605 global.ssl_used_backend = 1;
3606
3607 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003608 srv->ssl_ctx.reused_sess = NULL;
3609 if (srv->use_ssl)
3610 srv->xprt = &ssl_sock;
3611 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003612 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003613
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003614#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL || defined OPENSSL_IS_BORINGSSL)
3615 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12) {
3616 ctx = SSL_CTX_new(TLS_client_method());
3617 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
3618 SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION);
3619 }
3620 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11) {
3621 ctx = SSL_CTX_new(TLS_client_method());
3622 SSL_CTX_set_min_proto_version(ctx, TLS1_1_VERSION);
3623 SSL_CTX_set_max_proto_version(ctx, TLS1_1_VERSION);
3624 }
3625 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10) {
3626 ctx = SSL_CTX_new(TLS_client_method());
3627 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
3628 SSL_CTX_set_max_proto_version(ctx, TLS1_VERSION);
3629 }
3630 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3631 ctx = SSL_CTX_new(TLS_client_method());
3632 SSL_CTX_set_min_proto_version(ctx, SSL3_VERSION);
3633 SSL_CTX_set_max_proto_version(ctx, SSL3_VERSION);
3634 }
3635#else
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003636#if SSL_OP_NO_TLSv1_2
3637 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3638 ctx = SSL_CTX_new(TLSv1_2_client_method());
3639#endif
3640#if SSL_OP_NO_TLSv1_1
3641 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3642 ctx = SSL_CTX_new(TLSv1_1_client_method());
3643#endif
3644 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3645 ctx = SSL_CTX_new(TLSv1_client_method());
3646#ifndef OPENSSL_NO_SSL3
3647 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
3648 ctx = SSL_CTX_new(SSLv3_client_method());
3649#endif
Emeric Brunfa5c5c82017-04-28 16:19:51 +02003650#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003651 if (!ctx) {
3652 ctx = SSL_CTX_new(SSLv23_client_method());
3653 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3654 options |= SSL_OP_NO_SSLv3;
3655 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3656 options |= SSL_OP_NO_TLSv1;
3657 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3658 options |= SSL_OP_NO_TLSv1_1;
3659 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3660 options |= SSL_OP_NO_TLSv1_2;
3661 }
3662 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3663 options |= SSL_OP_NO_TICKET;
3664 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02003665 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3666 proxy_type_str(curproxy), curproxy->id,
3667 srv->id);
3668 cfgerr++;
3669 return cfgerr;
3670 }
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003671 SSL_CTX_set_options(ctx, options);
3672 SSL_CTX_set_mode(ctx, mode);
3673 srv->ssl_ctx.ctx = ctx;
3674
Emeric Bruna7aa3092012-10-26 12:58:00 +02003675 if (srv->ssl_ctx.client_crt) {
3676 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3677 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3678 proxy_type_str(curproxy), curproxy->id,
3679 srv->id, srv->ssl_ctx.client_crt);
3680 cfgerr++;
3681 }
3682 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3683 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3684 proxy_type_str(curproxy), curproxy->id,
3685 srv->id, srv->ssl_ctx.client_crt);
3686 cfgerr++;
3687 }
3688 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3689 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3690 proxy_type_str(curproxy), curproxy->id,
3691 srv->id, srv->ssl_ctx.client_crt);
3692 cfgerr++;
3693 }
3694 }
Emeric Brun94324a42012-10-11 14:00:19 +02003695
Emeric Brun850efd52014-01-29 12:24:34 +01003696 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3697 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01003698 switch (srv->ssl_ctx.verify) {
3699 case SSL_SOCK_VERIFY_NONE:
3700 verify = SSL_VERIFY_NONE;
3701 break;
3702 case SSL_SOCK_VERIFY_REQUIRED:
3703 verify = SSL_VERIFY_PEER;
3704 break;
3705 }
Evan Broderbe554312013-06-27 00:05:25 -07003706 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003707 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003708 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003709 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003710 if (srv->ssl_ctx.ca_file) {
3711 /* load CAfile to verify */
3712 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003713 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003714 curproxy->id, srv->id,
3715 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3716 cfgerr++;
3717 }
3718 }
Emeric Brun850efd52014-01-29 12:24:34 +01003719 else {
3720 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003721 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 +01003722 curproxy->id, srv->id,
3723 srv->conf.file, srv->conf.line);
3724 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003725 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003726 curproxy->id, srv->id,
3727 srv->conf.file, srv->conf.line);
3728 cfgerr++;
3729 }
Emeric Brunef42d922012-10-11 16:11:36 +02003730#ifdef X509_V_FLAG_CRL_CHECK
3731 if (srv->ssl_ctx.crl_file) {
3732 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3733
3734 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003735 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003736 curproxy->id, srv->id,
3737 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3738 cfgerr++;
3739 }
3740 else {
3741 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3742 }
3743 }
3744#endif
3745 }
3746
Emeric Brun94324a42012-10-11 14:00:19 +02003747 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3748 if (srv->ssl_ctx.ciphers &&
3749 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3750 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3751 curproxy->id, srv->id,
3752 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3753 cfgerr++;
3754 }
3755
3756 return cfgerr;
3757}
3758
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003759/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003760 * be NULL, in which case nothing is done. Returns the number of errors
3761 * encountered.
3762 */
Willy Tarreau03209342016-12-22 17:08:28 +01003763int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003764{
3765 struct ebmb_node *node;
3766 struct sni_ctx *sni;
3767 int err = 0;
3768
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003769 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003770 return 0;
3771
Willy Tarreaufce03112015-01-15 21:32:40 +01003772 /* Automatic memory computations need to know we use SSL there */
3773 global.ssl_used_frontend = 1;
3774
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003775 /* Make sure openssl opens /dev/urandom before the chroot */
3776 if (!ssl_initialize_random()) {
3777 Alert("OpenSSL random data generator initialization failed.\n");
3778 err++;
3779 }
3780 /* Create initial_ctx used to start the ssl connection before do switchctx */
3781 if (!bind_conf->initial_ctx) {
3782 bind_conf->initial_ctx = ssl_sock_initial_ctx(bind_conf);
3783 /* It should not be necessary to call this function, but it's
3784 necessary first to check and move all initialisation related
3785 to initial_ctx in ssl_sock_initial_ctx. */
3786 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
3787 }
Emeric Brun0bed9942014-10-30 19:25:24 +01003788 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003789 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003790
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003791 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003792 while (node) {
3793 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003794 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3795 /* only initialize the CTX on its first occurrence and
3796 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003797 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003798 node = ebmb_next(node);
3799 }
3800
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003801 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003802 while (node) {
3803 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003804 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3805 /* only initialize the CTX on its first occurrence and
3806 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003807 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003808 node = ebmb_next(node);
3809 }
3810 return err;
3811}
3812
Willy Tarreau55d37912016-12-21 23:38:39 +01003813/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3814 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3815 * alerts are directly emitted since the rest of the stack does it below.
3816 */
3817int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3818{
3819 struct proxy *px = bind_conf->frontend;
3820 int alloc_ctx;
3821 int err;
3822
3823 if (!bind_conf->is_ssl) {
3824 if (bind_conf->default_ctx) {
3825 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3826 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3827 }
3828 return 0;
3829 }
3830 if (!bind_conf->default_ctx) {
3831 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3832 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3833 return -1;
3834 }
3835
Willy Tarreauef934602016-12-22 23:12:01 +01003836 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003837 if (alloc_ctx < 0) {
3838 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3839 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");
3840 else
3841 Alert("Unable to allocate SSL session cache.\n");
3842 return -1;
3843 }
3844
3845 err = 0;
3846 /* initialize all certificate contexts */
3847 err += ssl_sock_prepare_all_ctx(bind_conf);
3848
3849 /* initialize CA variables if the certificates generation is enabled */
3850 err += ssl_sock_load_ca(bind_conf);
3851
3852 return -err;
3853}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003854
3855/* release ssl context allocated for servers. */
3856void ssl_sock_free_srv_ctx(struct server *srv)
3857{
3858 if (srv->ssl_ctx.ctx)
3859 SSL_CTX_free(srv->ssl_ctx.ctx);
3860}
3861
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003862/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003863 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3864 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003865void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003866{
3867 struct ebmb_node *node, *back;
3868 struct sni_ctx *sni;
3869
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003870 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003871 return;
3872
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003873 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003874 while (node) {
3875 sni = ebmb_entry(node, struct sni_ctx, name);
3876 back = ebmb_next(node);
3877 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003878 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003879 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003880 ssl_sock_free_ssl_conf(sni->conf);
3881 free(sni->conf);
3882 sni->conf = NULL;
3883 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003884 free(sni);
3885 node = back;
3886 }
3887
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003888 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003889 while (node) {
3890 sni = ebmb_entry(node, struct sni_ctx, name);
3891 back = ebmb_next(node);
3892 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003893 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003894 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003895 ssl_sock_free_ssl_conf(sni->conf);
3896 free(sni->conf);
3897 sni->conf = NULL;
3898 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003899 free(sni);
3900 node = back;
3901 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003902 SSL_CTX_free(bind_conf->initial_ctx);
3903 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003904 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003905 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003906}
3907
Willy Tarreau795cdab2016-12-22 17:30:54 +01003908/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3909void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3910{
3911 ssl_sock_free_ca(bind_conf);
3912 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003913 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003914 free(bind_conf->ca_sign_file);
3915 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003916 if (bind_conf->keys_ref) {
3917 free(bind_conf->keys_ref->filename);
3918 free(bind_conf->keys_ref->tlskeys);
3919 LIST_DEL(&bind_conf->keys_ref->list);
3920 free(bind_conf->keys_ref);
3921 }
3922 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003923 bind_conf->ca_sign_pass = NULL;
3924 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003925}
3926
Christopher Faulet31af49d2015-06-09 17:29:50 +02003927/* Load CA cert file and private key used to generate certificates */
3928int
Willy Tarreau03209342016-12-22 17:08:28 +01003929ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003930{
Willy Tarreau03209342016-12-22 17:08:28 +01003931 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003932 FILE *fp;
3933 X509 *cacert = NULL;
3934 EVP_PKEY *capkey = NULL;
3935 int err = 0;
3936
3937 if (!bind_conf || !bind_conf->generate_certs)
3938 return err;
3939
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003940#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01003941 if (global_ssl.ctx_cache)
3942 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003943 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003944#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003945
Christopher Faulet31af49d2015-06-09 17:29:50 +02003946 if (!bind_conf->ca_sign_file) {
3947 Alert("Proxy '%s': cannot enable certificate generation, "
3948 "no CA certificate File configured at [%s:%d].\n",
3949 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003950 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003951 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003952
3953 /* read in the CA certificate */
3954 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3955 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3956 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003957 goto load_error;
3958 }
3959 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3960 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3961 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003962 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003963 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003964 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003965 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3966 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3967 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003968 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003969 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003970
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003971 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003972 bind_conf->ca_sign_cert = cacert;
3973 bind_conf->ca_sign_pkey = capkey;
3974 return err;
3975
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003976 read_error:
3977 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003978 if (capkey) EVP_PKEY_free(capkey);
3979 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003980 load_error:
3981 bind_conf->generate_certs = 0;
3982 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003983 return err;
3984}
3985
3986/* Release CA cert and private key used to generate certificated */
3987void
3988ssl_sock_free_ca(struct bind_conf *bind_conf)
3989{
3990 if (!bind_conf)
3991 return;
3992
3993 if (bind_conf->ca_sign_pkey)
3994 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3995 if (bind_conf->ca_sign_cert)
3996 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003997 bind_conf->ca_sign_pkey = NULL;
3998 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003999}
4000
Emeric Brun46591952012-05-18 15:47:34 +02004001/*
4002 * This function is called if SSL * context is not yet allocated. The function
4003 * is designed to be called before any other data-layer operation and sets the
4004 * handshake flag on the connection. It is safe to call it multiple times.
4005 * It returns 0 on success and -1 in error case.
4006 */
4007static int ssl_sock_init(struct connection *conn)
4008{
4009 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004010 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004011 return 0;
4012
Willy Tarreau3c728722014-01-23 13:50:42 +01004013 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004014 return 0;
4015
Willy Tarreau20879a02012-12-03 16:32:10 +01004016 if (global.maxsslconn && sslconns >= global.maxsslconn) {
4017 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02004018 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004019 }
Willy Tarreau403edff2012-09-06 11:58:37 +02004020
Emeric Brun46591952012-05-18 15:47:34 +02004021 /* If it is in client mode initiate SSL session
4022 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004023 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004024 int may_retry = 1;
4025
4026 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02004027 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004028 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004029 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004030 if (may_retry--) {
4031 pool_gc2();
4032 goto retry_connect;
4033 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004034 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004035 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004036 }
Emeric Brun46591952012-05-18 15:47:34 +02004037
Emeric Brun46591952012-05-18 15:47:34 +02004038 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004039 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4040 SSL_free(conn->xprt_ctx);
4041 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004042 if (may_retry--) {
4043 pool_gc2();
4044 goto retry_connect;
4045 }
Emeric Brun55476152014-11-12 17:35:37 +01004046 conn->err_code = CO_ER_SSL_NO_MEM;
4047 return -1;
4048 }
Emeric Brun46591952012-05-18 15:47:34 +02004049
Evan Broderbe554312013-06-27 00:05:25 -07004050 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004051 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4052 SSL_free(conn->xprt_ctx);
4053 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004054 if (may_retry--) {
4055 pool_gc2();
4056 goto retry_connect;
4057 }
Emeric Brun55476152014-11-12 17:35:37 +01004058 conn->err_code = CO_ER_SSL_NO_MEM;
4059 return -1;
4060 }
4061
4062 SSL_set_connect_state(conn->xprt_ctx);
4063 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4064 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4065 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4066 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4067 }
4068 }
Evan Broderbe554312013-06-27 00:05:25 -07004069
Emeric Brun46591952012-05-18 15:47:34 +02004070 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004071 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004072
4073 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004074 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004075 return 0;
4076 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004077 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004078 int may_retry = 1;
4079
4080 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004081 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004082 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004083 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004084 if (may_retry--) {
4085 pool_gc2();
4086 goto retry_accept;
4087 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004088 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004089 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004090 }
Emeric Brun46591952012-05-18 15:47:34 +02004091
Emeric Brun46591952012-05-18 15:47:34 +02004092 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004093 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4094 SSL_free(conn->xprt_ctx);
4095 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004096 if (may_retry--) {
4097 pool_gc2();
4098 goto retry_accept;
4099 }
Emeric Brun55476152014-11-12 17:35:37 +01004100 conn->err_code = CO_ER_SSL_NO_MEM;
4101 return -1;
4102 }
Emeric Brun46591952012-05-18 15:47:34 +02004103
Emeric Brune1f38db2012-09-03 20:36:47 +02004104 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004105 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4106 SSL_free(conn->xprt_ctx);
4107 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004108 if (may_retry--) {
4109 pool_gc2();
4110 goto retry_accept;
4111 }
Emeric Brun55476152014-11-12 17:35:37 +01004112 conn->err_code = CO_ER_SSL_NO_MEM;
4113 return -1;
4114 }
4115
4116 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004117
Emeric Brun46591952012-05-18 15:47:34 +02004118 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004119 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004120
4121 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004122 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004123 return 0;
4124 }
4125 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004126 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004127 return -1;
4128}
4129
4130
4131/* This is the callback which is used when an SSL handshake is pending. It
4132 * updates the FD status if it wants some polling before being called again.
4133 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4134 * otherwise it returns non-zero and removes itself from the connection's
4135 * flags (the bit is provided in <flag> by the caller).
4136 */
4137int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4138{
4139 int ret;
4140
Willy Tarreau3c728722014-01-23 13:50:42 +01004141 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004142 return 0;
4143
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004144 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004145 goto out_error;
4146
Emeric Brun674b7432012-11-08 19:21:55 +01004147 /* If we use SSL_do_handshake to process a reneg initiated by
4148 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4149 * Usually SSL_write and SSL_read are used and process implicitly
4150 * the reneg handshake.
4151 * Here we use SSL_peek as a workaround for reneg.
4152 */
4153 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4154 char c;
4155
4156 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4157 if (ret <= 0) {
4158 /* handshake may have not been completed, let's find why */
4159 ret = SSL_get_error(conn->xprt_ctx, ret);
4160 if (ret == SSL_ERROR_WANT_WRITE) {
4161 /* SSL handshake needs to write, L4 connection may not be ready */
4162 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004163 __conn_sock_want_send(conn);
4164 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004165 return 0;
4166 }
4167 else if (ret == SSL_ERROR_WANT_READ) {
4168 /* handshake may have been completed but we have
4169 * no more data to read.
4170 */
4171 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4172 ret = 1;
4173 goto reneg_ok;
4174 }
4175 /* SSL handshake needs to read, L4 connection is ready */
4176 if (conn->flags & CO_FL_WAIT_L4_CONN)
4177 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4178 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004179 __conn_sock_want_recv(conn);
4180 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004181 return 0;
4182 }
4183 else if (ret == SSL_ERROR_SYSCALL) {
4184 /* if errno is null, then connection was successfully established */
4185 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4186 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004187 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004188#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4189 conn->err_code = CO_ER_SSL_HANDSHAKE;
4190#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004191 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004192#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004193 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4194 empty_handshake = state == TLS_ST_BEFORE;
4195#else
4196 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4197#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004198 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004199 if (!errno) {
4200 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4201 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4202 else
4203 conn->err_code = CO_ER_SSL_EMPTY;
4204 }
4205 else {
4206 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4207 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4208 else
4209 conn->err_code = CO_ER_SSL_ABORT;
4210 }
4211 }
4212 else {
4213 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4214 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004215 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004216 conn->err_code = CO_ER_SSL_HANDSHAKE;
4217 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004218#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004219 }
Emeric Brun674b7432012-11-08 19:21:55 +01004220 goto out_error;
4221 }
4222 else {
4223 /* Fail on all other handshake errors */
4224 /* Note: OpenSSL may leave unread bytes in the socket's
4225 * buffer, causing an RST to be emitted upon close() on
4226 * TCP sockets. We first try to drain possibly pending
4227 * data to avoid this as much as possible.
4228 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004229 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004230 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004231 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4232 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004233 goto out_error;
4234 }
4235 }
4236 /* read some data: consider handshake completed */
4237 goto reneg_ok;
4238 }
4239
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004240 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004241 if (ret != 1) {
4242 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004243 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004244
4245 if (ret == SSL_ERROR_WANT_WRITE) {
4246 /* SSL handshake needs to write, L4 connection may not be ready */
4247 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004248 __conn_sock_want_send(conn);
4249 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004250 return 0;
4251 }
4252 else if (ret == SSL_ERROR_WANT_READ) {
4253 /* SSL handshake needs to read, L4 connection is ready */
4254 if (conn->flags & CO_FL_WAIT_L4_CONN)
4255 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4256 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004257 __conn_sock_want_recv(conn);
4258 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004259 return 0;
4260 }
Willy Tarreau89230192012-09-28 20:22:13 +02004261 else if (ret == SSL_ERROR_SYSCALL) {
4262 /* if errno is null, then connection was successfully established */
4263 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4264 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004265 if (!conn->err_code) {
4266#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4267 conn->err_code = CO_ER_SSL_HANDSHAKE;
4268#else
4269 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004270#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004271 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4272 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004273#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004274 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004275#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004276 if (empty_handshake) {
4277 if (!errno) {
4278 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4279 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4280 else
4281 conn->err_code = CO_ER_SSL_EMPTY;
4282 }
4283 else {
4284 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4285 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4286 else
4287 conn->err_code = CO_ER_SSL_ABORT;
4288 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004289 }
4290 else {
4291 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4292 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4293 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004294 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004295 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004296#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004297 }
Willy Tarreau89230192012-09-28 20:22:13 +02004298 goto out_error;
4299 }
Emeric Brun46591952012-05-18 15:47:34 +02004300 else {
4301 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004302 /* Note: OpenSSL may leave unread bytes in the socket's
4303 * buffer, causing an RST to be emitted upon close() on
4304 * TCP sockets. We first try to drain possibly pending
4305 * data to avoid this as much as possible.
4306 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004307 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004308 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004309 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4310 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004311 goto out_error;
4312 }
4313 }
4314
Emeric Brun674b7432012-11-08 19:21:55 +01004315reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004316 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004317 if (!SSL_session_reused(conn->xprt_ctx)) {
4318 if (objt_server(conn->target)) {
4319 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4320 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4321 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4322
Emeric Brun46591952012-05-18 15:47:34 +02004323 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004324 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004325 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004326 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4327 }
Emeric Brun46591952012-05-18 15:47:34 +02004328
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004329 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4330 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004331 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004332 else {
4333 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4334 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4335 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4336 }
Emeric Brun46591952012-05-18 15:47:34 +02004337 }
4338
4339 /* The connection is now established at both layers, it's time to leave */
4340 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4341 return 1;
4342
4343 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004344 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004345 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004346 ERR_clear_error();
4347
Emeric Brun9fa89732012-10-04 17:09:56 +02004348 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004349 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4350 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4351 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004352 }
4353
Emeric Brun46591952012-05-18 15:47:34 +02004354 /* Fail on all other handshake errors */
4355 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004356 if (!conn->err_code)
4357 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004358 return 0;
4359}
4360
4361/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004362 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004363 * buffer wraps, in which case a second call may be performed. The connection's
4364 * flags are updated with whatever special event is detected (error, read0,
4365 * empty). The caller is responsible for taking care of those events and
4366 * avoiding the call if inappropriate. The function does not call the
4367 * connection's polling update function, so the caller is responsible for this.
4368 */
4369static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4370{
4371 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004372 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004373
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004374 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004375 goto out_error;
4376
4377 if (conn->flags & CO_FL_HANDSHAKE)
4378 /* a handshake was requested */
4379 return 0;
4380
Willy Tarreauabf08d92014-01-14 11:31:27 +01004381 /* let's realign the buffer to optimize I/O */
4382 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004383 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004384
4385 /* read the largest possible block. For this, we perform only one call
4386 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4387 * in which case we accept to do it once again. A new attempt is made on
4388 * EINTR too.
4389 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004390 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004391 /* first check if we have some room after p+i */
4392 try = buf->data + buf->size - (buf->p + buf->i);
4393 /* otherwise continue between data and p-o */
4394 if (try <= 0) {
4395 try = buf->p - (buf->data + buf->o);
4396 if (try <= 0)
4397 break;
4398 }
4399 if (try > count)
4400 try = count;
4401
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004402 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004403 if (conn->flags & CO_FL_ERROR) {
4404 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004405 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004406 }
Emeric Brun46591952012-05-18 15:47:34 +02004407 if (ret > 0) {
4408 buf->i += ret;
4409 done += ret;
4410 if (ret < try)
4411 break;
4412 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004413 }
4414 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004415 ret = SSL_get_error(conn->xprt_ctx, ret);
4416 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004417 /* error on protocol or underlying transport */
4418 if ((ret != SSL_ERROR_SYSCALL)
4419 || (errno && (errno != EAGAIN)))
4420 conn->flags |= CO_FL_ERROR;
4421
Emeric Brun644cde02012-12-14 11:21:13 +01004422 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004423 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004424 ERR_clear_error();
4425 }
Emeric Brun46591952012-05-18 15:47:34 +02004426 goto read0;
4427 }
4428 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004429 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004430 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004431 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004432 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004433 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004434 break;
4435 }
4436 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004437 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4438 /* handshake is running, and it may need to re-enable read */
4439 conn->flags |= CO_FL_SSL_WAIT_HS;
4440 __conn_sock_want_recv(conn);
4441 break;
4442 }
Emeric Brun46591952012-05-18 15:47:34 +02004443 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004444 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004445 break;
4446 }
4447 /* otherwise it's a real error */
4448 goto out_error;
4449 }
4450 }
4451 return done;
4452
4453 read0:
4454 conn_sock_read0(conn);
4455 return done;
4456 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004457 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004458 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004459 ERR_clear_error();
4460
Emeric Brun46591952012-05-18 15:47:34 +02004461 conn->flags |= CO_FL_ERROR;
4462 return done;
4463}
4464
4465
4466/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004467 * <flags> may contain some CO_SFL_* flags to hint the system about other
4468 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004469 * Only one call to send() is performed, unless the buffer wraps, in which case
4470 * a second call may be performed. The connection's flags are updated with
4471 * whatever special event is detected (error, empty). The caller is responsible
4472 * for taking care of those events and avoiding the call if inappropriate. The
4473 * function does not call the connection's polling update function, so the caller
4474 * is responsible for this.
4475 */
4476static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4477{
4478 int ret, try, done;
4479
4480 done = 0;
4481
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004482 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004483 goto out_error;
4484
4485 if (conn->flags & CO_FL_HANDSHAKE)
4486 /* a handshake was requested */
4487 return 0;
4488
4489 /* send the largest possible block. For this we perform only one call
4490 * to send() unless the buffer wraps and we exactly fill the first hunk,
4491 * in which case we accept to do it once again.
4492 */
4493 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004494 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004495
Willy Tarreau7bed9452014-02-02 02:00:24 +01004496 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004497 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004498 global_ssl.max_record && try > global_ssl.max_record) {
4499 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004500 }
4501 else {
4502 /* we need to keep the information about the fact that
4503 * we're not limiting the upcoming send(), because if it
4504 * fails, we'll have to retry with at least as many data.
4505 */
4506 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4507 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004508
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004509 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004510
Emeric Brune1f38db2012-09-03 20:36:47 +02004511 if (conn->flags & CO_FL_ERROR) {
4512 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004513 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004514 }
Emeric Brun46591952012-05-18 15:47:34 +02004515 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004516 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4517
Emeric Brun46591952012-05-18 15:47:34 +02004518 buf->o -= ret;
4519 done += ret;
4520
Willy Tarreau5fb38032012-12-16 19:39:09 +01004521 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004522 /* optimize data alignment in the buffer */
4523 buf->p = buf->data;
4524
4525 /* if the system buffer is full, don't insist */
4526 if (ret < try)
4527 break;
4528 }
4529 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004530 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004531 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004532 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4533 /* handshake is running, and it may need to re-enable write */
4534 conn->flags |= CO_FL_SSL_WAIT_HS;
4535 __conn_sock_want_send(conn);
4536 break;
4537 }
Emeric Brun46591952012-05-18 15:47:34 +02004538 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004539 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004540 break;
4541 }
4542 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004543 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004544 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004545 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004546 break;
4547 }
4548 goto out_error;
4549 }
4550 }
4551 return done;
4552
4553 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004554 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004555 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004556 ERR_clear_error();
4557
Emeric Brun46591952012-05-18 15:47:34 +02004558 conn->flags |= CO_FL_ERROR;
4559 return done;
4560}
4561
Emeric Brun46591952012-05-18 15:47:34 +02004562static void ssl_sock_close(struct connection *conn) {
4563
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004564 if (conn->xprt_ctx) {
4565 SSL_free(conn->xprt_ctx);
4566 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004567 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004568 }
Emeric Brun46591952012-05-18 15:47:34 +02004569}
4570
4571/* This function tries to perform a clean shutdown on an SSL connection, and in
4572 * any case, flags the connection as reusable if no handshake was in progress.
4573 */
4574static void ssl_sock_shutw(struct connection *conn, int clean)
4575{
4576 if (conn->flags & CO_FL_HANDSHAKE)
4577 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004578 if (!clean)
4579 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004580 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004581 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004582 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004583 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004584 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004585 ERR_clear_error();
4586 }
Emeric Brun46591952012-05-18 15:47:34 +02004587}
4588
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004589/* used for logging, may be changed for a sample fetch later */
4590const char *ssl_sock_get_cipher_name(struct connection *conn)
4591{
4592 if (!conn->xprt && !conn->xprt_ctx)
4593 return NULL;
4594 return SSL_get_cipher_name(conn->xprt_ctx);
4595}
4596
4597/* used for logging, may be changed for a sample fetch later */
4598const char *ssl_sock_get_proto_version(struct connection *conn)
4599{
4600 if (!conn->xprt && !conn->xprt_ctx)
4601 return NULL;
4602 return SSL_get_version(conn->xprt_ctx);
4603}
4604
Willy Tarreau8d598402012-10-22 17:58:39 +02004605/* Extract a serial from a cert, and copy it to a chunk.
4606 * Returns 1 if serial is found and copied, 0 if no serial found and
4607 * -1 if output is not large enough.
4608 */
4609static int
4610ssl_sock_get_serial(X509 *crt, struct chunk *out)
4611{
4612 ASN1_INTEGER *serial;
4613
4614 serial = X509_get_serialNumber(crt);
4615 if (!serial)
4616 return 0;
4617
4618 if (out->size < serial->length)
4619 return -1;
4620
4621 memcpy(out->str, serial->data, serial->length);
4622 out->len = serial->length;
4623 return 1;
4624}
4625
Emeric Brun43e79582014-10-29 19:03:26 +01004626/* Extract a cert to der, and copy it to a chunk.
4627 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4628 * -1 if output is not large enough.
4629 */
4630static int
4631ssl_sock_crt2der(X509 *crt, struct chunk *out)
4632{
4633 int len;
4634 unsigned char *p = (unsigned char *)out->str;;
4635
4636 len =i2d_X509(crt, NULL);
4637 if (len <= 0)
4638 return 1;
4639
4640 if (out->size < len)
4641 return -1;
4642
4643 i2d_X509(crt,&p);
4644 out->len = len;
4645 return 1;
4646}
4647
Emeric Brunce5ad802012-10-22 14:11:22 +02004648
4649/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4650 * Returns 1 if serial is found and copied, 0 if no valid time found
4651 * and -1 if output is not large enough.
4652 */
4653static int
4654ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4655{
4656 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4657 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4658
4659 if (gentm->length < 12)
4660 return 0;
4661 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4662 return 0;
4663 if (out->size < gentm->length-2)
4664 return -1;
4665
4666 memcpy(out->str, gentm->data+2, gentm->length-2);
4667 out->len = gentm->length-2;
4668 return 1;
4669 }
4670 else if (tm->type == V_ASN1_UTCTIME) {
4671 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4672
4673 if (utctm->length < 10)
4674 return 0;
4675 if (utctm->data[0] >= 0x35)
4676 return 0;
4677 if (out->size < utctm->length)
4678 return -1;
4679
4680 memcpy(out->str, utctm->data, utctm->length);
4681 out->len = utctm->length;
4682 return 1;
4683 }
4684
4685 return 0;
4686}
4687
Emeric Brun87855892012-10-17 17:39:35 +02004688/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4689 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4690 */
4691static int
4692ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4693{
4694 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004695 ASN1_OBJECT *obj;
4696 ASN1_STRING *data;
4697 const unsigned char *data_ptr;
4698 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004699 int i, j, n;
4700 int cur = 0;
4701 const char *s;
4702 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004703 int name_count;
4704
4705 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004706
4707 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004708 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004709 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004710 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004711 else
4712 j = i;
4713
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004714 ne = X509_NAME_get_entry(a, j);
4715 obj = X509_NAME_ENTRY_get_object(ne);
4716 data = X509_NAME_ENTRY_get_data(ne);
4717 data_ptr = ASN1_STRING_get0_data(data);
4718 data_len = ASN1_STRING_length(data);
4719 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004720 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004721 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004722 s = tmp;
4723 }
4724
4725 if (chunk_strcasecmp(entry, s) != 0)
4726 continue;
4727
4728 if (pos < 0)
4729 cur--;
4730 else
4731 cur++;
4732
4733 if (cur != pos)
4734 continue;
4735
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004736 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004737 return -1;
4738
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004739 memcpy(out->str, data_ptr, data_len);
4740 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004741 return 1;
4742 }
4743
4744 return 0;
4745
4746}
4747
4748/* Extract and format full DN from a X509_NAME and copy result into a chunk
4749 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4750 */
4751static int
4752ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4753{
4754 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004755 ASN1_OBJECT *obj;
4756 ASN1_STRING *data;
4757 const unsigned char *data_ptr;
4758 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004759 int i, n, ln;
4760 int l = 0;
4761 const char *s;
4762 char *p;
4763 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004764 int name_count;
4765
4766
4767 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004768
4769 out->len = 0;
4770 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004771 for (i = 0; i < name_count; i++) {
4772 ne = X509_NAME_get_entry(a, i);
4773 obj = X509_NAME_ENTRY_get_object(ne);
4774 data = X509_NAME_ENTRY_get_data(ne);
4775 data_ptr = ASN1_STRING_get0_data(data);
4776 data_len = ASN1_STRING_length(data);
4777 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004778 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004779 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004780 s = tmp;
4781 }
4782 ln = strlen(s);
4783
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004784 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004785 if (l > out->size)
4786 return -1;
4787 out->len = l;
4788
4789 *(p++)='/';
4790 memcpy(p, s, ln);
4791 p += ln;
4792 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004793 memcpy(p, data_ptr, data_len);
4794 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004795 }
4796
4797 if (!out->len)
4798 return 0;
4799
4800 return 1;
4801}
4802
David Safb76832014-05-08 23:42:08 -04004803char *ssl_sock_get_version(struct connection *conn)
4804{
4805 if (!ssl_sock_is_ssl(conn))
4806 return NULL;
4807
4808 return (char *)SSL_get_version(conn->xprt_ctx);
4809}
4810
Willy Tarreau119a4082016-12-22 21:58:38 +01004811/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4812 * to disable SNI.
4813 */
Willy Tarreau63076412015-07-10 11:33:32 +02004814void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4815{
4816#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004817 char *prev_name;
4818
Willy Tarreau63076412015-07-10 11:33:32 +02004819 if (!ssl_sock_is_ssl(conn))
4820 return;
4821
Willy Tarreau119a4082016-12-22 21:58:38 +01004822 /* if the SNI changes, we must destroy the reusable context so that a
4823 * new connection will present a new SNI. As an optimization we could
4824 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4825 * server.
4826 */
4827 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4828 if ((!prev_name && hostname) ||
4829 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4830 SSL_set_session(conn->xprt_ctx, NULL);
4831
Willy Tarreau63076412015-07-10 11:33:32 +02004832 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4833#endif
4834}
4835
Emeric Brun0abf8362014-06-24 18:26:41 +02004836/* Extract peer certificate's common name into the chunk dest
4837 * Returns
4838 * the len of the extracted common name
4839 * or 0 if no CN found in DN
4840 * or -1 on error case (i.e. no peer certificate)
4841 */
4842int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004843{
4844 X509 *crt = NULL;
4845 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004846 const char find_cn[] = "CN";
4847 const struct chunk find_cn_chunk = {
4848 .str = (char *)&find_cn,
4849 .len = sizeof(find_cn)-1
4850 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004851 int result = -1;
David Safb76832014-05-08 23:42:08 -04004852
4853 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004854 goto out;
David Safb76832014-05-08 23:42:08 -04004855
4856 /* SSL_get_peer_certificate, it increase X509 * ref count */
4857 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4858 if (!crt)
4859 goto out;
4860
4861 name = X509_get_subject_name(crt);
4862 if (!name)
4863 goto out;
David Safb76832014-05-08 23:42:08 -04004864
Emeric Brun0abf8362014-06-24 18:26:41 +02004865 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4866out:
David Safb76832014-05-08 23:42:08 -04004867 if (crt)
4868 X509_free(crt);
4869
4870 return result;
4871}
4872
Dave McCowan328fb582014-07-30 10:39:13 -04004873/* returns 1 if client passed a certificate for this session, 0 if not */
4874int ssl_sock_get_cert_used_sess(struct connection *conn)
4875{
4876 X509 *crt = NULL;
4877
4878 if (!ssl_sock_is_ssl(conn))
4879 return 0;
4880
4881 /* SSL_get_peer_certificate, it increase X509 * ref count */
4882 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4883 if (!crt)
4884 return 0;
4885
4886 X509_free(crt);
4887 return 1;
4888}
4889
4890/* returns 1 if client passed a certificate for this connection, 0 if not */
4891int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004892{
4893 if (!ssl_sock_is_ssl(conn))
4894 return 0;
4895
4896 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4897}
4898
4899/* returns result from SSL verify */
4900unsigned int ssl_sock_get_verify_result(struct connection *conn)
4901{
4902 if (!ssl_sock_is_ssl(conn))
4903 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4904
4905 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4906}
4907
Willy Tarreau7875d092012-09-10 08:20:03 +02004908/***** Below are some sample fetching functions for ACL/patterns *****/
4909
Emeric Brune64aef12012-09-21 13:15:06 +02004910/* boolean, returns true if client cert was present */
4911static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004912smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004913{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004914 struct connection *conn;
4915
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004916 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004917 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004918 return 0;
4919
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004920 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004921 smp->flags |= SMP_F_MAY_CHANGE;
4922 return 0;
4923 }
4924
4925 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004926 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004927 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004928
4929 return 1;
4930}
4931
Emeric Brun43e79582014-10-29 19:03:26 +01004932/* binary, returns a certificate in a binary chunk (der/raw).
4933 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4934 * should be use.
4935 */
4936static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004937smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004938{
4939 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4940 X509 *crt = NULL;
4941 int ret = 0;
4942 struct chunk *smp_trash;
4943 struct connection *conn;
4944
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004945 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004946 if (!conn || conn->xprt != &ssl_sock)
4947 return 0;
4948
4949 if (!(conn->flags & CO_FL_CONNECTED)) {
4950 smp->flags |= SMP_F_MAY_CHANGE;
4951 return 0;
4952 }
4953
4954 if (cert_peer)
4955 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4956 else
4957 crt = SSL_get_certificate(conn->xprt_ctx);
4958
4959 if (!crt)
4960 goto out;
4961
4962 smp_trash = get_trash_chunk();
4963 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4964 goto out;
4965
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004966 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004967 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004968 ret = 1;
4969out:
4970 /* SSL_get_peer_certificate, it increase X509 * ref count */
4971 if (cert_peer && crt)
4972 X509_free(crt);
4973 return ret;
4974}
4975
Emeric Brunba841a12014-04-30 17:05:08 +02004976/* binary, returns serial of certificate in a binary chunk.
4977 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4978 * should be use.
4979 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004980static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004981smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004982{
Emeric Brunba841a12014-04-30 17:05:08 +02004983 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004984 X509 *crt = NULL;
4985 int ret = 0;
4986 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004987 struct connection *conn;
4988
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004989 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004990 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004991 return 0;
4992
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004993 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004994 smp->flags |= SMP_F_MAY_CHANGE;
4995 return 0;
4996 }
4997
Emeric Brunba841a12014-04-30 17:05:08 +02004998 if (cert_peer)
4999 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5000 else
5001 crt = SSL_get_certificate(conn->xprt_ctx);
5002
Willy Tarreau8d598402012-10-22 17:58:39 +02005003 if (!crt)
5004 goto out;
5005
Willy Tarreau47ca5452012-12-23 20:22:19 +01005006 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02005007 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
5008 goto out;
5009
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005010 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005011 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02005012 ret = 1;
5013out:
Emeric Brunba841a12014-04-30 17:05:08 +02005014 /* SSL_get_peer_certificate, it increase X509 * ref count */
5015 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02005016 X509_free(crt);
5017 return ret;
5018}
Emeric Brune64aef12012-09-21 13:15:06 +02005019
Emeric Brunba841a12014-04-30 17:05:08 +02005020/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
5021 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5022 * should be use.
5023 */
James Votha051b4a2013-05-14 20:37:59 +02005024static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005025smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02005026{
Emeric Brunba841a12014-04-30 17:05:08 +02005027 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02005028 X509 *crt = NULL;
5029 const EVP_MD *digest;
5030 int ret = 0;
5031 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005032 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02005033
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005034 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005035 if (!conn || conn->xprt != &ssl_sock)
5036 return 0;
5037
5038 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02005039 smp->flags |= SMP_F_MAY_CHANGE;
5040 return 0;
5041 }
5042
Emeric Brunba841a12014-04-30 17:05:08 +02005043 if (cert_peer)
5044 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5045 else
5046 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02005047 if (!crt)
5048 goto out;
5049
5050 smp_trash = get_trash_chunk();
5051 digest = EVP_sha1();
5052 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5053
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005054 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005055 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005056 ret = 1;
5057out:
Emeric Brunba841a12014-04-30 17:05:08 +02005058 /* SSL_get_peer_certificate, it increase X509 * ref count */
5059 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005060 X509_free(crt);
5061 return ret;
5062}
5063
Emeric Brunba841a12014-04-30 17:05:08 +02005064/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5065 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5066 * should be use.
5067 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005068static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005069smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005070{
Emeric Brunba841a12014-04-30 17:05:08 +02005071 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005072 X509 *crt = NULL;
5073 int ret = 0;
5074 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005075 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005076
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005077 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005078 if (!conn || conn->xprt != &ssl_sock)
5079 return 0;
5080
5081 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005082 smp->flags |= SMP_F_MAY_CHANGE;
5083 return 0;
5084 }
5085
Emeric Brunba841a12014-04-30 17:05:08 +02005086 if (cert_peer)
5087 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5088 else
5089 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005090 if (!crt)
5091 goto out;
5092
Willy Tarreau47ca5452012-12-23 20:22:19 +01005093 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005094 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5095 goto out;
5096
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005097 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005098 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005099 ret = 1;
5100out:
Emeric Brunba841a12014-04-30 17:05:08 +02005101 /* SSL_get_peer_certificate, it increase X509 * ref count */
5102 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005103 X509_free(crt);
5104 return ret;
5105}
5106
Emeric Brunba841a12014-04-30 17:05:08 +02005107/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5108 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5109 * should be use.
5110 */
Emeric Brun87855892012-10-17 17:39:35 +02005111static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005112smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005113{
Emeric Brunba841a12014-04-30 17:05:08 +02005114 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005115 X509 *crt = NULL;
5116 X509_NAME *name;
5117 int ret = 0;
5118 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005119 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005120
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005121 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005122 if (!conn || conn->xprt != &ssl_sock)
5123 return 0;
5124
5125 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005126 smp->flags |= SMP_F_MAY_CHANGE;
5127 return 0;
5128 }
5129
Emeric Brunba841a12014-04-30 17:05:08 +02005130 if (cert_peer)
5131 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5132 else
5133 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005134 if (!crt)
5135 goto out;
5136
5137 name = X509_get_issuer_name(crt);
5138 if (!name)
5139 goto out;
5140
Willy Tarreau47ca5452012-12-23 20:22:19 +01005141 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005142 if (args && args[0].type == ARGT_STR) {
5143 int pos = 1;
5144
5145 if (args[1].type == ARGT_SINT)
5146 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005147
5148 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5149 goto out;
5150 }
5151 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5152 goto out;
5153
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005154 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005155 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005156 ret = 1;
5157out:
Emeric Brunba841a12014-04-30 17:05:08 +02005158 /* SSL_get_peer_certificate, it increase X509 * ref count */
5159 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005160 X509_free(crt);
5161 return ret;
5162}
5163
Emeric Brunba841a12014-04-30 17:05:08 +02005164/* string, returns notbefore date in ASN1_UTCTIME format.
5165 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5166 * should be use.
5167 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005168static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005169smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005170{
Emeric Brunba841a12014-04-30 17:05:08 +02005171 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005172 X509 *crt = NULL;
5173 int ret = 0;
5174 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005175 struct connection *conn;
5176
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005177 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005178 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005179 return 0;
5180
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005181 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005182 smp->flags |= SMP_F_MAY_CHANGE;
5183 return 0;
5184 }
5185
Emeric Brunba841a12014-04-30 17:05:08 +02005186 if (cert_peer)
5187 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5188 else
5189 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005190 if (!crt)
5191 goto out;
5192
Willy Tarreau47ca5452012-12-23 20:22:19 +01005193 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005194 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5195 goto out;
5196
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005197 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005198 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005199 ret = 1;
5200out:
Emeric Brunba841a12014-04-30 17:05:08 +02005201 /* SSL_get_peer_certificate, it increase X509 * ref count */
5202 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005203 X509_free(crt);
5204 return ret;
5205}
5206
Emeric Brunba841a12014-04-30 17:05:08 +02005207/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5208 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5209 * should be use.
5210 */
Emeric Brun87855892012-10-17 17:39:35 +02005211static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005212smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005213{
Emeric Brunba841a12014-04-30 17:05:08 +02005214 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005215 X509 *crt = NULL;
5216 X509_NAME *name;
5217 int ret = 0;
5218 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005219 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005220
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005221 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005222 if (!conn || conn->xprt != &ssl_sock)
5223 return 0;
5224
5225 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005226 smp->flags |= SMP_F_MAY_CHANGE;
5227 return 0;
5228 }
5229
Emeric Brunba841a12014-04-30 17:05:08 +02005230 if (cert_peer)
5231 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5232 else
5233 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005234 if (!crt)
5235 goto out;
5236
5237 name = X509_get_subject_name(crt);
5238 if (!name)
5239 goto out;
5240
Willy Tarreau47ca5452012-12-23 20:22:19 +01005241 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005242 if (args && args[0].type == ARGT_STR) {
5243 int pos = 1;
5244
5245 if (args[1].type == ARGT_SINT)
5246 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005247
5248 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5249 goto out;
5250 }
5251 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5252 goto out;
5253
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005254 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005255 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005256 ret = 1;
5257out:
Emeric Brunba841a12014-04-30 17:05:08 +02005258 /* SSL_get_peer_certificate, it increase X509 * ref count */
5259 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005260 X509_free(crt);
5261 return ret;
5262}
Emeric Brun9143d372012-12-20 15:44:16 +01005263
5264/* integer, returns true if current session use a client certificate */
5265static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005266smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005267{
5268 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005269 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005270
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005271 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005272 if (!conn || conn->xprt != &ssl_sock)
5273 return 0;
5274
5275 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005276 smp->flags |= SMP_F_MAY_CHANGE;
5277 return 0;
5278 }
5279
5280 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005281 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005282 if (crt) {
5283 X509_free(crt);
5284 }
5285
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005286 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005287 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005288 return 1;
5289}
5290
Emeric Brunba841a12014-04-30 17:05:08 +02005291/* integer, returns the certificate version
5292 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5293 * should be use.
5294 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005295static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005296smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005297{
Emeric Brunba841a12014-04-30 17:05:08 +02005298 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005299 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005300 struct connection *conn;
5301
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005302 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005303 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005304 return 0;
5305
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005306 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005307 smp->flags |= SMP_F_MAY_CHANGE;
5308 return 0;
5309 }
5310
Emeric Brunba841a12014-04-30 17:05:08 +02005311 if (cert_peer)
5312 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5313 else
5314 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005315 if (!crt)
5316 return 0;
5317
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005318 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005319 /* SSL_get_peer_certificate increase X509 * ref count */
5320 if (cert_peer)
5321 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005322 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005323
5324 return 1;
5325}
5326
Emeric Brunba841a12014-04-30 17:05:08 +02005327/* string, returns the certificate's signature algorithm.
5328 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5329 * should be use.
5330 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005331static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005332smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005333{
Emeric Brunba841a12014-04-30 17:05:08 +02005334 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005335 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005336 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005337 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005338 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005339
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005340 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005341 if (!conn || conn->xprt != &ssl_sock)
5342 return 0;
5343
5344 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005345 smp->flags |= SMP_F_MAY_CHANGE;
5346 return 0;
5347 }
5348
Emeric Brunba841a12014-04-30 17:05:08 +02005349 if (cert_peer)
5350 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5351 else
5352 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005353 if (!crt)
5354 return 0;
5355
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005356 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5357 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005358
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005359 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5360 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005361 /* SSL_get_peer_certificate increase X509 * ref count */
5362 if (cert_peer)
5363 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005364 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005365 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005366
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005367 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005368 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005369 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005370 /* SSL_get_peer_certificate increase X509 * ref count */
5371 if (cert_peer)
5372 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005373
5374 return 1;
5375}
5376
Emeric Brunba841a12014-04-30 17:05:08 +02005377/* string, returns the certificate's key algorithm.
5378 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5379 * should be use.
5380 */
Emeric Brun521a0112012-10-22 12:22:55 +02005381static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005382smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005383{
Emeric Brunba841a12014-04-30 17:05:08 +02005384 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005385 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005386 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005387 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005388 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005389
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005390 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005391 if (!conn || conn->xprt != &ssl_sock)
5392 return 0;
5393
5394 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005395 smp->flags |= SMP_F_MAY_CHANGE;
5396 return 0;
5397 }
5398
Emeric Brunba841a12014-04-30 17:05:08 +02005399 if (cert_peer)
5400 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5401 else
5402 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005403 if (!crt)
5404 return 0;
5405
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005406 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5407 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005408
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005409 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5410 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005411 /* SSL_get_peer_certificate increase X509 * ref count */
5412 if (cert_peer)
5413 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005414 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005415 }
Emeric Brun521a0112012-10-22 12:22:55 +02005416
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005417 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005418 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005419 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005420 if (cert_peer)
5421 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005422
5423 return 1;
5424}
5425
Emeric Brun645ae792014-04-30 14:21:06 +02005426/* boolean, returns true if front conn. transport layer is SSL.
5427 * This function is also usable on backend conn if the fetch keyword 5th
5428 * char is 'b'.
5429 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005430static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005431smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005432{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005433 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5434 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005435
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005436 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005437 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005438 return 1;
5439}
5440
Emeric Brun2525b6b2012-10-18 15:59:43 +02005441/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005442static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005443smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005444{
5445#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005446 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005447
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005448 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005449 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005450 conn->xprt_ctx &&
5451 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005452 return 1;
5453#else
5454 return 0;
5455#endif
5456}
5457
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005458/* boolean, returns true if client session has been resumed */
5459static int
5460smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5461{
5462 struct connection *conn = objt_conn(smp->sess->origin);
5463
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005464 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005465 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005466 conn->xprt_ctx &&
5467 SSL_session_reused(conn->xprt_ctx);
5468 return 1;
5469}
5470
Emeric Brun645ae792014-04-30 14:21:06 +02005471/* string, returns the used cipher if front conn. transport layer is SSL.
5472 * This function is also usable on backend conn if the fetch keyword 5th
5473 * char is 'b'.
5474 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005475static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005476smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005477{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005478 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5479 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005480
Willy Tarreaube508f12016-03-10 11:47:01 +01005481 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005482 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005483 return 0;
5484
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005485 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5486 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005487 return 0;
5488
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005489 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005490 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005491 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005492
5493 return 1;
5494}
5495
Emeric Brun645ae792014-04-30 14:21:06 +02005496/* integer, returns the algoritm's keysize if front conn. transport layer
5497 * is SSL.
5498 * This function is also usable on backend conn if the fetch keyword 5th
5499 * char is 'b'.
5500 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005501static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005502smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005503{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005504 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5505 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005506
Willy Tarreaue237fe12016-03-10 17:05:28 +01005507 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005508
Emeric Brun589fcad2012-10-16 14:13:26 +02005509 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005510 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005511 return 0;
5512
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005513 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005514 return 0;
5515
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005516 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005517 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005518
5519 return 1;
5520}
5521
Emeric Brun645ae792014-04-30 14:21:06 +02005522/* integer, returns the used keysize if front conn. transport layer is SSL.
5523 * This function is also usable on backend conn if the fetch keyword 5th
5524 * char is 'b'.
5525 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005526static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005527smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005528{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005529 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5530 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005531
Emeric Brun589fcad2012-10-16 14:13:26 +02005532 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005533 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5534 return 0;
5535
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005536 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5537 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005538 return 0;
5539
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005540 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005541
5542 return 1;
5543}
5544
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005545#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005546static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005547smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005548{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005549 struct connection *conn;
5550
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005551 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005552 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005553
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005554 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005555 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5556 return 0;
5557
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005558 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005559 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005560 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005561
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005562 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005563 return 0;
5564
5565 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005566}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005567#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005568
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005569#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005570static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005571smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005572{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005573 struct connection *conn;
5574
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005575 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005576 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005577
Willy Tarreaue26bf052015-05-12 10:30:12 +02005578 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005579 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005580 return 0;
5581
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005582 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005583 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005584 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005585
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005586 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005587 return 0;
5588
5589 return 1;
5590}
5591#endif
5592
Emeric Brun645ae792014-04-30 14:21:06 +02005593/* string, returns the used protocol if front conn. transport layer is SSL.
5594 * This function is also usable on backend conn if the fetch keyword 5th
5595 * char is 'b'.
5596 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005597static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005598smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005599{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005600 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5601 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005602
Emeric Brun589fcad2012-10-16 14:13:26 +02005603 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005604 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5605 return 0;
5606
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005607 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5608 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005609 return 0;
5610
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005611 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005612 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005613 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005614
5615 return 1;
5616}
5617
Willy Tarreau87b09662015-04-03 00:22:06 +02005618/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005619 * This function is also usable on backend conn if the fetch keyword 5th
5620 * char is 'b'.
5621 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005622static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005623smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005624{
5625#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005626 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5627 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005628
Willy Tarreaue237fe12016-03-10 17:05:28 +01005629 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005630
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005631 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005632 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005633
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005634 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5635 return 0;
5636
Willy Tarreau192252e2015-04-04 01:47:55 +02005637 ssl_sess = SSL_get_session(conn->xprt_ctx);
5638 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005639 return 0;
5640
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005641 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5642 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005643 return 0;
5644
5645 return 1;
5646#else
5647 return 0;
5648#endif
5649}
5650
5651static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005652smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005653{
5654#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005655 struct connection *conn;
5656
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005657 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005658 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005659
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005660 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005661 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5662 return 0;
5663
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005664 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5665 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005666 return 0;
5667
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005668 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005669 return 1;
5670#else
5671 return 0;
5672#endif
5673}
5674
David Sc1ad52e2014-04-08 18:48:47 -04005675static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005676smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
5677{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005678 struct connection *conn;
5679 struct ssl_capture *capture;
5680
5681 conn = objt_conn(smp->sess->origin);
5682 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5683 return 0;
5684
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005685 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005686 if (!capture)
5687 return 0;
5688
5689 smp->flags = SMP_F_CONST;
5690 smp->data.type = SMP_T_BIN;
5691 smp->data.u.str.str = capture->ciphersuite;
5692 smp->data.u.str.len = capture->ciphersuite_len;
5693 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005694}
5695
5696static int
5697smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
5698{
5699 struct chunk *data;
5700
5701 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5702 return 0;
5703
5704 data = get_trash_chunk();
5705 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
5706 smp->data.type = SMP_T_BIN;
5707 smp->data.u.str = *data;
5708 return 1;
5709}
5710
5711static int
5712smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
5713{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005714 struct connection *conn;
5715 struct ssl_capture *capture;
5716
5717 conn = objt_conn(smp->sess->origin);
5718 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5719 return 0;
5720
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005721 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005722 if (!capture)
5723 return 0;
5724
5725 smp->data.type = SMP_T_SINT;
5726 smp->data.u.sint = capture->xxh64;
5727 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005728}
5729
5730static int
5731smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
5732{
5733#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
5734 struct chunk *data;
5735 SSL_CIPHER cipher;
5736 int i;
5737 const char *str;
5738 unsigned char *bin;
5739
5740 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5741 return 0;
5742
5743 /* The cipher algorith must not be SSL_SSLV2, because this
5744 * SSL version seems to not have the same cipher encoding,
5745 * and it is not supported by OpenSSL. Unfortunately, the
5746 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
5747 * with standard defines. We just set the variable to 0,
5748 * ensure that the match with SSL_SSLV2 fails.
5749 */
5750 cipher.algorithm_ssl = 0;
5751
5752 data = get_trash_chunk();
5753 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
5754 bin = (unsigned char *)smp->data.u.str.str + i;
5755 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
5756 str = SSL_CIPHER_standard_name(&cipher);
5757 if (!str || strcmp(str, "UNKNOWN") == 0)
5758 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
5759 else
5760 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
5761 }
5762 smp->data.type = SMP_T_STR;
5763 smp->data.u.str = *data;
5764 return 1;
5765#else
5766 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
5767#endif
5768}
5769
5770static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005771smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005772{
5773#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005774 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5775 smp->strm ? smp->strm->si[1].end : NULL);
5776
David Sc1ad52e2014-04-08 18:48:47 -04005777 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005778 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005779
5780 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005781 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5782 return 0;
5783
5784 if (!(conn->flags & CO_FL_CONNECTED)) {
5785 smp->flags |= SMP_F_MAY_CHANGE;
5786 return 0;
5787 }
5788
5789 finished_trash = get_trash_chunk();
5790 if (!SSL_session_reused(conn->xprt_ctx))
5791 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5792 else
5793 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5794
5795 if (!finished_len)
5796 return 0;
5797
Emeric Brunb73a9b02014-04-30 18:49:19 +02005798 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005799 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005800 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005801
5802 return 1;
5803#else
5804 return 0;
5805#endif
5806}
5807
Emeric Brun2525b6b2012-10-18 15:59:43 +02005808/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005809static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005810smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005811{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005812 struct connection *conn;
5813
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005814 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005815 if (!conn || conn->xprt != &ssl_sock)
5816 return 0;
5817
5818 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005819 smp->flags = SMP_F_MAY_CHANGE;
5820 return 0;
5821 }
5822
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005823 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005824 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005825 smp->flags = 0;
5826
5827 return 1;
5828}
5829
Emeric Brun2525b6b2012-10-18 15:59:43 +02005830/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005831static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005832smp_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 +02005833{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005834 struct connection *conn;
5835
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005836 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005837 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005838 return 0;
5839
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005840 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005841 smp->flags = SMP_F_MAY_CHANGE;
5842 return 0;
5843 }
5844
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005845 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005846 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005847 smp->flags = 0;
5848
5849 return 1;
5850}
5851
Emeric Brun2525b6b2012-10-18 15:59:43 +02005852/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005853static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005854smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005855{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005856 struct connection *conn;
5857
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005858 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005859 if (!conn || conn->xprt != &ssl_sock)
5860 return 0;
5861
5862 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005863 smp->flags = SMP_F_MAY_CHANGE;
5864 return 0;
5865 }
5866
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005867 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005868 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005869 smp->flags = 0;
5870
5871 return 1;
5872}
5873
Emeric Brun2525b6b2012-10-18 15:59:43 +02005874/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005875static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005876smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005877{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005878 struct connection *conn;
5879
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005880 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005881 if (!conn || conn->xprt != &ssl_sock)
5882 return 0;
5883
5884 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005885 smp->flags = SMP_F_MAY_CHANGE;
5886 return 0;
5887 }
5888
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005889 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005890 return 0;
5891
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005892 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005893 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005894 smp->flags = 0;
5895
5896 return 1;
5897}
5898
Emeric Brunfb510ea2012-10-05 12:00:26 +02005899/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005900static 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 +02005901{
5902 if (!*args[cur_arg + 1]) {
5903 if (err)
5904 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5905 return ERR_ALERT | ERR_FATAL;
5906 }
5907
Willy Tarreauef934602016-12-22 23:12:01 +01005908 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5909 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005910 else
5911 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005912
Emeric Brund94b3fe2012-09-20 18:23:56 +02005913 return 0;
5914}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005915static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5916{
5917 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5918}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005919
Christopher Faulet31af49d2015-06-09 17:29:50 +02005920/* parse the "ca-sign-file" bind keyword */
5921static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5922{
5923 if (!*args[cur_arg + 1]) {
5924 if (err)
5925 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5926 return ERR_ALERT | ERR_FATAL;
5927 }
5928
Willy Tarreauef934602016-12-22 23:12:01 +01005929 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5930 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005931 else
5932 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5933
5934 return 0;
5935}
5936
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005937/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005938static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5939{
5940 if (!*args[cur_arg + 1]) {
5941 if (err)
5942 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5943 return ERR_ALERT | ERR_FATAL;
5944 }
5945 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5946 return 0;
5947}
5948
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005949/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005950static 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 +02005951{
5952 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005953 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005954 return ERR_ALERT | ERR_FATAL;
5955 }
5956
Emeric Brun76d88952012-10-05 15:47:31 +02005957 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005958 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005959 return 0;
5960}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005961static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5962{
5963 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5964}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005965/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005966static 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 +02005967{
Willy Tarreau38011032013-08-13 16:59:39 +02005968 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005969
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005970 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005971 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005972 return ERR_ALERT | ERR_FATAL;
5973 }
5974
Willy Tarreauef934602016-12-22 23:12:01 +01005975 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5976 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005977 memprintf(err, "'%s' : path too long", args[cur_arg]);
5978 return ERR_ALERT | ERR_FATAL;
5979 }
Willy Tarreauef934602016-12-22 23:12:01 +01005980 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005981 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005982 return ERR_ALERT | ERR_FATAL;
5983
5984 return 0;
5985 }
5986
Willy Tarreau03209342016-12-22 17:08:28 +01005987 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005988 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005989
5990 return 0;
5991}
5992
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005993/* parse the "crt-list" bind keyword */
5994static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5995{
5996 if (!*args[cur_arg + 1]) {
5997 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5998 return ERR_ALERT | ERR_FATAL;
5999 }
6000
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006001 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02006002 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006003 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02006004 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01006005
6006 return 0;
6007}
6008
Emeric Brunfb510ea2012-10-05 12:00:26 +02006009/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006010static 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 +02006011{
Emeric Brun051cdab2012-10-02 19:25:50 +02006012#ifndef X509_V_FLAG_CRL_CHECK
6013 if (err)
6014 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
6015 return ERR_ALERT | ERR_FATAL;
6016#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02006017 if (!*args[cur_arg + 1]) {
6018 if (err)
6019 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
6020 return ERR_ALERT | ERR_FATAL;
6021 }
Emeric Brun2b58d042012-09-20 17:10:03 +02006022
Willy Tarreauef934602016-12-22 23:12:01 +01006023 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
6024 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006025 else
6026 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02006027
Emeric Brun2b58d042012-09-20 17:10:03 +02006028 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02006029#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02006030}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006031static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6032{
6033 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
6034}
Emeric Brun2b58d042012-09-20 17:10:03 +02006035
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01006036/* parse the "curves" bind keyword keyword */
6037static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
6038{
6039#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
6040 if (!*args[cur_arg + 1]) {
6041 if (err)
6042 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
6043 return ERR_ALERT | ERR_FATAL;
6044 }
6045 conf->curves = strdup(args[cur_arg + 1]);
6046 return 0;
6047#else
6048 if (err)
6049 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6050 return ERR_ALERT | ERR_FATAL;
6051#endif
6052}
6053static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6054{
6055 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6056}
6057
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006058/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006059static 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 +02006060{
6061#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6062 if (err)
6063 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6064 return ERR_ALERT | ERR_FATAL;
6065#elif defined(OPENSSL_NO_ECDH)
6066 if (err)
6067 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6068 return ERR_ALERT | ERR_FATAL;
6069#else
6070 if (!*args[cur_arg + 1]) {
6071 if (err)
6072 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6073 return ERR_ALERT | ERR_FATAL;
6074 }
6075
6076 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006077
6078 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006079#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006080}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006081static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6082{
6083 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6084}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006085
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006086/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006087static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6088{
6089 int code;
6090 char *p = args[cur_arg + 1];
6091 unsigned long long *ignerr = &conf->crt_ignerr;
6092
6093 if (!*p) {
6094 if (err)
6095 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6096 return ERR_ALERT | ERR_FATAL;
6097 }
6098
6099 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6100 ignerr = &conf->ca_ignerr;
6101
6102 if (strcmp(p, "all") == 0) {
6103 *ignerr = ~0ULL;
6104 return 0;
6105 }
6106
6107 while (p) {
6108 code = atoi(p);
6109 if ((code <= 0) || (code > 63)) {
6110 if (err)
6111 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6112 args[cur_arg], code, args[cur_arg + 1]);
6113 return ERR_ALERT | ERR_FATAL;
6114 }
6115 *ignerr |= 1ULL << code;
6116 p = strchr(p, ',');
6117 if (p)
6118 p++;
6119 }
6120
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006121 return 0;
6122}
6123
6124/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006125static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006126{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006127#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006128 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
6129 return 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006130#else
6131 if (err)
6132 memprintf(err, "'%s' : library does not support protocol SSLv3", args[cur_arg]);
6133 return ERR_ALERT | ERR_FATAL;
6134#endif
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006135}
6136
6137/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006138static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006139{
6140 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006141 return 0;
6142}
6143
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006144/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006145static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006146{
6147#if SSL_OP_NO_TLSv1_1
6148 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
6149 return 0;
6150#else
6151 if (err)
6152 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
6153 return ERR_ALERT | ERR_FATAL;
6154#endif
6155}
6156
6157/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006158static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006159{
6160#if SSL_OP_NO_TLSv1_2
6161 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
6162 return 0;
6163#else
6164 if (err)
6165 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
6166 return ERR_ALERT | ERR_FATAL;
6167#endif
6168}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006169
Emeric Brun2d0c4822012-10-02 13:45:20 +02006170/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006171static 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 +02006172{
Emeric Brun89675492012-10-05 13:48:26 +02006173 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006174 return 0;
6175}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006176
Emeric Brun9b3009b2012-10-05 11:55:06 +02006177/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006178static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006179{
Emeric Brun89675492012-10-05 13:48:26 +02006180 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006181 return 0;
6182}
6183
Emeric Brun9b3009b2012-10-05 11:55:06 +02006184/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006185static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02006186{
Emeric Brun89675492012-10-05 13:48:26 +02006187 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02006188 return 0;
6189}
6190
Emeric Brun9b3009b2012-10-05 11:55:06 +02006191/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006192static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02006193{
Emeric Brun89675492012-10-05 13:48:26 +02006194 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02006195 return 0;
6196}
6197
Emeric Brun9b3009b2012-10-05 11:55:06 +02006198/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006199static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006200{
Emeric Brun89675492012-10-05 13:48:26 +02006201 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006202 return 0;
6203}
6204
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006205/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006206static 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 +02006207{
6208#ifdef OPENSSL_NPN_NEGOTIATED
6209 char *p1, *p2;
6210
6211 if (!*args[cur_arg + 1]) {
6212 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6213 return ERR_ALERT | ERR_FATAL;
6214 }
6215
6216 free(conf->npn_str);
6217
Willy Tarreau3724da12016-02-12 17:11:12 +01006218 /* the NPN string is built as a suite of (<len> <name>)*,
6219 * so we reuse each comma to store the next <len> and need
6220 * one more for the end of the string.
6221 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006222 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006223 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006224 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6225
6226 /* replace commas with the name length */
6227 p1 = conf->npn_str;
6228 p2 = p1 + 1;
6229 while (1) {
6230 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6231 if (!p2)
6232 p2 = p1 + 1 + strlen(p1 + 1);
6233
6234 if (p2 - (p1 + 1) > 255) {
6235 *p2 = '\0';
6236 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6237 return ERR_ALERT | ERR_FATAL;
6238 }
6239
6240 *p1 = p2 - (p1 + 1);
6241 p1 = p2;
6242
6243 if (!*p2)
6244 break;
6245
6246 *(p2++) = '\0';
6247 }
6248 return 0;
6249#else
6250 if (err)
6251 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6252 return ERR_ALERT | ERR_FATAL;
6253#endif
6254}
6255
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006256static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6257{
6258 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6259}
6260
Willy Tarreauab861d32013-04-02 02:30:41 +02006261/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006262static 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 +02006263{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006264#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006265 char *p1, *p2;
6266
6267 if (!*args[cur_arg + 1]) {
6268 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6269 return ERR_ALERT | ERR_FATAL;
6270 }
6271
6272 free(conf->alpn_str);
6273
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006274 /* the ALPN string is built as a suite of (<len> <name>)*,
6275 * so we reuse each comma to store the next <len> and need
6276 * one more for the end of the string.
6277 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006278 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006279 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006280 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6281
6282 /* replace commas with the name length */
6283 p1 = conf->alpn_str;
6284 p2 = p1 + 1;
6285 while (1) {
6286 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6287 if (!p2)
6288 p2 = p1 + 1 + strlen(p1 + 1);
6289
6290 if (p2 - (p1 + 1) > 255) {
6291 *p2 = '\0';
6292 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6293 return ERR_ALERT | ERR_FATAL;
6294 }
6295
6296 *p1 = p2 - (p1 + 1);
6297 p1 = p2;
6298
6299 if (!*p2)
6300 break;
6301
6302 *(p2++) = '\0';
6303 }
6304 return 0;
6305#else
6306 if (err)
6307 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6308 return ERR_ALERT | ERR_FATAL;
6309#endif
6310}
6311
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006312static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6313{
6314 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6315}
6316
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006317/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006318static 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 +02006319{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006320 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006321 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006322
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006323 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6324 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006325 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02006326
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006327 return 0;
6328}
6329
Christopher Faulet31af49d2015-06-09 17:29:50 +02006330/* parse the "generate-certificates" bind keyword */
6331static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6332{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006333#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006334 conf->generate_certs = 1;
6335#else
6336 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6337 err && *err ? *err : "");
6338#endif
6339 return 0;
6340}
6341
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006342/* parse the "strict-sni" bind keyword */
6343static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6344{
6345 conf->strict_sni = 1;
6346 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006347}
6348
6349/* parse the "tls-ticket-keys" bind keyword */
6350static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6351{
6352#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6353 FILE *f;
6354 int i = 0;
6355 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006356 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006357
6358 if (!*args[cur_arg + 1]) {
6359 if (err)
6360 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6361 return ERR_ALERT | ERR_FATAL;
6362 }
6363
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006364 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6365 if(keys_ref) {
6366 conf->keys_ref = keys_ref;
6367 return 0;
6368 }
6369
Vincent Bernat02779b62016-04-03 13:48:43 +02006370 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006371 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006372
6373 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6374 if (err)
6375 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6376 return ERR_ALERT | ERR_FATAL;
6377 }
6378
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006379 keys_ref->filename = strdup(args[cur_arg + 1]);
6380
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006381 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6382 int len = strlen(thisline);
6383 /* Strip newline characters from the end */
6384 if(thisline[len - 1] == '\n')
6385 thisline[--len] = 0;
6386
6387 if(thisline[len - 1] == '\r')
6388 thisline[--len] = 0;
6389
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006390 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 +01006391 if (err)
6392 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006393 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006394 return ERR_ALERT | ERR_FATAL;
6395 }
6396 i++;
6397 }
6398
6399 if (i < TLS_TICKETS_NO) {
6400 if (err)
6401 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 +02006402 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006403 return ERR_ALERT | ERR_FATAL;
6404 }
6405
6406 fclose(f);
6407
6408 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006409 i -= 2;
6410 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006411 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006412 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006413
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006414 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6415
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006416 return 0;
6417#else
6418 if (err)
6419 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6420 return ERR_ALERT | ERR_FATAL;
6421#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006422}
6423
Emeric Brund94b3fe2012-09-20 18:23:56 +02006424/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006425static 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 +02006426{
6427 if (!*args[cur_arg + 1]) {
6428 if (err)
6429 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6430 return ERR_ALERT | ERR_FATAL;
6431 }
6432
6433 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006434 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006435 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006436 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006437 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006438 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006439 else {
6440 if (err)
6441 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6442 args[cur_arg], args[cur_arg + 1]);
6443 return ERR_ALERT | ERR_FATAL;
6444 }
6445
6446 return 0;
6447}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006448static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6449{
6450 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6451}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006452
Willy Tarreau92faadf2012-10-10 23:04:25 +02006453/************** "server" keywords ****************/
6454
Emeric Brunef42d922012-10-11 16:11:36 +02006455/* parse the "ca-file" server keyword */
6456static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6457{
6458 if (!*args[*cur_arg + 1]) {
6459 if (err)
6460 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6461 return ERR_ALERT | ERR_FATAL;
6462 }
6463
Willy Tarreauef934602016-12-22 23:12:01 +01006464 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6465 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006466 else
6467 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6468
6469 return 0;
6470}
6471
Willy Tarreau92faadf2012-10-10 23:04:25 +02006472/* parse the "check-ssl" server keyword */
6473static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6474{
6475 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006476 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6477 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6478 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02006479 return 0;
6480}
6481
6482/* parse the "ciphers" server keyword */
6483static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6484{
6485 if (!*args[*cur_arg + 1]) {
6486 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6487 return ERR_ALERT | ERR_FATAL;
6488 }
6489
6490 free(newsrv->ssl_ctx.ciphers);
6491 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6492 return 0;
6493}
6494
Emeric Brunef42d922012-10-11 16:11:36 +02006495/* parse the "crl-file" server keyword */
6496static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6497{
6498#ifndef X509_V_FLAG_CRL_CHECK
6499 if (err)
6500 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6501 return ERR_ALERT | ERR_FATAL;
6502#else
6503 if (!*args[*cur_arg + 1]) {
6504 if (err)
6505 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6506 return ERR_ALERT | ERR_FATAL;
6507 }
6508
Willy Tarreauef934602016-12-22 23:12:01 +01006509 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6510 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006511 else
6512 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6513
6514 return 0;
6515#endif
6516}
6517
Emeric Bruna7aa3092012-10-26 12:58:00 +02006518/* parse the "crt" server keyword */
6519static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6520{
6521 if (!*args[*cur_arg + 1]) {
6522 if (err)
6523 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6524 return ERR_ALERT | ERR_FATAL;
6525 }
6526
Willy Tarreauef934602016-12-22 23:12:01 +01006527 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6528 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006529 else
6530 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6531
6532 return 0;
6533}
Emeric Brunef42d922012-10-11 16:11:36 +02006534
Willy Tarreau92faadf2012-10-10 23:04:25 +02006535/* parse the "force-sslv3" server keyword */
6536static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6537{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006538#ifndef OPENSSL_NO_SSL3
Willy Tarreau92faadf2012-10-10 23:04:25 +02006539 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6540 return 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006541#else
6542 if (err)
6543 memprintf(err, "'%s' : library does not support protocol SSLv3", args[*cur_arg]);
6544 return ERR_ALERT | ERR_FATAL;
6545#endif
Willy Tarreau92faadf2012-10-10 23:04:25 +02006546}
6547
6548/* parse the "force-tlsv10" server keyword */
6549static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6550{
6551 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6552 return 0;
6553}
6554
6555/* parse the "force-tlsv11" server keyword */
6556static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6557{
6558#if SSL_OP_NO_TLSv1_1
6559 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6560 return 0;
6561#else
6562 if (err)
6563 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6564 return ERR_ALERT | ERR_FATAL;
6565#endif
6566}
6567
6568/* parse the "force-tlsv12" server keyword */
6569static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6570{
6571#if SSL_OP_NO_TLSv1_2
6572 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6573 return 0;
6574#else
6575 if (err)
6576 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6577 return ERR_ALERT | ERR_FATAL;
6578#endif
6579}
6580
Frédéric Lécaille340ae602017-03-13 10:38:04 +01006581/* parse the "no-check-ssl" server keyword */
6582static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6583{
6584 newsrv->check.use_ssl = 0;
6585 free(newsrv->ssl_ctx.ciphers);
6586 newsrv->ssl_ctx.ciphers = NULL;
6587 newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
6588 return 0;
6589}
6590
Frédéric Lécaille96980922017-03-13 10:54:52 +01006591/* parse the "no-force-sslv3" server keyword */
6592static int srv_parse_no_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6593{
6594#ifndef OPENSSL_NO_SSL3
6595 newsrv->ssl_ctx.options &= ~SRV_SSL_O_USE_SSLV3;
6596 return 0;
6597#else
6598 if (err)
6599 memprintf(err, "'%s' : library does not support protocol SSLv3", args[*cur_arg]);
6600 return ERR_ALERT | ERR_FATAL;
6601#endif
6602}
6603
6604/* parse the "no-force-tlsv10" server keyword */
6605static int srv_parse_no_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6606{
6607 newsrv->ssl_ctx.options &= ~SRV_SSL_O_USE_TLSV10;
6608 return 0;
6609}
6610
6611/* parse the "no-force-tlsv11" server keyword */
6612static int srv_parse_no_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6613{
6614#if SSL_OP_NO_TLSv1_1
6615 newsrv->ssl_ctx.options &= ~SRV_SSL_O_USE_TLSV11;
6616 return 0;
6617#else
6618 if (err)
6619 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6620 return ERR_ALERT | ERR_FATAL;
6621#endif
6622}
6623
6624/* parse the "no-force-tlsv12" server keyword */
6625static int srv_parse_no_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6626{
6627#if SSL_OP_NO_TLSv1_2
6628 newsrv->ssl_ctx.options &= ~SRV_SSL_O_USE_TLSV12;
6629 return 0;
6630#else
6631 if (err)
6632 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6633 return ERR_ALERT | ERR_FATAL;
6634#endif
6635}
6636
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01006637/* parse the "no-send-proxy-v2-ssl" server keyword */
6638static int srv_parse_no_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6639{
6640 newsrv->pp_opts &= ~SRV_PP_V2;
6641 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
6642 return 0;
6643}
6644
6645/* parse the "no-send-proxy-v2-ssl-cn" server keyword */
6646static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6647{
6648 newsrv->pp_opts &= ~SRV_PP_V2;
6649 newsrv->pp_opts &= ~SRV_PP_V2_SSL;
6650 newsrv->pp_opts &= ~SRV_PP_V2_SSL_CN;
6651 return 0;
6652}
6653
Frédéric Lécaillee381d762017-03-13 11:54:17 +01006654/* parse the "no-ssl" server keyword */
6655static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6656{
6657 newsrv->use_ssl = 0;
6658 free(newsrv->ssl_ctx.ciphers);
6659 newsrv->ssl_ctx.ciphers = NULL;
6660 return 0;
6661}
6662
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006663/* parse the "no-ssl-reuse" server keyword */
6664static int srv_parse_no_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
Willy Tarreau92faadf2012-10-10 23:04:25 +02006670/* parse the "no-sslv3" server keyword */
6671static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6672{
6673 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6674 return 0;
6675}
6676
6677/* parse the "no-tlsv10" server keyword */
6678static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6679{
6680 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6681 return 0;
6682}
6683
6684/* parse the "no-tlsv11" server keyword */
6685static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6686{
6687 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6688 return 0;
6689}
6690
6691/* parse the "no-tlsv12" server keyword */
6692static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6693{
6694 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6695 return 0;
6696}
6697
Emeric Brunf9c5c472012-10-11 15:28:34 +02006698/* parse the "no-tls-tickets" server keyword */
6699static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6700{
6701 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6702 return 0;
6703}
David Safb76832014-05-08 23:42:08 -04006704/* parse the "send-proxy-v2-ssl" server keyword */
6705static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6706{
6707 newsrv->pp_opts |= SRV_PP_V2;
6708 newsrv->pp_opts |= SRV_PP_V2_SSL;
6709 return 0;
6710}
6711
6712/* parse the "send-proxy-v2-ssl-cn" server keyword */
6713static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6714{
6715 newsrv->pp_opts |= SRV_PP_V2;
6716 newsrv->pp_opts |= SRV_PP_V2_SSL;
6717 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6718 return 0;
6719}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006720
Willy Tarreau732eac42015-07-09 11:40:25 +02006721/* parse the "sni" server keyword */
6722static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6723{
6724#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6725 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6726 return ERR_ALERT | ERR_FATAL;
6727#else
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006728 char *arg;
Willy Tarreau732eac42015-07-09 11:40:25 +02006729
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006730 arg = args[*cur_arg + 1];
6731 if (!*arg) {
Willy Tarreau732eac42015-07-09 11:40:25 +02006732 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6733 return ERR_ALERT | ERR_FATAL;
6734 }
6735
Frédéric Lécaille9a146de2017-03-20 14:54:41 +01006736 free(newsrv->sni_expr);
6737 newsrv->sni_expr = strdup(arg);
Willy Tarreau732eac42015-07-09 11:40:25 +02006738
Willy Tarreau732eac42015-07-09 11:40:25 +02006739 return 0;
6740#endif
6741}
6742
Willy Tarreau92faadf2012-10-10 23:04:25 +02006743/* parse the "ssl" server keyword */
6744static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6745{
6746 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006747 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6748 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006749 return 0;
6750}
6751
Frédéric Lécaille2cfcdbe2017-03-13 11:32:20 +01006752/* parse the "ssl-reuse" server keyword */
6753static int srv_parse_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6754{
6755 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_REUSE;
6756 return 0;
6757}
6758
6759/* parse the "sslv3" server keyword */
6760static int srv_parse_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6761{
6762 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_SSLV3;
6763 return 0;
6764}
6765
6766/* parse the "tlsv10" server keyword */
6767static int srv_parse_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6768{
6769 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLSV10;
6770 return 0;
6771}
6772
6773/* parse the "tlsv11" server keyword */
6774static int srv_parse_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6775{
6776 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLSV11;
6777 return 0;
6778}
6779
6780/* parse the "tlsv12" server keyword */
6781static int srv_parse_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6782{
6783 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLSV12;
6784 return 0;
6785}
6786
6787/* parse the "tls-tickets" server keyword */
6788static int srv_parse_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6789{
6790 newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_TLS_TICKETS;
6791 return 0;
6792}
6793
Emeric Brunef42d922012-10-11 16:11:36 +02006794/* parse the "verify" server keyword */
6795static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6796{
6797 if (!*args[*cur_arg + 1]) {
6798 if (err)
6799 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6800 return ERR_ALERT | ERR_FATAL;
6801 }
6802
6803 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006804 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006805 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006806 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006807 else {
6808 if (err)
6809 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6810 args[*cur_arg], args[*cur_arg + 1]);
6811 return ERR_ALERT | ERR_FATAL;
6812 }
6813
Evan Broderbe554312013-06-27 00:05:25 -07006814 return 0;
6815}
6816
6817/* parse the "verifyhost" server keyword */
6818static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6819{
6820 if (!*args[*cur_arg + 1]) {
6821 if (err)
6822 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6823 return ERR_ALERT | ERR_FATAL;
6824 }
6825
Frédéric Lécaille273f3212017-03-13 15:52:01 +01006826 free(newsrv->ssl_ctx.verify_host);
Evan Broderbe554312013-06-27 00:05:25 -07006827 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6828
Emeric Brunef42d922012-10-11 16:11:36 +02006829 return 0;
6830}
6831
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006832/* parse the "ssl-default-bind-options" keyword in global section */
6833static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6834 struct proxy *defpx, const char *file, int line,
6835 char **err) {
6836 int i = 1;
6837
6838 if (*(args[i]) == 0) {
6839 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6840 return -1;
6841 }
6842 while (*(args[i])) {
6843 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006844 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006845 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006846 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006847 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006848 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006849 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006850 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006851 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006852 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006853 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006854 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006855 else if (!strcmp(args[i], "force-tlsv11")) {
6856#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006857 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006858#else
6859 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6860 return -1;
6861#endif
6862 }
6863 else if (!strcmp(args[i], "force-tlsv12")) {
6864#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006865 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006866#else
6867 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6868 return -1;
6869#endif
6870 }
6871 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006872 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006873 else {
6874 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6875 return -1;
6876 }
6877 i++;
6878 }
6879 return 0;
6880}
6881
6882/* parse the "ssl-default-server-options" keyword in global section */
6883static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6884 struct proxy *defpx, const char *file, int line,
6885 char **err) {
6886 int i = 1;
6887
6888 if (*(args[i]) == 0) {
6889 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6890 return -1;
6891 }
6892 while (*(args[i])) {
6893 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006894 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006895 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006896 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006897 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006898 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006899 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006900 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006901 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006902 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006903 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006904 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006905 else if (!strcmp(args[i], "force-tlsv11")) {
6906#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006907 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006908#else
6909 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6910 return -1;
6911#endif
6912 }
6913 else if (!strcmp(args[i], "force-tlsv12")) {
6914#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006915 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006916#else
6917 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6918 return -1;
6919#endif
6920 }
6921 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006922 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006923 else {
6924 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6925 return -1;
6926 }
6927 i++;
6928 }
6929 return 0;
6930}
6931
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006932/* parse the "ca-base" / "crt-base" keywords in global section.
6933 * Returns <0 on alert, >0 on warning, 0 on success.
6934 */
6935static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6936 struct proxy *defpx, const char *file, int line,
6937 char **err)
6938{
6939 char **target;
6940
Willy Tarreauef934602016-12-22 23:12:01 +01006941 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006942
6943 if (too_many_args(1, args, err, NULL))
6944 return -1;
6945
6946 if (*target) {
6947 memprintf(err, "'%s' already specified.", args[0]);
6948 return -1;
6949 }
6950
6951 if (*(args[1]) == 0) {
6952 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6953 return -1;
6954 }
6955 *target = strdup(args[1]);
6956 return 0;
6957}
6958
Willy Tarreauf22e9682016-12-21 23:23:19 +01006959/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6960 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6961 */
6962static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6963 struct proxy *defpx, const char *file, int line,
6964 char **err)
6965{
6966 char **target;
6967
Willy Tarreauef934602016-12-22 23:12:01 +01006968 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006969
6970 if (too_many_args(1, args, err, NULL))
6971 return -1;
6972
6973 if (*(args[1]) == 0) {
6974 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6975 return -1;
6976 }
6977
6978 free(*target);
6979 *target = strdup(args[1]);
6980 return 0;
6981}
6982
Willy Tarreau9ceda382016-12-21 23:13:03 +01006983/* parse various global tune.ssl settings consisting in positive integers.
6984 * Returns <0 on alert, >0 on warning, 0 on success.
6985 */
6986static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6987 struct proxy *defpx, const char *file, int line,
6988 char **err)
6989{
6990 int *target;
6991
6992 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6993 target = &global.tune.sslcachesize;
6994 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006995 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006996 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006997 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006998 else if (strcmp(args[0], "maxsslconn") == 0)
6999 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007000 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
7001 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007002 else {
7003 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
7004 return -1;
7005 }
7006
7007 if (too_many_args(1, args, err, NULL))
7008 return -1;
7009
7010 if (*(args[1]) == 0) {
7011 memprintf(err, "'%s' expects an integer argument.", args[0]);
7012 return -1;
7013 }
7014
7015 *target = atoi(args[1]);
7016 if (*target < 0) {
7017 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
7018 return -1;
7019 }
7020 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007021}
7022
7023static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
7024 struct proxy *defpx, const char *file, int line,
7025 char **err)
7026{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007027 int ret;
7028
7029 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
7030 if (ret != 0)
7031 return ret;
7032
7033 if (pool2_ssl_capture) {
7034 memprintf(err, "'%s' is already configured.", args[0]);
7035 return -1;
7036 }
7037
7038 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
7039 if (!pool2_ssl_capture) {
7040 memprintf(err, "Out of memory error.");
7041 return -1;
7042 }
7043 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007044}
7045
7046/* parse "ssl.force-private-cache".
7047 * Returns <0 on alert, >0 on warning, 0 on success.
7048 */
7049static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
7050 struct proxy *defpx, const char *file, int line,
7051 char **err)
7052{
7053 if (too_many_args(0, args, err, NULL))
7054 return -1;
7055
Willy Tarreauef934602016-12-22 23:12:01 +01007056 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01007057 return 0;
7058}
7059
7060/* parse "ssl.lifetime".
7061 * Returns <0 on alert, >0 on warning, 0 on success.
7062 */
7063static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
7064 struct proxy *defpx, const char *file, int line,
7065 char **err)
7066{
7067 const char *res;
7068
7069 if (too_many_args(1, args, err, NULL))
7070 return -1;
7071
7072 if (*(args[1]) == 0) {
7073 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
7074 return -1;
7075 }
7076
Willy Tarreauef934602016-12-22 23:12:01 +01007077 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01007078 if (res) {
7079 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
7080 return -1;
7081 }
7082 return 0;
7083}
7084
7085#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01007086/* parse "ssl-dh-param-file".
7087 * Returns <0 on alert, >0 on warning, 0 on success.
7088 */
7089static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
7090 struct proxy *defpx, const char *file, int line,
7091 char **err)
7092{
7093 if (too_many_args(1, args, err, NULL))
7094 return -1;
7095
7096 if (*(args[1]) == 0) {
7097 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
7098 return -1;
7099 }
7100
7101 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
7102 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
7103 return -1;
7104 }
7105 return 0;
7106}
7107
Willy Tarreau9ceda382016-12-21 23:13:03 +01007108/* parse "ssl.default-dh-param".
7109 * Returns <0 on alert, >0 on warning, 0 on success.
7110 */
7111static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
7112 struct proxy *defpx, const char *file, int line,
7113 char **err)
7114{
7115 if (too_many_args(1, args, err, NULL))
7116 return -1;
7117
7118 if (*(args[1]) == 0) {
7119 memprintf(err, "'%s' expects an integer argument.", args[0]);
7120 return -1;
7121 }
7122
Willy Tarreauef934602016-12-22 23:12:01 +01007123 global_ssl.default_dh_param = atoi(args[1]);
7124 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01007125 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
7126 return -1;
7127 }
7128 return 0;
7129}
7130#endif
7131
7132
William Lallemand32af2032016-10-29 18:09:35 +02007133/* This function is used with TLS ticket keys management. It permits to browse
7134 * each reference. The variable <getnext> must contain the current node,
7135 * <end> point to the root node.
7136 */
7137#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7138static inline
7139struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
7140{
7141 struct tls_keys_ref *ref = getnext;
7142
7143 while (1) {
7144
7145 /* Get next list entry. */
7146 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
7147
7148 /* If the entry is the last of the list, return NULL. */
7149 if (&ref->list == end)
7150 return NULL;
7151
7152 return ref;
7153 }
7154}
7155
7156static inline
7157struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
7158{
7159 int id;
7160 char *error;
7161
7162 /* If the reference starts by a '#', this is numeric id. */
7163 if (reference[0] == '#') {
7164 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7165 id = strtol(reference + 1, &error, 10);
7166 if (*error != '\0')
7167 return NULL;
7168
7169 /* Perform the unique id lookup. */
7170 return tlskeys_ref_lookupid(id);
7171 }
7172
7173 /* Perform the string lookup. */
7174 return tlskeys_ref_lookup(reference);
7175}
7176#endif
7177
7178
7179#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7180
7181static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7182
7183static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7184 return cli_io_handler_tlskeys_files(appctx);
7185}
7186
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007187/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7188 * (next index to be dumped), and cli.p0 (next key reference).
7189 */
William Lallemand32af2032016-10-29 18:09:35 +02007190static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7191
7192 struct stream_interface *si = appctx->owner;
7193
7194 switch (appctx->st2) {
7195 case STAT_ST_INIT:
7196 /* Display the column headers. If the message cannot be sent,
7197 * quit the fucntion with returning 0. The function is called
7198 * later and restart at the state "STAT_ST_INIT".
7199 */
7200 chunk_reset(&trash);
7201
7202 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7203 chunk_appendf(&trash, "# id secret\n");
7204 else
7205 chunk_appendf(&trash, "# id (file)\n");
7206
7207 if (bi_putchk(si_ic(si), &trash) == -1) {
7208 si_applet_cant_put(si);
7209 return 0;
7210 }
7211
William Lallemand32af2032016-10-29 18:09:35 +02007212 /* Now, we start the browsing of the references lists.
7213 * Note that the following call to LIST_ELEM return bad pointer. The only
7214 * available field of this pointer is <list>. It is used with the function
7215 * tlskeys_list_get_next() for retruning the first available entry
7216 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007217 if (appctx->ctx.cli.p0 == NULL) {
7218 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7219 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007220 }
7221
7222 appctx->st2 = STAT_ST_LIST;
7223 /* fall through */
7224
7225 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007226 while (appctx->ctx.cli.p0) {
7227 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7228 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007229
7230 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007231 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007232 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007233
7234 if (appctx->ctx.cli.i1 == 0)
7235 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7236
William Lallemand32af2032016-10-29 18:09:35 +02007237 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007238 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007239 struct chunk *t2 = get_trash_chunk();
7240
7241 chunk_reset(t2);
7242 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007243 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007244 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007245 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007246
7247 if (bi_putchk(si_ic(si), &trash) == -1) {
7248 /* let's try again later from this stream. We add ourselves into
7249 * this stream's users so that it can remove us upon termination.
7250 */
7251 si_applet_cant_put(si);
7252 return 0;
7253 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007254 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007255 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007256 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007257 }
7258 if (bi_putchk(si_ic(si), &trash) == -1) {
7259 /* let's try again later from this stream. We add ourselves into
7260 * this stream's users so that it can remove us upon termination.
7261 */
7262 si_applet_cant_put(si);
7263 return 0;
7264 }
7265
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007266 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007267 break;
7268
7269 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007270 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007271 }
7272
7273 appctx->st2 = STAT_ST_FIN;
7274 /* fall through */
7275
7276 default:
7277 appctx->st2 = STAT_ST_FIN;
7278 return 1;
7279 }
7280 return 0;
7281}
7282
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007283/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007284static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7285{
William Lallemand32af2032016-10-29 18:09:35 +02007286 /* no parameter, shows only file list */
7287 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007288 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007289 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007290 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007291 }
7292
7293 if (args[2][0] == '*') {
7294 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007295 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007296 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007297 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7298 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007299 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007300 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007301 return 1;
7302 }
7303 }
William Lallemand32af2032016-10-29 18:09:35 +02007304 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007305 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007306}
7307
William Lallemand32af2032016-10-29 18:09:35 +02007308static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7309{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007310 struct tls_keys_ref *ref;
7311
William Lallemand32af2032016-10-29 18:09:35 +02007312 /* Expect two parameters: the filename and the new new TLS key in encoding */
7313 if (!*args[3] || !*args[4]) {
7314 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 +01007315 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007316 return 1;
7317 }
7318
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007319 ref = tlskeys_ref_lookup_ref(args[3]);
7320 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007321 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007322 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007323 return 1;
7324 }
7325
7326 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7327 if (trash.len != sizeof(struct tls_sess_key)) {
7328 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007329 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007330 return 1;
7331 }
7332
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007333 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7334 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007335
7336 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007337 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007338 return 1;
7339
7340}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007341#endif
William Lallemand32af2032016-10-29 18:09:35 +02007342
7343static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7344{
7345#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7346 char *err = NULL;
7347
7348 /* Expect one parameter: the new response in base64 encoding */
7349 if (!*args[3]) {
7350 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007351 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007352 return 1;
7353 }
7354
7355 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7356 if (trash.len < 0) {
7357 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007358 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007359 return 1;
7360 }
7361
7362 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7363 if (err) {
7364 memprintf(&err, "%s.\n", err);
7365 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007366 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007367 }
7368 return 1;
7369 }
7370 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007371 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007372 return 1;
7373#else
7374 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 +01007375 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007376 return 1;
7377#endif
7378
7379}
7380
7381/* register cli keywords */
7382static struct cli_kw_list cli_kws = {{ },{
7383#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7384 { { "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 },
7385 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007386#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007387 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007388 { { NULL }, NULL, NULL, NULL }
7389}};
7390
7391
Willy Tarreau7875d092012-09-10 08:20:03 +02007392/* Note: must not be declared <const> as its list will be overwritten.
7393 * Please take care of keeping this list alphabetically sorted.
7394 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007395static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007396 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007397 { "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 +02007398 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7399 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007400 { "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 +02007401 { "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 +02007402 { "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 +02007403 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7404 { "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 +01007405 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007406 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007407 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7408 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7409 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7410 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7411 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7412 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7413 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7414 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007415 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007416 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7417 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007418 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007419 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7420 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7421 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7422 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7423 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7424 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7425 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007426 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007427 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007428 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007429 { "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 +01007430 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007431 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7432 { "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 +02007433 { "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 +02007434#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007435 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007436#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007437#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007438 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007439#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007440 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007441 { "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 +02007442 { "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 +01007443 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7444 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007445 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7446 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7447 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7448 { "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 +02007449 { NULL, NULL, 0, 0, 0 },
7450}};
7451
7452/* Note: must not be declared <const> as its list will be overwritten.
7453 * Please take care of keeping this list alphabetically sorted.
7454 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007455static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007456 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7457 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007458 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007459}};
7460
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007461/* Note: must not be declared <const> as its list will be overwritten.
7462 * Please take care of keeping this list alphabetically sorted, doing so helps
7463 * all code contributors.
7464 * Optional keywords are also declared with a NULL ->parse() function so that
7465 * the config parser can report an appropriate error when a known keyword was
7466 * not enabled.
7467 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007468static struct ssl_bind_kw ssl_bind_kws[] = {
7469 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7470 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7471 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7472 { "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 +01007473 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007474 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007475 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7476 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7477 { NULL, NULL, 0 },
7478};
7479
Willy Tarreau51fb7652012-09-18 18:24:39 +02007480static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007481 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7482 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7483 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007484 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7485 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007486 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7487 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7488 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7489 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7490 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01007491 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007492 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7493 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
7494 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
7495 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
7496 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007497 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007498 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
7499 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
7500 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
7501 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
7502 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7503 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
7504 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7505 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7506 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7507 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007508 { NULL, NULL, 0 },
7509}};
Emeric Brun46591952012-05-18 15:47:34 +02007510
Willy Tarreau92faadf2012-10-10 23:04:25 +02007511/* Note: must not be declared <const> as its list will be overwritten.
7512 * Please take care of keeping this list alphabetically sorted, doing so helps
7513 * all code contributors.
7514 * Optional keywords are also declared with a NULL ->parse() function so that
7515 * the config parser can report an appropriate error when a known keyword was
7516 * not enabled.
7517 */
7518static struct srv_kw_list srv_kws = { "SSL", { }, {
Frédéric Lécaille5e576432017-03-14 15:52:04 +01007519 { "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 +01007520 { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
Frédéric Lécaillebcaf1d72017-03-15 16:20:02 +01007521 { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
Frédéric Lécaille5e576432017-03-14 15:52:04 +01007522 { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
7523 { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
Frédéric Lécaille18388c92017-03-13 13:10:59 +01007524 { "force-sslv3", srv_parse_force_sslv3, 0, 1 }, /* force SSLv3 */
7525 { "force-tlsv10", srv_parse_force_tlsv10, 0, 1 }, /* force TLSv10 */
7526 { "force-tlsv11", srv_parse_force_tlsv11, 0, 1 }, /* force TLSv11 */
7527 { "force-tlsv12", srv_parse_force_tlsv12, 0, 1 }, /* force TLSv12 */
7528 { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
7529 { "no-force-sslv3", srv_parse_no_force_sslv3, 0, 1 }, /* do not force SSLv3 */
7530 { "no-force-tlsv10", srv_parse_no_force_tlsv10, 0, 1 }, /* do not force TLSv10 */
7531 { "no-force-tlsv11", srv_parse_no_force_tlsv11, 0, 1 }, /* do not force TLSv11 */
7532 { "no-force-tlsv12", srv_parse_no_force_tlsv12, 0, 1 }, /* do not force TLSv12 */
Frédéric Lécaillee892c4c2017-03-13 12:08:01 +01007533 { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
7534 { "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 +01007535 { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
7536 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
7537 { "no-sslv3", srv_parse_no_sslv3, 0, 1 }, /* disable SSLv3 */
7538 { "no-tlsv10", srv_parse_no_tlsv10, 0, 1 }, /* disable TLSv10 */
7539 { "no-tlsv11", srv_parse_no_tlsv11, 0, 1 }, /* disable TLSv11 */
7540 { "no-tlsv12", srv_parse_no_tlsv12, 0, 1 }, /* disable TLSv12 */
7541 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
7542 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
7543 { "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 +01007544 { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
Frédéric Lécaille18388c92017-03-13 13:10:59 +01007545 { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
7546 { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
7547 { "sslv3", srv_parse_sslv3, 0, 1 }, /* enable SSLv3 */
7548 { "tlsv10", srv_parse_tlsv10, 0, 1 }, /* enable TLSv10 */
7549 { "tlsv11", srv_parse_tlsv11, 0, 1 }, /* enable TLSv11 */
7550 { "tlsv12", srv_parse_tlsv12, 0, 1 }, /* enable TLSv12 */
7551 { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
Frédéric Lécaille7c8cd582017-03-13 13:41:16 +01007552 { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
Frédéric Lécaille273f3212017-03-13 15:52:01 +01007553 { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007554 { NULL, NULL, 0, 0 },
7555}};
7556
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007557static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007558 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7559 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007560 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007561 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7562 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007563#ifndef OPENSSL_NO_DH
7564 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7565#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007566 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7567#ifndef OPENSSL_NO_DH
7568 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7569#endif
7570 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7571 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7572 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7573 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007574 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007575 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7576 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007577 { 0, NULL, NULL },
7578}};
7579
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007580/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007581static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007582 .snd_buf = ssl_sock_from_buf,
7583 .rcv_buf = ssl_sock_to_buf,
7584 .rcv_pipe = NULL,
7585 .snd_pipe = NULL,
7586 .shutr = NULL,
7587 .shutw = ssl_sock_shutw,
7588 .close = ssl_sock_close,
7589 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007590 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007591 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007592 .prepare_srv = ssl_sock_prepare_srv_ctx,
7593 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007594 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007595};
7596
Daniel Jakots54ffb912015-11-06 20:02:41 +01007597#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007598
7599static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7600{
7601 if (ptr) {
7602 chunk_destroy(ptr);
7603 free(ptr);
7604 }
7605}
7606
7607#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007608static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7609{
7610 pool_free2(pool2_ssl_capture, ptr);
7611}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007612
Emeric Brun46591952012-05-18 15:47:34 +02007613__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007614static void __ssl_sock_init(void)
7615{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007616 char *ptr;
7617
Emeric Brun46591952012-05-18 15:47:34 +02007618 STACK_OF(SSL_COMP)* cm;
7619
Willy Tarreauef934602016-12-22 23:12:01 +01007620 if (global_ssl.listen_default_ciphers)
7621 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7622 if (global_ssl.connect_default_ciphers)
7623 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007624
Willy Tarreau13e14102016-12-22 20:25:26 +01007625 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007626 SSL_library_init();
7627 cm = SSL_COMP_get_compression_methods();
7628 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007629#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007630 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7631#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007632 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 +02007633 sample_register_fetches(&sample_fetch_keywords);
7634 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007635 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007636 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007637 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007638 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007639#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7640 hap_register_post_check(tlskeys_finalize_config);
7641#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007642
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007643 ptr = NULL;
7644 memprintf(&ptr, "Built with OpenSSL version : "
7645#ifdef OPENSSL_IS_BORINGSSL
7646 "BoringSSL\n");
7647#else /* OPENSSL_IS_BORINGSSL */
7648 OPENSSL_VERSION_TEXT
7649 "\nRunning on OpenSSL version : %s%s",
7650 SSLeay_version(SSLEAY_VERSION),
7651 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7652#endif
7653 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7654#if OPENSSL_VERSION_NUMBER < 0x00907000L
7655 "no (library version too old)"
7656#elif defined(OPENSSL_NO_TLSEXT)
7657 "no (disabled via OPENSSL_NO_TLSEXT)"
7658#else
7659 "yes"
7660#endif
7661 "", ptr);
7662
7663 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7664#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7665 "yes"
7666#else
7667#ifdef OPENSSL_NO_TLSEXT
7668 "no (because of OPENSSL_NO_TLSEXT)"
7669#else
7670 "no (version might be too old, 0.9.8f min needed)"
7671#endif
7672#endif
7673 "", ptr);
7674
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007675 hap_register_build_opts(ptr, 1);
7676
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007677 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7678 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007679
7680#ifndef OPENSSL_NO_DH
7681 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7682#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007683
7684 /* Load SSL string for the verbose & debug mode. */
7685 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007686}
7687
Remi Gacogned3a23c32015-05-28 16:39:47 +02007688__attribute__((destructor))
7689static void __ssl_sock_deinit(void)
7690{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007691#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007692 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007693#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007694
Remi Gacogned3a23c32015-05-28 16:39:47 +02007695#ifndef OPENSSL_NO_DH
7696 if (local_dh_1024) {
7697 DH_free(local_dh_1024);
7698 local_dh_1024 = NULL;
7699 }
7700
7701 if (local_dh_2048) {
7702 DH_free(local_dh_2048);
7703 local_dh_2048 = NULL;
7704 }
7705
7706 if (local_dh_4096) {
7707 DH_free(local_dh_4096);
7708 local_dh_4096 = NULL;
7709 }
7710
Remi Gacogne47783ef2015-05-29 15:53:22 +02007711 if (global_dh) {
7712 DH_free(global_dh);
7713 global_dh = NULL;
7714 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007715#endif
7716
7717 ERR_remove_state(0);
7718 ERR_free_strings();
7719
7720 EVP_cleanup();
7721
7722#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7723 CRYPTO_cleanup_all_ex_data();
7724#endif
7725}
7726
7727
Emeric Brun46591952012-05-18 15:47:34 +02007728/*
7729 * Local variables:
7730 * c-indent-level: 8
7731 * c-basic-offset: 8
7732 * End:
7733 */