blob: 91a15af727b09e3276249f51edea831baf1a3e13 [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:
481 if (bs)
482 OCSP_BASICRESP_free(bs);
483
484 if (resp)
485 OCSP_RESPONSE_free(resp);
486
487 return ret;
488}
489/*
490 * External function use to update the OCSP response in the OCSP response's
491 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
492 * to update in DER format.
493 *
494 * Returns 0 on success, 1 in error case.
495 */
496int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
497{
498 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
499}
500
501/*
502 * This function load the OCSP Resonse in DER format contained in file at
503 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
504 *
505 * Returns 0 on success, 1 in error case.
506 */
507static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
508{
509 int fd = -1;
510 int r = 0;
511 int ret = 1;
512
513 fd = open(ocsp_path, O_RDONLY);
514 if (fd == -1) {
515 memprintf(err, "Error opening OCSP response file");
516 goto end;
517 }
518
519 trash.len = 0;
520 while (trash.len < trash.size) {
521 r = read(fd, trash.str + trash.len, trash.size - trash.len);
522 if (r < 0) {
523 if (errno == EINTR)
524 continue;
525
526 memprintf(err, "Error reading OCSP response from file");
527 goto end;
528 }
529 else if (r == 0) {
530 break;
531 }
532 trash.len += r;
533 }
534
535 close(fd);
536 fd = -1;
537
538 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
539end:
540 if (fd != -1)
541 close(fd);
542
543 return ret;
544}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100545#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200546
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100547#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
548static 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)
549{
550 struct tls_sess_key *keys;
551 struct connection *conn;
552 int head;
553 int i;
554
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200555 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200556 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
557 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100558
559 if (enc) {
560 memcpy(key_name, keys[head].name, 16);
561
562 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
563 return -1;
564
565 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
566 return -1;
567
568 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
569
570 return 1;
571 } else {
572 for (i = 0; i < TLS_TICKETS_NO; i++) {
573 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
574 goto found;
575 }
576 return 0;
577
578 found:
579 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
580 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
581 return -1;
582 /* 2 for key renewal, 1 if current key is still valid */
583 return i ? 2 : 1;
584 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200585}
586
587struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
588{
589 struct tls_keys_ref *ref;
590
591 list_for_each_entry(ref, &tlskeys_reference, list)
592 if (ref->filename && strcmp(filename, ref->filename) == 0)
593 return ref;
594 return NULL;
595}
596
597struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
598{
599 struct tls_keys_ref *ref;
600
601 list_for_each_entry(ref, &tlskeys_reference, list)
602 if (ref->unique_id == unique_id)
603 return ref;
604 return NULL;
605}
606
607int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
608 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
609
610 if(!ref) {
611 memprintf(err, "Unable to locate the referenced filename: %s", filename);
612 return 1;
613 }
614
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530615 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
616 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200617
618 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100619}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200620
621/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100622 * automatic ids. It's called just after the basic checks. It returns
623 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200624 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100625static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200626{
627 int i = 0;
628 struct tls_keys_ref *ref, *ref2, *ref3;
629 struct list tkr = LIST_HEAD_INIT(tkr);
630
631 list_for_each_entry(ref, &tlskeys_reference, list) {
632 if (ref->unique_id == -1) {
633 /* Look for the first free id. */
634 while (1) {
635 list_for_each_entry(ref2, &tlskeys_reference, list) {
636 if (ref2->unique_id == i) {
637 i++;
638 break;
639 }
640 }
641 if (&ref2->list == &tlskeys_reference)
642 break;
643 }
644
645 /* Uses the unique id and increment it for the next entry. */
646 ref->unique_id = i;
647 i++;
648 }
649 }
650
651 /* This sort the reference list by id. */
652 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
653 LIST_DEL(&ref->list);
654 list_for_each_entry(ref3, &tkr, list) {
655 if (ref->unique_id < ref3->unique_id) {
656 LIST_ADDQ(&ref3->list, &ref->list);
657 break;
658 }
659 }
660 if (&ref3->list == &tkr)
661 LIST_ADDQ(&tkr, &ref->list);
662 }
663
664 /* swap root */
665 LIST_ADD(&tkr, &tlskeys_reference);
666 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100667 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200668}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100669#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
670
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100671#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500672int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
673{
674 switch (evp_keytype) {
675 case EVP_PKEY_RSA:
676 return 2;
677 case EVP_PKEY_DSA:
678 return 0;
679 case EVP_PKEY_EC:
680 return 1;
681 }
682
683 return -1;
684}
685
Emeric Brun4147b2e2014-06-16 18:36:30 +0200686/*
687 * Callback used to set OCSP status extension content in server hello.
688 */
689int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
690{
yanbzhube2774d2015-12-10 15:07:30 -0500691 struct certificate_ocsp *ocsp;
692 struct ocsp_cbk_arg *ocsp_arg;
693 char *ssl_buf;
694 EVP_PKEY *ssl_pkey;
695 int key_type;
696 int index;
697
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200698 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500699
700 ssl_pkey = SSL_get_privatekey(ssl);
701 if (!ssl_pkey)
702 return SSL_TLSEXT_ERR_NOACK;
703
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200704 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500705
706 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
707 ocsp = ocsp_arg->s_ocsp;
708 else {
709 /* For multiple certs per context, we have to find the correct OCSP response based on
710 * the certificate type
711 */
712 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
713
714 if (index < 0)
715 return SSL_TLSEXT_ERR_NOACK;
716
717 ocsp = ocsp_arg->m_ocsp[index];
718
719 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200720
721 if (!ocsp ||
722 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200723 !ocsp->response.len ||
724 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200725 return SSL_TLSEXT_ERR_NOACK;
726
727 ssl_buf = OPENSSL_malloc(ocsp->response.len);
728 if (!ssl_buf)
729 return SSL_TLSEXT_ERR_NOACK;
730
731 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
732 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
733
734 return SSL_TLSEXT_ERR_OK;
735}
736
737/*
738 * This function enables the handling of OCSP status extension on 'ctx' if a
739 * file name 'cert_path' suffixed using ".ocsp" is present.
740 * To enable OCSP status extension, the issuer's certificate is mandatory.
741 * It should be present in the certificate's extra chain builded from file
742 * 'cert_path'. If not found, the issuer certificate is loaded from a file
743 * named 'cert_path' suffixed using '.issuer'.
744 *
745 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
746 * response. If file is empty or content is not a valid OCSP response,
747 * OCSP status extension is enabled but OCSP response is ignored (a warning
748 * is displayed).
749 *
750 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
751 * succesfully enabled, or -1 in other error case.
752 */
753static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
754{
755
756 BIO *in = NULL;
757 X509 *x, *xi = NULL, *issuer = NULL;
758 STACK_OF(X509) *chain = NULL;
759 OCSP_CERTID *cid = NULL;
760 SSL *ssl;
761 char ocsp_path[MAXPATHLEN+1];
762 int i, ret = -1;
763 struct stat st;
764 struct certificate_ocsp *ocsp = NULL, *iocsp;
765 char *warn = NULL;
766 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200767 pem_password_cb *passwd_cb;
768 void *passwd_cb_userdata;
769 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200770
771 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
772
773 if (stat(ocsp_path, &st))
774 return 1;
775
776 ssl = SSL_new(ctx);
777 if (!ssl)
778 goto out;
779
780 x = SSL_get_certificate(ssl);
781 if (!x)
782 goto out;
783
784 /* Try to lookup for issuer in certificate extra chain */
785#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
786 SSL_CTX_get_extra_chain_certs(ctx, &chain);
787#else
788 chain = ctx->extra_certs;
789#endif
790 for (i = 0; i < sk_X509_num(chain); i++) {
791 issuer = sk_X509_value(chain, i);
792 if (X509_check_issued(issuer, x) == X509_V_OK)
793 break;
794 else
795 issuer = NULL;
796 }
797
798 /* If not found try to load issuer from a suffixed file */
799 if (!issuer) {
800 char issuer_path[MAXPATHLEN+1];
801
802 in = BIO_new(BIO_s_file());
803 if (!in)
804 goto out;
805
806 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
807 if (BIO_read_filename(in, issuer_path) <= 0)
808 goto out;
809
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200810 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
811 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
812
813 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200814 if (!xi)
815 goto out;
816
817 if (X509_check_issued(xi, x) != X509_V_OK)
818 goto out;
819
820 issuer = xi;
821 }
822
823 cid = OCSP_cert_to_id(0, x, issuer);
824 if (!cid)
825 goto out;
826
827 i = i2d_OCSP_CERTID(cid, NULL);
828 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
829 goto out;
830
Vincent Bernat02779b62016-04-03 13:48:43 +0200831 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200832 if (!ocsp)
833 goto out;
834
835 p = ocsp->key_data;
836 i2d_OCSP_CERTID(cid, &p);
837
838 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
839 if (iocsp == ocsp)
840 ocsp = NULL;
841
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200842#ifndef SSL_CTX_get_tlsext_status_cb
843# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
844 *cb = (void (*) (void))ctx->tlsext_status_cb;
845#endif
846 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
847
848 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200849 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100850 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500851
852 cb_arg->is_single = 1;
853 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200854
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100855 pkey = X509_get_pubkey(x);
856 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
857 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500858
859 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
860 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
861 } else {
862 /*
863 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
864 * Update that cb_arg with the new cert's staple
865 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200866 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500867 struct certificate_ocsp *tmp_ocsp;
868 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200869 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100870 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200871
872#ifdef SSL_CTX_get_tlsext_status_arg
873 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
874#else
875 cb_arg = ctx->tlsext_status_arg;
876#endif
yanbzhube2774d2015-12-10 15:07:30 -0500877
878 /*
879 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
880 * the order of operations below matter, take care when changing it
881 */
882 tmp_ocsp = cb_arg->s_ocsp;
883 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
884 cb_arg->s_ocsp = NULL;
885 cb_arg->m_ocsp[index] = tmp_ocsp;
886 cb_arg->is_single = 0;
887 cb_arg->single_kt = 0;
888
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100889 pkey = X509_get_pubkey(x);
890 key_type = EVP_PKEY_base_id(pkey);
891 EVP_PKEY_free(pkey);
892
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200893 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500894 if (index >= 0 && !cb_arg->m_ocsp[index])
895 cb_arg->m_ocsp[index] = iocsp;
896
897 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200898
899 ret = 0;
900
901 warn = NULL;
902 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
903 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
904 Warning("%s.\n", warn);
905 }
906
907out:
908 if (ssl)
909 SSL_free(ssl);
910
911 if (in)
912 BIO_free(in);
913
914 if (xi)
915 X509_free(xi);
916
917 if (cid)
918 OCSP_CERTID_free(cid);
919
920 if (ocsp)
921 free(ocsp);
922
923 if (warn)
924 free(warn);
925
926
927 return ret;
928}
929
930#endif
931
Daniel Jakots54ffb912015-11-06 20:02:41 +0100932#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100933
934#define CT_EXTENSION_TYPE 18
935
936static int sctl_ex_index = -1;
937
938/*
939 * Try to parse Signed Certificate Timestamp List structure. This function
940 * makes only basic test if the data seems like SCTL. No signature validation
941 * is performed.
942 */
943static int ssl_sock_parse_sctl(struct chunk *sctl)
944{
945 int ret = 1;
946 int len, pos, sct_len;
947 unsigned char *data;
948
949 if (sctl->len < 2)
950 goto out;
951
952 data = (unsigned char *)sctl->str;
953 len = (data[0] << 8) | data[1];
954
955 if (len + 2 != sctl->len)
956 goto out;
957
958 data = data + 2;
959 pos = 0;
960 while (pos < len) {
961 if (len - pos < 2)
962 goto out;
963
964 sct_len = (data[pos] << 8) | data[pos + 1];
965 if (pos + sct_len + 2 > len)
966 goto out;
967
968 pos += sct_len + 2;
969 }
970
971 ret = 0;
972
973out:
974 return ret;
975}
976
977static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
978{
979 int fd = -1;
980 int r = 0;
981 int ret = 1;
982
983 *sctl = NULL;
984
985 fd = open(sctl_path, O_RDONLY);
986 if (fd == -1)
987 goto end;
988
989 trash.len = 0;
990 while (trash.len < trash.size) {
991 r = read(fd, trash.str + trash.len, trash.size - trash.len);
992 if (r < 0) {
993 if (errno == EINTR)
994 continue;
995
996 goto end;
997 }
998 else if (r == 0) {
999 break;
1000 }
1001 trash.len += r;
1002 }
1003
1004 ret = ssl_sock_parse_sctl(&trash);
1005 if (ret)
1006 goto end;
1007
Vincent Bernat02779b62016-04-03 13:48:43 +02001008 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001009 if (!chunk_dup(*sctl, &trash)) {
1010 free(*sctl);
1011 *sctl = NULL;
1012 goto end;
1013 }
1014
1015end:
1016 if (fd != -1)
1017 close(fd);
1018
1019 return ret;
1020}
1021
1022int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1023{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001024 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001025
1026 *out = (unsigned char *)sctl->str;
1027 *outlen = sctl->len;
1028
1029 return 1;
1030}
1031
1032int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1033{
1034 return 1;
1035}
1036
1037static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1038{
1039 char sctl_path[MAXPATHLEN+1];
1040 int ret = -1;
1041 struct stat st;
1042 struct chunk *sctl = NULL;
1043
1044 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1045
1046 if (stat(sctl_path, &st))
1047 return 1;
1048
1049 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1050 goto out;
1051
1052 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1053 free(sctl);
1054 goto out;
1055 }
1056
1057 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1058
1059 ret = 0;
1060
1061out:
1062 return ret;
1063}
1064
1065#endif
1066
Emeric Brune1f38db2012-09-03 20:36:47 +02001067void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1068{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001069 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001070 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001071 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001072
1073 if (where & SSL_CB_HANDSHAKE_START) {
1074 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001075 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001076 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001077 conn->err_code = CO_ER_SSL_RENEG;
1078 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001079 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001080
1081 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1082 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1083 /* Long certificate chains optimz
1084 If write and read bios are differents, we
1085 consider that the buffering was activated,
1086 so we rise the output buffer size from 4k
1087 to 16k */
1088 write_bio = SSL_get_wbio(ssl);
1089 if (write_bio != SSL_get_rbio(ssl)) {
1090 BIO_set_write_buffer_size(write_bio, 16384);
1091 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1092 }
1093 }
1094 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001095}
1096
Emeric Brune64aef12012-09-21 13:15:06 +02001097/* Callback is called for each certificate of the chain during a verify
1098 ok is set to 1 if preverify detect no error on current certificate.
1099 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001100int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001101{
1102 SSL *ssl;
1103 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001104 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001105
1106 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001107 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001108
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001109 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001110
Emeric Brun81c00f02012-09-21 14:31:21 +02001111 if (ok) /* no errors */
1112 return ok;
1113
1114 depth = X509_STORE_CTX_get_error_depth(x_store);
1115 err = X509_STORE_CTX_get_error(x_store);
1116
1117 /* check if CA error needs to be ignored */
1118 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001119 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1120 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1121 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001122 }
1123
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001124 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001125 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001126 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001127 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001128 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001129
Willy Tarreau20879a02012-12-03 16:32:10 +01001130 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001131 return 0;
1132 }
1133
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001134 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1135 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001136
Emeric Brun81c00f02012-09-21 14:31:21 +02001137 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001138 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001139 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001140 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001141 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001142 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001143
Willy Tarreau20879a02012-12-03 16:32:10 +01001144 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001145 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001146}
1147
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001148static inline
1149void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001150 const void *buf, size_t len, SSL *ssl)
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001151{
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001152 struct ssl_capture *capture;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001153 unsigned char *msg;
1154 unsigned char *end;
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001155 size_t rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001156
1157 /* This function is called for "from client" and "to server"
1158 * connections. The combination of write_p == 0 and content_type == 22
1159 * is only avalaible during "from client" connection.
1160 */
1161
1162 /* "write_p" is set to 0 is the bytes are received messages,
1163 * otherwise it is set to 1.
1164 */
1165 if (write_p != 0)
1166 return;
1167
1168 /* content_type contains the type of message received or sent
1169 * according with the SSL/TLS protocol spec. This message is
1170 * encoded with one byte. The value 256 (two bytes) is used
1171 * for designing the SSL/TLS record layer. According with the
1172 * rfc6101, the expected message (other than 256) are:
1173 * - change_cipher_spec(20)
1174 * - alert(21)
1175 * - handshake(22)
1176 * - application_data(23)
1177 * - (255)
1178 * We are interessed by the handshake and specially the client
1179 * hello.
1180 */
1181 if (content_type != 22)
1182 return;
1183
1184 /* The message length is at least 4 bytes, containing the
1185 * message type and the message length.
1186 */
1187 if (len < 4)
1188 return;
1189
1190 /* First byte of the handshake message id the type of
1191 * message. The konwn types are:
1192 * - hello_request(0)
1193 * - client_hello(1)
1194 * - server_hello(2)
1195 * - certificate(11)
1196 * - server_key_exchange (12)
1197 * - certificate_request(13)
1198 * - server_hello_done(14)
1199 * We are interested by the client hello.
1200 */
1201 msg = (unsigned char *)buf;
1202 if (msg[0] != 1)
1203 return;
1204
1205 /* Next three bytes are the length of the message. The total length
1206 * must be this decoded length + 4. If the length given as argument
1207 * is not the same, we abort the protocol dissector.
1208 */
1209 rec_len = (msg[1] << 16) + (msg[2] << 8) + msg[3];
1210 if (len < rec_len + 4)
1211 return;
1212 msg += 4;
1213 end = msg + rec_len;
1214 if (end < msg)
1215 return;
1216
1217 /* Expect 2 bytes for protocol version (1 byte for major and 1 byte
1218 * for minor, the random, composed by 4 bytes for the unix time and
1219 * 28 bytes for unix payload, and them 1 byte for the session id. So
1220 * we jump 1 + 1 + 4 + 28 + 1 bytes.
1221 */
1222 msg += 1 + 1 + 4 + 28 + 1;
1223 if (msg > end)
1224 return;
1225
1226 /* Next two bytes are the ciphersuite length. */
1227 if (msg + 2 > end)
1228 return;
1229 rec_len = (msg[0] << 8) + msg[1];
1230 msg += 2;
1231 if (msg + rec_len > end || msg + rec_len < msg)
1232 return;
1233
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001234 capture = pool_alloc_dirty(pool2_ssl_capture);
1235 if (!capture)
1236 return;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001237 /* Compute the xxh64 of the ciphersuite. */
1238 capture->xxh64 = XXH64(msg, rec_len, 0);
1239
1240 /* Capture the ciphersuite. */
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001241 capture->ciphersuite_len = (global_ssl.capture_cipherlist < rec_len) ?
1242 global_ssl.capture_cipherlist : rec_len;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001243 memcpy(capture->ciphersuite, msg, capture->ciphersuite_len);
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001244
1245 SSL_set_ex_data(ssl, ssl_capture_ptr_index, capture);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01001246}
1247
Emeric Brun29f037d2014-04-25 19:05:36 +02001248/* Callback is called for ssl protocol analyse */
1249void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1250{
Emeric Brun29f037d2014-04-25 19:05:36 +02001251#ifdef TLS1_RT_HEARTBEAT
1252 /* test heartbeat received (write_p is set to 0
1253 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001254 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001255 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001256 const unsigned char *p = buf;
1257 unsigned int payload;
1258
Emeric Brun29f037d2014-04-25 19:05:36 +02001259 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001260
1261 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1262 if (*p != TLS1_HB_REQUEST)
1263 return;
1264
Willy Tarreauaeed6722014-04-25 23:59:58 +02001265 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001266 goto kill_it;
1267
1268 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001269 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001270 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001271 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001272 /* We have a clear heartbleed attack (CVE-2014-0160), the
1273 * advertised payload is larger than the advertised packet
1274 * length, so we have garbage in the buffer between the
1275 * payload and the end of the buffer (p+len). We can't know
1276 * if the SSL stack is patched, and we don't know if we can
1277 * safely wipe out the area between p+3+len and payload.
1278 * So instead, we prevent the response from being sent by
1279 * setting the max_send_fragment to 0 and we report an SSL
1280 * error, which will kill this connection. It will be reported
1281 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001282 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1283 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001284 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001285 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1286 return;
1287 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001288#endif
Emmanuel Hocdete3804742017-03-08 11:07:10 +01001289 if (global_ssl.capture_cipherlist > 0)
1290 ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
Emeric Brun29f037d2014-04-25 19:05:36 +02001291}
1292
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001293#ifdef OPENSSL_NPN_NEGOTIATED
1294/* This callback is used so that the server advertises the list of
1295 * negociable protocols for NPN.
1296 */
1297static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1298 unsigned int *len, void *arg)
1299{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001300 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001301
1302 *data = (const unsigned char *)conf->npn_str;
1303 *len = conf->npn_len;
1304 return SSL_TLSEXT_ERR_OK;
1305}
1306#endif
1307
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001308#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001309/* This callback is used so that the server advertises the list of
1310 * negociable protocols for ALPN.
1311 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001312static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1313 unsigned char *outlen,
1314 const unsigned char *server,
1315 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001316{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001317 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001318
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001319 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1320 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1321 return SSL_TLSEXT_ERR_NOACK;
1322 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001323 return SSL_TLSEXT_ERR_OK;
1324}
1325#endif
1326
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001327#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001328#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001329
Christopher Faulet30548802015-06-11 13:39:32 +02001330/* Create a X509 certificate with the specified servername and serial. This
1331 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001332static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001333ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001334{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001335 static unsigned int serial = 0;
1336
Christopher Faulet7969a332015-10-09 11:15:03 +02001337 X509 *cacert = bind_conf->ca_sign_cert;
1338 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001339 SSL_CTX *ssl_ctx = NULL;
1340 X509 *newcrt = NULL;
1341 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001342 X509_NAME *name;
1343 const EVP_MD *digest;
1344 X509V3_CTX ctx;
1345 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001346 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001347
Christopher Faulet7969a332015-10-09 11:15:03 +02001348 /* Get the private key of the defautl certificate and use it */
1349 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001350 goto mkcert_error;
1351
1352 /* Create the certificate */
1353 if (!(newcrt = X509_new()))
1354 goto mkcert_error;
1355
1356 /* Set version number for the certificate (X509v3) and the serial
1357 * number */
1358 if (X509_set_version(newcrt, 2L) != 1)
1359 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001360 if (!serial)
1361 serial = now_ms;
1362 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001363
1364 /* Set duration for the certificate */
1365 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1366 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1367 goto mkcert_error;
1368
1369 /* set public key in the certificate */
1370 if (X509_set_pubkey(newcrt, pkey) != 1)
1371 goto mkcert_error;
1372
1373 /* Set issuer name from the CA */
1374 if (!(name = X509_get_subject_name(cacert)))
1375 goto mkcert_error;
1376 if (X509_set_issuer_name(newcrt, name) != 1)
1377 goto mkcert_error;
1378
1379 /* Set the subject name using the same, but the CN */
1380 name = X509_NAME_dup(name);
1381 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1382 (const unsigned char *)servername,
1383 -1, -1, 0) != 1) {
1384 X509_NAME_free(name);
1385 goto mkcert_error;
1386 }
1387 if (X509_set_subject_name(newcrt, name) != 1) {
1388 X509_NAME_free(name);
1389 goto mkcert_error;
1390 }
1391 X509_NAME_free(name);
1392
1393 /* Add x509v3 extensions as specified */
1394 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1395 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1396 X509_EXTENSION *ext;
1397
1398 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1399 goto mkcert_error;
1400 if (!X509_add_ext(newcrt, ext, -1)) {
1401 X509_EXTENSION_free(ext);
1402 goto mkcert_error;
1403 }
1404 X509_EXTENSION_free(ext);
1405 }
1406
1407 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001408
1409 key_type = EVP_PKEY_base_id(capkey);
1410
1411 if (key_type == EVP_PKEY_DSA)
1412 digest = EVP_sha1();
1413 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001414 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001415 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001416 digest = EVP_sha256();
1417 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001418#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001419 int nid;
1420
1421 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1422 goto mkcert_error;
1423 if (!(digest = EVP_get_digestbynid(nid)))
1424 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001425#else
1426 goto mkcert_error;
1427#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001428 }
1429
Christopher Faulet31af49d2015-06-09 17:29:50 +02001430 if (!(X509_sign(newcrt, capkey, digest)))
1431 goto mkcert_error;
1432
1433 /* Create and set the new SSL_CTX */
1434 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1435 goto mkcert_error;
1436 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1437 goto mkcert_error;
1438 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1439 goto mkcert_error;
1440 if (!SSL_CTX_check_private_key(ssl_ctx))
1441 goto mkcert_error;
1442
1443 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001444
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001445#ifndef OPENSSL_NO_DH
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001446 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01001447#endif
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001448#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1449 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001450 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001451 EC_KEY *ecc;
1452 int nid;
1453
1454 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1455 goto end;
1456 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1457 goto end;
1458 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1459 EC_KEY_free(ecc);
1460 }
1461#endif
1462 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001463 return ssl_ctx;
1464
1465 mkcert_error:
1466 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1467 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001468 return NULL;
1469}
1470
Christopher Faulet7969a332015-10-09 11:15:03 +02001471SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001472ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001473{
1474 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001475
1476 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001477}
1478
Christopher Faulet30548802015-06-11 13:39:32 +02001479/* Do a lookup for a certificate in the LRU cache used to store generated
1480 * certificates. */
1481SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001482ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001483{
1484 struct lru64 *lru = NULL;
1485
1486 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001487 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001488 if (lru && lru->domain)
1489 return (SSL_CTX *)lru->data;
1490 }
1491 return NULL;
1492}
1493
Christopher Fauletd2cab922015-07-28 16:03:47 +02001494/* Set a certificate int the LRU cache used to store generated
1495 * certificate. Return 0 on success, otherwise -1 */
1496int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001497ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001498{
1499 struct lru64 *lru = NULL;
1500
1501 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001502 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001503 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001504 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001505 if (lru->domain && lru->data)
1506 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001507 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001508 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001509 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001510 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001511}
1512
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001513/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001514unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001515ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001516{
1517 return XXH32(data, len, ssl_ctx_lru_seed);
1518}
1519
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001520/* Generate a cert and immediately assign it to the SSL session so that the cert's
1521 * refcount is maintained regardless of the cert's presence in the LRU cache.
1522 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001523static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001524ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001525{
1526 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001527 SSL_CTX *ssl_ctx = NULL;
1528 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001529 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001530
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001531 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001532 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001533 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001534 if (lru && lru->domain)
1535 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001536 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001537 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001538 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001539 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001540 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001541 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001542 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001543 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001544 SSL_set_SSL_CTX(ssl, ssl_ctx);
1545 /* No LRU cache, this CTX will be released as soon as the session dies */
1546 SSL_CTX_free(ssl_ctx);
1547 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001548 return ssl_ctx;
1549}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001550#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001551
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001552static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1553{
1554 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1555 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1556 SSL_set_SSL_CTX(ssl, ctx);
1557}
1558
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001559#ifdef OPENSSL_IS_BORINGSSL
1560
1561static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1562{
1563 (void)al; /* shut gcc stupid warning */
1564 (void)priv;
1565
1566 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1567 return SSL_TLSEXT_ERR_NOACK;
1568 return SSL_TLSEXT_ERR_OK;
1569}
1570
1571static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1572{
1573 struct connection *conn;
1574 struct bind_conf *s;
1575 const uint8_t *extension_data;
1576 size_t extension_len;
1577 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1578 const SSL_CIPHER *cipher;
1579 uint16_t cipher_suite;
1580 uint8_t name_type, hash, sign;
1581 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1582
1583 char *wildp = NULL;
1584 const uint8_t *servername;
1585 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1586 int i;
1587
1588 conn = SSL_get_app_data(ctx->ssl);
1589 s = objt_listener(conn->target)->bind_conf;
1590
1591 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1592 &extension_data, &extension_len)) {
1593 CBS_init(&extension, extension_data, extension_len);
1594
1595 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1596 || !CBS_get_u8(&server_name_list, &name_type)
1597 /* Although the server_name extension was intended to be extensible to
1598 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1599 * different name types will cause an error. Further, RFC 4366 originally
1600 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1601 * adding new name types is no longer feasible.
1602 *
1603 * Act as if the extensibility does not exist to simplify parsing. */
1604 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1605 || CBS_len(&server_name_list) != 0
1606 || CBS_len(&extension) != 0
1607 || name_type != TLSEXT_NAMETYPE_host_name
1608 || CBS_len(&host_name) == 0
1609 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1610 || CBS_contains_zero_byte(&host_name)) {
1611 goto abort;
1612 }
1613 } else {
1614 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001615 if (!s->strict_sni) {
1616 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001617 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001618 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001619 goto abort;
1620 }
1621
1622 /* extract/check clientHello informations */
1623 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
1624 CBS_init(&extension, extension_data, extension_len);
1625
1626 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
1627 || CBS_len(&sig_algs) == 0
1628 || CBS_len(&extension) != 0) {
1629 goto abort;
1630 }
1631 if (CBS_len(&sig_algs) % 2 != 0) {
1632 goto abort;
1633 }
1634 while (CBS_len(&sig_algs) != 0) {
1635 if (!CBS_get_u8(&sig_algs, &hash)
1636 || !CBS_get_u8(&sig_algs, &sign)) {
1637 goto abort;
1638 }
1639 switch (sign) {
1640 case TLSEXT_signature_rsa:
1641 has_rsa = 1;
1642 break;
1643 case TLSEXT_signature_ecdsa:
1644 has_ecdsa_sig = 1;
1645 break;
1646 default:
1647 continue;
1648 }
1649 if (has_ecdsa_sig && has_rsa)
1650 break;
1651 }
1652 } else {
1653 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
1654 has_rsa = 1;
1655 }
1656 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
1657 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
1658
1659 while (CBS_len(&cipher_suites) != 0) {
1660 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1661 goto abort;
1662 }
1663 cipher = SSL_get_cipher_by_value(cipher_suite);
1664 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
1665 has_ecdsa = 1;
1666 break;
1667 }
1668 }
1669 }
1670
1671 servername = CBS_data(&host_name);
1672 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
1673 trash.str[i] = tolower(servername[i]);
1674 if (!wildp && (trash.str[i] == '.'))
1675 wildp = &trash.str[i];
1676 }
1677 trash.str[i] = 0;
1678
1679 /* lookup in full qualified names */
1680 node = ebst_lookup(&s->sni_ctx, trash.str);
1681
1682 /* lookup a not neg filter */
1683 for (n = node; n; n = ebmb_next_dup(n)) {
1684 if (!container_of(n, struct sni_ctx, name)->neg) {
1685 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1686 case TLSEXT_signature_ecdsa:
1687 if (has_ecdsa) {
1688 node_ecdsa = n;
1689 goto find_one;
1690 }
1691 break;
1692 case TLSEXT_signature_rsa:
1693 if (has_rsa && !node_rsa) {
1694 node_rsa = n;
1695 if (!has_ecdsa)
1696 goto find_one;
1697 }
1698 break;
1699 default: /* TLSEXT_signature_anonymous */
1700 if (!node_anonymous)
1701 node_anonymous = n;
1702 break;
1703 }
1704 }
1705 }
1706 if (wildp) {
1707 /* lookup in wildcards names */
1708 node = ebst_lookup(&s->sni_w_ctx, wildp);
1709 for (n = node; n; n = ebmb_next_dup(n)) {
1710 if (!container_of(n, struct sni_ctx, name)->neg) {
1711 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1712 case TLSEXT_signature_ecdsa:
1713 if (has_ecdsa) {
1714 node_ecdsa = n;
1715 goto find_one;
1716 }
1717 break;
1718 case TLSEXT_signature_rsa:
1719 if (has_rsa && !node_rsa) {
1720 node_rsa = n;
1721 if (!has_ecdsa)
1722 goto find_one;
1723 }
1724 break;
1725 default: /* TLSEXT_signature_anonymous */
1726 if (!node_anonymous)
1727 node_anonymous = n;
1728 break;
1729 }
1730 }
1731 }
1732 }
1733 find_one:
1734 /* select by key_signature priority order */
1735 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
1736
1737 if (node) {
1738 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001739 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001740 return 1;
1741 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001742 if (!s->strict_sni) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001743 /* no certificate match, is the default_ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001744 ssl_sock_switchctx_set(ctx->ssl, s->default_ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001745 return 1;
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001746 }
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001747 abort:
1748 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
1749 conn->err_code = CO_ER_SSL_HANDSHAKE;
1750 return -1;
1751}
1752
1753#else /* OPENSSL_IS_BORINGSSL */
1754
Emeric Brunfc0421f2012-09-07 17:30:07 +02001755/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1756 * warning when no match is found, which implies the default (first) cert
1757 * will keep being used.
1758 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001759static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001760{
1761 const char *servername;
1762 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001763 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001764 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001765 int i;
1766 (void)al; /* shut gcc stupid warning */
1767
1768 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001769 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001770#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02001771 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001772 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001773 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001774 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001775
Willy Tarreauf6721452015-07-07 18:04:38 +02001776 conn_get_to_addr(conn);
1777 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001778 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1779 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001780 if (ctx) {
1781 /* switch ctx */
1782 SSL_set_SSL_CTX(ssl, ctx);
1783 return SSL_TLSEXT_ERR_OK;
1784 }
Christopher Faulet30548802015-06-11 13:39:32 +02001785 }
1786 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001787#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001788 if (s->strict_sni)
1789 return SSL_TLSEXT_ERR_ALERT_FATAL;
1790 ssl_sock_switchctx_set(ssl, s->default_ctx);
1791 return SSL_TLSEXT_ERR_NOACK;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001792 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001793
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001794 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001795 if (!servername[i])
1796 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001797 trash.str[i] = tolower(servername[i]);
1798 if (!wildp && (trash.str[i] == '.'))
1799 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001800 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001801 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001802
1803 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001804 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001805
1806 /* lookup a not neg filter */
1807 for (n = node; n; n = ebmb_next_dup(n)) {
1808 if (!container_of(n, struct sni_ctx, name)->neg) {
1809 node = n;
1810 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001811 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001812 }
1813 if (!node && wildp) {
1814 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001815 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001816 }
1817 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001818#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001819 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001820 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001821 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001822 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001823 return SSL_TLSEXT_ERR_OK;
1824 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001825#endif
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01001826 if (s->strict_sni)
1827 return SSL_TLSEXT_ERR_ALERT_FATAL;
1828 ssl_sock_switchctx_set(ssl, s->default_ctx);
1829 return SSL_TLSEXT_ERR_OK;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001830 }
1831
1832 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001833 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001834 return SSL_TLSEXT_ERR_OK;
1835}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001836#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001837#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1838
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001839#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001840
1841static DH * ssl_get_dh_1024(void)
1842{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001843 static unsigned char dh1024_p[]={
1844 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1845 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1846 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1847 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1848 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1849 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1850 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1851 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1852 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1853 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1854 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1855 };
1856 static unsigned char dh1024_g[]={
1857 0x02,
1858 };
1859
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001860 BIGNUM *p;
1861 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001862 DH *dh = DH_new();
1863 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001864 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1865 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001866
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001867 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001868 DH_free(dh);
1869 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001870 } else {
1871 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001872 }
1873 }
1874 return dh;
1875}
1876
1877static DH *ssl_get_dh_2048(void)
1878{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001879 static unsigned char dh2048_p[]={
1880 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1881 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1882 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1883 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1884 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1885 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1886 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1887 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1888 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1889 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1890 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1891 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1892 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1893 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1894 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1895 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1896 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1897 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1898 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1899 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1900 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1901 0xB7,0x1F,0x77,0xF3,
1902 };
1903 static unsigned char dh2048_g[]={
1904 0x02,
1905 };
1906
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001907 BIGNUM *p;
1908 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001909 DH *dh = DH_new();
1910 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001911 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1912 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001913
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001914 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001915 DH_free(dh);
1916 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001917 } else {
1918 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001919 }
1920 }
1921 return dh;
1922}
1923
1924static DH *ssl_get_dh_4096(void)
1925{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001926 static unsigned char dh4096_p[]={
1927 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1928 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1929 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1930 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1931 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1932 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1933 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1934 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1935 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1936 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1937 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1938 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1939 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1940 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1941 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1942 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1943 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1944 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1945 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1946 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1947 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1948 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1949 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1950 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1951 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1952 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1953 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1954 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1955 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1956 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1957 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1958 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1959 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1960 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1961 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1962 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1963 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1964 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1965 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1966 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1967 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1968 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1969 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001970 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001971 static unsigned char dh4096_g[]={
1972 0x02,
1973 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001974
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001975 BIGNUM *p;
1976 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001977 DH *dh = DH_new();
1978 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001979 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1980 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001981
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001982 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001983 DH_free(dh);
1984 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001985 } else {
1986 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001987 }
1988 }
1989 return dh;
1990}
1991
1992/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001993 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001994static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1995{
1996 DH *dh = NULL;
1997 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001998 int type;
1999
2000 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002001
2002 /* The keylen supplied by OpenSSL can only be 512 or 1024.
2003 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
2004 */
2005 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
2006 keylen = EVP_PKEY_bits(pkey);
2007 }
2008
Willy Tarreauef934602016-12-22 23:12:01 +01002009 if (keylen > global_ssl.default_dh_param) {
2010 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002011 }
2012
Remi Gacogned3a341a2015-05-29 16:26:17 +02002013 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002014 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002015 }
2016 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002017 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002018 }
2019 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02002020 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002021 }
2022
2023 return dh;
2024}
2025
Remi Gacogne47783ef2015-05-29 15:53:22 +02002026static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002027{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002028 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02002029 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002030
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002031 if (in == NULL)
2032 goto end;
2033
Remi Gacogne47783ef2015-05-29 15:53:22 +02002034 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002035 goto end;
2036
Remi Gacogne47783ef2015-05-29 15:53:22 +02002037 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
2038
2039end:
2040 if (in)
2041 BIO_free(in);
2042
2043 return dh;
2044}
2045
2046int ssl_sock_load_global_dh_param_from_file(const char *filename)
2047{
2048 global_dh = ssl_sock_get_dh_from_file(filename);
2049
2050 if (global_dh) {
2051 return 0;
2052 }
2053
2054 return -1;
2055}
2056
2057/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
2058 if an error occured, and 0 if parameter not found. */
2059int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
2060{
2061 int ret = -1;
2062 DH *dh = ssl_sock_get_dh_from_file(file);
2063
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002064 if (dh) {
2065 ret = 1;
2066 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02002067
2068 if (ssl_dh_ptr_index >= 0) {
2069 /* store a pointer to the DH params to avoid complaining about
2070 ssl-default-dh-param not being set for this SSL_CTX */
2071 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
2072 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002073 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02002074 else if (global_dh) {
2075 SSL_CTX_set_tmp_dh(ctx, global_dh);
2076 ret = 0; /* DH params not found */
2077 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002078 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002079 /* Clear openssl global errors stack */
2080 ERR_clear_error();
2081
Willy Tarreauef934602016-12-22 23:12:01 +01002082 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002083 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02002084 if (local_dh_1024 == NULL)
2085 local_dh_1024 = ssl_get_dh_1024();
2086
Remi Gacogne8de54152014-07-15 11:36:40 +02002087 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002088 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02002089
Remi Gacogne8de54152014-07-15 11:36:40 +02002090 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002091 }
2092 else {
2093 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
2094 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02002095
Emeric Brun41fdb3c2013-04-26 11:05:44 +02002096 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002097 }
Emeric Brun644cde02012-12-14 11:21:13 +01002098
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002099end:
2100 if (dh)
2101 DH_free(dh);
2102
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002103 return ret;
2104}
2105#endif
2106
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002107static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
2108 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002109{
2110 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002111 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002112 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002113
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002114 if (*name == '!') {
2115 neg = 1;
2116 name++;
2117 }
2118 if (*name == '*') {
2119 wild = 1;
2120 name++;
2121 }
2122 /* !* filter is a nop */
2123 if (neg && wild)
2124 return order;
2125 if (*name) {
2126 int j, len;
2127 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002128 for (j = 0; j < len && j < trash.size; j++)
2129 trash.str[j] = tolower(name[j]);
2130 if (j >= trash.size)
2131 return order;
2132 trash.str[j] = 0;
2133
2134 /* Check for duplicates. */
2135 if (wild)
2136 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2137 else
2138 node = ebst_lookup(&s->sni_ctx, trash.str);
2139 for (; node; node = ebmb_next_dup(node)) {
2140 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002141 if (sc->ctx == ctx && sc->conf == conf &&
2142 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002143 return order;
2144 }
2145
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002146 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002147 if (!sc)
2148 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002149 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002150 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002151 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002152 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002153 sc->order = order++;
2154 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002155 if (wild)
2156 ebst_insert(&s->sni_w_ctx, &sc->name);
2157 else
2158 ebst_insert(&s->sni_ctx, &sc->name);
2159 }
2160 return order;
2161}
2162
yanbzhu488a4d22015-12-01 15:16:07 -05002163
2164/* The following code is used for loading multiple crt files into
2165 * SSL_CTX's based on CN/SAN
2166 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002167#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002168/* This is used to preload the certifcate, private key
2169 * and Cert Chain of a file passed in via the crt
2170 * argument
2171 *
2172 * This way, we do not have to read the file multiple times
2173 */
2174struct cert_key_and_chain {
2175 X509 *cert;
2176 EVP_PKEY *key;
2177 unsigned int num_chain_certs;
2178 /* This is an array of X509 pointers */
2179 X509 **chain_certs;
2180};
2181
yanbzhu08ce6ab2015-12-02 13:01:29 -05002182#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2183
2184struct key_combo_ctx {
2185 SSL_CTX *ctx;
2186 int order;
2187};
2188
2189/* Map used for processing multiple keypairs for a single purpose
2190 *
2191 * This maps CN/SNI name to certificate type
2192 */
2193struct sni_keytype {
2194 int keytypes; /* BITMASK for keytypes */
2195 struct ebmb_node name; /* node holding the servername value */
2196};
2197
2198
yanbzhu488a4d22015-12-01 15:16:07 -05002199/* Frees the contents of a cert_key_and_chain
2200 */
2201static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2202{
2203 int i;
2204
2205 if (!ckch)
2206 return;
2207
2208 /* Free the certificate and set pointer to NULL */
2209 if (ckch->cert)
2210 X509_free(ckch->cert);
2211 ckch->cert = NULL;
2212
2213 /* Free the key and set pointer to NULL */
2214 if (ckch->key)
2215 EVP_PKEY_free(ckch->key);
2216 ckch->key = NULL;
2217
2218 /* Free each certificate in the chain */
2219 for (i = 0; i < ckch->num_chain_certs; i++) {
2220 if (ckch->chain_certs[i])
2221 X509_free(ckch->chain_certs[i]);
2222 }
2223
2224 /* Free the chain obj itself and set to NULL */
2225 if (ckch->num_chain_certs > 0) {
2226 free(ckch->chain_certs);
2227 ckch->num_chain_certs = 0;
2228 ckch->chain_certs = NULL;
2229 }
2230
2231}
2232
2233/* checks if a key and cert exists in the ckch
2234 */
2235static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2236{
2237 return (ckch->cert != NULL && ckch->key != NULL);
2238}
2239
2240
2241/* Loads the contents of a crt file (path) into a cert_key_and_chain
2242 * This allows us to carry the contents of the file without having to
2243 * read the file multiple times.
2244 *
2245 * returns:
2246 * 0 on Success
2247 * 1 on SSL Failure
2248 * 2 on file not found
2249 */
2250static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2251{
2252
2253 BIO *in;
2254 X509 *ca = NULL;
2255 int ret = 1;
2256
2257 ssl_sock_free_cert_key_and_chain_contents(ckch);
2258
2259 in = BIO_new(BIO_s_file());
2260 if (in == NULL)
2261 goto end;
2262
2263 if (BIO_read_filename(in, path) <= 0)
2264 goto end;
2265
yanbzhu488a4d22015-12-01 15:16:07 -05002266 /* Read Private Key */
2267 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2268 if (ckch->key == NULL) {
2269 memprintf(err, "%sunable to load private key from file '%s'.\n",
2270 err && *err ? *err : "", path);
2271 goto end;
2272 }
2273
Willy Tarreaubb137a82016-04-06 19:02:38 +02002274 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002275 if (BIO_reset(in) == -1) {
2276 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2277 err && *err ? *err : "", path);
2278 goto end;
2279 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002280
2281 /* Read Certificate */
2282 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2283 if (ckch->cert == NULL) {
2284 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2285 err && *err ? *err : "", path);
2286 goto end;
2287 }
2288
yanbzhu488a4d22015-12-01 15:16:07 -05002289 /* Read Certificate Chain */
2290 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2291 /* Grow the chain certs */
2292 ckch->num_chain_certs++;
2293 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2294
2295 /* use - 1 here since we just incremented it above */
2296 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2297 }
2298 ret = ERR_get_error();
2299 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2300 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2301 err && *err ? *err : "", path);
2302 ret = 1;
2303 goto end;
2304 }
2305
2306 ret = 0;
2307
2308end:
2309
2310 ERR_clear_error();
2311 if (in)
2312 BIO_free(in);
2313
2314 /* Something went wrong in one of the reads */
2315 if (ret != 0)
2316 ssl_sock_free_cert_key_and_chain_contents(ckch);
2317
2318 return ret;
2319}
2320
2321/* Loads the info in ckch into ctx
2322 * Currently, this does not process any information about ocsp, dhparams or
2323 * sctl
2324 * Returns
2325 * 0 on success
2326 * 1 on failure
2327 */
2328static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2329{
2330 int i = 0;
2331
2332 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2333 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2334 err && *err ? *err : "", path);
2335 return 1;
2336 }
2337
2338 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2339 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2340 err && *err ? *err : "", path);
2341 return 1;
2342 }
2343
yanbzhu488a4d22015-12-01 15:16:07 -05002344 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2345 for (i = 0; i < ckch->num_chain_certs; i++) {
2346 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002347 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2348 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002349 return 1;
2350 }
2351 }
2352
2353 if (SSL_CTX_check_private_key(ctx) <= 0) {
2354 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2355 err && *err ? *err : "", path);
2356 return 1;
2357 }
2358
2359 return 0;
2360}
2361
yanbzhu08ce6ab2015-12-02 13:01:29 -05002362
2363static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2364{
2365 struct sni_keytype *s_kt = NULL;
2366 struct ebmb_node *node;
2367 int i;
2368
2369 for (i = 0; i < trash.size; i++) {
2370 if (!str[i])
2371 break;
2372 trash.str[i] = tolower(str[i]);
2373 }
2374 trash.str[i] = 0;
2375 node = ebst_lookup(sni_keytypes, trash.str);
2376 if (!node) {
2377 /* CN not found in tree */
2378 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2379 /* Using memcpy here instead of strncpy.
2380 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2381 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2382 */
2383 memcpy(s_kt->name.key, trash.str, i+1);
2384 s_kt->keytypes = 0;
2385 ebst_insert(sni_keytypes, &s_kt->name);
2386 } else {
2387 /* CN found in tree */
2388 s_kt = container_of(node, struct sni_keytype, name);
2389 }
2390
2391 /* Mark that this CN has the keytype of key_index via keytypes mask */
2392 s_kt->keytypes |= 1<<key_index;
2393
2394}
2395
2396
2397/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2398 * If any are found, group these files into a set of SSL_CTX*
2399 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2400 *
2401 * This will allow the user to explictly group multiple cert/keys for a single purpose
2402 *
2403 * Returns
2404 * 0 on success
2405 * 1 on failure
2406 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002407static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2408 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002409{
2410 char fp[MAXPATHLEN+1] = {0};
2411 int n = 0;
2412 int i = 0;
2413 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2414 struct eb_root sni_keytypes_map = { {0} };
2415 struct ebmb_node *node;
2416 struct ebmb_node *next;
2417 /* Array of SSL_CTX pointers corresponding to each possible combo
2418 * of keytypes
2419 */
2420 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2421 int rv = 0;
2422 X509_NAME *xname = NULL;
2423 char *str = NULL;
2424#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2425 STACK_OF(GENERAL_NAME) *names = NULL;
2426#endif
2427
2428 /* Load all possible certs and keys */
2429 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2430 struct stat buf;
2431
2432 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2433 if (stat(fp, &buf) == 0) {
2434 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2435 rv = 1;
2436 goto end;
2437 }
2438 }
2439 }
2440
2441 /* Process each ckch and update keytypes for each CN/SAN
2442 * for example, if CN/SAN www.a.com is associated with
2443 * certs with keytype 0 and 2, then at the end of the loop,
2444 * www.a.com will have:
2445 * keyindex = 0 | 1 | 4 = 5
2446 */
2447 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2448
2449 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2450 continue;
2451
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002452 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002453 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002454 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2455 } else {
2456 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2457 * so the line that contains logic is marked via comments
2458 */
2459 xname = X509_get_subject_name(certs_and_keys[n].cert);
2460 i = -1;
2461 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2462 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002463 ASN1_STRING *value;
2464 value = X509_NAME_ENTRY_get_data(entry);
2465 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002466 /* Important line is here */
2467 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002468
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002469 OPENSSL_free(str);
2470 str = NULL;
2471 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002472 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002473
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002474 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002475#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002476 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2477 if (names) {
2478 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2479 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002480
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002481 if (name->type == GEN_DNS) {
2482 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2483 /* Important line is here */
2484 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002485
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002486 OPENSSL_free(str);
2487 str = NULL;
2488 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002489 }
2490 }
2491 }
2492 }
2493#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2494 }
2495
2496 /* If no files found, return error */
2497 if (eb_is_empty(&sni_keytypes_map)) {
2498 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2499 err && *err ? *err : "", path);
2500 rv = 1;
2501 goto end;
2502 }
2503
2504 /* We now have a map of CN/SAN to keytypes that are loaded in
2505 * Iterate through the map to create the SSL_CTX's (if needed)
2506 * and add each CTX to the SNI tree
2507 *
2508 * Some math here:
2509 * There are 2^n - 1 possibile combinations, each unique
2510 * combination is denoted by the key in the map. Each key
2511 * has a value between 1 and 2^n - 1. Conveniently, the array
2512 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2513 * entry in the array to correspond to the unique combo (key)
2514 * associated with i. This unique key combo (i) will be associated
2515 * with combos[i-1]
2516 */
2517
2518 node = ebmb_first(&sni_keytypes_map);
2519 while (node) {
2520 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002521 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002522
2523 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2524 i = container_of(node, struct sni_keytype, name)->keytypes;
2525 cur_ctx = key_combos[i-1].ctx;
2526
2527 if (cur_ctx == NULL) {
2528 /* need to create SSL_CTX */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002529 cur_ctx = SSL_CTX_new(SSLv23_server_method());
yanbzhu08ce6ab2015-12-02 13:01:29 -05002530 if (cur_ctx == NULL) {
2531 memprintf(err, "%sunable to allocate SSL context.\n",
2532 err && *err ? *err : "");
2533 rv = 1;
2534 goto end;
2535 }
2536
yanbzhube2774d2015-12-10 15:07:30 -05002537 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002538 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2539 if (i & (1<<n)) {
2540 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002541 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2542 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002543 SSL_CTX_free(cur_ctx);
2544 rv = 1;
2545 goto end;
2546 }
yanbzhube2774d2015-12-10 15:07:30 -05002547
2548#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2549 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002550 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002551 if (err)
2552 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 +00002553 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002554 SSL_CTX_free(cur_ctx);
2555 rv = 1;
2556 goto end;
2557 }
2558#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002559 }
2560 }
2561
2562 /* Load DH params into the ctx to support DHE keys */
2563#ifndef OPENSSL_NO_DH
2564 if (ssl_dh_ptr_index >= 0)
2565 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2566
2567 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2568 if (rv < 0) {
2569 if (err)
2570 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2571 *err ? *err : "", path);
2572 rv = 1;
2573 goto end;
2574 }
2575#endif
2576
2577 /* Update key_combos */
2578 key_combos[i-1].ctx = cur_ctx;
2579 }
2580
2581 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002582 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2583 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002584 node = ebmb_next(node);
2585 }
2586
2587
2588 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2589 if (!bind_conf->default_ctx) {
2590 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2591 if (key_combos[i].ctx) {
2592 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002593 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002594 break;
2595 }
2596 }
2597 }
2598
2599end:
2600
2601 if (names)
2602 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2603
2604 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2605 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2606
2607 node = ebmb_first(&sni_keytypes_map);
2608 while (node) {
2609 next = ebmb_next(node);
2610 ebmb_delete(node);
2611 node = next;
2612 }
2613
2614 return rv;
2615}
2616#else
2617/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002618static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2619 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002620{
2621 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2622 err && *err ? *err : "", path, strerror(errno));
2623 return 1;
2624}
2625
yanbzhu488a4d22015-12-01 15:16:07 -05002626#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2627
Emeric Brunfc0421f2012-09-07 17:30:07 +02002628/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2629 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2630 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002631static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2632 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002633{
2634 BIO *in;
2635 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002636 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002637 int ret = -1;
2638 int order = 0;
2639 X509_NAME *xname;
2640 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002641 pem_password_cb *passwd_cb;
2642 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002643 EVP_PKEY *pkey;
2644 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002645
Emeric Brunfc0421f2012-09-07 17:30:07 +02002646#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2647 STACK_OF(GENERAL_NAME) *names;
2648#endif
2649
2650 in = BIO_new(BIO_s_file());
2651 if (in == NULL)
2652 goto end;
2653
2654 if (BIO_read_filename(in, file) <= 0)
2655 goto end;
2656
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002657
2658 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2659 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2660
2661 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002662 if (x == NULL)
2663 goto end;
2664
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002665 pkey = X509_get_pubkey(x);
2666 if (pkey) {
2667 switch(EVP_PKEY_base_id(pkey)) {
2668 case EVP_PKEY_RSA:
2669 key_sig = TLSEXT_signature_rsa;
2670 break;
2671 case EVP_PKEY_EC:
2672 key_sig = TLSEXT_signature_ecdsa;
2673 break;
2674 }
2675 EVP_PKEY_free(pkey);
2676 }
2677
Emeric Brun50bcecc2013-04-22 13:05:23 +02002678 if (fcount) {
2679 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002680 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002681 }
2682 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002683#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002684 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2685 if (names) {
2686 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2687 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2688 if (name->type == GEN_DNS) {
2689 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002690 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002691 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002692 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002693 }
2694 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002695 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002696 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002697#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002698 xname = X509_get_subject_name(x);
2699 i = -1;
2700 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2701 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002702 ASN1_STRING *value;
2703
2704 value = X509_NAME_ENTRY_get_data(entry);
2705 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002706 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002707 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002708 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002709 }
2710 }
2711
2712 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2713 if (!SSL_CTX_use_certificate(ctx, x))
2714 goto end;
2715
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002716#ifdef SSL_CTX_clear_extra_chain_certs
2717 SSL_CTX_clear_extra_chain_certs(ctx);
2718#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002719 if (ctx->extra_certs != NULL) {
2720 sk_X509_pop_free(ctx->extra_certs, X509_free);
2721 ctx->extra_certs = NULL;
2722 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002723#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002724
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002725 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002726 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2727 X509_free(ca);
2728 goto end;
2729 }
2730 }
2731
2732 err = ERR_get_error();
2733 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2734 /* we successfully reached the last cert in the file */
2735 ret = 1;
2736 }
2737 ERR_clear_error();
2738
2739end:
2740 if (x)
2741 X509_free(x);
2742
2743 if (in)
2744 BIO_free(in);
2745
2746 return ret;
2747}
2748
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002749static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2750 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002751{
2752 int ret;
2753 SSL_CTX *ctx;
2754
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01002755 ctx = SSL_CTX_new(SSLv23_server_method());
Emeric Brunfc0421f2012-09-07 17:30:07 +02002756 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002757 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2758 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002759 return 1;
2760 }
2761
2762 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002763 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2764 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002765 SSL_CTX_free(ctx);
2766 return 1;
2767 }
2768
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002769 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002770 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002771 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2772 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002773 if (ret < 0) /* serious error, must do that ourselves */
2774 SSL_CTX_free(ctx);
2775 return 1;
2776 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002777
2778 if (SSL_CTX_check_private_key(ctx) <= 0) {
2779 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2780 err && *err ? *err : "", path);
2781 return 1;
2782 }
2783
Emeric Brunfc0421f2012-09-07 17:30:07 +02002784 /* we must not free the SSL_CTX anymore below, since it's already in
2785 * the tree, so it will be discovered and cleaned in time.
2786 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002787#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002788 /* store a NULL pointer to indicate we have not yet loaded
2789 a custom DH param file */
2790 if (ssl_dh_ptr_index >= 0) {
2791 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2792 }
2793
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002794 ret = ssl_sock_load_dh_params(ctx, path);
2795 if (ret < 0) {
2796 if (err)
2797 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2798 *err ? *err : "", path);
2799 return 1;
2800 }
2801#endif
2802
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002803#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002804 ret = ssl_sock_load_ocsp(ctx, path);
2805 if (ret < 0) {
2806 if (err)
2807 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",
2808 *err ? *err : "", path);
2809 return 1;
2810 }
2811#endif
2812
Daniel Jakots54ffb912015-11-06 20:02:41 +01002813#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002814 if (sctl_ex_index >= 0) {
2815 ret = ssl_sock_load_sctl(ctx, path);
2816 if (ret < 0) {
2817 if (err)
2818 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2819 *err ? *err : "", path);
2820 return 1;
2821 }
2822 }
2823#endif
2824
Emeric Brunfc0421f2012-09-07 17:30:07 +02002825#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002826 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002827 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2828 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002829 return 1;
2830 }
2831#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002832 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002833 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002834 bind_conf->default_ssl_conf = ssl_conf;
2835 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002836
2837 return 0;
2838}
2839
Willy Tarreau03209342016-12-22 17:08:28 +01002840int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002841{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002842 struct dirent **de_list;
2843 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002844 DIR *dir;
2845 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002846 char *end;
2847 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002848 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002849#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2850 int is_bundle;
2851 int j;
2852#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002853
yanbzhu08ce6ab2015-12-02 13:01:29 -05002854 if (stat(path, &buf) == 0) {
2855 dir = opendir(path);
2856 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002857 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002858
yanbzhu08ce6ab2015-12-02 13:01:29 -05002859 /* strip trailing slashes, including first one */
2860 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2861 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002862
yanbzhu08ce6ab2015-12-02 13:01:29 -05002863 n = scandir(path, &de_list, 0, alphasort);
2864 if (n < 0) {
2865 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2866 err && *err ? *err : "", path, strerror(errno));
2867 cfgerr++;
2868 }
2869 else {
2870 for (i = 0; i < n; i++) {
2871 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002872
yanbzhu08ce6ab2015-12-02 13:01:29 -05002873 end = strrchr(de->d_name, '.');
2874 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2875 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002876
yanbzhu08ce6ab2015-12-02 13:01:29 -05002877 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2878 if (stat(fp, &buf) != 0) {
2879 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2880 err && *err ? *err : "", fp, strerror(errno));
2881 cfgerr++;
2882 goto ignore_entry;
2883 }
2884 if (!S_ISREG(buf.st_mode))
2885 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002886
2887#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2888 is_bundle = 0;
2889 /* Check if current entry in directory is part of a multi-cert bundle */
2890
2891 if (end) {
2892 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2893 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2894 is_bundle = 1;
2895 break;
2896 }
2897 }
2898
2899 if (is_bundle) {
2900 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2901 int dp_len;
2902
2903 dp_len = end - de->d_name;
2904 snprintf(dp, dp_len + 1, "%s", de->d_name);
2905
2906 /* increment i and free de until we get to a non-bundle cert
2907 * Note here that we look at de_list[i + 1] before freeing de
2908 * this is important since ignore_entry will free de
2909 */
2910 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2911 free(de);
2912 i++;
2913 de = de_list[i];
2914 }
2915
2916 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002917 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002918
2919 /* Successfully processed the bundle */
2920 goto ignore_entry;
2921 }
2922 }
2923
2924#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002925 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002926ignore_entry:
2927 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002928 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002929 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002930 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002931 closedir(dir);
2932 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002933 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002934
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002935 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002936
Emeric Brunfc0421f2012-09-07 17:30:07 +02002937 return cfgerr;
2938}
2939
Thierry Fournier383085f2013-01-24 14:15:43 +01002940/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2941 * done once. Zero is returned if the operation fails. No error is returned
2942 * if the random is said as not implemented, because we expect that openssl
2943 * will use another method once needed.
2944 */
2945static int ssl_initialize_random()
2946{
2947 unsigned char random;
2948 static int random_initialized = 0;
2949
2950 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2951 random_initialized = 1;
2952
2953 return random_initialized;
2954}
2955
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002956/* release ssl bind conf */
2957void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002958{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002959 if (conf) {
2960#ifdef OPENSSL_NPN_NEGOTIATED
2961 free(conf->npn_str);
2962 conf->npn_str = NULL;
2963#endif
2964#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2965 free(conf->alpn_str);
2966 conf->alpn_str = NULL;
2967#endif
2968 free(conf->ca_file);
2969 conf->ca_file = NULL;
2970 free(conf->crl_file);
2971 conf->crl_file = NULL;
2972 free(conf->ciphers);
2973 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002974 free(conf->curves);
2975 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002976 free(conf->ecdhe);
2977 conf->ecdhe = NULL;
2978 }
2979}
2980
2981int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2982{
2983 char thisline[CRT_LINESIZE];
2984 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002985 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002986 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002987 int linenum = 0;
2988 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002989
Willy Tarreauad1731d2013-04-02 17:35:58 +02002990 if ((f = fopen(file, "r")) == NULL) {
2991 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002992 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002993 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002994
2995 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002996 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002997 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002998 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002999 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003000 char *crt_path;
3001 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003002
3003 linenum++;
3004 end = line + strlen(line);
3005 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
3006 /* Check if we reached the limit and the last char is not \n.
3007 * Watch out for the last line without the terminating '\n'!
3008 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02003009 memprintf(err, "line %d too long in file '%s', limit is %d characters",
3010 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003011 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003012 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003013 }
3014
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003015 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02003016 newarg = 1;
3017 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003018 if (*line == '#' || *line == '\n' || *line == '\r') {
3019 /* end of string, end of loop */
3020 *line = 0;
3021 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003022 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02003023 newarg = 1;
3024 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003025 } else if (*line == '[') {
3026 if (ssl_b) {
3027 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
3028 cfgerr = 1;
3029 break;
3030 }
3031 if (!arg) {
3032 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
3033 cfgerr = 1;
3034 break;
3035 }
3036 ssl_b = arg;
3037 newarg = 1;
3038 *line = 0;
3039 } else if (*line == ']') {
3040 if (ssl_e) {
3041 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02003042 cfgerr = 1;
3043 break;
3044 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003045 if (!ssl_b) {
3046 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
3047 cfgerr = 1;
3048 break;
3049 }
3050 ssl_e = arg;
3051 newarg = 1;
3052 *line = 0;
3053 } else if (newarg) {
3054 if (arg == MAX_CRT_ARGS) {
3055 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
3056 cfgerr = 1;
3057 break;
3058 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003059 newarg = 0;
3060 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003061 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02003062 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003063 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02003064 if (cfgerr)
3065 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003066 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003067
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003068 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003069 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003070 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003071
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003072 crt_path = args[0];
3073 if (*crt_path != '/' && global_ssl.crt_base) {
3074 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
3075 memprintf(err, "'%s' : path too long on line %d in file '%s'",
3076 crt_path, linenum, file);
3077 cfgerr = 1;
3078 break;
3079 }
3080 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
3081 crt_path = path;
3082 }
3083
3084 ssl_conf = calloc(1, sizeof *ssl_conf);
3085 cur_arg = ssl_b ? ssl_b : 1;
3086 while (cur_arg < ssl_e) {
3087 newarg = 0;
3088 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
3089 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
3090 newarg = 1;
3091 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
3092 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
3093 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
3094 args[cur_arg], linenum, file);
3095 cfgerr = 1;
3096 }
3097 cur_arg += 1 + ssl_bind_kws[i].skip;
3098 break;
3099 }
3100 }
3101 if (!cfgerr && !newarg) {
3102 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
3103 args[cur_arg], linenum, file);
3104 cfgerr = 1;
3105 break;
3106 }
3107 }
3108 if (cfgerr) {
3109 ssl_sock_free_ssl_conf(ssl_conf);
3110 free(ssl_conf);
3111 ssl_conf = NULL;
3112 break;
3113 }
3114
3115 if (stat(crt_path, &buf) == 0) {
3116 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
3117 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003118 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003119 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3120 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003121 }
3122
Willy Tarreauad1731d2013-04-02 17:35:58 +02003123 if (cfgerr) {
3124 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003125 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003126 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003127 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003128 fclose(f);
3129 return cfgerr;
3130}
3131
Emeric Brunfc0421f2012-09-07 17:30:07 +02003132#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
3133#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
3134#endif
3135
3136#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
3137#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01003138#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02003139#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003140#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
3141#define SSL_OP_SINGLE_ECDH_USE 0
3142#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02003143#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
3144#define SSL_OP_NO_TICKET 0
3145#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003146#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
3147#define SSL_OP_NO_COMPRESSION 0
3148#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02003149#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
3150#define SSL_OP_NO_TLSv1_1 0
3151#endif
3152#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
3153#define SSL_OP_NO_TLSv1_2 0
3154#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003155#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
3156#define SSL_OP_SINGLE_DH_USE 0
3157#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003158#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
3159#define SSL_OP_SINGLE_ECDH_USE 0
3160#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003161#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
3162#define SSL_MODE_RELEASE_BUFFERS 0
3163#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01003164#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
3165#define SSL_MODE_SMALL_BUFFERS 0
3166#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003167
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003168
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003169/* Create an initial CTX used to start the SSL connection before switchctx */
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003170static SSL_CTX *
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003171ssl_sock_initial_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003172{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003173 SSL_CTX *ctx = NULL;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003174 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003175 SSL_OP_ALL | /* all known workarounds for bugs */
3176 SSL_OP_NO_SSLv2 |
3177 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003178 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003179 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003180 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3181 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003182 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003183 SSL_MODE_ENABLE_PARTIAL_WRITE |
3184 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003185 SSL_MODE_RELEASE_BUFFERS |
3186 SSL_MODE_SMALL_BUFFERS;
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01003187 int conf_ssl_options = bind_conf->ssl_options;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003188
3189#if SSL_OP_NO_TLSv1_2
3190 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV12)
3191 ctx = SSL_CTX_new(TLSv1_2_server_method());
3192#endif
3193#if SSL_OP_NO_TLSv1_1
3194 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV11)
3195 ctx = SSL_CTX_new(TLSv1_1_server_method());
3196#endif
3197 if (!ctx && conf_ssl_options & BC_SSL_O_USE_TLSV10)
3198 ctx = SSL_CTX_new(TLSv1_server_method());
3199#ifndef OPENSSL_NO_SSL3
3200 if (!ctx && conf_ssl_options & BC_SSL_O_USE_SSLV3)
3201 ctx = SSL_CTX_new(SSLv3_server_method());
3202#endif
3203 if (!ctx) {
3204 ctx = SSL_CTX_new(SSLv23_server_method());
3205 if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
3206 ssloptions |= SSL_OP_NO_SSLv3;
3207 if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
3208 ssloptions |= SSL_OP_NO_TLSv1;
3209 if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
3210 ssloptions |= SSL_OP_NO_TLSv1_1;
3211 if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
3212 ssloptions |= SSL_OP_NO_TLSv1_2;
3213 }
3214 if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
3215 ssloptions |= SSL_OP_NO_TICKET;
3216 SSL_CTX_set_options(ctx, ssloptions);
3217 SSL_CTX_set_mode(ctx, sslmode);
3218 if (global_ssl.life_time)
3219 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003220
3221#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3222#ifdef OPENSSL_IS_BORINGSSL
3223 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3224 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3225#else
3226 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
3227 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
3228#endif
3229#endif
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003230 return ctx;
3231}
3232
3233int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
3234{
3235 struct proxy *curproxy = bind_conf->frontend;
3236 int cfgerr = 0;
3237 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003238 struct ssl_bind_conf *ssl_conf_cur;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003239 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003240 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003241
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003242 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003243 case SSL_SOCK_VERIFY_NONE:
3244 verify = SSL_VERIFY_NONE;
3245 break;
3246 case SSL_SOCK_VERIFY_OPTIONAL:
3247 verify = SSL_VERIFY_PEER;
3248 break;
3249 case SSL_SOCK_VERIFY_REQUIRED:
3250 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3251 break;
3252 }
3253 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3254 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003255 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3256 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3257 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003258 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003259 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003260 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003261 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003262 cfgerr++;
3263 }
3264 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003265 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003266 }
Emeric Brun850efd52014-01-29 12:24:34 +01003267 else {
3268 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3269 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3270 cfgerr++;
3271 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003272#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003273 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003274 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3275
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003276 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003277 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003278 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003279 cfgerr++;
3280 }
Emeric Brun561e5742012-10-02 15:20:55 +02003281 else {
3282 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3283 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003284 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003285#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003286 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003287 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003288#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003289 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003290 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3291 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3292 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3293 cfgerr++;
3294 }
3295 }
3296#endif
3297
Emeric Brunfc0421f2012-09-07 17:30:07 +02003298 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003299 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3300 if (conf_ciphers &&
3301 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003302 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 +01003303 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003304 cfgerr++;
3305 }
3306
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003307#ifndef OPENSSL_NO_DH
Remi Gacogne47783ef2015-05-29 15:53:22 +02003308 /* If tune.ssl.default-dh-param has not been set,
3309 neither has ssl-default-dh-file and no static DH
3310 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003311 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003312 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003313 (ssl_dh_ptr_index == -1 ||
3314 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Emmanuel Hocdetcc6c2a22017-03-03 17:04:14 +01003315 STACK_OF(SSL_CIPHER) * ciphers = NULL;
3316 const SSL_CIPHER * cipher = NULL;
3317 char cipher_description[128];
3318 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3319 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3320 which is not ephemeral DH. */
3321 const char dhe_description[] = " Kx=DH ";
3322 const char dhe_export_description[] = " Kx=DH(";
3323 int idx = 0;
3324 int dhe_found = 0;
3325 SSL *ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003326
Remi Gacogne23d5d372014-10-10 17:04:26 +02003327 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003328
Remi Gacogne23d5d372014-10-10 17:04:26 +02003329 if (ssl) {
3330 ciphers = SSL_get_ciphers(ssl);
3331
3332 if (ciphers) {
3333 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3334 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3335 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3336 if (strstr(cipher_description, dhe_description) != NULL ||
3337 strstr(cipher_description, dhe_export_description) != NULL) {
3338 dhe_found = 1;
3339 break;
3340 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003341 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003342 }
3343 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003344 SSL_free(ssl);
3345 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003346 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003347
Lukas Tribus90132722014-08-18 00:56:33 +02003348 if (dhe_found) {
3349 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 +02003350 }
3351
Willy Tarreauef934602016-12-22 23:12:01 +01003352 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003353 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003354
Willy Tarreauef934602016-12-22 23:12:01 +01003355 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003356 if (local_dh_1024 == NULL) {
3357 local_dh_1024 = ssl_get_dh_1024();
3358 }
Willy Tarreauef934602016-12-22 23:12:01 +01003359 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003360 if (local_dh_2048 == NULL) {
3361 local_dh_2048 = ssl_get_dh_2048();
3362 }
Willy Tarreauef934602016-12-22 23:12:01 +01003363 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003364 if (local_dh_4096 == NULL) {
3365 local_dh_4096 = ssl_get_dh_4096();
3366 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003367 }
3368 }
3369 }
3370#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003371
Emeric Brunfc0421f2012-09-07 17:30:07 +02003372 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003373#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003374 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003375#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003376
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003377#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003378 ssl_conf_cur = NULL;
3379 if (ssl_conf && ssl_conf->npn_str)
3380 ssl_conf_cur = ssl_conf;
3381 else if (bind_conf->ssl_conf.npn_str)
3382 ssl_conf_cur = &bind_conf->ssl_conf;
3383 if (ssl_conf_cur)
3384 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003385#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003386#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003387 ssl_conf_cur = NULL;
3388 if (ssl_conf && ssl_conf->alpn_str)
3389 ssl_conf_cur = ssl_conf;
3390 else if (bind_conf->ssl_conf.alpn_str)
3391 ssl_conf_cur = &bind_conf->ssl_conf;
3392 if (ssl_conf_cur)
3393 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003394#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003395#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3396 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3397 if (conf_curves) {
3398 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3399 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3400 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3401 cfgerr++;
3402 }
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003403 else
3404 SSL_CTX_set_ecdh_auto(ctx, 1);
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003405 }
3406#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003407#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003408 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003409 int i;
3410 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003411 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3412 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003413
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003414 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003415 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3416 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 +01003417 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003418 cfgerr++;
3419 }
3420 else {
3421 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3422 EC_KEY_free(ecdh);
3423 }
3424 }
3425#endif
3426
Emeric Brunfc0421f2012-09-07 17:30:07 +02003427 return cfgerr;
3428}
3429
Evan Broderbe554312013-06-27 00:05:25 -07003430static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3431{
3432 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3433 size_t prefixlen, suffixlen;
3434
3435 /* Trivial case */
3436 if (strcmp(pattern, hostname) == 0)
3437 return 1;
3438
Evan Broderbe554312013-06-27 00:05:25 -07003439 /* The rest of this logic is based on RFC 6125, section 6.4.3
3440 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3441
Emeric Bruna848dae2013-10-08 11:27:28 +02003442 pattern_wildcard = NULL;
3443 pattern_left_label_end = pattern;
3444 while (*pattern_left_label_end != '.') {
3445 switch (*pattern_left_label_end) {
3446 case 0:
3447 /* End of label not found */
3448 return 0;
3449 case '*':
3450 /* If there is more than one wildcards */
3451 if (pattern_wildcard)
3452 return 0;
3453 pattern_wildcard = pattern_left_label_end;
3454 break;
3455 }
3456 pattern_left_label_end++;
3457 }
3458
3459 /* If it's not trivial and there is no wildcard, it can't
3460 * match */
3461 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003462 return 0;
3463
3464 /* Make sure all labels match except the leftmost */
3465 hostname_left_label_end = strchr(hostname, '.');
3466 if (!hostname_left_label_end
3467 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3468 return 0;
3469
3470 /* Make sure the leftmost label of the hostname is long enough
3471 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003472 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003473 return 0;
3474
3475 /* Finally compare the string on either side of the
3476 * wildcard */
3477 prefixlen = pattern_wildcard - pattern;
3478 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003479 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3480 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003481 return 0;
3482
3483 return 1;
3484}
3485
3486static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3487{
3488 SSL *ssl;
3489 struct connection *conn;
3490 char *servername;
3491
3492 int depth;
3493 X509 *cert;
3494 STACK_OF(GENERAL_NAME) *alt_names;
3495 int i;
3496 X509_NAME *cert_subject;
3497 char *str;
3498
3499 if (ok == 0)
3500 return ok;
3501
3502 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003503 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003504
3505 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3506
3507 /* We only need to verify the CN on the actual server cert,
3508 * not the indirect CAs */
3509 depth = X509_STORE_CTX_get_error_depth(ctx);
3510 if (depth != 0)
3511 return ok;
3512
3513 /* At this point, the cert is *not* OK unless we can find a
3514 * hostname match */
3515 ok = 0;
3516
3517 cert = X509_STORE_CTX_get_current_cert(ctx);
3518 /* It seems like this might happen if verify peer isn't set */
3519 if (!cert)
3520 return ok;
3521
3522 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3523 if (alt_names) {
3524 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3525 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3526 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003527#if OPENSSL_VERSION_NUMBER < 0x00907000L
3528 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3529#else
Evan Broderbe554312013-06-27 00:05:25 -07003530 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003531#endif
Evan Broderbe554312013-06-27 00:05:25 -07003532 ok = ssl_sock_srv_hostcheck(str, servername);
3533 OPENSSL_free(str);
3534 }
3535 }
3536 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003537 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003538 }
3539
3540 cert_subject = X509_get_subject_name(cert);
3541 i = -1;
3542 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3543 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003544 ASN1_STRING *value;
3545 value = X509_NAME_ENTRY_get_data(entry);
3546 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003547 ok = ssl_sock_srv_hostcheck(str, servername);
3548 OPENSSL_free(str);
3549 }
3550 }
3551
3552 return ok;
3553}
3554
Emeric Brun94324a42012-10-11 14:00:19 +02003555/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003556int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003557{
Willy Tarreau03209342016-12-22 17:08:28 +01003558 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003559 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003560 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003561 SSL_OP_ALL | /* all known workarounds for bugs */
3562 SSL_OP_NO_SSLv2 |
3563 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003564 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003565 SSL_MODE_ENABLE_PARTIAL_WRITE |
3566 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003567 SSL_MODE_RELEASE_BUFFERS |
3568 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003569 int verify = SSL_VERIFY_NONE;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003570 SSL_CTX *ctx = NULL;
Emeric Brun94324a42012-10-11 14:00:19 +02003571
Thierry Fournier383085f2013-01-24 14:15:43 +01003572 /* Make sure openssl opens /dev/urandom before the chroot */
3573 if (!ssl_initialize_random()) {
3574 Alert("OpenSSL random data generator initialization failed.\n");
3575 cfgerr++;
3576 }
3577
Willy Tarreaufce03112015-01-15 21:32:40 +01003578 /* Automatic memory computations need to know we use SSL there */
3579 global.ssl_used_backend = 1;
3580
3581 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003582 srv->ssl_ctx.reused_sess = NULL;
3583 if (srv->use_ssl)
3584 srv->xprt = &ssl_sock;
3585 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003586 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003587
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003588#if SSL_OP_NO_TLSv1_2
3589 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3590 ctx = SSL_CTX_new(TLSv1_2_client_method());
3591#endif
3592#if SSL_OP_NO_TLSv1_1
3593 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3594 ctx = SSL_CTX_new(TLSv1_1_client_method());
3595#endif
3596 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3597 ctx = SSL_CTX_new(TLSv1_client_method());
3598#ifndef OPENSSL_NO_SSL3
3599 if (!ctx && srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
3600 ctx = SSL_CTX_new(SSLv3_client_method());
3601#endif
3602 if (!ctx) {
3603 ctx = SSL_CTX_new(SSLv23_client_method());
3604 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3605 options |= SSL_OP_NO_SSLv3;
3606 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3607 options |= SSL_OP_NO_TLSv1;
3608 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3609 options |= SSL_OP_NO_TLSv1_1;
3610 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3611 options |= SSL_OP_NO_TLSv1_2;
3612 }
3613 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3614 options |= SSL_OP_NO_TICKET;
3615 if (!ctx) {
Emeric Brun94324a42012-10-11 14:00:19 +02003616 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3617 proxy_type_str(curproxy), curproxy->id,
3618 srv->id);
3619 cfgerr++;
3620 return cfgerr;
3621 }
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01003622 SSL_CTX_set_options(ctx, options);
3623 SSL_CTX_set_mode(ctx, mode);
3624 srv->ssl_ctx.ctx = ctx;
3625
Emeric Bruna7aa3092012-10-26 12:58:00 +02003626 if (srv->ssl_ctx.client_crt) {
3627 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3628 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3629 proxy_type_str(curproxy), curproxy->id,
3630 srv->id, srv->ssl_ctx.client_crt);
3631 cfgerr++;
3632 }
3633 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3634 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3635 proxy_type_str(curproxy), curproxy->id,
3636 srv->id, srv->ssl_ctx.client_crt);
3637 cfgerr++;
3638 }
3639 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3640 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3641 proxy_type_str(curproxy), curproxy->id,
3642 srv->id, srv->ssl_ctx.client_crt);
3643 cfgerr++;
3644 }
3645 }
Emeric Brun94324a42012-10-11 14:00:19 +02003646
Emeric Brun850efd52014-01-29 12:24:34 +01003647 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3648 verify = SSL_VERIFY_PEER;
Emeric Brun850efd52014-01-29 12:24:34 +01003649 switch (srv->ssl_ctx.verify) {
3650 case SSL_SOCK_VERIFY_NONE:
3651 verify = SSL_VERIFY_NONE;
3652 break;
3653 case SSL_SOCK_VERIFY_REQUIRED:
3654 verify = SSL_VERIFY_PEER;
3655 break;
3656 }
Evan Broderbe554312013-06-27 00:05:25 -07003657 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003658 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003659 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003660 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003661 if (srv->ssl_ctx.ca_file) {
3662 /* load CAfile to verify */
3663 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003664 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003665 curproxy->id, srv->id,
3666 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3667 cfgerr++;
3668 }
3669 }
Emeric Brun850efd52014-01-29 12:24:34 +01003670 else {
3671 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003672 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 +01003673 curproxy->id, srv->id,
3674 srv->conf.file, srv->conf.line);
3675 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003676 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003677 curproxy->id, srv->id,
3678 srv->conf.file, srv->conf.line);
3679 cfgerr++;
3680 }
Emeric Brunef42d922012-10-11 16:11:36 +02003681#ifdef X509_V_FLAG_CRL_CHECK
3682 if (srv->ssl_ctx.crl_file) {
3683 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3684
3685 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003686 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003687 curproxy->id, srv->id,
3688 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3689 cfgerr++;
3690 }
3691 else {
3692 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3693 }
3694 }
3695#endif
3696 }
3697
Emeric Brun94324a42012-10-11 14:00:19 +02003698 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3699 if (srv->ssl_ctx.ciphers &&
3700 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3701 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3702 curproxy->id, srv->id,
3703 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3704 cfgerr++;
3705 }
3706
3707 return cfgerr;
3708}
3709
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003710/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003711 * be NULL, in which case nothing is done. Returns the number of errors
3712 * encountered.
3713 */
Willy Tarreau03209342016-12-22 17:08:28 +01003714int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003715{
3716 struct ebmb_node *node;
3717 struct sni_ctx *sni;
3718 int err = 0;
3719
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003720 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003721 return 0;
3722
Willy Tarreaufce03112015-01-15 21:32:40 +01003723 /* Automatic memory computations need to know we use SSL there */
3724 global.ssl_used_frontend = 1;
3725
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003726 /* Make sure openssl opens /dev/urandom before the chroot */
3727 if (!ssl_initialize_random()) {
3728 Alert("OpenSSL random data generator initialization failed.\n");
3729 err++;
3730 }
3731 /* Create initial_ctx used to start the ssl connection before do switchctx */
3732 if (!bind_conf->initial_ctx) {
3733 bind_conf->initial_ctx = ssl_sock_initial_ctx(bind_conf);
3734 /* It should not be necessary to call this function, but it's
3735 necessary first to check and move all initialisation related
3736 to initial_ctx in ssl_sock_initial_ctx. */
3737 err += ssl_sock_prepare_ctx(bind_conf, NULL, bind_conf->initial_ctx);
3738 }
Emeric Brun0bed9942014-10-30 19:25:24 +01003739 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003740 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003741
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003742 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003743 while (node) {
3744 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003745 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3746 /* only initialize the CTX on its first occurrence and
3747 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003748 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003749 node = ebmb_next(node);
3750 }
3751
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003752 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003753 while (node) {
3754 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003755 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3756 /* only initialize the CTX on its first occurrence and
3757 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003758 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003759 node = ebmb_next(node);
3760 }
3761 return err;
3762}
3763
Willy Tarreau55d37912016-12-21 23:38:39 +01003764/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3765 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3766 * alerts are directly emitted since the rest of the stack does it below.
3767 */
3768int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3769{
3770 struct proxy *px = bind_conf->frontend;
3771 int alloc_ctx;
3772 int err;
3773
3774 if (!bind_conf->is_ssl) {
3775 if (bind_conf->default_ctx) {
3776 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3777 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3778 }
3779 return 0;
3780 }
3781 if (!bind_conf->default_ctx) {
3782 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3783 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3784 return -1;
3785 }
3786
Willy Tarreauef934602016-12-22 23:12:01 +01003787 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003788 if (alloc_ctx < 0) {
3789 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3790 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");
3791 else
3792 Alert("Unable to allocate SSL session cache.\n");
3793 return -1;
3794 }
3795
3796 err = 0;
3797 /* initialize all certificate contexts */
3798 err += ssl_sock_prepare_all_ctx(bind_conf);
3799
3800 /* initialize CA variables if the certificates generation is enabled */
3801 err += ssl_sock_load_ca(bind_conf);
3802
3803 return -err;
3804}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003805
3806/* release ssl context allocated for servers. */
3807void ssl_sock_free_srv_ctx(struct server *srv)
3808{
3809 if (srv->ssl_ctx.ctx)
3810 SSL_CTX_free(srv->ssl_ctx.ctx);
3811}
3812
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003813/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003814 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3815 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003816void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003817{
3818 struct ebmb_node *node, *back;
3819 struct sni_ctx *sni;
3820
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003821 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003822 return;
3823
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003824 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003825 while (node) {
3826 sni = ebmb_entry(node, struct sni_ctx, name);
3827 back = ebmb_next(node);
3828 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003829 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003830 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003831 ssl_sock_free_ssl_conf(sni->conf);
3832 free(sni->conf);
3833 sni->conf = NULL;
3834 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003835 free(sni);
3836 node = back;
3837 }
3838
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003839 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003840 while (node) {
3841 sni = ebmb_entry(node, struct sni_ctx, name);
3842 back = ebmb_next(node);
3843 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003844 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003845 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003846 ssl_sock_free_ssl_conf(sni->conf);
3847 free(sni->conf);
3848 sni->conf = NULL;
3849 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003850 free(sni);
3851 node = back;
3852 }
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01003853 SSL_CTX_free(bind_conf->initial_ctx);
3854 bind_conf->initial_ctx = NULL;
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003855 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003856 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003857}
3858
Willy Tarreau795cdab2016-12-22 17:30:54 +01003859/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3860void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3861{
3862 ssl_sock_free_ca(bind_conf);
3863 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003864 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003865 free(bind_conf->ca_sign_file);
3866 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003867 if (bind_conf->keys_ref) {
3868 free(bind_conf->keys_ref->filename);
3869 free(bind_conf->keys_ref->tlskeys);
3870 LIST_DEL(&bind_conf->keys_ref->list);
3871 free(bind_conf->keys_ref);
3872 }
3873 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003874 bind_conf->ca_sign_pass = NULL;
3875 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003876}
3877
Christopher Faulet31af49d2015-06-09 17:29:50 +02003878/* Load CA cert file and private key used to generate certificates */
3879int
Willy Tarreau03209342016-12-22 17:08:28 +01003880ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003881{
Willy Tarreau03209342016-12-22 17:08:28 +01003882 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003883 FILE *fp;
3884 X509 *cacert = NULL;
3885 EVP_PKEY *capkey = NULL;
3886 int err = 0;
3887
3888 if (!bind_conf || !bind_conf->generate_certs)
3889 return err;
3890
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003891#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01003892 if (global_ssl.ctx_cache)
3893 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003894 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003895#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003896
Christopher Faulet31af49d2015-06-09 17:29:50 +02003897 if (!bind_conf->ca_sign_file) {
3898 Alert("Proxy '%s': cannot enable certificate generation, "
3899 "no CA certificate File configured at [%s:%d].\n",
3900 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003901 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003902 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003903
3904 /* read in the CA certificate */
3905 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3906 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3907 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003908 goto load_error;
3909 }
3910 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3911 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3912 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003913 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003914 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003915 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003916 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3917 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3918 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003919 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003920 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003921
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003922 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003923 bind_conf->ca_sign_cert = cacert;
3924 bind_conf->ca_sign_pkey = capkey;
3925 return err;
3926
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003927 read_error:
3928 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003929 if (capkey) EVP_PKEY_free(capkey);
3930 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003931 load_error:
3932 bind_conf->generate_certs = 0;
3933 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003934 return err;
3935}
3936
3937/* Release CA cert and private key used to generate certificated */
3938void
3939ssl_sock_free_ca(struct bind_conf *bind_conf)
3940{
3941 if (!bind_conf)
3942 return;
3943
3944 if (bind_conf->ca_sign_pkey)
3945 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3946 if (bind_conf->ca_sign_cert)
3947 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003948 bind_conf->ca_sign_pkey = NULL;
3949 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003950}
3951
Emeric Brun46591952012-05-18 15:47:34 +02003952/*
3953 * This function is called if SSL * context is not yet allocated. The function
3954 * is designed to be called before any other data-layer operation and sets the
3955 * handshake flag on the connection. It is safe to call it multiple times.
3956 * It returns 0 on success and -1 in error case.
3957 */
3958static int ssl_sock_init(struct connection *conn)
3959{
3960 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003961 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003962 return 0;
3963
Willy Tarreau3c728722014-01-23 13:50:42 +01003964 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003965 return 0;
3966
Willy Tarreau20879a02012-12-03 16:32:10 +01003967 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3968 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003969 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003970 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003971
Emeric Brun46591952012-05-18 15:47:34 +02003972 /* If it is in client mode initiate SSL session
3973 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003974 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003975 int may_retry = 1;
3976
3977 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003978 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003979 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003980 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003981 if (may_retry--) {
3982 pool_gc2();
3983 goto retry_connect;
3984 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003985 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003986 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003987 }
Emeric Brun46591952012-05-18 15:47:34 +02003988
Emeric Brun46591952012-05-18 15:47:34 +02003989 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003990 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3991 SSL_free(conn->xprt_ctx);
3992 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003993 if (may_retry--) {
3994 pool_gc2();
3995 goto retry_connect;
3996 }
Emeric Brun55476152014-11-12 17:35:37 +01003997 conn->err_code = CO_ER_SSL_NO_MEM;
3998 return -1;
3999 }
Emeric Brun46591952012-05-18 15:47:34 +02004000
Evan Broderbe554312013-06-27 00:05:25 -07004001 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004002 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4003 SSL_free(conn->xprt_ctx);
4004 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004005 if (may_retry--) {
4006 pool_gc2();
4007 goto retry_connect;
4008 }
Emeric Brun55476152014-11-12 17:35:37 +01004009 conn->err_code = CO_ER_SSL_NO_MEM;
4010 return -1;
4011 }
4012
4013 SSL_set_connect_state(conn->xprt_ctx);
4014 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
4015 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
4016 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4017 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4018 }
4019 }
Evan Broderbe554312013-06-27 00:05:25 -07004020
Emeric Brun46591952012-05-18 15:47:34 +02004021 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004022 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004023
4024 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004025 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004026 return 0;
4027 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004028 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004029 int may_retry = 1;
4030
4031 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02004032 /* Alloc a new SSL session ctx */
Emmanuel Hocdetf6b37c62017-03-06 15:34:44 +01004033 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->initial_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01004034 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004035 if (may_retry--) {
4036 pool_gc2();
4037 goto retry_accept;
4038 }
Willy Tarreau20879a02012-12-03 16:32:10 +01004039 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02004040 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01004041 }
Emeric Brun46591952012-05-18 15:47:34 +02004042
Emeric Brun46591952012-05-18 15:47:34 +02004043 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01004044 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
4045 SSL_free(conn->xprt_ctx);
4046 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004047 if (may_retry--) {
4048 pool_gc2();
4049 goto retry_accept;
4050 }
Emeric Brun55476152014-11-12 17:35:37 +01004051 conn->err_code = CO_ER_SSL_NO_MEM;
4052 return -1;
4053 }
Emeric Brun46591952012-05-18 15:47:34 +02004054
Emeric Brune1f38db2012-09-03 20:36:47 +02004055 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01004056 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
4057 SSL_free(conn->xprt_ctx);
4058 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01004059 if (may_retry--) {
4060 pool_gc2();
4061 goto retry_accept;
4062 }
Emeric Brun55476152014-11-12 17:35:37 +01004063 conn->err_code = CO_ER_SSL_NO_MEM;
4064 return -1;
4065 }
4066
4067 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02004068
Emeric Brun46591952012-05-18 15:47:34 +02004069 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02004070 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02004071
4072 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01004073 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02004074 return 0;
4075 }
4076 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01004077 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02004078 return -1;
4079}
4080
4081
4082/* This is the callback which is used when an SSL handshake is pending. It
4083 * updates the FD status if it wants some polling before being called again.
4084 * It returns 0 if it fails in a fatal way or needs to poll to go further,
4085 * otherwise it returns non-zero and removes itself from the connection's
4086 * flags (the bit is provided in <flag> by the caller).
4087 */
4088int ssl_sock_handshake(struct connection *conn, unsigned int flag)
4089{
4090 int ret;
4091
Willy Tarreau3c728722014-01-23 13:50:42 +01004092 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02004093 return 0;
4094
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004095 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004096 goto out_error;
4097
Emeric Brun674b7432012-11-08 19:21:55 +01004098 /* If we use SSL_do_handshake to process a reneg initiated by
4099 * the remote peer, it sometimes returns SSL_ERROR_SSL.
4100 * Usually SSL_write and SSL_read are used and process implicitly
4101 * the reneg handshake.
4102 * Here we use SSL_peek as a workaround for reneg.
4103 */
4104 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
4105 char c;
4106
4107 ret = SSL_peek(conn->xprt_ctx, &c, 1);
4108 if (ret <= 0) {
4109 /* handshake may have not been completed, let's find why */
4110 ret = SSL_get_error(conn->xprt_ctx, ret);
4111 if (ret == SSL_ERROR_WANT_WRITE) {
4112 /* SSL handshake needs to write, L4 connection may not be ready */
4113 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004114 __conn_sock_want_send(conn);
4115 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004116 return 0;
4117 }
4118 else if (ret == SSL_ERROR_WANT_READ) {
4119 /* handshake may have been completed but we have
4120 * no more data to read.
4121 */
4122 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
4123 ret = 1;
4124 goto reneg_ok;
4125 }
4126 /* SSL handshake needs to read, L4 connection is ready */
4127 if (conn->flags & CO_FL_WAIT_L4_CONN)
4128 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4129 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004130 __conn_sock_want_recv(conn);
4131 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004132 return 0;
4133 }
4134 else if (ret == SSL_ERROR_SYSCALL) {
4135 /* if errno is null, then connection was successfully established */
4136 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4137 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004138 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004139#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4140 conn->err_code = CO_ER_SSL_HANDSHAKE;
4141#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004142 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004143#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004144 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4145 empty_handshake = state == TLS_ST_BEFORE;
4146#else
4147 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4148#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004149 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004150 if (!errno) {
4151 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4152 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4153 else
4154 conn->err_code = CO_ER_SSL_EMPTY;
4155 }
4156 else {
4157 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4158 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4159 else
4160 conn->err_code = CO_ER_SSL_ABORT;
4161 }
4162 }
4163 else {
4164 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4165 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004166 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004167 conn->err_code = CO_ER_SSL_HANDSHAKE;
4168 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004169#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004170 }
Emeric Brun674b7432012-11-08 19:21:55 +01004171 goto out_error;
4172 }
4173 else {
4174 /* Fail on all other handshake errors */
4175 /* Note: OpenSSL may leave unread bytes in the socket's
4176 * buffer, causing an RST to be emitted upon close() on
4177 * TCP sockets. We first try to drain possibly pending
4178 * data to avoid this as much as possible.
4179 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004180 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004181 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004182 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4183 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004184 goto out_error;
4185 }
4186 }
4187 /* read some data: consider handshake completed */
4188 goto reneg_ok;
4189 }
4190
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004191 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004192 if (ret != 1) {
4193 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004194 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004195
4196 if (ret == SSL_ERROR_WANT_WRITE) {
4197 /* SSL handshake needs to write, L4 connection may not be ready */
4198 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004199 __conn_sock_want_send(conn);
4200 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004201 return 0;
4202 }
4203 else if (ret == SSL_ERROR_WANT_READ) {
4204 /* SSL handshake needs to read, L4 connection is ready */
4205 if (conn->flags & CO_FL_WAIT_L4_CONN)
4206 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4207 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004208 __conn_sock_want_recv(conn);
4209 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004210 return 0;
4211 }
Willy Tarreau89230192012-09-28 20:22:13 +02004212 else if (ret == SSL_ERROR_SYSCALL) {
4213 /* if errno is null, then connection was successfully established */
4214 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4215 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004216 if (!conn->err_code) {
4217#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4218 conn->err_code = CO_ER_SSL_HANDSHAKE;
4219#else
4220 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004221#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004222 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4223 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004224#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004225 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004226#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004227 if (empty_handshake) {
4228 if (!errno) {
4229 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4230 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4231 else
4232 conn->err_code = CO_ER_SSL_EMPTY;
4233 }
4234 else {
4235 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4236 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4237 else
4238 conn->err_code = CO_ER_SSL_ABORT;
4239 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004240 }
4241 else {
4242 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4243 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4244 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004245 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004246 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004247#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004248 }
Willy Tarreau89230192012-09-28 20:22:13 +02004249 goto out_error;
4250 }
Emeric Brun46591952012-05-18 15:47:34 +02004251 else {
4252 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004253 /* Note: OpenSSL may leave unread bytes in the socket's
4254 * buffer, causing an RST to be emitted upon close() on
4255 * TCP sockets. We first try to drain possibly pending
4256 * data to avoid this as much as possible.
4257 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004258 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004259 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004260 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4261 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004262 goto out_error;
4263 }
4264 }
4265
Emeric Brun674b7432012-11-08 19:21:55 +01004266reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004267 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004268 if (!SSL_session_reused(conn->xprt_ctx)) {
4269 if (objt_server(conn->target)) {
4270 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4271 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4272 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4273
Emeric Brun46591952012-05-18 15:47:34 +02004274 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004275 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004276 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004277 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4278 }
Emeric Brun46591952012-05-18 15:47:34 +02004279
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004280 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4281 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004282 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004283 else {
4284 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4285 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4286 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4287 }
Emeric Brun46591952012-05-18 15:47:34 +02004288 }
4289
4290 /* The connection is now established at both layers, it's time to leave */
4291 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4292 return 1;
4293
4294 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004295 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004296 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004297 ERR_clear_error();
4298
Emeric Brun9fa89732012-10-04 17:09:56 +02004299 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004300 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4301 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4302 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004303 }
4304
Emeric Brun46591952012-05-18 15:47:34 +02004305 /* Fail on all other handshake errors */
4306 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004307 if (!conn->err_code)
4308 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004309 return 0;
4310}
4311
4312/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004313 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004314 * buffer wraps, in which case a second call may be performed. The connection's
4315 * flags are updated with whatever special event is detected (error, read0,
4316 * empty). The caller is responsible for taking care of those events and
4317 * avoiding the call if inappropriate. The function does not call the
4318 * connection's polling update function, so the caller is responsible for this.
4319 */
4320static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4321{
4322 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004323 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004324
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004325 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004326 goto out_error;
4327
4328 if (conn->flags & CO_FL_HANDSHAKE)
4329 /* a handshake was requested */
4330 return 0;
4331
Willy Tarreauabf08d92014-01-14 11:31:27 +01004332 /* let's realign the buffer to optimize I/O */
4333 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004334 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004335
4336 /* read the largest possible block. For this, we perform only one call
4337 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4338 * in which case we accept to do it once again. A new attempt is made on
4339 * EINTR too.
4340 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004341 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004342 /* first check if we have some room after p+i */
4343 try = buf->data + buf->size - (buf->p + buf->i);
4344 /* otherwise continue between data and p-o */
4345 if (try <= 0) {
4346 try = buf->p - (buf->data + buf->o);
4347 if (try <= 0)
4348 break;
4349 }
4350 if (try > count)
4351 try = count;
4352
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004353 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004354 if (conn->flags & CO_FL_ERROR) {
4355 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004356 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004357 }
Emeric Brun46591952012-05-18 15:47:34 +02004358 if (ret > 0) {
4359 buf->i += ret;
4360 done += ret;
4361 if (ret < try)
4362 break;
4363 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004364 }
4365 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004366 ret = SSL_get_error(conn->xprt_ctx, ret);
4367 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004368 /* error on protocol or underlying transport */
4369 if ((ret != SSL_ERROR_SYSCALL)
4370 || (errno && (errno != EAGAIN)))
4371 conn->flags |= CO_FL_ERROR;
4372
Emeric Brun644cde02012-12-14 11:21:13 +01004373 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004374 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004375 ERR_clear_error();
4376 }
Emeric Brun46591952012-05-18 15:47:34 +02004377 goto read0;
4378 }
4379 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004380 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004381 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004382 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004383 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004384 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004385 break;
4386 }
4387 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004388 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4389 /* handshake is running, and it may need to re-enable read */
4390 conn->flags |= CO_FL_SSL_WAIT_HS;
4391 __conn_sock_want_recv(conn);
4392 break;
4393 }
Emeric Brun46591952012-05-18 15:47:34 +02004394 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004395 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004396 break;
4397 }
4398 /* otherwise it's a real error */
4399 goto out_error;
4400 }
4401 }
4402 return done;
4403
4404 read0:
4405 conn_sock_read0(conn);
4406 return done;
4407 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004408 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004409 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004410 ERR_clear_error();
4411
Emeric Brun46591952012-05-18 15:47:34 +02004412 conn->flags |= CO_FL_ERROR;
4413 return done;
4414}
4415
4416
4417/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004418 * <flags> may contain some CO_SFL_* flags to hint the system about other
4419 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004420 * Only one call to send() is performed, unless the buffer wraps, in which case
4421 * a second call may be performed. The connection's flags are updated with
4422 * whatever special event is detected (error, empty). The caller is responsible
4423 * for taking care of those events and avoiding the call if inappropriate. The
4424 * function does not call the connection's polling update function, so the caller
4425 * is responsible for this.
4426 */
4427static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4428{
4429 int ret, try, done;
4430
4431 done = 0;
4432
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004433 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004434 goto out_error;
4435
4436 if (conn->flags & CO_FL_HANDSHAKE)
4437 /* a handshake was requested */
4438 return 0;
4439
4440 /* send the largest possible block. For this we perform only one call
4441 * to send() unless the buffer wraps and we exactly fill the first hunk,
4442 * in which case we accept to do it once again.
4443 */
4444 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004445 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004446
Willy Tarreau7bed9452014-02-02 02:00:24 +01004447 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004448 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004449 global_ssl.max_record && try > global_ssl.max_record) {
4450 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004451 }
4452 else {
4453 /* we need to keep the information about the fact that
4454 * we're not limiting the upcoming send(), because if it
4455 * fails, we'll have to retry with at least as many data.
4456 */
4457 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4458 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004459
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004460 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004461
Emeric Brune1f38db2012-09-03 20:36:47 +02004462 if (conn->flags & CO_FL_ERROR) {
4463 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004464 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004465 }
Emeric Brun46591952012-05-18 15:47:34 +02004466 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004467 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4468
Emeric Brun46591952012-05-18 15:47:34 +02004469 buf->o -= ret;
4470 done += ret;
4471
Willy Tarreau5fb38032012-12-16 19:39:09 +01004472 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004473 /* optimize data alignment in the buffer */
4474 buf->p = buf->data;
4475
4476 /* if the system buffer is full, don't insist */
4477 if (ret < try)
4478 break;
4479 }
4480 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004481 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004482 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004483 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4484 /* handshake is running, and it may need to re-enable write */
4485 conn->flags |= CO_FL_SSL_WAIT_HS;
4486 __conn_sock_want_send(conn);
4487 break;
4488 }
Emeric Brun46591952012-05-18 15:47:34 +02004489 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004490 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004491 break;
4492 }
4493 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004494 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004495 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004496 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004497 break;
4498 }
4499 goto out_error;
4500 }
4501 }
4502 return done;
4503
4504 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004505 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004506 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004507 ERR_clear_error();
4508
Emeric Brun46591952012-05-18 15:47:34 +02004509 conn->flags |= CO_FL_ERROR;
4510 return done;
4511}
4512
Emeric Brun46591952012-05-18 15:47:34 +02004513static void ssl_sock_close(struct connection *conn) {
4514
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004515 if (conn->xprt_ctx) {
4516 SSL_free(conn->xprt_ctx);
4517 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004518 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004519 }
Emeric Brun46591952012-05-18 15:47:34 +02004520}
4521
4522/* This function tries to perform a clean shutdown on an SSL connection, and in
4523 * any case, flags the connection as reusable if no handshake was in progress.
4524 */
4525static void ssl_sock_shutw(struct connection *conn, int clean)
4526{
4527 if (conn->flags & CO_FL_HANDSHAKE)
4528 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004529 if (!clean)
4530 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004531 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004532 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004533 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004534 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004535 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004536 ERR_clear_error();
4537 }
Emeric Brun46591952012-05-18 15:47:34 +02004538}
4539
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004540/* used for logging, may be changed for a sample fetch later */
4541const char *ssl_sock_get_cipher_name(struct connection *conn)
4542{
4543 if (!conn->xprt && !conn->xprt_ctx)
4544 return NULL;
4545 return SSL_get_cipher_name(conn->xprt_ctx);
4546}
4547
4548/* used for logging, may be changed for a sample fetch later */
4549const char *ssl_sock_get_proto_version(struct connection *conn)
4550{
4551 if (!conn->xprt && !conn->xprt_ctx)
4552 return NULL;
4553 return SSL_get_version(conn->xprt_ctx);
4554}
4555
Willy Tarreau8d598402012-10-22 17:58:39 +02004556/* Extract a serial from a cert, and copy it to a chunk.
4557 * Returns 1 if serial is found and copied, 0 if no serial found and
4558 * -1 if output is not large enough.
4559 */
4560static int
4561ssl_sock_get_serial(X509 *crt, struct chunk *out)
4562{
4563 ASN1_INTEGER *serial;
4564
4565 serial = X509_get_serialNumber(crt);
4566 if (!serial)
4567 return 0;
4568
4569 if (out->size < serial->length)
4570 return -1;
4571
4572 memcpy(out->str, serial->data, serial->length);
4573 out->len = serial->length;
4574 return 1;
4575}
4576
Emeric Brun43e79582014-10-29 19:03:26 +01004577/* Extract a cert to der, and copy it to a chunk.
4578 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4579 * -1 if output is not large enough.
4580 */
4581static int
4582ssl_sock_crt2der(X509 *crt, struct chunk *out)
4583{
4584 int len;
4585 unsigned char *p = (unsigned char *)out->str;;
4586
4587 len =i2d_X509(crt, NULL);
4588 if (len <= 0)
4589 return 1;
4590
4591 if (out->size < len)
4592 return -1;
4593
4594 i2d_X509(crt,&p);
4595 out->len = len;
4596 return 1;
4597}
4598
Emeric Brunce5ad802012-10-22 14:11:22 +02004599
4600/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4601 * Returns 1 if serial is found and copied, 0 if no valid time found
4602 * and -1 if output is not large enough.
4603 */
4604static int
4605ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4606{
4607 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4608 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4609
4610 if (gentm->length < 12)
4611 return 0;
4612 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4613 return 0;
4614 if (out->size < gentm->length-2)
4615 return -1;
4616
4617 memcpy(out->str, gentm->data+2, gentm->length-2);
4618 out->len = gentm->length-2;
4619 return 1;
4620 }
4621 else if (tm->type == V_ASN1_UTCTIME) {
4622 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4623
4624 if (utctm->length < 10)
4625 return 0;
4626 if (utctm->data[0] >= 0x35)
4627 return 0;
4628 if (out->size < utctm->length)
4629 return -1;
4630
4631 memcpy(out->str, utctm->data, utctm->length);
4632 out->len = utctm->length;
4633 return 1;
4634 }
4635
4636 return 0;
4637}
4638
Emeric Brun87855892012-10-17 17:39:35 +02004639/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4640 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4641 */
4642static int
4643ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4644{
4645 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004646 ASN1_OBJECT *obj;
4647 ASN1_STRING *data;
4648 const unsigned char *data_ptr;
4649 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004650 int i, j, n;
4651 int cur = 0;
4652 const char *s;
4653 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004654 int name_count;
4655
4656 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004657
4658 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004659 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004660 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004661 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004662 else
4663 j = i;
4664
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004665 ne = X509_NAME_get_entry(a, j);
4666 obj = X509_NAME_ENTRY_get_object(ne);
4667 data = X509_NAME_ENTRY_get_data(ne);
4668 data_ptr = ASN1_STRING_get0_data(data);
4669 data_len = ASN1_STRING_length(data);
4670 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004671 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004672 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004673 s = tmp;
4674 }
4675
4676 if (chunk_strcasecmp(entry, s) != 0)
4677 continue;
4678
4679 if (pos < 0)
4680 cur--;
4681 else
4682 cur++;
4683
4684 if (cur != pos)
4685 continue;
4686
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004687 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004688 return -1;
4689
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004690 memcpy(out->str, data_ptr, data_len);
4691 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004692 return 1;
4693 }
4694
4695 return 0;
4696
4697}
4698
4699/* Extract and format full DN from a X509_NAME and copy result into a chunk
4700 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4701 */
4702static int
4703ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4704{
4705 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004706 ASN1_OBJECT *obj;
4707 ASN1_STRING *data;
4708 const unsigned char *data_ptr;
4709 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004710 int i, n, ln;
4711 int l = 0;
4712 const char *s;
4713 char *p;
4714 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004715 int name_count;
4716
4717
4718 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004719
4720 out->len = 0;
4721 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004722 for (i = 0; i < name_count; i++) {
4723 ne = X509_NAME_get_entry(a, i);
4724 obj = X509_NAME_ENTRY_get_object(ne);
4725 data = X509_NAME_ENTRY_get_data(ne);
4726 data_ptr = ASN1_STRING_get0_data(data);
4727 data_len = ASN1_STRING_length(data);
4728 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004729 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004730 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004731 s = tmp;
4732 }
4733 ln = strlen(s);
4734
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004735 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004736 if (l > out->size)
4737 return -1;
4738 out->len = l;
4739
4740 *(p++)='/';
4741 memcpy(p, s, ln);
4742 p += ln;
4743 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004744 memcpy(p, data_ptr, data_len);
4745 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004746 }
4747
4748 if (!out->len)
4749 return 0;
4750
4751 return 1;
4752}
4753
David Safb76832014-05-08 23:42:08 -04004754char *ssl_sock_get_version(struct connection *conn)
4755{
4756 if (!ssl_sock_is_ssl(conn))
4757 return NULL;
4758
4759 return (char *)SSL_get_version(conn->xprt_ctx);
4760}
4761
Willy Tarreau119a4082016-12-22 21:58:38 +01004762/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4763 * to disable SNI.
4764 */
Willy Tarreau63076412015-07-10 11:33:32 +02004765void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4766{
4767#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004768 char *prev_name;
4769
Willy Tarreau63076412015-07-10 11:33:32 +02004770 if (!ssl_sock_is_ssl(conn))
4771 return;
4772
Willy Tarreau119a4082016-12-22 21:58:38 +01004773 /* if the SNI changes, we must destroy the reusable context so that a
4774 * new connection will present a new SNI. As an optimization we could
4775 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4776 * server.
4777 */
4778 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4779 if ((!prev_name && hostname) ||
4780 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4781 SSL_set_session(conn->xprt_ctx, NULL);
4782
Willy Tarreau63076412015-07-10 11:33:32 +02004783 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4784#endif
4785}
4786
Emeric Brun0abf8362014-06-24 18:26:41 +02004787/* Extract peer certificate's common name into the chunk dest
4788 * Returns
4789 * the len of the extracted common name
4790 * or 0 if no CN found in DN
4791 * or -1 on error case (i.e. no peer certificate)
4792 */
4793int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004794{
4795 X509 *crt = NULL;
4796 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004797 const char find_cn[] = "CN";
4798 const struct chunk find_cn_chunk = {
4799 .str = (char *)&find_cn,
4800 .len = sizeof(find_cn)-1
4801 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004802 int result = -1;
David Safb76832014-05-08 23:42:08 -04004803
4804 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004805 goto out;
David Safb76832014-05-08 23:42:08 -04004806
4807 /* SSL_get_peer_certificate, it increase X509 * ref count */
4808 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4809 if (!crt)
4810 goto out;
4811
4812 name = X509_get_subject_name(crt);
4813 if (!name)
4814 goto out;
David Safb76832014-05-08 23:42:08 -04004815
Emeric Brun0abf8362014-06-24 18:26:41 +02004816 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4817out:
David Safb76832014-05-08 23:42:08 -04004818 if (crt)
4819 X509_free(crt);
4820
4821 return result;
4822}
4823
Dave McCowan328fb582014-07-30 10:39:13 -04004824/* returns 1 if client passed a certificate for this session, 0 if not */
4825int ssl_sock_get_cert_used_sess(struct connection *conn)
4826{
4827 X509 *crt = NULL;
4828
4829 if (!ssl_sock_is_ssl(conn))
4830 return 0;
4831
4832 /* SSL_get_peer_certificate, it increase X509 * ref count */
4833 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4834 if (!crt)
4835 return 0;
4836
4837 X509_free(crt);
4838 return 1;
4839}
4840
4841/* returns 1 if client passed a certificate for this connection, 0 if not */
4842int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004843{
4844 if (!ssl_sock_is_ssl(conn))
4845 return 0;
4846
4847 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4848}
4849
4850/* returns result from SSL verify */
4851unsigned int ssl_sock_get_verify_result(struct connection *conn)
4852{
4853 if (!ssl_sock_is_ssl(conn))
4854 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4855
4856 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4857}
4858
Willy Tarreau7875d092012-09-10 08:20:03 +02004859/***** Below are some sample fetching functions for ACL/patterns *****/
4860
Emeric Brune64aef12012-09-21 13:15:06 +02004861/* boolean, returns true if client cert was present */
4862static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004863smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004864{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004865 struct connection *conn;
4866
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004867 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004868 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004869 return 0;
4870
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004871 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004872 smp->flags |= SMP_F_MAY_CHANGE;
4873 return 0;
4874 }
4875
4876 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004877 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004878 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004879
4880 return 1;
4881}
4882
Emeric Brun43e79582014-10-29 19:03:26 +01004883/* binary, returns a certificate in a binary chunk (der/raw).
4884 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4885 * should be use.
4886 */
4887static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004888smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004889{
4890 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4891 X509 *crt = NULL;
4892 int ret = 0;
4893 struct chunk *smp_trash;
4894 struct connection *conn;
4895
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004896 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004897 if (!conn || conn->xprt != &ssl_sock)
4898 return 0;
4899
4900 if (!(conn->flags & CO_FL_CONNECTED)) {
4901 smp->flags |= SMP_F_MAY_CHANGE;
4902 return 0;
4903 }
4904
4905 if (cert_peer)
4906 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4907 else
4908 crt = SSL_get_certificate(conn->xprt_ctx);
4909
4910 if (!crt)
4911 goto out;
4912
4913 smp_trash = get_trash_chunk();
4914 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4915 goto out;
4916
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004917 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004918 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004919 ret = 1;
4920out:
4921 /* SSL_get_peer_certificate, it increase X509 * ref count */
4922 if (cert_peer && crt)
4923 X509_free(crt);
4924 return ret;
4925}
4926
Emeric Brunba841a12014-04-30 17:05:08 +02004927/* binary, returns serial of certificate in a binary chunk.
4928 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4929 * should be use.
4930 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004931static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004932smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004933{
Emeric Brunba841a12014-04-30 17:05:08 +02004934 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004935 X509 *crt = NULL;
4936 int ret = 0;
4937 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004938 struct connection *conn;
4939
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004940 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004941 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004942 return 0;
4943
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004944 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004945 smp->flags |= SMP_F_MAY_CHANGE;
4946 return 0;
4947 }
4948
Emeric Brunba841a12014-04-30 17:05:08 +02004949 if (cert_peer)
4950 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4951 else
4952 crt = SSL_get_certificate(conn->xprt_ctx);
4953
Willy Tarreau8d598402012-10-22 17:58:39 +02004954 if (!crt)
4955 goto out;
4956
Willy Tarreau47ca5452012-12-23 20:22:19 +01004957 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004958 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4959 goto out;
4960
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004961 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004962 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004963 ret = 1;
4964out:
Emeric Brunba841a12014-04-30 17:05:08 +02004965 /* SSL_get_peer_certificate, it increase X509 * ref count */
4966 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004967 X509_free(crt);
4968 return ret;
4969}
Emeric Brune64aef12012-09-21 13:15:06 +02004970
Emeric Brunba841a12014-04-30 17:05:08 +02004971/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4972 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4973 * should be use.
4974 */
James Votha051b4a2013-05-14 20:37:59 +02004975static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004976smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004977{
Emeric Brunba841a12014-04-30 17:05:08 +02004978 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004979 X509 *crt = NULL;
4980 const EVP_MD *digest;
4981 int ret = 0;
4982 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004983 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004984
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004985 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004986 if (!conn || conn->xprt != &ssl_sock)
4987 return 0;
4988
4989 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004990 smp->flags |= SMP_F_MAY_CHANGE;
4991 return 0;
4992 }
4993
Emeric Brunba841a12014-04-30 17:05:08 +02004994 if (cert_peer)
4995 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4996 else
4997 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004998 if (!crt)
4999 goto out;
5000
5001 smp_trash = get_trash_chunk();
5002 digest = EVP_sha1();
5003 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
5004
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005005 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005006 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02005007 ret = 1;
5008out:
Emeric Brunba841a12014-04-30 17:05:08 +02005009 /* SSL_get_peer_certificate, it increase X509 * ref count */
5010 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02005011 X509_free(crt);
5012 return ret;
5013}
5014
Emeric Brunba841a12014-04-30 17:05:08 +02005015/* string, returns certificate's notafter date in ASN1_UTCTIME format.
5016 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5017 * should be use.
5018 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005019static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005020smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005021{
Emeric Brunba841a12014-04-30 17:05:08 +02005022 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005023 X509 *crt = NULL;
5024 int ret = 0;
5025 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005026 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02005027
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005028 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005029 if (!conn || conn->xprt != &ssl_sock)
5030 return 0;
5031
5032 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005033 smp->flags |= SMP_F_MAY_CHANGE;
5034 return 0;
5035 }
5036
Emeric Brunba841a12014-04-30 17:05:08 +02005037 if (cert_peer)
5038 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5039 else
5040 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005041 if (!crt)
5042 goto out;
5043
Willy Tarreau47ca5452012-12-23 20:22:19 +01005044 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005045 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
5046 goto out;
5047
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005048 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005049 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005050 ret = 1;
5051out:
Emeric Brunba841a12014-04-30 17:05:08 +02005052 /* SSL_get_peer_certificate, it increase X509 * ref count */
5053 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005054 X509_free(crt);
5055 return ret;
5056}
5057
Emeric Brunba841a12014-04-30 17:05:08 +02005058/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
5059 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5060 * should be use.
5061 */
Emeric Brun87855892012-10-17 17:39:35 +02005062static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005063smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005064{
Emeric Brunba841a12014-04-30 17:05:08 +02005065 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005066 X509 *crt = NULL;
5067 X509_NAME *name;
5068 int ret = 0;
5069 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005070 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005071
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005072 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005073 if (!conn || conn->xprt != &ssl_sock)
5074 return 0;
5075
5076 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005077 smp->flags |= SMP_F_MAY_CHANGE;
5078 return 0;
5079 }
5080
Emeric Brunba841a12014-04-30 17:05:08 +02005081 if (cert_peer)
5082 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5083 else
5084 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005085 if (!crt)
5086 goto out;
5087
5088 name = X509_get_issuer_name(crt);
5089 if (!name)
5090 goto out;
5091
Willy Tarreau47ca5452012-12-23 20:22:19 +01005092 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005093 if (args && args[0].type == ARGT_STR) {
5094 int pos = 1;
5095
5096 if (args[1].type == ARGT_SINT)
5097 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005098
5099 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5100 goto out;
5101 }
5102 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5103 goto out;
5104
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005105 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005106 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005107 ret = 1;
5108out:
Emeric Brunba841a12014-04-30 17:05:08 +02005109 /* SSL_get_peer_certificate, it increase X509 * ref count */
5110 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005111 X509_free(crt);
5112 return ret;
5113}
5114
Emeric Brunba841a12014-04-30 17:05:08 +02005115/* string, returns notbefore date in ASN1_UTCTIME format.
5116 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5117 * should be use.
5118 */
Emeric Brunce5ad802012-10-22 14:11:22 +02005119static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005120smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02005121{
Emeric Brunba841a12014-04-30 17:05:08 +02005122 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02005123 X509 *crt = NULL;
5124 int ret = 0;
5125 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005126 struct connection *conn;
5127
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005128 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005129 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005130 return 0;
5131
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005132 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005133 smp->flags |= SMP_F_MAY_CHANGE;
5134 return 0;
5135 }
5136
Emeric Brunba841a12014-04-30 17:05:08 +02005137 if (cert_peer)
5138 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5139 else
5140 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005141 if (!crt)
5142 goto out;
5143
Willy Tarreau47ca5452012-12-23 20:22:19 +01005144 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005145 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5146 goto out;
5147
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005148 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005149 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005150 ret = 1;
5151out:
Emeric Brunba841a12014-04-30 17:05:08 +02005152 /* SSL_get_peer_certificate, it increase X509 * ref count */
5153 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005154 X509_free(crt);
5155 return ret;
5156}
5157
Emeric Brunba841a12014-04-30 17:05:08 +02005158/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5159 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5160 * should be use.
5161 */
Emeric Brun87855892012-10-17 17:39:35 +02005162static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005163smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005164{
Emeric Brunba841a12014-04-30 17:05:08 +02005165 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005166 X509 *crt = NULL;
5167 X509_NAME *name;
5168 int ret = 0;
5169 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005170 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005171
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005172 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005173 if (!conn || conn->xprt != &ssl_sock)
5174 return 0;
5175
5176 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005177 smp->flags |= SMP_F_MAY_CHANGE;
5178 return 0;
5179 }
5180
Emeric Brunba841a12014-04-30 17:05:08 +02005181 if (cert_peer)
5182 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5183 else
5184 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005185 if (!crt)
5186 goto out;
5187
5188 name = X509_get_subject_name(crt);
5189 if (!name)
5190 goto out;
5191
Willy Tarreau47ca5452012-12-23 20:22:19 +01005192 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005193 if (args && args[0].type == ARGT_STR) {
5194 int pos = 1;
5195
5196 if (args[1].type == ARGT_SINT)
5197 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005198
5199 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5200 goto out;
5201 }
5202 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5203 goto out;
5204
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005205 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005206 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005207 ret = 1;
5208out:
Emeric Brunba841a12014-04-30 17:05:08 +02005209 /* SSL_get_peer_certificate, it increase X509 * ref count */
5210 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005211 X509_free(crt);
5212 return ret;
5213}
Emeric Brun9143d372012-12-20 15:44:16 +01005214
5215/* integer, returns true if current session use a client certificate */
5216static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005217smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005218{
5219 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005220 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005221
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005222 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005223 if (!conn || conn->xprt != &ssl_sock)
5224 return 0;
5225
5226 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005227 smp->flags |= SMP_F_MAY_CHANGE;
5228 return 0;
5229 }
5230
5231 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005232 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005233 if (crt) {
5234 X509_free(crt);
5235 }
5236
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005237 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005238 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005239 return 1;
5240}
5241
Emeric Brunba841a12014-04-30 17:05:08 +02005242/* integer, returns the certificate version
5243 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5244 * should be use.
5245 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005246static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005247smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005248{
Emeric Brunba841a12014-04-30 17:05:08 +02005249 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005250 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005251 struct connection *conn;
5252
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005253 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005254 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005255 return 0;
5256
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005257 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005258 smp->flags |= SMP_F_MAY_CHANGE;
5259 return 0;
5260 }
5261
Emeric Brunba841a12014-04-30 17:05:08 +02005262 if (cert_peer)
5263 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5264 else
5265 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005266 if (!crt)
5267 return 0;
5268
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005269 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005270 /* SSL_get_peer_certificate increase X509 * ref count */
5271 if (cert_peer)
5272 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005273 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005274
5275 return 1;
5276}
5277
Emeric Brunba841a12014-04-30 17:05:08 +02005278/* string, returns the certificate's signature algorithm.
5279 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5280 * should be use.
5281 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005282static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005283smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005284{
Emeric Brunba841a12014-04-30 17:05:08 +02005285 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005286 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005287 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005288 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005289 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005290
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005291 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005292 if (!conn || conn->xprt != &ssl_sock)
5293 return 0;
5294
5295 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005296 smp->flags |= SMP_F_MAY_CHANGE;
5297 return 0;
5298 }
5299
Emeric Brunba841a12014-04-30 17:05:08 +02005300 if (cert_peer)
5301 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5302 else
5303 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005304 if (!crt)
5305 return 0;
5306
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005307 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5308 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005309
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005310 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5311 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005312 /* SSL_get_peer_certificate increase X509 * ref count */
5313 if (cert_peer)
5314 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005315 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005316 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005317
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005318 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005319 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005320 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005321 /* SSL_get_peer_certificate increase X509 * ref count */
5322 if (cert_peer)
5323 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005324
5325 return 1;
5326}
5327
Emeric Brunba841a12014-04-30 17:05:08 +02005328/* string, returns the certificate's key algorithm.
5329 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5330 * should be use.
5331 */
Emeric Brun521a0112012-10-22 12:22:55 +02005332static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005333smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005334{
Emeric Brunba841a12014-04-30 17:05:08 +02005335 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005336 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005337 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005338 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005339 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005340
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005341 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005342 if (!conn || conn->xprt != &ssl_sock)
5343 return 0;
5344
5345 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005346 smp->flags |= SMP_F_MAY_CHANGE;
5347 return 0;
5348 }
5349
Emeric Brunba841a12014-04-30 17:05:08 +02005350 if (cert_peer)
5351 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5352 else
5353 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005354 if (!crt)
5355 return 0;
5356
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005357 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5358 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005359
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005360 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5361 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005362 /* SSL_get_peer_certificate increase X509 * ref count */
5363 if (cert_peer)
5364 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005365 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005366 }
Emeric Brun521a0112012-10-22 12:22:55 +02005367
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005368 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005369 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005370 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005371 if (cert_peer)
5372 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005373
5374 return 1;
5375}
5376
Emeric Brun645ae792014-04-30 14:21:06 +02005377/* boolean, returns true if front conn. transport layer is SSL.
5378 * This function is also usable on backend conn if the fetch keyword 5th
5379 * char is 'b'.
5380 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005381static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005382smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005383{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005384 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5385 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005386
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005387 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005388 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005389 return 1;
5390}
5391
Emeric Brun2525b6b2012-10-18 15:59:43 +02005392/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005393static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005394smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005395{
5396#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005397 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005398
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005399 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005400 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005401 conn->xprt_ctx &&
5402 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005403 return 1;
5404#else
5405 return 0;
5406#endif
5407}
5408
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005409/* boolean, returns true if client session has been resumed */
5410static int
5411smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5412{
5413 struct connection *conn = objt_conn(smp->sess->origin);
5414
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005415 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005416 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005417 conn->xprt_ctx &&
5418 SSL_session_reused(conn->xprt_ctx);
5419 return 1;
5420}
5421
Emeric Brun645ae792014-04-30 14:21:06 +02005422/* string, returns the used cipher if front conn. transport layer is SSL.
5423 * This function is also usable on backend conn if the fetch keyword 5th
5424 * char is 'b'.
5425 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005426static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005427smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005428{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005429 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5430 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005431
Willy Tarreaube508f12016-03-10 11:47:01 +01005432 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005433 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005434 return 0;
5435
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005436 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5437 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005438 return 0;
5439
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005440 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005441 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005442 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005443
5444 return 1;
5445}
5446
Emeric Brun645ae792014-04-30 14:21:06 +02005447/* integer, returns the algoritm's keysize if front conn. transport layer
5448 * is SSL.
5449 * This function is also usable on backend conn if the fetch keyword 5th
5450 * char is 'b'.
5451 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005452static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005453smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005454{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005455 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5456 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005457
Willy Tarreaue237fe12016-03-10 17:05:28 +01005458 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005459
Emeric Brun589fcad2012-10-16 14:13:26 +02005460 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005461 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005462 return 0;
5463
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005464 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005465 return 0;
5466
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005467 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005468 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005469
5470 return 1;
5471}
5472
Emeric Brun645ae792014-04-30 14:21:06 +02005473/* integer, returns the used keysize if front conn. transport layer is SSL.
5474 * This function is also usable on backend conn if the fetch keyword 5th
5475 * char is 'b'.
5476 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005477static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005478smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005479{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005480 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5481 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005482
Emeric Brun589fcad2012-10-16 14:13:26 +02005483 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005484 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5485 return 0;
5486
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005487 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5488 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005489 return 0;
5490
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005491 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005492
5493 return 1;
5494}
5495
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005496#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005497static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005498smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005499{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005500 struct connection *conn;
5501
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005502 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005503 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005504
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005505 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005506 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5507 return 0;
5508
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005509 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005510 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005511 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005512
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005513 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005514 return 0;
5515
5516 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005517}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005518#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005519
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005520#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005521static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005522smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005523{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005524 struct connection *conn;
5525
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005526 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005527 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005528
Willy Tarreaue26bf052015-05-12 10:30:12 +02005529 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005530 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005531 return 0;
5532
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005533 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005534 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005535 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005536
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005537 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005538 return 0;
5539
5540 return 1;
5541}
5542#endif
5543
Emeric Brun645ae792014-04-30 14:21:06 +02005544/* string, returns the used protocol if front conn. transport layer is SSL.
5545 * This function is also usable on backend conn if the fetch keyword 5th
5546 * char is 'b'.
5547 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005548static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005549smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005550{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005551 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5552 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005553
Emeric Brun589fcad2012-10-16 14:13:26 +02005554 smp->flags = 0;
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 = (char *)SSL_get_version(conn->xprt_ctx);
5559 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005560 return 0;
5561
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005562 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005563 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005564 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005565
5566 return 1;
5567}
5568
Willy Tarreau87b09662015-04-03 00:22:06 +02005569/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005570 * This function is also usable on backend conn if the fetch keyword 5th
5571 * char is 'b'.
5572 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005573static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005574smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005575{
5576#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005577 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5578 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005579
Willy Tarreaue237fe12016-03-10 17:05:28 +01005580 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005581
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005582 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005583 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005584
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005585 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5586 return 0;
5587
Willy Tarreau192252e2015-04-04 01:47:55 +02005588 ssl_sess = SSL_get_session(conn->xprt_ctx);
5589 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005590 return 0;
5591
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005592 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5593 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005594 return 0;
5595
5596 return 1;
5597#else
5598 return 0;
5599#endif
5600}
5601
5602static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005603smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005604{
5605#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005606 struct connection *conn;
5607
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005608 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005609 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005610
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005611 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005612 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5613 return 0;
5614
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005615 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5616 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005617 return 0;
5618
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005619 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005620 return 1;
5621#else
5622 return 0;
5623#endif
5624}
5625
David Sc1ad52e2014-04-08 18:48:47 -04005626static int
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005627smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
5628{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005629 struct connection *conn;
5630 struct ssl_capture *capture;
5631
5632 conn = objt_conn(smp->sess->origin);
5633 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5634 return 0;
5635
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005636 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005637 if (!capture)
5638 return 0;
5639
5640 smp->flags = SMP_F_CONST;
5641 smp->data.type = SMP_T_BIN;
5642 smp->data.u.str.str = capture->ciphersuite;
5643 smp->data.u.str.len = capture->ciphersuite_len;
5644 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005645}
5646
5647static int
5648smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
5649{
5650 struct chunk *data;
5651
5652 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5653 return 0;
5654
5655 data = get_trash_chunk();
5656 dump_binary(data, smp->data.u.str.str, smp->data.u.str.len);
5657 smp->data.type = SMP_T_BIN;
5658 smp->data.u.str = *data;
5659 return 1;
5660}
5661
5662static int
5663smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
5664{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005665 struct connection *conn;
5666 struct ssl_capture *capture;
5667
5668 conn = objt_conn(smp->sess->origin);
5669 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5670 return 0;
5671
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01005672 capture = SSL_get_ex_data(conn->xprt_ctx, ssl_capture_ptr_index);
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005673 if (!capture)
5674 return 0;
5675
5676 smp->data.type = SMP_T_SINT;
5677 smp->data.u.sint = capture->xxh64;
5678 return 1;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01005679}
5680
5681static int
5682smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
5683{
5684#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && !defined(OPENSSL_NO_SSL_TRACE)
5685 struct chunk *data;
5686 SSL_CIPHER cipher;
5687 int i;
5688 const char *str;
5689 unsigned char *bin;
5690
5691 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
5692 return 0;
5693
5694 /* The cipher algorith must not be SSL_SSLV2, because this
5695 * SSL version seems to not have the same cipher encoding,
5696 * and it is not supported by OpenSSL. Unfortunately, the
5697 * #define SSL_SSLV2, SSL_SSLV3 and others are not available
5698 * with standard defines. We just set the variable to 0,
5699 * ensure that the match with SSL_SSLV2 fails.
5700 */
5701 cipher.algorithm_ssl = 0;
5702
5703 data = get_trash_chunk();
5704 for (i = 0; i + 1 < smp->data.u.str.len; i += 2) {
5705 bin = (unsigned char *)smp->data.u.str.str + i;
5706 cipher.id = (unsigned int)(bin[0] << 8) | bin[1];
5707 str = SSL_CIPHER_standard_name(&cipher);
5708 if (!str || strcmp(str, "UNKNOWN") == 0)
5709 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", (unsigned int)cipher.id);
5710 else
5711 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
5712 }
5713 smp->data.type = SMP_T_STR;
5714 smp->data.u.str = *data;
5715 return 1;
5716#else
5717 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
5718#endif
5719}
5720
5721static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005722smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005723{
5724#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005725 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5726 smp->strm ? smp->strm->si[1].end : NULL);
5727
David Sc1ad52e2014-04-08 18:48:47 -04005728 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005729 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005730
5731 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005732 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5733 return 0;
5734
5735 if (!(conn->flags & CO_FL_CONNECTED)) {
5736 smp->flags |= SMP_F_MAY_CHANGE;
5737 return 0;
5738 }
5739
5740 finished_trash = get_trash_chunk();
5741 if (!SSL_session_reused(conn->xprt_ctx))
5742 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5743 else
5744 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5745
5746 if (!finished_len)
5747 return 0;
5748
Emeric Brunb73a9b02014-04-30 18:49:19 +02005749 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005750 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005751 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005752
5753 return 1;
5754#else
5755 return 0;
5756#endif
5757}
5758
Emeric Brun2525b6b2012-10-18 15:59:43 +02005759/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005760static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005761smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005762{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005763 struct connection *conn;
5764
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005765 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005766 if (!conn || conn->xprt != &ssl_sock)
5767 return 0;
5768
5769 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005770 smp->flags = SMP_F_MAY_CHANGE;
5771 return 0;
5772 }
5773
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005774 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005775 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005776 smp->flags = 0;
5777
5778 return 1;
5779}
5780
Emeric Brun2525b6b2012-10-18 15:59:43 +02005781/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005782static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005783smp_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 +02005784{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005785 struct connection *conn;
5786
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005787 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005788 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005789 return 0;
5790
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005791 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005792 smp->flags = SMP_F_MAY_CHANGE;
5793 return 0;
5794 }
5795
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005796 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005797 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005798 smp->flags = 0;
5799
5800 return 1;
5801}
5802
Emeric Brun2525b6b2012-10-18 15:59:43 +02005803/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005804static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005805smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005806{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005807 struct connection *conn;
5808
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005809 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005810 if (!conn || conn->xprt != &ssl_sock)
5811 return 0;
5812
5813 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005814 smp->flags = SMP_F_MAY_CHANGE;
5815 return 0;
5816 }
5817
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005818 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005819 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005820 smp->flags = 0;
5821
5822 return 1;
5823}
5824
Emeric Brun2525b6b2012-10-18 15:59:43 +02005825/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005826static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005827smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005828{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005829 struct connection *conn;
5830
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005831 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005832 if (!conn || conn->xprt != &ssl_sock)
5833 return 0;
5834
5835 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005836 smp->flags = SMP_F_MAY_CHANGE;
5837 return 0;
5838 }
5839
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005840 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005841 return 0;
5842
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005843 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005844 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005845 smp->flags = 0;
5846
5847 return 1;
5848}
5849
Emeric Brunfb510ea2012-10-05 12:00:26 +02005850/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005851static 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 +02005852{
5853 if (!*args[cur_arg + 1]) {
5854 if (err)
5855 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5856 return ERR_ALERT | ERR_FATAL;
5857 }
5858
Willy Tarreauef934602016-12-22 23:12:01 +01005859 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5860 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005861 else
5862 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005863
Emeric Brund94b3fe2012-09-20 18:23:56 +02005864 return 0;
5865}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005866static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5867{
5868 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5869}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005870
Christopher Faulet31af49d2015-06-09 17:29:50 +02005871/* parse the "ca-sign-file" bind keyword */
5872static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5873{
5874 if (!*args[cur_arg + 1]) {
5875 if (err)
5876 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5877 return ERR_ALERT | ERR_FATAL;
5878 }
5879
Willy Tarreauef934602016-12-22 23:12:01 +01005880 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5881 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005882 else
5883 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5884
5885 return 0;
5886}
5887
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005888/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005889static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5890{
5891 if (!*args[cur_arg + 1]) {
5892 if (err)
5893 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5894 return ERR_ALERT | ERR_FATAL;
5895 }
5896 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5897 return 0;
5898}
5899
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005900/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005901static 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 +02005902{
5903 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005904 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005905 return ERR_ALERT | ERR_FATAL;
5906 }
5907
Emeric Brun76d88952012-10-05 15:47:31 +02005908 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005909 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005910 return 0;
5911}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005912static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5913{
5914 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5915}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005916/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005917static 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 +02005918{
Willy Tarreau38011032013-08-13 16:59:39 +02005919 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005920
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005921 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005922 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005923 return ERR_ALERT | ERR_FATAL;
5924 }
5925
Willy Tarreauef934602016-12-22 23:12:01 +01005926 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5927 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005928 memprintf(err, "'%s' : path too long", args[cur_arg]);
5929 return ERR_ALERT | ERR_FATAL;
5930 }
Willy Tarreauef934602016-12-22 23:12:01 +01005931 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005932 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005933 return ERR_ALERT | ERR_FATAL;
5934
5935 return 0;
5936 }
5937
Willy Tarreau03209342016-12-22 17:08:28 +01005938 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005939 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005940
5941 return 0;
5942}
5943
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005944/* parse the "crt-list" bind keyword */
5945static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5946{
5947 if (!*args[cur_arg + 1]) {
5948 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5949 return ERR_ALERT | ERR_FATAL;
5950 }
5951
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005952 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005953 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005954 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005955 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005956
5957 return 0;
5958}
5959
Emeric Brunfb510ea2012-10-05 12:00:26 +02005960/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005961static 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 +02005962{
Emeric Brun051cdab2012-10-02 19:25:50 +02005963#ifndef X509_V_FLAG_CRL_CHECK
5964 if (err)
5965 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5966 return ERR_ALERT | ERR_FATAL;
5967#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005968 if (!*args[cur_arg + 1]) {
5969 if (err)
5970 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5971 return ERR_ALERT | ERR_FATAL;
5972 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005973
Willy Tarreauef934602016-12-22 23:12:01 +01005974 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5975 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005976 else
5977 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005978
Emeric Brun2b58d042012-09-20 17:10:03 +02005979 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005980#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005981}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005982static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5983{
5984 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
5985}
Emeric Brun2b58d042012-09-20 17:10:03 +02005986
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01005987/* parse the "curves" bind keyword keyword */
5988static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
5989{
5990#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
5991 if (!*args[cur_arg + 1]) {
5992 if (err)
5993 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
5994 return ERR_ALERT | ERR_FATAL;
5995 }
5996 conf->curves = strdup(args[cur_arg + 1]);
5997 return 0;
5998#else
5999 if (err)
6000 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
6001 return ERR_ALERT | ERR_FATAL;
6002#endif
6003}
6004static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6005{
6006 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
6007}
6008
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006009/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006010static 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 +02006011{
6012#if OPENSSL_VERSION_NUMBER < 0x0090800fL
6013 if (err)
6014 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
6015 return ERR_ALERT | ERR_FATAL;
6016#elif defined(OPENSSL_NO_ECDH)
6017 if (err)
6018 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
6019 return ERR_ALERT | ERR_FATAL;
6020#else
6021 if (!*args[cur_arg + 1]) {
6022 if (err)
6023 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
6024 return ERR_ALERT | ERR_FATAL;
6025 }
6026
6027 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006028
6029 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02006030#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006031}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006032static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6033{
6034 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
6035}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006036
Bertrand Jacquinff13c062016-11-13 16:37:11 +00006037/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02006038static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6039{
6040 int code;
6041 char *p = args[cur_arg + 1];
6042 unsigned long long *ignerr = &conf->crt_ignerr;
6043
6044 if (!*p) {
6045 if (err)
6046 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
6047 return ERR_ALERT | ERR_FATAL;
6048 }
6049
6050 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
6051 ignerr = &conf->ca_ignerr;
6052
6053 if (strcmp(p, "all") == 0) {
6054 *ignerr = ~0ULL;
6055 return 0;
6056 }
6057
6058 while (p) {
6059 code = atoi(p);
6060 if ((code <= 0) || (code > 63)) {
6061 if (err)
6062 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
6063 args[cur_arg], code, args[cur_arg + 1]);
6064 return ERR_ALERT | ERR_FATAL;
6065 }
6066 *ignerr |= 1ULL << code;
6067 p = strchr(p, ',');
6068 if (p)
6069 p++;
6070 }
6071
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006072 return 0;
6073}
6074
6075/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006076static 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 +02006077{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006078#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006079 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
6080 return 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006081#else
6082 if (err)
6083 memprintf(err, "'%s' : library does not support protocol SSLv3", args[cur_arg]);
6084 return ERR_ALERT | ERR_FATAL;
6085#endif
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006086}
6087
6088/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006089static 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 +02006090{
6091 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02006092 return 0;
6093}
6094
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006095/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006096static 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 +02006097{
6098#if SSL_OP_NO_TLSv1_1
6099 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
6100 return 0;
6101#else
6102 if (err)
6103 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
6104 return ERR_ALERT | ERR_FATAL;
6105#endif
6106}
6107
6108/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006109static 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 +02006110{
6111#if SSL_OP_NO_TLSv1_2
6112 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
6113 return 0;
6114#else
6115 if (err)
6116 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
6117 return ERR_ALERT | ERR_FATAL;
6118#endif
6119}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02006120
Emeric Brun2d0c4822012-10-02 13:45:20 +02006121/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006122static 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 +02006123{
Emeric Brun89675492012-10-05 13:48:26 +02006124 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02006125 return 0;
6126}
Emeric Brun2d0c4822012-10-02 13:45:20 +02006127
Emeric Brun9b3009b2012-10-05 11:55:06 +02006128/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006129static 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 +02006130{
Emeric Brun89675492012-10-05 13:48:26 +02006131 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006132 return 0;
6133}
6134
Emeric Brun9b3009b2012-10-05 11:55:06 +02006135/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006136static 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 +02006137{
Emeric Brun89675492012-10-05 13:48:26 +02006138 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02006139 return 0;
6140}
6141
Emeric Brun9b3009b2012-10-05 11:55:06 +02006142/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006143static 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 +02006144{
Emeric Brun89675492012-10-05 13:48:26 +02006145 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02006146 return 0;
6147}
6148
Emeric Brun9b3009b2012-10-05 11:55:06 +02006149/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006150static 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 +02006151{
Emeric Brun89675492012-10-05 13:48:26 +02006152 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006153 return 0;
6154}
6155
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006156/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006157static 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 +02006158{
6159#ifdef OPENSSL_NPN_NEGOTIATED
6160 char *p1, *p2;
6161
6162 if (!*args[cur_arg + 1]) {
6163 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
6164 return ERR_ALERT | ERR_FATAL;
6165 }
6166
6167 free(conf->npn_str);
6168
Willy Tarreau3724da12016-02-12 17:11:12 +01006169 /* the NPN string is built as a suite of (<len> <name>)*,
6170 * so we reuse each comma to store the next <len> and need
6171 * one more for the end of the string.
6172 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006173 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01006174 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02006175 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
6176
6177 /* replace commas with the name length */
6178 p1 = conf->npn_str;
6179 p2 = p1 + 1;
6180 while (1) {
6181 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
6182 if (!p2)
6183 p2 = p1 + 1 + strlen(p1 + 1);
6184
6185 if (p2 - (p1 + 1) > 255) {
6186 *p2 = '\0';
6187 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6188 return ERR_ALERT | ERR_FATAL;
6189 }
6190
6191 *p1 = p2 - (p1 + 1);
6192 p1 = p2;
6193
6194 if (!*p2)
6195 break;
6196
6197 *(p2++) = '\0';
6198 }
6199 return 0;
6200#else
6201 if (err)
6202 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6203 return ERR_ALERT | ERR_FATAL;
6204#endif
6205}
6206
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006207static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6208{
6209 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6210}
6211
Willy Tarreauab861d32013-04-02 02:30:41 +02006212/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006213static 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 +02006214{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006215#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006216 char *p1, *p2;
6217
6218 if (!*args[cur_arg + 1]) {
6219 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6220 return ERR_ALERT | ERR_FATAL;
6221 }
6222
6223 free(conf->alpn_str);
6224
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006225 /* the ALPN string is built as a suite of (<len> <name>)*,
6226 * so we reuse each comma to store the next <len> and need
6227 * one more for the end of the string.
6228 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006229 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006230 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006231 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6232
6233 /* replace commas with the name length */
6234 p1 = conf->alpn_str;
6235 p2 = p1 + 1;
6236 while (1) {
6237 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6238 if (!p2)
6239 p2 = p1 + 1 + strlen(p1 + 1);
6240
6241 if (p2 - (p1 + 1) > 255) {
6242 *p2 = '\0';
6243 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6244 return ERR_ALERT | ERR_FATAL;
6245 }
6246
6247 *p1 = p2 - (p1 + 1);
6248 p1 = p2;
6249
6250 if (!*p2)
6251 break;
6252
6253 *(p2++) = '\0';
6254 }
6255 return 0;
6256#else
6257 if (err)
6258 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6259 return ERR_ALERT | ERR_FATAL;
6260#endif
6261}
6262
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006263static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6264{
6265 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6266}
6267
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006268/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006269static 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 +02006270{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006271 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006272 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006273
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006274 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6275 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
Emmanuel Hocdet4608ed92017-01-20 13:06:27 +01006276 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02006277
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006278 return 0;
6279}
6280
Christopher Faulet31af49d2015-06-09 17:29:50 +02006281/* parse the "generate-certificates" bind keyword */
6282static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6283{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006284#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006285 conf->generate_certs = 1;
6286#else
6287 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6288 err && *err ? *err : "");
6289#endif
6290 return 0;
6291}
6292
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006293/* parse the "strict-sni" bind keyword */
6294static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6295{
6296 conf->strict_sni = 1;
6297 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006298}
6299
6300/* parse the "tls-ticket-keys" bind keyword */
6301static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6302{
6303#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6304 FILE *f;
6305 int i = 0;
6306 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006307 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006308
6309 if (!*args[cur_arg + 1]) {
6310 if (err)
6311 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6312 return ERR_ALERT | ERR_FATAL;
6313 }
6314
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006315 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6316 if(keys_ref) {
6317 conf->keys_ref = keys_ref;
6318 return 0;
6319 }
6320
Vincent Bernat02779b62016-04-03 13:48:43 +02006321 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006322 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006323
6324 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6325 if (err)
6326 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6327 return ERR_ALERT | ERR_FATAL;
6328 }
6329
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006330 keys_ref->filename = strdup(args[cur_arg + 1]);
6331
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006332 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6333 int len = strlen(thisline);
6334 /* Strip newline characters from the end */
6335 if(thisline[len - 1] == '\n')
6336 thisline[--len] = 0;
6337
6338 if(thisline[len - 1] == '\r')
6339 thisline[--len] = 0;
6340
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006341 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 +01006342 if (err)
6343 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006344 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006345 return ERR_ALERT | ERR_FATAL;
6346 }
6347 i++;
6348 }
6349
6350 if (i < TLS_TICKETS_NO) {
6351 if (err)
6352 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 +02006353 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006354 return ERR_ALERT | ERR_FATAL;
6355 }
6356
6357 fclose(f);
6358
6359 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006360 i -= 2;
6361 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006362 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006363 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006364
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006365 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6366
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006367 return 0;
6368#else
6369 if (err)
6370 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6371 return ERR_ALERT | ERR_FATAL;
6372#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006373}
6374
Emeric Brund94b3fe2012-09-20 18:23:56 +02006375/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006376static 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 +02006377{
6378 if (!*args[cur_arg + 1]) {
6379 if (err)
6380 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6381 return ERR_ALERT | ERR_FATAL;
6382 }
6383
6384 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006385 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006386 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006387 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006388 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006389 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006390 else {
6391 if (err)
6392 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6393 args[cur_arg], args[cur_arg + 1]);
6394 return ERR_ALERT | ERR_FATAL;
6395 }
6396
6397 return 0;
6398}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006399static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6400{
6401 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6402}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006403
Willy Tarreau92faadf2012-10-10 23:04:25 +02006404/************** "server" keywords ****************/
6405
Emeric Brunef42d922012-10-11 16:11:36 +02006406/* parse the "ca-file" server keyword */
6407static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6408{
6409 if (!*args[*cur_arg + 1]) {
6410 if (err)
6411 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6412 return ERR_ALERT | ERR_FATAL;
6413 }
6414
Willy Tarreauef934602016-12-22 23:12:01 +01006415 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6416 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006417 else
6418 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6419
6420 return 0;
6421}
6422
Willy Tarreau92faadf2012-10-10 23:04:25 +02006423/* parse the "check-ssl" server keyword */
6424static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6425{
6426 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006427 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6428 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6429 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02006430 return 0;
6431}
6432
6433/* parse the "ciphers" server keyword */
6434static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6435{
6436 if (!*args[*cur_arg + 1]) {
6437 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6438 return ERR_ALERT | ERR_FATAL;
6439 }
6440
6441 free(newsrv->ssl_ctx.ciphers);
6442 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6443 return 0;
6444}
6445
Emeric Brunef42d922012-10-11 16:11:36 +02006446/* parse the "crl-file" server keyword */
6447static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6448{
6449#ifndef X509_V_FLAG_CRL_CHECK
6450 if (err)
6451 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6452 return ERR_ALERT | ERR_FATAL;
6453#else
6454 if (!*args[*cur_arg + 1]) {
6455 if (err)
6456 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6457 return ERR_ALERT | ERR_FATAL;
6458 }
6459
Willy Tarreauef934602016-12-22 23:12:01 +01006460 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6461 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006462 else
6463 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6464
6465 return 0;
6466#endif
6467}
6468
Emeric Bruna7aa3092012-10-26 12:58:00 +02006469/* parse the "crt" server keyword */
6470static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6471{
6472 if (!*args[*cur_arg + 1]) {
6473 if (err)
6474 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6475 return ERR_ALERT | ERR_FATAL;
6476 }
6477
Willy Tarreauef934602016-12-22 23:12:01 +01006478 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6479 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006480 else
6481 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6482
6483 return 0;
6484}
Emeric Brunef42d922012-10-11 16:11:36 +02006485
Willy Tarreau92faadf2012-10-10 23:04:25 +02006486/* parse the "force-sslv3" server keyword */
6487static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6488{
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006489#ifndef OPENSSL_NO_SSL3
Willy Tarreau92faadf2012-10-10 23:04:25 +02006490 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6491 return 0;
Emmanuel Hocdet4de1ff12017-03-03 12:21:32 +01006492#else
6493 if (err)
6494 memprintf(err, "'%s' : library does not support protocol SSLv3", args[*cur_arg]);
6495 return ERR_ALERT | ERR_FATAL;
6496#endif
Willy Tarreau92faadf2012-10-10 23:04:25 +02006497}
6498
6499/* parse the "force-tlsv10" server keyword */
6500static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6501{
6502 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6503 return 0;
6504}
6505
6506/* parse the "force-tlsv11" server keyword */
6507static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6508{
6509#if SSL_OP_NO_TLSv1_1
6510 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6511 return 0;
6512#else
6513 if (err)
6514 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6515 return ERR_ALERT | ERR_FATAL;
6516#endif
6517}
6518
6519/* parse the "force-tlsv12" server keyword */
6520static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6521{
6522#if SSL_OP_NO_TLSv1_2
6523 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6524 return 0;
6525#else
6526 if (err)
6527 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6528 return ERR_ALERT | ERR_FATAL;
6529#endif
6530}
6531
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006532/* parse the "no-ssl-reuse" server keyword */
6533static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6534{
6535 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6536 return 0;
6537}
6538
Willy Tarreau92faadf2012-10-10 23:04:25 +02006539/* parse the "no-sslv3" server keyword */
6540static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6541{
6542 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6543 return 0;
6544}
6545
6546/* parse the "no-tlsv10" server keyword */
6547static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6548{
6549 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6550 return 0;
6551}
6552
6553/* parse the "no-tlsv11" server keyword */
6554static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6555{
6556 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6557 return 0;
6558}
6559
6560/* parse the "no-tlsv12" server keyword */
6561static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6562{
6563 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6564 return 0;
6565}
6566
Emeric Brunf9c5c472012-10-11 15:28:34 +02006567/* parse the "no-tls-tickets" server keyword */
6568static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6569{
6570 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6571 return 0;
6572}
David Safb76832014-05-08 23:42:08 -04006573/* parse the "send-proxy-v2-ssl" server keyword */
6574static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6575{
6576 newsrv->pp_opts |= SRV_PP_V2;
6577 newsrv->pp_opts |= SRV_PP_V2_SSL;
6578 return 0;
6579}
6580
6581/* parse the "send-proxy-v2-ssl-cn" server keyword */
6582static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6583{
6584 newsrv->pp_opts |= SRV_PP_V2;
6585 newsrv->pp_opts |= SRV_PP_V2_SSL;
6586 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6587 return 0;
6588}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006589
Willy Tarreau732eac42015-07-09 11:40:25 +02006590/* parse the "sni" server keyword */
6591static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6592{
6593#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6594 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6595 return ERR_ALERT | ERR_FATAL;
6596#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01006597 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02006598 struct sample_expr *expr;
6599
6600 if (!*args[*cur_arg + 1]) {
6601 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6602 return ERR_ALERT | ERR_FATAL;
6603 }
6604
Cyril Bonté23d19d62016-03-07 22:13:22 +01006605 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02006606 proxy->conf.args.ctx = ARGC_SRV;
6607
Cyril Bonté23d19d62016-03-07 22:13:22 +01006608 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02006609 if (!expr) {
6610 memprintf(err, "error detected while parsing sni expression : %s", *err);
6611 return ERR_ALERT | ERR_FATAL;
6612 }
6613
6614 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
6615 memprintf(err, "error detected while parsing sni expression : "
6616 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01006617 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02006618 return ERR_ALERT | ERR_FATAL;
6619 }
6620
6621 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
6622 newsrv->ssl_ctx.sni = expr;
6623 return 0;
6624#endif
6625}
6626
Willy Tarreau92faadf2012-10-10 23:04:25 +02006627/* parse the "ssl" server keyword */
6628static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6629{
6630 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006631 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6632 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006633 return 0;
6634}
6635
Emeric Brunef42d922012-10-11 16:11:36 +02006636/* parse the "verify" server keyword */
6637static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6638{
6639 if (!*args[*cur_arg + 1]) {
6640 if (err)
6641 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6642 return ERR_ALERT | ERR_FATAL;
6643 }
6644
6645 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006646 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006647 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006648 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006649 else {
6650 if (err)
6651 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6652 args[*cur_arg], args[*cur_arg + 1]);
6653 return ERR_ALERT | ERR_FATAL;
6654 }
6655
Evan Broderbe554312013-06-27 00:05:25 -07006656 return 0;
6657}
6658
6659/* parse the "verifyhost" server keyword */
6660static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6661{
6662 if (!*args[*cur_arg + 1]) {
6663 if (err)
6664 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6665 return ERR_ALERT | ERR_FATAL;
6666 }
6667
6668 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6669
Emeric Brunef42d922012-10-11 16:11:36 +02006670 return 0;
6671}
6672
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006673/* parse the "ssl-default-bind-options" keyword in global section */
6674static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6675 struct proxy *defpx, const char *file, int line,
6676 char **err) {
6677 int i = 1;
6678
6679 if (*(args[i]) == 0) {
6680 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6681 return -1;
6682 }
6683 while (*(args[i])) {
6684 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006685 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006686 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006687 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006688 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006689 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006690 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006691 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006692 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006693 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006694 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006695 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006696 else if (!strcmp(args[i], "force-tlsv11")) {
6697#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006698 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006699#else
6700 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6701 return -1;
6702#endif
6703 }
6704 else if (!strcmp(args[i], "force-tlsv12")) {
6705#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006706 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006707#else
6708 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6709 return -1;
6710#endif
6711 }
6712 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006713 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006714 else {
6715 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6716 return -1;
6717 }
6718 i++;
6719 }
6720 return 0;
6721}
6722
6723/* parse the "ssl-default-server-options" keyword in global section */
6724static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6725 struct proxy *defpx, const char *file, int line,
6726 char **err) {
6727 int i = 1;
6728
6729 if (*(args[i]) == 0) {
6730 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6731 return -1;
6732 }
6733 while (*(args[i])) {
6734 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006735 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006736 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006737 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006738 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006739 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006740 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006741 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006742 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006743 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006744 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006745 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006746 else if (!strcmp(args[i], "force-tlsv11")) {
6747#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006748 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006749#else
6750 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6751 return -1;
6752#endif
6753 }
6754 else if (!strcmp(args[i], "force-tlsv12")) {
6755#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006756 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006757#else
6758 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6759 return -1;
6760#endif
6761 }
6762 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006763 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006764 else {
6765 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6766 return -1;
6767 }
6768 i++;
6769 }
6770 return 0;
6771}
6772
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006773/* parse the "ca-base" / "crt-base" keywords in global section.
6774 * Returns <0 on alert, >0 on warning, 0 on success.
6775 */
6776static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6777 struct proxy *defpx, const char *file, int line,
6778 char **err)
6779{
6780 char **target;
6781
Willy Tarreauef934602016-12-22 23:12:01 +01006782 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006783
6784 if (too_many_args(1, args, err, NULL))
6785 return -1;
6786
6787 if (*target) {
6788 memprintf(err, "'%s' already specified.", args[0]);
6789 return -1;
6790 }
6791
6792 if (*(args[1]) == 0) {
6793 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6794 return -1;
6795 }
6796 *target = strdup(args[1]);
6797 return 0;
6798}
6799
Willy Tarreauf22e9682016-12-21 23:23:19 +01006800/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6801 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6802 */
6803static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6804 struct proxy *defpx, const char *file, int line,
6805 char **err)
6806{
6807 char **target;
6808
Willy Tarreauef934602016-12-22 23:12:01 +01006809 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006810
6811 if (too_many_args(1, args, err, NULL))
6812 return -1;
6813
6814 if (*(args[1]) == 0) {
6815 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6816 return -1;
6817 }
6818
6819 free(*target);
6820 *target = strdup(args[1]);
6821 return 0;
6822}
6823
Willy Tarreau9ceda382016-12-21 23:13:03 +01006824/* parse various global tune.ssl settings consisting in positive integers.
6825 * Returns <0 on alert, >0 on warning, 0 on success.
6826 */
6827static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6828 struct proxy *defpx, const char *file, int line,
6829 char **err)
6830{
6831 int *target;
6832
6833 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6834 target = &global.tune.sslcachesize;
6835 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006836 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006837 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006838 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006839 else if (strcmp(args[0], "maxsslconn") == 0)
6840 target = &global.maxsslconn;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006841 else if (strcmp(args[0], "tune.ssl.capture-cipherlist-size") == 0)
6842 target = &global_ssl.capture_cipherlist;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006843 else {
6844 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6845 return -1;
6846 }
6847
6848 if (too_many_args(1, args, err, NULL))
6849 return -1;
6850
6851 if (*(args[1]) == 0) {
6852 memprintf(err, "'%s' expects an integer argument.", args[0]);
6853 return -1;
6854 }
6855
6856 *target = atoi(args[1]);
6857 if (*target < 0) {
6858 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6859 return -1;
6860 }
6861 return 0;
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006862}
6863
6864static int ssl_parse_global_capture_cipherlist(char **args, int section_type, struct proxy *curpx,
6865 struct proxy *defpx, const char *file, int line,
6866 char **err)
6867{
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01006868 int ret;
6869
6870 ret = ssl_parse_global_int(args, section_type, curpx, defpx, file, line, err);
6871 if (ret != 0)
6872 return ret;
6873
6874 if (pool2_ssl_capture) {
6875 memprintf(err, "'%s' is already configured.", args[0]);
6876 return -1;
6877 }
6878
6879 pool2_ssl_capture = create_pool("ssl-capture", sizeof(struct ssl_capture) + global_ssl.capture_cipherlist, MEM_F_SHARED);
6880 if (!pool2_ssl_capture) {
6881 memprintf(err, "Out of memory error.");
6882 return -1;
6883 }
6884 return 0;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006885}
6886
6887/* parse "ssl.force-private-cache".
6888 * Returns <0 on alert, >0 on warning, 0 on success.
6889 */
6890static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6891 struct proxy *defpx, const char *file, int line,
6892 char **err)
6893{
6894 if (too_many_args(0, args, err, NULL))
6895 return -1;
6896
Willy Tarreauef934602016-12-22 23:12:01 +01006897 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006898 return 0;
6899}
6900
6901/* parse "ssl.lifetime".
6902 * Returns <0 on alert, >0 on warning, 0 on success.
6903 */
6904static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6905 struct proxy *defpx, const char *file, int line,
6906 char **err)
6907{
6908 const char *res;
6909
6910 if (too_many_args(1, args, err, NULL))
6911 return -1;
6912
6913 if (*(args[1]) == 0) {
6914 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6915 return -1;
6916 }
6917
Willy Tarreauef934602016-12-22 23:12:01 +01006918 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006919 if (res) {
6920 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6921 return -1;
6922 }
6923 return 0;
6924}
6925
6926#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006927/* parse "ssl-dh-param-file".
6928 * Returns <0 on alert, >0 on warning, 0 on success.
6929 */
6930static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6931 struct proxy *defpx, const char *file, int line,
6932 char **err)
6933{
6934 if (too_many_args(1, args, err, NULL))
6935 return -1;
6936
6937 if (*(args[1]) == 0) {
6938 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6939 return -1;
6940 }
6941
6942 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6943 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6944 return -1;
6945 }
6946 return 0;
6947}
6948
Willy Tarreau9ceda382016-12-21 23:13:03 +01006949/* parse "ssl.default-dh-param".
6950 * Returns <0 on alert, >0 on warning, 0 on success.
6951 */
6952static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6953 struct proxy *defpx, const char *file, int line,
6954 char **err)
6955{
6956 if (too_many_args(1, args, err, NULL))
6957 return -1;
6958
6959 if (*(args[1]) == 0) {
6960 memprintf(err, "'%s' expects an integer argument.", args[0]);
6961 return -1;
6962 }
6963
Willy Tarreauef934602016-12-22 23:12:01 +01006964 global_ssl.default_dh_param = atoi(args[1]);
6965 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006966 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6967 return -1;
6968 }
6969 return 0;
6970}
6971#endif
6972
6973
William Lallemand32af2032016-10-29 18:09:35 +02006974/* This function is used with TLS ticket keys management. It permits to browse
6975 * each reference. The variable <getnext> must contain the current node,
6976 * <end> point to the root node.
6977 */
6978#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6979static inline
6980struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6981{
6982 struct tls_keys_ref *ref = getnext;
6983
6984 while (1) {
6985
6986 /* Get next list entry. */
6987 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6988
6989 /* If the entry is the last of the list, return NULL. */
6990 if (&ref->list == end)
6991 return NULL;
6992
6993 return ref;
6994 }
6995}
6996
6997static inline
6998struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6999{
7000 int id;
7001 char *error;
7002
7003 /* If the reference starts by a '#', this is numeric id. */
7004 if (reference[0] == '#') {
7005 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
7006 id = strtol(reference + 1, &error, 10);
7007 if (*error != '\0')
7008 return NULL;
7009
7010 /* Perform the unique id lookup. */
7011 return tlskeys_ref_lookupid(id);
7012 }
7013
7014 /* Perform the string lookup. */
7015 return tlskeys_ref_lookup(reference);
7016}
7017#endif
7018
7019
7020#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7021
7022static int cli_io_handler_tlskeys_files(struct appctx *appctx);
7023
7024static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
7025 return cli_io_handler_tlskeys_files(appctx);
7026}
7027
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007028/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
7029 * (next index to be dumped), and cli.p0 (next key reference).
7030 */
William Lallemand32af2032016-10-29 18:09:35 +02007031static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
7032
7033 struct stream_interface *si = appctx->owner;
7034
7035 switch (appctx->st2) {
7036 case STAT_ST_INIT:
7037 /* Display the column headers. If the message cannot be sent,
7038 * quit the fucntion with returning 0. The function is called
7039 * later and restart at the state "STAT_ST_INIT".
7040 */
7041 chunk_reset(&trash);
7042
7043 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
7044 chunk_appendf(&trash, "# id secret\n");
7045 else
7046 chunk_appendf(&trash, "# id (file)\n");
7047
7048 if (bi_putchk(si_ic(si), &trash) == -1) {
7049 si_applet_cant_put(si);
7050 return 0;
7051 }
7052
William Lallemand32af2032016-10-29 18:09:35 +02007053 /* Now, we start the browsing of the references lists.
7054 * Note that the following call to LIST_ELEM return bad pointer. The only
7055 * available field of this pointer is <list>. It is used with the function
7056 * tlskeys_list_get_next() for retruning the first available entry
7057 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007058 if (appctx->ctx.cli.p0 == NULL) {
7059 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
7060 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007061 }
7062
7063 appctx->st2 = STAT_ST_LIST;
7064 /* fall through */
7065
7066 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007067 while (appctx->ctx.cli.p0) {
7068 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
7069 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02007070
7071 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007072 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02007073 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007074
7075 if (appctx->ctx.cli.i1 == 0)
7076 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
7077
William Lallemand32af2032016-10-29 18:09:35 +02007078 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007079 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02007080 struct chunk *t2 = get_trash_chunk();
7081
7082 chunk_reset(t2);
7083 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007084 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02007085 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007086 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02007087
7088 if (bi_putchk(si_ic(si), &trash) == -1) {
7089 /* let's try again later from this stream. We add ourselves into
7090 * this stream's users so that it can remove us upon termination.
7091 */
7092 si_applet_cant_put(si);
7093 return 0;
7094 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007095 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02007096 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007097 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02007098 }
7099 if (bi_putchk(si_ic(si), &trash) == -1) {
7100 /* let's try again later from this stream. We add ourselves into
7101 * this stream's users so that it can remove us upon termination.
7102 */
7103 si_applet_cant_put(si);
7104 return 0;
7105 }
7106
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007107 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02007108 break;
7109
7110 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007111 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02007112 }
7113
7114 appctx->st2 = STAT_ST_FIN;
7115 /* fall through */
7116
7117 default:
7118 appctx->st2 = STAT_ST_FIN;
7119 return 1;
7120 }
7121 return 0;
7122}
7123
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007124/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02007125static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
7126{
William Lallemand32af2032016-10-29 18:09:35 +02007127 /* no parameter, shows only file list */
7128 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007129 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007130 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007131 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007132 }
7133
7134 if (args[2][0] == '*') {
7135 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007136 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02007137 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007138 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
7139 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02007140 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007141 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007142 return 1;
7143 }
7144 }
William Lallemand32af2032016-10-29 18:09:35 +02007145 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01007146 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02007147}
7148
William Lallemand32af2032016-10-29 18:09:35 +02007149static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
7150{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007151 struct tls_keys_ref *ref;
7152
William Lallemand32af2032016-10-29 18:09:35 +02007153 /* Expect two parameters: the filename and the new new TLS key in encoding */
7154 if (!*args[3] || !*args[4]) {
7155 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 +01007156 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007157 return 1;
7158 }
7159
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007160 ref = tlskeys_ref_lookup_ref(args[3]);
7161 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02007162 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007163 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007164 return 1;
7165 }
7166
7167 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
7168 if (trash.len != sizeof(struct tls_sess_key)) {
7169 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007170 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007171 return 1;
7172 }
7173
Willy Tarreauf5f26e82016-12-16 18:47:27 +01007174 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
7175 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02007176
7177 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007178 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007179 return 1;
7180
7181}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007182#endif
William Lallemand32af2032016-10-29 18:09:35 +02007183
7184static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
7185{
7186#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
7187 char *err = NULL;
7188
7189 /* Expect one parameter: the new response in base64 encoding */
7190 if (!*args[3]) {
7191 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007192 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007193 return 1;
7194 }
7195
7196 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
7197 if (trash.len < 0) {
7198 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007199 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007200 return 1;
7201 }
7202
7203 if (ssl_sock_update_ocsp_response(&trash, &err)) {
7204 if (err) {
7205 memprintf(&err, "%s.\n", err);
7206 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007207 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02007208 }
7209 return 1;
7210 }
7211 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01007212 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007213 return 1;
7214#else
7215 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 +01007216 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02007217 return 1;
7218#endif
7219
7220}
7221
7222/* register cli keywords */
7223static struct cli_kw_list cli_kws = {{ },{
7224#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7225 { { "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 },
7226 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007227#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007228 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007229 { { NULL }, NULL, NULL, NULL }
7230}};
7231
7232
Willy Tarreau7875d092012-09-10 08:20:03 +02007233/* Note: must not be declared <const> as its list will be overwritten.
7234 * Please take care of keeping this list alphabetically sorted.
7235 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007236static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007237 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007238 { "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 +02007239 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7240 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007241 { "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 +02007242 { "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 +02007243 { "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 +02007244 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7245 { "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 +01007246 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007247 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007248 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7249 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7250 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7251 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7252 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7253 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7254 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7255 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007256 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007257 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7258 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007259 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007260 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7261 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7262 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7263 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7264 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7265 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7266 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007267 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007268 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007269 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007270 { "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 +01007271 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007272 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7273 { "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 +02007274 { "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 +02007275#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007276 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007277#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007278#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007279 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007280#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007281 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007282 { "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 +02007283 { "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 +01007284 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7285 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007286 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7287 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7288 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7289 { "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 +02007290 { NULL, NULL, 0, 0, 0 },
7291}};
7292
7293/* Note: must not be declared <const> as its list will be overwritten.
7294 * Please take care of keeping this list alphabetically sorted.
7295 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007296static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007297 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7298 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007299 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007300}};
7301
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007302/* Note: must not be declared <const> as its list will be overwritten.
7303 * Please take care of keeping this list alphabetically sorted, doing so helps
7304 * all code contributors.
7305 * Optional keywords are also declared with a NULL ->parse() function so that
7306 * the config parser can report an appropriate error when a known keyword was
7307 * not enabled.
7308 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007309static struct ssl_bind_kw ssl_bind_kws[] = {
7310 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7311 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7312 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7313 { "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 +01007314 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007315 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007316 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7317 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7318 { NULL, NULL, 0 },
7319};
7320
Willy Tarreau51fb7652012-09-18 18:24:39 +02007321static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007322 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7323 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7324 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007325 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7326 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007327 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7328 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7329 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7330 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7331 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01007332 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007333 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7334 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
7335 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
7336 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
7337 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007338 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007339 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
7340 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
7341 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
7342 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
7343 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7344 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
7345 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7346 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7347 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7348 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007349 { NULL, NULL, 0 },
7350}};
Emeric Brun46591952012-05-18 15:47:34 +02007351
Willy Tarreau92faadf2012-10-10 23:04:25 +02007352/* Note: must not be declared <const> as its list will be overwritten.
7353 * Please take care of keeping this list alphabetically sorted, doing so helps
7354 * all code contributors.
7355 * Optional keywords are also declared with a NULL ->parse() function so that
7356 * the config parser can report an appropriate error when a known keyword was
7357 * not enabled.
7358 */
7359static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02007360 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007361 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
7362 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02007363 { "crl-file", srv_parse_crl_file, 1, 0 }, /* set certificate revocation list file use on server cert verify */
Emeric Bruna7aa3092012-10-26 12:58:00 +02007364 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007365 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
7366 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
7367 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
7368 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007369 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007370 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
7371 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
7372 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
7373 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02007374 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04007375 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
7376 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
Willy Tarreau732eac42015-07-09 11:40:25 +02007377 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007378 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02007379 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07007380 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007381 { NULL, NULL, 0, 0 },
7382}};
7383
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007384static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007385 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7386 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007387 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007388 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7389 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007390#ifndef OPENSSL_NO_DH
7391 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7392#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007393 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7394#ifndef OPENSSL_NO_DH
7395 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7396#endif
7397 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7398 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7399 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7400 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Thierry FOURNIER5bf77322017-02-25 12:45:22 +01007401 { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_cipherlist },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007402 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7403 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007404 { 0, NULL, NULL },
7405}};
7406
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007407/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007408static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007409 .snd_buf = ssl_sock_from_buf,
7410 .rcv_buf = ssl_sock_to_buf,
7411 .rcv_pipe = NULL,
7412 .snd_pipe = NULL,
7413 .shutr = NULL,
7414 .shutw = ssl_sock_shutw,
7415 .close = ssl_sock_close,
7416 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007417 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007418 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007419 .prepare_srv = ssl_sock_prepare_srv_ctx,
7420 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007421 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007422};
7423
Daniel Jakots54ffb912015-11-06 20:02:41 +01007424#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007425
7426static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7427{
7428 if (ptr) {
7429 chunk_destroy(ptr);
7430 free(ptr);
7431 }
7432}
7433
7434#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007435static void ssl_sock_capture_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7436{
7437 pool_free2(pool2_ssl_capture, ptr);
7438}
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007439
Emeric Brun46591952012-05-18 15:47:34 +02007440__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007441static void __ssl_sock_init(void)
7442{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007443 char *ptr;
7444
Emeric Brun46591952012-05-18 15:47:34 +02007445 STACK_OF(SSL_COMP)* cm;
7446
Willy Tarreauef934602016-12-22 23:12:01 +01007447 if (global_ssl.listen_default_ciphers)
7448 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7449 if (global_ssl.connect_default_ciphers)
7450 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007451
Willy Tarreau13e14102016-12-22 20:25:26 +01007452 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007453 SSL_library_init();
7454 cm = SSL_COMP_get_compression_methods();
7455 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007456#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007457 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7458#endif
Emmanuel Hocdetaaee7502017-03-07 18:34:58 +01007459 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 +02007460 sample_register_fetches(&sample_fetch_keywords);
7461 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007462 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007463 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007464 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007465 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007466#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7467 hap_register_post_check(tlskeys_finalize_config);
7468#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007469
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007470 ptr = NULL;
7471 memprintf(&ptr, "Built with OpenSSL version : "
7472#ifdef OPENSSL_IS_BORINGSSL
7473 "BoringSSL\n");
7474#else /* OPENSSL_IS_BORINGSSL */
7475 OPENSSL_VERSION_TEXT
7476 "\nRunning on OpenSSL version : %s%s",
7477 SSLeay_version(SSLEAY_VERSION),
7478 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7479#endif
7480 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7481#if OPENSSL_VERSION_NUMBER < 0x00907000L
7482 "no (library version too old)"
7483#elif defined(OPENSSL_NO_TLSEXT)
7484 "no (disabled via OPENSSL_NO_TLSEXT)"
7485#else
7486 "yes"
7487#endif
7488 "", ptr);
7489
7490 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7491#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7492 "yes"
7493#else
7494#ifdef OPENSSL_NO_TLSEXT
7495 "no (because of OPENSSL_NO_TLSEXT)"
7496#else
7497 "no (version might be too old, 0.9.8f min needed)"
7498#endif
7499#endif
7500 "", ptr);
7501
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007502 hap_register_build_opts(ptr, 1);
7503
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007504 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7505 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007506
7507#ifndef OPENSSL_NO_DH
7508 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7509#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007510
7511 /* Load SSL string for the verbose & debug mode. */
7512 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007513}
7514
Remi Gacogned3a23c32015-05-28 16:39:47 +02007515__attribute__((destructor))
7516static void __ssl_sock_deinit(void)
7517{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007518#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007519 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007520#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007521
Remi Gacogned3a23c32015-05-28 16:39:47 +02007522#ifndef OPENSSL_NO_DH
7523 if (local_dh_1024) {
7524 DH_free(local_dh_1024);
7525 local_dh_1024 = NULL;
7526 }
7527
7528 if (local_dh_2048) {
7529 DH_free(local_dh_2048);
7530 local_dh_2048 = NULL;
7531 }
7532
7533 if (local_dh_4096) {
7534 DH_free(local_dh_4096);
7535 local_dh_4096 = NULL;
7536 }
7537
Remi Gacogne47783ef2015-05-29 15:53:22 +02007538 if (global_dh) {
7539 DH_free(global_dh);
7540 global_dh = NULL;
7541 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007542#endif
7543
7544 ERR_remove_state(0);
7545 ERR_free_strings();
7546
7547 EVP_cleanup();
7548
7549#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7550 CRYPTO_cleanup_all_ex_data();
7551#endif
7552}
7553
7554
Emeric Brun46591952012-05-18 15:47:34 +02007555/*
7556 * Local variables:
7557 * c-indent-level: 8
7558 * c-basic-offset: 8
7559 * End:
7560 */